X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fpersist.rs;h=46f82d2c113bce38daae9f56a56e6036ddf13be7;hb=806b7f0e312c59c87fd628fb71e7c4a77a39645a;hp=a7b4bda6f31110a569645affba56f6a9a862e465;hpb=6159325ee7022508ddd3c4178ba0fe3fe630fc8e;p=rust-lightning diff --git a/lightning/src/util/persist.rs b/lightning/src/util/persist.rs index a7b4bda6..46f82d2c 100644 --- a/lightning/src/util/persist.rs +++ b/lightning/src/util/persist.rs @@ -11,18 +11,16 @@ //! [`ChannelManager`]: crate::ln::channelmanager::ChannelManager use core::cmp; -use core::convert::{TryFrom, TryInto}; use core::ops::Deref; use core::str::FromStr; use bitcoin::{BlockHash, Txid}; use crate::{io, log_error}; -use crate::alloc::string::ToString; use crate::prelude::*; use crate::chain; use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; -use crate::chain::chainmonitor::{Persist, MonitorUpdateId}; +use crate::chain::chainmonitor::Persist; use crate::sign::{EntropySource, ecdsa::WriteableEcdsaChannelSigner, SignerProvider}; use crate::chain::transaction::OutPoint; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, CLOSED_CHANNEL_UPDATE_ID}; @@ -58,6 +56,11 @@ pub const CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE: &str = ""; /// The primary namespace under which [`ChannelMonitorUpdate`]s will be persisted. pub const CHANNEL_MONITOR_UPDATE_PERSISTENCE_PRIMARY_NAMESPACE: &str = "monitor_updates"; +/// The primary namespace under which archived [`ChannelMonitor`]s will be persisted. +pub const ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE: &str = "archived_monitors"; +/// The secondary namespace under which archived [`ChannelMonitor`]s will be persisted. +pub const ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE: &str = ""; + /// The primary namespace under which the [`NetworkGraph`] will be persisted. pub const NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE: &str = ""; /// The secondary namespace under which the [`NetworkGraph`] will be persisted. @@ -72,6 +75,20 @@ pub const SCORER_PERSISTENCE_SECONDARY_NAMESPACE: &str = ""; /// The key under which the [`WriteableScore`] will be persisted. pub const SCORER_PERSISTENCE_KEY: &str = "scorer"; +/// The primary namespace under which [`OutputSweeper`] state will be persisted. +/// +/// [`OutputSweeper`]: crate::util::sweep::OutputSweeper +pub const OUTPUT_SWEEPER_PERSISTENCE_PRIMARY_NAMESPACE: &str = ""; +/// The secondary namespace under which [`OutputSweeper`] state will be persisted. +/// +/// [`OutputSweeper`]: crate::util::sweep::OutputSweeper +pub const OUTPUT_SWEEPER_PERSISTENCE_SECONDARY_NAMESPACE: &str = ""; +/// The secondary namespace under which [`OutputSweeper`] state will be persisted. +/// The key under which [`OutputSweeper`] state will be persisted. +/// +/// [`OutputSweeper`]: crate::util::sweep::OutputSweeper +pub const OUTPUT_SWEEPER_PERSISTENCE_KEY: &str = "output_sweeper"; + /// A sentinel value to be prepended to monitors persisted by the [`MonitorUpdatingPersister`]. /// /// This serves to prevent someone from accidentally loading such monitors (which may need @@ -191,7 +208,7 @@ impl Persist, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus { + fn persist_new_channel(&self, funding_txo: OutPoint, monitor: &ChannelMonitor) -> chain::ChannelMonitorUpdateStatus { let key = format!("{}_{}", funding_txo.txid.to_string(), funding_txo.index); match self.write( CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, @@ -203,7 +220,7 @@ impl Persist, monitor: &ChannelMonitor, _update_id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus { + fn update_persisted_channel(&self, funding_txo: OutPoint, _update: Option<&ChannelMonitorUpdate>, monitor: &ChannelMonitor) -> chain::ChannelMonitorUpdateStatus { let key = format!("{}_{}", funding_txo.txid.to_string(), funding_txo.index); match self.write( CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, @@ -214,6 +231,33 @@ impl Persist chain::ChannelMonitorUpdateStatus::UnrecoverableError } } + + fn archive_persisted_channel(&self, funding_txo: OutPoint) { + let monitor_name = MonitorName::from(funding_txo); + let monitor = match self.read( + CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, + CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, + monitor_name.as_str(), + ) { + Ok(monitor) => monitor, + Err(_) => return + }; + match self.write( + ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, + ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, + monitor_name.as_str(), + &monitor, + ) { + Ok(()) => {} + Err(_e) => return + }; + let _ = self.remove( + CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, + CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, + monitor_name.as_str(), + true, + ); + } } /// Read previously persisted [`ChannelMonitor`]s from the store. @@ -604,8 +648,7 @@ where /// Persists a new channel. This means writing the entire monitor to the /// parametrized [`KVStore`]. fn persist_new_channel( - &self, funding_txo: OutPoint, monitor: &ChannelMonitor, - _monitor_update_call_id: MonitorUpdateId, + &self, funding_txo: OutPoint, monitor: &ChannelMonitor ) -> chain::ChannelMonitorUpdateStatus { // Determine the proper key for this monitor let monitor_name = MonitorName::from(funding_txo); @@ -649,10 +692,8 @@ where /// - The update is at [`CLOSED_CHANNEL_UPDATE_ID`] fn update_persisted_channel( &self, funding_txo: OutPoint, update: Option<&ChannelMonitorUpdate>, - monitor: &ChannelMonitor, monitor_update_call_id: MonitorUpdateId, + monitor: &ChannelMonitor ) -> chain::ChannelMonitorUpdateStatus { - // IMPORTANT: monitor_update_call_id: MonitorUpdateId is not to be confused with - // ChannelMonitorUpdate's update_id. if let Some(update) = update { if update.update_id != CLOSED_CHANNEL_UPDATE_ID && update.update_id % self.maximum_pending_updates != 0 @@ -688,7 +729,7 @@ where }; // We could write this update, but it meets criteria of our design that calls for a full monitor write. - let monitor_update_status = self.persist_new_channel(funding_txo, monitor, monitor_update_call_id); + let monitor_update_status = self.persist_new_channel(funding_txo, monitor); if let chain::ChannelMonitorUpdateStatus::Completed = monitor_update_status { let cleanup_range = if monitor.get_latest_update_id() == CLOSED_CHANNEL_UPDATE_ID { @@ -717,9 +758,32 @@ where } } else { // There is no update given, so we must persist a new monitor. - self.persist_new_channel(funding_txo, monitor, monitor_update_call_id) + self.persist_new_channel(funding_txo, monitor) } } + + fn archive_persisted_channel(&self, funding_txo: OutPoint) { + let monitor_name = MonitorName::from(funding_txo); + let monitor = match self.read_monitor(&monitor_name) { + Ok((_block_hash, monitor)) => monitor, + Err(_) => return + }; + match self.kv_store.write( + ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, + ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, + monitor_name.as_str(), + &monitor.encode() + ) { + Ok(()) => {}, + Err(_e) => return, + }; + let _ = self.kv_store.remove( + CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, + CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, + monitor_name.as_str(), + true, + ); + } } impl MonitorUpdatingPersister @@ -837,7 +901,6 @@ impl From for UpdateName { #[cfg(test)] mod tests { use super::*; - use crate::chain::chainmonitor::Persist; use crate::chain::ChannelMonitorUpdateStatus; use crate::events::{ClosureReason, MessageSendEventsProvider}; use crate::ln::functional_test_utils::*; @@ -1051,8 +1114,6 @@ mod tests { check_closed_event(&nodes[1], 1, ClosureReason::HolderForceClosed, false, &[nodes[0].node.get_our_node_id()], 100000); { let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); - let update_map = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap(); - let update_id = update_map.get(&added_monitors[0].1.channel_id()).unwrap(); let cmu_map = nodes[1].chain_monitor.monitor_updates.lock().unwrap(); let cmu = &cmu_map.get(&added_monitors[0].1.channel_id()).unwrap()[0]; let test_txo = OutPoint { txid: Txid::from_str("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), index: 0 }; @@ -1064,7 +1125,7 @@ mod tests { entropy_source: node_cfgs[0].keys_manager, signer_provider: node_cfgs[0].keys_manager, }; - match ro_persister.persist_new_channel(test_txo, &added_monitors[0].1, update_id.2) { + match ro_persister.persist_new_channel(test_txo, &added_monitors[0].1) { ChannelMonitorUpdateStatus::UnrecoverableError => { // correct result } @@ -1075,7 +1136,7 @@ mod tests { panic!("Returned InProgress when shouldn't have") } } - match ro_persister.update_persisted_channel(test_txo, Some(cmu), &added_monitors[0].1, update_id.2) { + match ro_persister.update_persisted_channel(test_txo, Some(cmu), &added_monitors[0].1) { ChannelMonitorUpdateStatus::UnrecoverableError => { // correct result }