X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchainmonitor.rs;h=8969427a0f960bc5766c153c8479a46974035b93;hb=de9fba82f233fa185e54e833c7faf9c6a0f2b670;hp=0f0958ee8c3108d8fcad942f78a5b002aab104d8;hpb=6494e53a8f6f3d00c9dc202a9e95b0e21558b458;p=rust-lightning diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index 0f0958ee..8969427a 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -35,11 +35,11 @@ use chain::transaction::{OutPoint, TransactionData}; use chain::keysinterface::Sign; use util::logger::Logger; use util::events; -use util::events::Event; +use util::events::EventHandler; -use std::collections::{HashMap, hash_map}; -use std::sync::RwLock; -use std::ops::Deref; +use prelude::*; +use sync::RwLock; +use core::ops::Deref; /// An implementation of [`chain::Watch`] for monitoring channels. /// @@ -139,12 +139,20 @@ where C::Target: chain::Filter, persister, } } + + #[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] + pub fn get_and_clear_pending_events(&self) -> Vec { + use util::events::EventsProvider; + let events = core::cell::RefCell::new(Vec::new()); + let event_handler = |event| events.borrow_mut().push(event); + self.process_pending_events(&event_handler); + events.into_inner() + } } impl chain::Listen for ChainMonitor where - ChannelSigner: Sign, C::Target: chain::Filter, T::Target: BroadcasterInterface, F::Target: FeeEstimator, @@ -154,6 +162,7 @@ where fn block_connected(&self, block: &Block, height: u32) { let header = &block.header; let txdata: Vec<_> = block.txdata.iter().enumerate().collect(); + log_debug!(self.logger, "New best block {} at height {} provided via block_connected", header.block_hash(), height); self.process_chain_data(header, &txdata, |monitor, txdata| { monitor.block_connected( header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger) @@ -162,6 +171,7 @@ where fn block_disconnected(&self, header: &BlockHeader, height: u32) { let monitors = self.monitors.read().unwrap(); + log_debug!(self.logger, "Latest block {} at height {} removed via block_disconnected", header.block_hash(), height); for monitor in monitors.values() { monitor.block_disconnected( header, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger); @@ -172,7 +182,6 @@ where impl chain::Confirm for ChainMonitor where - ChannelSigner: Sign, C::Target: chain::Filter, T::Target: BroadcasterInterface, F::Target: FeeEstimator, @@ -180,6 +189,7 @@ where P::Target: channelmonitor::Persist, { fn transactions_confirmed(&self, header: &BlockHeader, 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, txdata, |monitor, txdata| { monitor.transactions_confirmed( header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger) @@ -187,6 +197,7 @@ where } fn transaction_unconfirmed(&self, txid: &Txid) { + log_debug!(self.logger, "Transaction {} reorganized out of chain", txid); let monitors = self.monitors.read().unwrap(); for monitor in monitors.values() { monitor.transaction_unconfirmed(txid, &*self.broadcaster, &*self.fee_estimator, &*self.logger); @@ -194,6 +205,7 @@ where } fn best_block_updated(&self, header: &BlockHeader, 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, &[], |monitor, txdata| { // While in practice there shouldn't be any recursive calls when given empty txdata, // it's still possible if a chain::Filter implementation returns a transaction. @@ -216,7 +228,7 @@ where } } -impl +impl chain::Watch for ChainMonitor where C::Target: chain::Filter, T::Target: BroadcasterInterface, @@ -308,12 +320,20 @@ impl even L::Target: Logger, P::Target: channelmonitor::Persist, { - fn get_and_clear_pending_events(&self) -> Vec { + /// Processes [`SpendableOutputs`] events produced from each [`ChannelMonitor`] upon maturity. + /// + /// An [`EventHandler`] may safely call back to the provider, though this shouldn't be needed in + /// order to handle these events. + /// + /// [`SpendableOutputs`]: events::Event::SpendableOutputs + fn process_pending_events(&self, handler: H) where H::Target: EventHandler { let mut pending_events = Vec::new(); for monitor in self.monitors.read().unwrap().values() { pending_events.append(&mut monitor.get_and_clear_pending_events()); } - pending_events + for event in pending_events.drain(..) { + handler.handle_event(event); + } } } @@ -322,7 +342,6 @@ mod tests { use ::{check_added_monitors, get_local_commitment_txn}; use ln::features::InitFeatures; use ln::functional_test_utils::*; - use util::events::EventsProvider; use util::events::MessageSendEventsProvider; use util::test_utils::{OnRegisterOutput, TxOutReference};