Merge pull request #2883 from tnull/2024-02-dyn-kvstore-blanket-impls
authorElias Rohrer <dev@tnull.de>
Wed, 14 Feb 2024 08:01:51 +0000 (09:01 +0100)
committerGitHub <noreply@github.com>
Wed, 14 Feb 2024 08:01:51 +0000 (09:01 +0100)
Add blanket `Persist`/`Persister` impls for `dyn KVStore + Send + Sync`

lightning/src/util/persist.rs
lightning/src/util/test_utils.rs

index 7d501345c3ce0d9a2c9c717ae41843b5fb79d79e..2f418a8efc284a4de2d60be4b2b958b369518529 100644 (file)
@@ -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())
+       }
+}
+
 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
+               }
+       }
+}
+
 /// 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,
index 09a8c3a26612725c07fedadc7cbb269814b54f88..8fc5a8197a78c38e13740ea663e678582676515f 100644 (file)
@@ -632,6 +632,9 @@ impl KVStore for TestStore {
        }
 }
 
+unsafe impl Sync for TestStore {}
+unsafe impl Send for TestStore {}
+
 pub struct TestBroadcaster {
        pub txn_broadcasted: Mutex<Vec<Transaction>>,
        pub blocks: Arc<Mutex<Vec<(Block, u32)>>>,