-
Notifications
You must be signed in to change notification settings - Fork 403
Add blanket Persist
/Persister
impls for dyn KVStore + Send + Sync
#2883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -187,6 +187,41 @@ impl<'a, A: KVStore, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Der | |
} | ||
} | ||
|
||
impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref, S: WriteableScore<'a>> Persister<'a, M, T, ES, NS, SP, F, R, L, S> for dyn KVStore + Send + Sync | ||
where M::Target: 'static + chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>, | ||
T::Target: 'static + BroadcasterInterface, | ||
ES::Target: 'static + EntropySource, | ||
NS::Target: 'static + NodeSigner, | ||
SP::Target: 'static + SignerProvider, | ||
F::Target: 'static + FeeEstimator, | ||
R::Target: 'static + Router, | ||
L::Target: 'static + Logger, | ||
{ | ||
/// Persist the given [`ChannelManager`] to disk, returning an error if persistence failed. | ||
fn persist_manager(&self, channel_manager: &ChannelManager<M, T, ES, NS, SP, F, R, L>) -> Result<(), io::Error> { | ||
self.write(CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE, | ||
CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE, | ||
CHANNEL_MANAGER_PERSISTENCE_KEY, | ||
&channel_manager.encode()) | ||
} | ||
|
||
/// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed. | ||
fn persist_graph(&self, network_graph: &NetworkGraph<L>) -> Result<(), io::Error> { | ||
self.write(NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE, | ||
NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE, | ||
NETWORK_GRAPH_PERSISTENCE_KEY, | ||
&network_graph.encode()) | ||
} | ||
|
||
/// Persist the given [`WriteableScore`] to disk, returning an error if persistence failed. | ||
fn persist_scorer(&self, scorer: &S) -> Result<(), io::Error> { | ||
self.write(SCORER_PERSISTENCE_PRIMARY_NAMESPACE, | ||
SCORER_PERSISTENCE_SECONDARY_NAMESPACE, | ||
SCORER_PERSISTENCE_KEY, | ||
&scorer.encode()) | ||
} | ||
} | ||
Comment on lines
+190
to
+223
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The implementation of |
||
|
||
impl<ChannelSigner: WriteableEcdsaChannelSigner, K: KVStore> Persist<ChannelSigner> for K { | ||
// TODO: We really need a way for the persister to inform the user that its time to crash/shut | ||
// down once these start returning failure. | ||
|
@@ -218,6 +253,37 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner, K: KVStore> Persist<ChannelSign | |
} | ||
} | ||
|
||
impl<ChannelSigner: WriteableEcdsaChannelSigner> Persist<ChannelSigner> for dyn KVStore + Send + Sync { | ||
// TODO: We really need a way for the persister to inform the user that its time to crash/shut | ||
// down once these start returning failure. | ||
// Then we should return InProgress rather than UnrecoverableError, implying we should probably | ||
// just shut down the node since we're not retrying persistence! | ||
|
||
fn persist_new_channel(&self, funding_txo: OutPoint, monitor: &ChannelMonitor<ChannelSigner>, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus { | ||
let key = format!("{}_{}", funding_txo.txid.to_string(), funding_txo.index); | ||
match self.write( | ||
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, | ||
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, | ||
&key, &monitor.encode()) | ||
{ | ||
Ok(()) => chain::ChannelMonitorUpdateStatus::Completed, | ||
Err(_) => chain::ChannelMonitorUpdateStatus::UnrecoverableError | ||
} | ||
} | ||
|
||
fn update_persisted_channel(&self, funding_txo: OutPoint, _update: Option<&ChannelMonitorUpdate>, monitor: &ChannelMonitor<ChannelSigner>, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus { | ||
let key = format!("{}_{}", funding_txo.txid.to_string(), funding_txo.index); | ||
match self.write( | ||
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, | ||
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, | ||
&key, &monitor.encode()) | ||
{ | ||
Ok(()) => chain::ChannelMonitorUpdateStatus::Completed, | ||
Err(_) => chain::ChannelMonitorUpdateStatus::UnrecoverableError | ||
} | ||
} | ||
Comment on lines
+256
to
+284
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the previous comment, the implementation for persisting |
||
} | ||
|
||
/// Read previously persisted [`ChannelMonitor`]s from the store. | ||
pub fn read_channel_monitors<K: Deref, ES: Deref, SP: Deref>( | ||
kv_store: K, entropy_source: ES, signer_provider: SP, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -632,6 +632,9 @@ impl KVStore for TestStore { | |
} | ||
} | ||
|
||
unsafe impl Sync for TestStore {} | ||
unsafe impl Send for TestStore {} | ||
Comment on lines
+635
to
+636
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe implementations of Ensure that the |
||
|
||
pub struct TestBroadcaster { | ||
pub txn_broadcasted: Mutex<Vec<Transaction>>, | ||
pub blocks: Arc<Mutex<Vec<(Block, u32)>>>, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, if we also changed the
KVStore
impl to requireSend + Sync
(i.e.trait KVStore: Send + Sync
), we wouldn't only make its use in ~all cases more ergonomic, but it would also allow us to expose it in the LDK Node bindings interface, i.e., allow users to implement customKVStore
s in the target language, which would be nice.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we discussed this offline, but is there a way to have some supertrait NodeKV that is implemented for all KVStore, but is required in LDK Node and expose that to bindings? Its kinda annoying but at least it would let LDK Node require Send+Sync everywhere and support bindings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mh, I'll explore that but currently suspect that it might not be worth the effort. Shlepping around
Sync + Send
is not that annoying, but it would be nice to find a solution to expose customKVStore
s in bindings. In any case I'd make this a follow-up and will just land this PR for the time being.