X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchainmonitor.rs;h=0186ac374884c82bdbfe4f0d63e1bc4ba0c37343;hb=9f4dcd0bd55bd22d418bcee162d529d2953efc0d;hp=d70ebd40d667ad840c012197484d4f94d1f2ced4;hpb=976acd8af03566427e70f7764bd5bdfdc6f08bd6;p=rust-lightning diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index d70ebd40..0186ac37 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -23,7 +23,7 @@ //! events. The remote server would make use of [`ChainMonitor`] for block processing and for //! servicing [`ChannelMonitor`] updates from the client. -use bitcoin::blockdata::block::BlockHeader; +use bitcoin::blockdata::block::Header; use bitcoin::hash_types::{Txid, BlockHash}; use crate::chain; @@ -110,7 +110,7 @@ impl MonitorUpdateId { /// If at some point no further progress can be made towards persisting the pending updates, the /// node should simply shut down. /// -/// * If the persistence has failed and cannot be retried further (e.g. because of some timeout), +/// * If the persistence has failed and cannot be retried further (e.g. because of an outage), /// [`ChannelMonitorUpdateStatus::UnrecoverableError`] can be used, though this will result in /// an immediate panic and future operations in LDK generally failing. /// @@ -125,7 +125,10 @@ impl MonitorUpdateId { /// [`ChainMonitor::channel_monitor_updated`] must be called once for *each* update which occurs. /// /// If at some point no further progress can be made towards persisting a pending update, the node -/// should simply shut down. +/// should simply shut down. Until then, the background task should either loop indefinitely, or +/// persistence should be regularly retried with [`ChainMonitor::list_pending_monitor_updates`] +/// and [`ChainMonitor::get_monitor`] (note that if a full monitor is persisted all pending +/// monitor updates may be marked completed). /// /// # Using remote watchtowers /// @@ -309,7 +312,7 @@ where C::Target: chain::Filter, /// updated `txdata`. /// /// Calls which represent a new blockchain tip height should set `best_height`. - fn process_chain_data(&self, header: &BlockHeader, best_height: Option, txdata: &TransactionData, process: FN) + fn process_chain_data(&self, header: &Header, best_height: Option, txdata: &TransactionData, process: FN) where FN: Fn(&ChannelMonitor, &TransactionData) -> Vec { @@ -321,7 +324,6 @@ where C::Target: chain::Filter, if self.update_monitor_with_chain_data(header, best_height, txdata, &process, funding_outpoint, &monitor_state).is_err() { // Take the monitors lock for writing so that we poison it and any future // operations going forward fail immediately. - core::mem::drop(monitor_state); core::mem::drop(monitor_lock); let _poison = self.monitors.write().unwrap(); log_error!(self.logger, "{}", err_str); @@ -353,7 +355,7 @@ where C::Target: chain::Filter, } fn update_monitor_with_chain_data( - &self, header: &BlockHeader, best_height: Option, txdata: &TransactionData, + &self, header: &Header, best_height: Option, txdata: &TransactionData, process: FN, funding_outpoint: &OutPoint, monitor_state: &MonitorHolder ) -> Result<(), ()> where FN: Fn(&ChannelMonitor, &TransactionData) -> Vec { let monitor = &monitor_state.monitor; @@ -432,7 +434,8 @@ where C::Target: chain::Filter, /// claims which are awaiting confirmation. /// /// Includes the balances from each [`ChannelMonitor`] *except* those included in - /// `ignored_channels`. + /// `ignored_channels`, allowing you to filter out balances from channels which are still open + /// (and whose balance should likely be pulled from the [`ChannelDetails`]). /// /// See [`ChannelMonitor::get_claimable_balances`] for more details on the exact criteria for /// inclusion in the return value. @@ -632,7 +635,7 @@ where L::Target: Logger, P::Target: Persist, { - fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) { + fn filtered_block_connected(&self, header: &Header, txdata: &TransactionData, height: u32) { log_debug!(self.logger, "New best block {} at height {} provided via block_connected", header.block_hash(), height); self.process_chain_data(header, Some(height), &txdata, |monitor, txdata| { monitor.block_connected( @@ -640,7 +643,7 @@ where }); } - fn block_disconnected(&self, header: &BlockHeader, height: u32) { + fn block_disconnected(&self, header: &Header, height: u32) { let monitor_states = self.monitors.read().unwrap(); log_debug!(self.logger, "Latest block {} at height {} removed via block_disconnected", header.block_hash(), height); for monitor_state in monitor_states.values() { @@ -659,7 +662,7 @@ where L::Target: Logger, P::Target: Persist, { - fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) { + fn transactions_confirmed(&self, header: &Header, txdata: &TransactionData, height: u32) { log_debug!(self.logger, "{} provided transactions confirmed at height {} in block {}", txdata.len(), height, header.block_hash()); self.process_chain_data(header, None, txdata, |monitor, txdata| { monitor.transactions_confirmed( @@ -675,7 +678,7 @@ where } } - fn best_block_updated(&self, header: &BlockHeader, height: u32) { + fn best_block_updated(&self, header: &Header, height: u32) { log_debug!(self.logger, "New best block {} at height {} provided via best_block_updated", header.block_hash(), height); self.process_chain_data(header, Some(height), &[], |monitor, txdata| { // While in practice there shouldn't be any recursive calls when given empty txdata, @@ -763,7 +766,7 @@ where C::Target: chain::Filter, Some(monitor_state) => { let monitor = &monitor_state.monitor; log_trace!(self.logger, "Updating ChannelMonitor for channel {}", log_funding_info!(monitor)); - let update_res = monitor.update_monitor(update, &self.broadcaster, &*self.fee_estimator, &self.logger); + let update_res = monitor.update_monitor(update, &self.broadcaster, &self.fee_estimator, &self.logger); let update_id = MonitorUpdateId::from_monitor_update(update); let mut pending_monitor_updates = monitor_state.pending_monitor_updates.lock().unwrap(); @@ -811,12 +814,7 @@ where C::Target: chain::Filter, let mut pending_monitor_events = self.pending_monitor_events.lock().unwrap().split_off(0); for monitor_state in self.monitors.read().unwrap().values() { let is_pending_monitor_update = monitor_state.has_pending_chainsync_updates(&monitor_state.pending_monitor_updates.lock().unwrap()); - if is_pending_monitor_update && - monitor_state.last_chain_persist_height.load(Ordering::Acquire) + LATENCY_GRACE_PERIOD_BLOCKS as usize - > self.highest_chain_height.load(Ordering::Acquire) - { - log_debug!(self.logger, "A Channel Monitor sync is still in progress, refusing to provide monitor events!"); - } else { + if !is_pending_monitor_update || monitor_state.last_chain_persist_height.load(Ordering::Acquire) + LATENCY_GRACE_PERIOD_BLOCKS as usize <= self.highest_chain_height.load(Ordering::Acquire) { if is_pending_monitor_update { log_error!(self.logger, "A ChannelMonitor sync took longer than {} blocks to complete.", LATENCY_GRACE_PERIOD_BLOCKS); log_error!(self.logger, " To avoid funds-loss, we are allowing monitor updates to be released.");