Skip to content

Commit 88af31d

Browse files
committed
Have Node take a genric KVStore parameter
Previously, we had `Node` take a concrete `FilesystemStore` struct. Here we switch to a generic `KVStore` type parameter. To this end we switched from `K: Deref` to concrete `Arc<K>` in all of the modules to avoid confusion of the type paramters or requirements to track `Arc`-ed and non-`Arc`ed version of the `K: KVStore` paramter. Moreover, as Uniffi doesn't support exposing generics we now expose a concretized `LDKNode` type alias in bindings, which will use `SqliteStore` in the future. Note that going the generic route was necessary as `dyn KVStore` wasn't an opion due to the incompatibility of `dyn` with associated types. In this case the incompatibility is in regard to `KVStore::Reader` and I opted to go this route over forcing any implementation of the trait to allocating and returning the same concrete value (e.g., `Vec<u8>`) which could potentially have significant performance impacts over returning a buffered reader for example.
1 parent b324166 commit 88af31d

File tree

9 files changed

+85
-88
lines changed

9 files changed

+85
-88
lines changed

bindings/ldk_node.udl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ interface Builder {
1313
constructor();
1414
[Name=from_config]
1515
constructor(Config config);
16-
Node build();
16+
LDKNode build();
1717
};
1818

19-
interface Node {
19+
interface LDKNode {
2020
[Throws=NodeError]
2121
void start();
2222
[Throws=NodeError]

src/event.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,23 +106,21 @@ impl_writeable_tlv_based_enum!(Event,
106106
};
107107
);
108108

109-
pub struct EventQueue<K: Deref, L: Deref>
109+
pub struct EventQueue<K: KVStore + Sync + Send, L: Deref>
110110
where
111-
K::Target: KVStore,
112111
L::Target: Logger,
113112
{
114113
queue: Mutex<VecDeque<Event>>,
115114
notifier: Condvar,
116-
kv_store: K,
115+
kv_store: Arc<K>,
117116
logger: L,
118117
}
119118

120-
impl<K: Deref, L: Deref> EventQueue<K, L>
119+
impl<K: KVStore + Sync + Send, L: Deref> EventQueue<K, L>
121120
where
122-
K::Target: KVStore,
123121
L::Target: Logger,
124122
{
125-
pub(crate) fn new(kv_store: K, logger: L) -> Self {
123+
pub(crate) fn new(kv_store: Arc<K>, logger: L) -> Self {
126124
let queue: Mutex<VecDeque<Event>> = Mutex::new(VecDeque::new());
127125
let notifier = Condvar::new();
128126
Self { queue, notifier, kv_store, logger }
@@ -178,14 +176,13 @@ where
178176
}
179177
}
180178

181-
impl<K: Deref, L: Deref> ReadableArgs<(K, L)> for EventQueue<K, L>
179+
impl<K: KVStore + Sync + Send, L: Deref> ReadableArgs<(Arc<K>, L)> for EventQueue<K, L>
182180
where
183-
K::Target: KVStore,
184181
L::Target: Logger,
185182
{
186183
#[inline]
187184
fn read<R: lightning::io::Read>(
188-
reader: &mut R, args: (K, L),
185+
reader: &mut R, args: (Arc<K>, L),
189186
) -> Result<Self, lightning::ln::msgs::DecodeError> {
190187
let (kv_store, logger) = args;
191188
let read_queue: EventQueueDeserWrapper = Readable::read(reader)?;
@@ -222,14 +219,13 @@ impl Writeable for EventQueueSerWrapper<'_> {
222219
}
223220
}
224221

225-
pub(crate) struct EventHandler<K: Deref + Clone, L: Deref>
222+
pub(crate) struct EventHandler<K: KVStore + Sync + Send, L: Deref>
226223
where
227-
K::Target: KVStore,
228224
L::Target: Logger,
229225
{
230226
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>,
231227
event_queue: Arc<EventQueue<K, L>>,
232-
channel_manager: Arc<ChannelManager>,
228+
channel_manager: Arc<ChannelManager<K>>,
233229
network_graph: Arc<NetworkGraph>,
234230
keys_manager: Arc<KeysManager>,
235231
payment_store: Arc<PaymentStore<K, L>>,
@@ -238,14 +234,13 @@ where
238234
_config: Arc<Config>,
239235
}
240236

241-
impl<K: Deref + Clone, L: Deref> EventHandler<K, L>
237+
impl<K: KVStore + Sync + Send + 'static, L: Deref> EventHandler<K, L>
242238
where
243-
K::Target: KVStore,
244239
L::Target: Logger,
245240
{
246241
pub fn new(
247242
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>, event_queue: Arc<EventQueue<K, L>>,
248-
channel_manager: Arc<ChannelManager>, network_graph: Arc<NetworkGraph>,
243+
channel_manager: Arc<ChannelManager<K>>, network_graph: Arc<NetworkGraph>,
249244
keys_manager: Arc<KeysManager>, payment_store: Arc<PaymentStore<K, L>>,
250245
runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>, logger: L, _config: Arc<Config>,
251246
) -> Self {

src/io/fs_store.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@ fn path_to_windows_str<T: AsRef<OsStr>>(path: T) -> Vec<winapi::shared::ntdef::W
3838
path.as_ref().encode_wide().chain(Some(0)).collect()
3939
}
4040

41+
/// A [`KVStore`] implementation that writes to and reads from the file system.
4142
pub struct FilesystemStore {
4243
dest_dir: PathBuf,
4344
locks: Mutex<HashMap<(String, String), Arc<RwLock<()>>>>,
4445
}
4546

4647
impl FilesystemStore {
47-
pub fn new(dest_dir: PathBuf) -> Self {
48+
pub(crate) fn new(dest_dir: PathBuf) -> Self {
4849
let locks = Mutex::new(HashMap::new());
4950
Self { dest_dir, locks }
5051
}

src/io/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
pub(crate) mod fs_store;
22
pub(crate) mod utils;
33

4+
pub use fs_store::FilesystemStore;
5+
46
use lightning::util::persist::KVStorePersister;
57

68
use std::io::Read;

src/io/utils.rs

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::fs;
2020
use std::io::Write;
2121
use std::ops::Deref;
2222
use std::path::Path;
23+
use std::sync::Arc;
2324

2425
use super::KVStore;
2526

@@ -46,11 +47,10 @@ pub(crate) fn read_or_generate_seed_file(keys_seed_path: &str) -> [u8; WALLET_KE
4647
}
4748

4849
/// Read previously persisted [`ChannelMonitor`]s from the store.
49-
pub(crate) fn read_channel_monitors<K: Deref, ES: Deref, SP: Deref>(
50-
kv_store: K, entropy_source: ES, signer_provider: SP,
50+
pub(crate) fn read_channel_monitors<K: KVStore + Sync + Send, ES: Deref, SP: Deref>(
51+
kv_store: Arc<K>, entropy_source: ES, signer_provider: SP,
5152
) -> std::io::Result<Vec<(BlockHash, ChannelMonitor<<SP::Target as SignerProvider>::Signer>)>>
5253
where
53-
K::Target: KVStore,
5454
ES::Target: EntropySource + Sized,
5555
SP::Target: SignerProvider + Sized,
5656
{
@@ -92,11 +92,10 @@ where
9292
}
9393

9494
/// Read a previously persisted [`NetworkGraph`] from the store.
95-
pub(crate) fn read_network_graph<K: Deref, L: Deref>(
96-
kv_store: K, logger: L,
95+
pub(crate) fn read_network_graph<K: KVStore + Sync + Send, L: Deref>(
96+
kv_store: Arc<K>, logger: L,
9797
) -> Result<NetworkGraph<L>, std::io::Error>
9898
where
99-
K::Target: KVStore,
10099
L::Target: Logger,
101100
{
102101
let mut reader =
@@ -108,11 +107,10 @@ where
108107
}
109108

110109
/// Read a previously persisted [`Scorer`] from the store.
111-
pub(crate) fn read_scorer<K: Deref, G: Deref<Target = NetworkGraph<L>>, L: Deref>(
112-
kv_store: K, network_graph: G, logger: L,
110+
pub(crate) fn read_scorer<K: KVStore + Sync + Send, G: Deref<Target = NetworkGraph<L>>, L: Deref>(
111+
kv_store: Arc<K>, network_graph: G, logger: L,
113112
) -> Result<ProbabilisticScorer<G, L>, std::io::Error>
114113
where
115-
K::Target: KVStore,
116114
L::Target: Logger,
117115
{
118116
let params = ProbabilisticScoringParameters::default();
@@ -125,11 +123,10 @@ where
125123
}
126124

127125
/// Read previously persisted events from the store.
128-
pub(crate) fn read_event_queue<K: Deref, L: Deref>(
129-
kv_store: K, logger: L,
126+
pub(crate) fn read_event_queue<K: KVStore + Sync + Send, L: Deref>(
127+
kv_store: Arc<K>, logger: L,
130128
) -> Result<EventQueue<K, L>, std::io::Error>
131129
where
132-
K::Target: KVStore,
133130
L::Target: Logger,
134131
{
135132
let mut reader =
@@ -141,11 +138,10 @@ where
141138
}
142139

143140
/// Read previously persisted peer info from the store.
144-
pub(crate) fn read_peer_info<K: Deref, L: Deref>(
145-
kv_store: K, logger: L,
141+
pub(crate) fn read_peer_info<K: KVStore + Sync + Send, L: Deref>(
142+
kv_store: Arc<K>, logger: L,
146143
) -> Result<PeerStore<K, L>, std::io::Error>
147144
where
148-
K::Target: KVStore,
149145
L::Target: Logger,
150146
{
151147
let mut reader = kv_store.read(PEER_INFO_PERSISTENCE_NAMESPACE, PEER_INFO_PERSISTENCE_KEY)?;
@@ -156,10 +152,9 @@ where
156152
}
157153

158154
/// Read previously persisted payments information from the store.
159-
pub(crate) fn read_payments<K: Deref>(kv_store: K) -> Result<Vec<PaymentDetails>, std::io::Error>
160-
where
161-
K::Target: KVStore,
162-
{
155+
pub(crate) fn read_payments<K: KVStore + Sync + Send>(
156+
kv_store: Arc<K>,
157+
) -> Result<Vec<PaymentDetails>, std::io::Error> {
163158
let mut res = Vec::new();
164159

165160
for stored_key in kv_store.list(PAYMENT_INFO_PERSISTENCE_NAMESPACE)? {
@@ -174,10 +169,9 @@ where
174169
Ok(res)
175170
}
176171

177-
pub(crate) fn read_latest_rgs_sync_timestamp<K: Deref>(kv_store: K) -> Result<u32, std::io::Error>
178-
where
179-
K::Target: KVStore,
180-
{
172+
pub(crate) fn read_latest_rgs_sync_timestamp<K: KVStore + Sync + Send>(
173+
kv_store: Arc<K>,
174+
) -> Result<u32, std::io::Error> {
181175
let mut reader =
182176
kv_store.read(LATEST_RGS_SYNC_TIMESTAMP_NAMESPACE, LATEST_RGS_SYNC_TIMESTAMP_KEY)?;
183177
u32::read(&mut reader).map_err(|_| {
@@ -188,11 +182,10 @@ where
188182
})
189183
}
190184

191-
pub(crate) fn write_latest_rgs_sync_timestamp<K: Deref, L: Deref>(
192-
updated_timestamp: u32, kv_store: K, logger: L,
185+
pub(crate) fn write_latest_rgs_sync_timestamp<K: KVStore + Sync + Send, L: Deref>(
186+
updated_timestamp: u32, kv_store: Arc<K>, logger: L,
193187
) -> Result<(), Error>
194188
where
195-
K::Target: KVStore,
196189
L::Target: Logger,
197190
{
198191
let data = updated_timestamp.encode();

src/lib.rs

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ mod error;
7878
mod event;
7979
mod gossip;
8080
mod hex_utils;
81-
mod io;
81+
pub mod io;
8282
mod logger;
8383
mod payment_store;
8484
mod peer_store;
@@ -317,8 +317,18 @@ impl Builder {
317317
self
318318
}
319319

320+
/// Builds a [`Node`] instance with a [`FilesystemStore`] backend and according to the options
321+
/// previously configured.
322+
pub fn build(&self) -> Arc<Node<FilesystemStore>> {
323+
let ldk_data_dir = format!("{}/ldk", self.config.storage_dir_path);
324+
let kv_store = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
325+
self.build_with_store(kv_store)
326+
}
327+
320328
/// Builds a [`Node`] instance according to the options previously configured.
321-
pub fn build(&self) -> Arc<Node> {
329+
pub fn build_with_store<K: KVStore + Sync + Send + 'static>(
330+
&self, kv_store: Arc<K>,
331+
) -> Arc<Node<K>> {
322332
let config = Arc::new(self.config.clone());
323333

324334
let ldk_data_dir = format!("{}/ldk", config.storage_dir_path);
@@ -389,10 +399,8 @@ impl Builder {
389399
Arc::clone(&logger),
390400
));
391401

392-
let kv_store = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
393-
394402
// Initialize the ChainMonitor
395-
let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
403+
let chain_monitor: Arc<ChainMonitor<K>> = Arc::new(chainmonitor::ChainMonitor::new(
396404
Some(Arc::clone(&tx_sync)),
397405
Arc::clone(&wallet),
398406
Arc::clone(&logger),
@@ -489,7 +497,7 @@ impl Builder {
489497
channel_monitor_references,
490498
);
491499
let (_hash, channel_manager) =
492-
<(BlockHash, ChannelManager)>::read(&mut reader, read_args)
500+
<(BlockHash, ChannelManager<K>)>::read(&mut reader, read_args)
493501
.expect("Failed to read channel manager from store");
494502
channel_manager
495503
} else {
@@ -659,31 +667,35 @@ impl Builder {
659667
}
660668
}
661669

670+
/// This type alias is required as Uniffi doesn't support generics, i.e., we can only expose the
671+
/// concretized types via this aliasing hack.
672+
type LDKNode = Node<FilesystemStore>;
673+
662674
/// The main interface object of LDK Node, wrapping the necessary LDK and BDK functionalities.
663675
///
664676
/// Needs to be initialized and instantiated through [`Builder::build`].
665-
pub struct Node {
677+
pub struct Node<K: KVStore + Sync + Send + 'static> {
666678
runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>,
667679
stop_sender: tokio::sync::watch::Sender<()>,
668680
stop_receiver: tokio::sync::watch::Receiver<()>,
669681
config: Arc<Config>,
670682
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>,
671683
tx_sync: Arc<EsploraSyncClient<Arc<FilesystemLogger>>>,
672-
event_queue: Arc<EventQueue<Arc<FilesystemStore>, Arc<FilesystemLogger>>>,
673-
channel_manager: Arc<ChannelManager>,
674-
chain_monitor: Arc<ChainMonitor>,
675-
peer_manager: Arc<PeerManager>,
684+
event_queue: Arc<EventQueue<K, Arc<FilesystemLogger>>>,
685+
channel_manager: Arc<ChannelManager<K>>,
686+
chain_monitor: Arc<ChainMonitor<K>>,
687+
peer_manager: Arc<PeerManager<K>>,
676688
keys_manager: Arc<KeysManager>,
677689
network_graph: Arc<NetworkGraph>,
678690
gossip_source: Arc<GossipSource>,
679-
kv_store: Arc<FilesystemStore>,
691+
kv_store: Arc<K>,
680692
logger: Arc<FilesystemLogger>,
681693
scorer: Arc<Mutex<Scorer>>,
682-
peer_store: Arc<PeerStore<Arc<FilesystemStore>, Arc<FilesystemLogger>>>,
683-
payment_store: Arc<PaymentStore<Arc<FilesystemStore>, Arc<FilesystemLogger>>>,
694+
peer_store: Arc<PeerStore<K, Arc<FilesystemLogger>>>,
695+
payment_store: Arc<PaymentStore<K, Arc<FilesystemLogger>>>,
684696
}
685697

686-
impl Node {
698+
impl<K: KVStore + Sync + Send + 'static> Node<K> {
687699
/// Starts the necessary background tasks, such as handling events coming from user input,
688700
/// LDK/BDK, and the peer-to-peer network.
689701
///
@@ -1624,14 +1636,14 @@ impl Node {
16241636
}
16251637
}
16261638

1627-
impl Drop for Node {
1639+
impl<K: KVStore + Sync + Send + 'static> Drop for Node<K> {
16281640
fn drop(&mut self) {
16291641
let _ = self.stop();
16301642
}
16311643
}
16321644

1633-
async fn connect_peer_if_necessary(
1634-
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
1645+
async fn connect_peer_if_necessary<K: KVStore + Sync + Send + 'static + 'static>(
1646+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager<K>>,
16351647
logger: Arc<FilesystemLogger>,
16361648
) -> Result<(), Error> {
16371649
for (pman_node_id, _pman_addr) in peer_manager.get_peer_node_ids() {
@@ -1643,8 +1655,8 @@ async fn connect_peer_if_necessary(
16431655
do_connect_peer(node_id, addr, peer_manager, logger).await
16441656
}
16451657

1646-
async fn do_connect_peer(
1647-
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
1658+
async fn do_connect_peer<K: KVStore + Sync + Send + 'static + 'static>(
1659+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager<K>>,
16481660
logger: Arc<FilesystemLogger>,
16491661
) -> Result<(), Error> {
16501662
log_info!(logger, "Connecting to peer: {}@{}", node_id, addr);

src/payment_store.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use lightning::{impl_writeable_tlv_based, impl_writeable_tlv_based_enum};
1010
use std::collections::HashMap;
1111
use std::iter::FromIterator;
1212
use std::ops::Deref;
13-
use std::sync::Mutex;
13+
use std::sync::{Arc, Mutex};
1414

1515
/// Represents a payment.
1616
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -92,22 +92,20 @@ impl PaymentDetailsUpdate {
9292
}
9393
}
9494

95-
pub(crate) struct PaymentStore<K: Deref + Clone, L: Deref>
95+
pub(crate) struct PaymentStore<K: KVStore + Sync + Send, L: Deref>
9696
where
97-
K::Target: KVStore,
9897
L::Target: Logger,
9998
{
10099
payments: Mutex<HashMap<PaymentHash, PaymentDetails>>,
101-
kv_store: K,
100+
kv_store: Arc<K>,
102101
logger: L,
103102
}
104103

105-
impl<K: Deref + Clone, L: Deref> PaymentStore<K, L>
104+
impl<K: KVStore + Sync + Send, L: Deref> PaymentStore<K, L>
106105
where
107-
K::Target: KVStore,
108106
L::Target: Logger,
109107
{
110-
pub(crate) fn new(payments: Vec<PaymentDetails>, kv_store: K, logger: L) -> Self {
108+
pub(crate) fn new(payments: Vec<PaymentDetails>, kv_store: Arc<K>, logger: L) -> Self {
111109
let payments = Mutex::new(HashMap::from_iter(
112110
payments.into_iter().map(|payment| (payment.hash, payment)),
113111
));

0 commit comments

Comments
 (0)