+ 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)
+ });
+ }
+
+ fn block_disconnected(&self, header: &BlockHeader, 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() {
+ monitor_state.monitor.block_disconnected(
+ header, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
+ }
+ }
+}
+
+impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
+chain::Confirm for ChainMonitor<ChannelSigner, C, T, F, L, P>
+where
+ C::Target: chain::Filter,
+ T::Target: BroadcasterInterface,
+ F::Target: FeeEstimator,
+ L::Target: Logger,
+ P::Target: Persist<ChannelSigner>,
+{
+ 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)
+ });
+ }
+
+ fn transaction_unconfirmed(&self, txid: &Txid) {
+ log_debug!(self.logger, "Transaction {} reorganized out of chain", txid);
+ let monitor_states = self.monitors.read().unwrap();
+ for monitor_state in monitor_states.values() {
+ monitor_state.monitor.transaction_unconfirmed(txid, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
+ }
+ }
+
+ 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.
+ debug_assert!(txdata.is_empty());
+ monitor.best_block_updated(
+ header, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
+ });
+ }
+
+ fn get_relevant_txids(&self) -> Vec<Txid> {
+ let mut txids = Vec::new();
+ let monitor_states = self.monitors.read().unwrap();
+ for monitor_state in monitor_states.values() {
+ txids.append(&mut monitor_state.monitor.get_relevant_txids());
+ }
+
+ txids.sort_unstable();
+ txids.dedup();
+ txids
+ }
+}
+
+impl<ChannelSigner: Sign, C: Deref , T: Deref , F: Deref , L: Deref , P: Deref >
+chain::Watch<ChannelSigner> for ChainMonitor<ChannelSigner, C, T, F, L, P>
+where C::Target: chain::Filter,
+ T::Target: BroadcasterInterface,
+ F::Target: FeeEstimator,
+ L::Target: Logger,
+ P::Target: Persist<ChannelSigner>,
+{
+ /// Adds the monitor that watches the channel referred to by the given outpoint.
+ ///
+ /// Calls back to [`chain::Filter`] with the funding transaction and outputs to watch.
+ ///
+ /// Note that we persist the given `ChannelMonitor` while holding the `ChainMonitor`
+ /// monitors lock.
+ fn watch_channel(&self, funding_outpoint: OutPoint, monitor: ChannelMonitor<ChannelSigner>) -> Result<(), ChannelMonitorUpdateErr> {
+ let mut monitors = self.monitors.write().unwrap();
+ let entry = match monitors.entry(funding_outpoint) {
+ hash_map::Entry::Occupied(_) => {
+ log_error!(self.logger, "Failed to add new channel data: channel monitor for given outpoint is already present");
+ return Err(ChannelMonitorUpdateErr::PermanentFailure)},
+ hash_map::Entry::Vacant(e) => e,
+ };
+ if let Err(e) = self.persister.persist_new_channel(funding_outpoint, &monitor) {
+ log_error!(self.logger, "Failed to persist new channel data");
+ return Err(e);
+ }
+ {
+ let funding_txo = monitor.get_funding_txo();
+ log_trace!(self.logger, "Got new Channel Monitor for channel {}", log_bytes!(funding_txo.0.to_channel_id()[..]));