Skip to content

Commit 62ae88e

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 6e91e29 commit 62ae88e

File tree

9 files changed

+96
-98
lines changed

9 files changed

+96
-98
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 }
@@ -173,14 +171,13 @@ where
173171
}
174172
}
175173

176-
impl<K: Deref, L: Deref> ReadableArgs<(K, L)> for EventQueue<K, L>
174+
impl<K: KVStore + Sync + Send, L: Deref> ReadableArgs<(Arc<K>, L)> for EventQueue<K, L>
177175
where
178-
K::Target: KVStore,
179176
L::Target: Logger,
180177
{
181178
#[inline]
182179
fn read<R: lightning::io::Read>(
183-
reader: &mut R, args: (K, L),
180+
reader: &mut R, args: (Arc<K>, L),
184181
) -> Result<Self, lightning::ln::msgs::DecodeError> {
185182
let (kv_store, logger) = args;
186183
let read_queue: EventQueueDeserWrapper = Readable::read(reader)?;
@@ -217,14 +214,13 @@ impl Writeable for EventQueueSerWrapper<'_> {
217214
}
218215
}
219216

220-
pub(crate) struct EventHandler<K: Deref + Clone, L: Deref>
217+
pub(crate) struct EventHandler<K: KVStore + Sync + Send, L: Deref>
221218
where
222-
K::Target: KVStore,
223219
L::Target: Logger,
224220
{
225221
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>,
226222
event_queue: Arc<EventQueue<K, L>>,
227-
channel_manager: Arc<ChannelManager>,
223+
channel_manager: Arc<ChannelManager<K>>,
228224
network_graph: Arc<NetworkGraph>,
229225
keys_manager: Arc<KeysManager>,
230226
payment_store: Arc<PaymentStore<K, L>>,
@@ -233,14 +229,13 @@ where
233229
_config: Arc<Config>,
234230
}
235231

236-
impl<K: Deref + Clone, L: Deref> EventHandler<K, L>
232+
impl<K: KVStore + Sync + Send + 'static, L: Deref> EventHandler<K, L>
237233
where
238-
K::Target: KVStore,
239234
L::Target: Logger,
240235
{
241236
pub fn new(
242237
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>, event_queue: Arc<EventQueue<K, L>>,
243-
channel_manager: Arc<ChannelManager>, network_graph: Arc<NetworkGraph>,
238+
channel_manager: Arc<ChannelManager<K>>, network_graph: Arc<NetworkGraph>,
244239
keys_manager: Arc<KeysManager>, payment_store: Arc<PaymentStore<K, L>>,
245240
runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>, logger: L, _config: Arc<Config>,
246241
) -> 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: 30 additions & 36 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_rgs_latest_sync_timestamp<K: Deref>(kv_store: K) -> Result<u32, std::io::Error>
178-
where
179-
K::Target: KVStore,
180-
{
172+
pub(crate) fn read_rgs_latest_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(RGS_LATEST_SYNC_TIMESTAMP_NAMESPACE, RGS_LATEST_SYNC_TIMESTAMP_KEY)?;
183177
u32::read(&mut reader).map_err(|_| {
@@ -188,24 +182,24 @@ where
188182
})
189183
}
190184

191-
pub(crate) fn write_rgs_latest_sync_timestamp<K: Deref, L: Deref>(
192-
updated_timestamp: u32, kv_store: K, logger: L,
185+
pub(crate) fn write_rgs_latest_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();
199-
kv_store.write(RGS_LATEST_SYNC_TIMESTAMP_NAMESPACE, RGS_LATEST_SYNC_TIMESTAMP_KEY, &data)
192+
kv_store
193+
.write(RGS_LATEST_SYNC_TIMESTAMP_NAMESPACE, RGS_LATEST_SYNC_TIMESTAMP_KEY, &data)
200194
.map_err(|e| {
201-
log_error!(
202-
logger,
203-
"Writing data to key {}/{} failed due to: {}",
204-
RGS_LATEST_SYNC_TIMESTAMP_NAMESPACE,
205-
RGS_LATEST_SYNC_TIMESTAMP_KEY,
206-
e
207-
);
208-
Error::PersistenceFailed
209-
})?;
195+
log_error!(
196+
logger,
197+
"Writing data to key {}/{} failed due to: {}",
198+
RGS_LATEST_SYNC_TIMESTAMP_NAMESPACE,
199+
RGS_LATEST_SYNC_TIMESTAMP_KEY,
200+
e
201+
);
202+
Error::PersistenceFailed
203+
})?;
210204
Ok(())
211205
}

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;
@@ -312,8 +312,18 @@ impl Builder {
312312
self
313313
}
314314

