#[must_use]
pub struct ChannelMonitorUpdate {
pub(crate) updates: Vec<ChannelMonitorUpdateStep>,
+ /// Historically, [`ChannelMonitor`]s didn't know their counterparty node id. However,
+ /// `ChannelManager` really wants to know it so that it can easily look up the corresponding
+ /// channel. For now, this results in a temporary map in `ChannelManager` to look up channels
+ /// by only the funding outpoint.
+ ///
+ /// To eventually remove that, we repeat the counterparty node id here so that we can upgrade
+ /// `ChannelMonitor`s to become aware of the counterparty node id if they were generated prior
+ /// to when it was stored directly in them.
+ pub(crate) counterparty_node_id: Option<PublicKey>,
/// The sequence number of this update. Updates *must* be replayed in-order according to this
/// sequence number (and updates may panic if they are not). The update_id values are strictly
/// increasing and increase by one for each new update, with two exceptions specified below.
for update_step in self.updates.iter() {
update_step.write(w)?;
}
- write_tlv_fields!(w, {});
+ write_tlv_fields!(w, {
+ (1, self.counterparty_node_id, option),
+ });
Ok(())
}
}
updates.push(upd);
}
}
- read_tlv_fields!(r, {});
- Ok(Self { update_id, updates })
+ let mut counterparty_node_id = None;
+ read_tlv_fields!(r, {
+ (1, counterparty_node_id, option),
+ });
+ Ok(Self { update_id, counterparty_node_id, updates })
}
}
/// Loads the funding txo and outputs to watch into the given `chain::Filter` by repeatedly
/// calling `chain::Filter::register_output` and `chain::Filter::register_tx` until all outputs
/// have been registered.
- pub fn load_outputs_to_watch<F: Deref>(&self, filter: &F) where F::Target: chain::Filter {
+ pub fn load_outputs_to_watch<F: Deref, L: Deref>(&self, filter: &F, logger: &L)
+ where
+ F::Target: chain::Filter, L::Target: Logger,
+ {
let lock = self.inner.lock().unwrap();
+ let logger = WithChannelMonitor::from_impl(logger, &*lock);
+ log_trace!(&logger, "Registering funding outpoint {}", &lock.get_funding_txo().0);
filter.register_tx(&lock.get_funding_txo().0.txid, &lock.get_funding_txo().1);
for (txid, outputs) in lock.get_outputs_to_watch().iter() {
for (index, script_pubkey) in outputs.iter() {
assert!(*index <= u16::max_value() as u32);
+ let outpoint = OutPoint { txid: *txid, index: *index as u16 };
+ log_trace!(logger, "Registering outpoint {} with the filter for monitoring spends", outpoint);
filter.register_output(WatchedOutput {
block_hash: None,
- outpoint: OutPoint { txid: *txid, index: *index as u16 },
+ outpoint,
script_pubkey: script_pubkey.clone(),
});
}
// broadcastable commitment transaction has the HTLC in it, but it
// cannot currently change after channel initialization, so we don't
// need to here.
- let confirmed_htlcs_iter: &mut Iterator<Item = (&HTLCOutputInCommitment, Option<&HTLCSource>)> = &mut $confirmed_htlcs_list;
+ let confirmed_htlcs_iter: &mut dyn Iterator<Item = (&HTLCOutputInCommitment, Option<&HTLCSource>)> = &mut $confirmed_htlcs_list;
let mut matched_htlc = false;
for (ref broadcast_htlc, ref broadcast_source) in confirmed_htlcs_iter {
log_info!(logger, "Applying update to monitor {}, bringing update_id from {} to {} with {} change(s).",
log_funding_info!(self), self.latest_update_id, updates.update_id, updates.updates.len());
}
+
+ if updates.counterparty_node_id.is_some() {
+ if self.counterparty_node_id.is_none() {
+ self.counterparty_node_id = updates.counterparty_node_id;
+ } else {
+ debug_assert_eq!(self.counterparty_node_id, updates.counterparty_node_id);
+ }
+ }
+
// ChannelMonitor updates may be applied after force close if we receive a preimage for a
// broadcasted commitment transaction HTLC output that we'd like to claim on-chain. If this
// is the case, we no longer have guaranteed access to the monitor's update ID, so we use a
if height > self.best_block.height() {
self.best_block = BestBlock::new(block_hash, height);
+ log_trace!(logger, "Connecting new block {} at height {}", block_hash, height);
self.block_confirmed(height, block_hash, vec![], vec![], vec![], &broadcaster, &fee_estimator, logger)
} else if block_hash != self.best_block.block_hash() {
self.best_block = BestBlock::new(block_hash, height);
+ log_trace!(logger, "Best block re-orged, replaced with new block {} at height {}", block_hash, height);
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| entry.height <= height);
self.onchain_tx_handler.block_disconnected(height + 1, broadcaster, fee_estimator, logger);
Vec::new()
let mut claimable_outpoints = Vec::new();
'tx_iter: for tx in &txn_matched {
let txid = tx.txid();
+ log_trace!(logger, "Transaction {} confirmed in block {}", txid , block_hash);
// If a transaction has already been confirmed, ensure we don't bother processing it duplicatively.
if Some(txid) == self.funding_spend_confirmed {
log_debug!(logger, "Skipping redundant processing of funding-spend tx {} as it was previously confirmed", txid);
preimages_slice_to_htlcs!($preimages_slice).into_iter().map(|(htlc, _)| (htlc, None)).collect()
}
}
- let dummy_sig = crate::util::crypto::sign(&secp_ctx,
+ let dummy_sig = crate::crypto::utils::sign(&secp_ctx,
&bitcoin::secp256k1::Message::from_slice(&[42; 32]).unwrap(),
&SecretKey::from_slice(&[42; 32]).unwrap());