315+
/// Builds a [`Node`] instance with a [`FilesystemStore`] backend and according to the options
316+
/// previously configured.
317+
pub fn build(&self) -> Arc<Node<FilesystemStore>> {
318+
let ldk_data_dir = format!("{}/ldk", self.config.storage_dir_path);
319+
let kv_store = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
320+
self.build_with_store(kv_store)
321+
}
322+
315323
/// Builds a [`Node`] instance according to the options previously configured.
316-
pub fn build(&self) -> Arc<Node> {
324+
pub fn build_with_store<K: KVStore + Sync + Send + 'static>(
325+
&self, kv_store: Arc<K>,
326+
) -> Arc<Node<K>> {
317327
let config = Arc::new(self.config.clone());
318328

319329
let ldk_data_dir = format!("{}/ldk", config.storage_dir_path);
@@ -384,10 +394,8 @@ impl Builder {
384394
Arc::clone(&logger),
385395
));
386396

387-
let kv_store = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
388-
389397
// Initialize the ChainMonitor
390-
let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
398+
let chain_monitor: Arc<ChainMonitor<K>> = Arc::new(chainmonitor::ChainMonitor::new(
391399
Some(Arc::clone(&tx_sync)),
392400
Arc::clone(&wallet),
393401
Arc::clone(&logger),
@@ -484,7 +492,7 @@ impl Builder {
484492
channel_monitor_references,
485493
);
486494
let (_hash, channel_manager) =
487-
<(BlockHash, ChannelManager)>::read(&mut reader, read_args)
495+
<(BlockHash, ChannelManager<K>)>::read(&mut reader, read_args)
488496
.expect("Failed to read channel manager from store");
489497
channel_manager
490498
} else {
@@ -653,30 +661,34 @@ impl Builder {
653661
}
654662
}
655663

664+
/// This type alias is required as Uniffi doesn't support generics, i.e., we can only expose the
665+
/// concretized types via this aliasing hack.
666+
type LDKNode = Node<FilesystemStore>;
667+
656668
/// The main interface object of LDK Node, wrapping the necessary LDK and BDK functionalities.
657669
///
658670
/// Needs to be initialized and instantiated through [`Builder::build`].
659-
pub struct Node {
671+
pub struct Node<K: KVStore + Sync + Send + 'static> {
660672
runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>,
661673
stop_running: Arc<AtomicBool>,
662674
config: Arc<Config>,
663675
wallet: Arc<Wallet<bdk::database::SqliteDatabase>>,
664676
tx_sync: Arc<EsploraSyncClient<Arc<FilesystemLogger>>>,
665-
event_queue: Arc<EventQueue<Arc<FilesystemStore>, Arc<FilesystemLogger>>>,
666-
channel_manager: Arc<ChannelManager>,
667-
chain_monitor: Arc<ChainMonitor>,
668-
peer_manager: Arc<PeerManager>,
677+
event_queue: Arc<EventQueue<K, Arc<FilesystemLogger>>>,
678+
channel_manager: Arc<ChannelManager<K>>,
679+
chain_monitor: Arc<ChainMonitor<K>>,
680+
peer_manager: Arc<PeerManager<K>>,
669681
keys_manager: Arc<KeysManager>,
670682
network_graph: Arc<NetworkGraph>,
671683
gossip_source: Arc<GossipSource>,
672-
kv_store: Arc<FilesystemStore>,
684+
kv_store: Arc<K>,
673685
logger: Arc<FilesystemLogger>,
674686
scorer: Arc<Mutex<Scorer>>,
675-
peer_store: Arc<PeerStore<Arc<FilesystemStore>, Arc<FilesystemLogger>>>,
676-
payment_store: Arc<PaymentStore<Arc<FilesystemStore>, Arc<FilesystemLogger>>>,
687+
peer_store: Arc<PeerStore<K, Arc<FilesystemLogger>>>,
688+
payment_store: Arc<PaymentStore<K, Arc<FilesystemLogger>>>,
677689
}
678690

679-
impl Node {
691+
impl<K: KVStore + Sync + Send + 'static> Node<K> {
680692
/// Starts the necessary background tasks, such as handling events coming from user input,
681693
/// LDK/BDK, and the peer-to-peer network.
682694
///
@@ -1558,14 +1570,14 @@ impl Node {
15581570
}
15591571
}
15601572

1561-
impl Drop for Node {
1573+
impl<K: KVStore + Sync + Send + 'static> Drop for Node<K> {
15621574
fn drop(&mut self) {
15631575
let _ = self.stop();
15641576
}
15651577
}
15661578

1567-
async fn connect_peer_if_necessary(
1568-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1579+
async fn connect_peer_if_necessary<K: KVStore + Sync + Send + 'static + 'static>(
1580+
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager<K>>,
15691581
logger: Arc<FilesystemLogger>,
15701582
) -> Result<(), Error> {
15711583
for (node_pubkey, _addr) in peer_manager.get_peer_node_ids() {
@@ -1577,8 +1589,8 @@ async fn connect_peer_if_necessary(
15771589
do_connect_peer(pubkey, peer_addr, peer_manager, logger).await
15781590
}
15791591

1580-
async fn do_connect_peer(
1581-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1592+
async fn do_connect_peer<K: KVStore + Sync + Send + 'static + 'static>(
1593+
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager<K>>,
15821594
logger: Arc<FilesystemLogger>,
15831595
) -> Result<(), Error> {
15841596
log_info!(logger, "Connecting to peer: {}@{}", pubkey, peer_addr);

0 commit comments

Comments
 (0)