X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchannelmonitor.rs;h=aa66603615f9ce7e3dd3806bfcbe5a6b78854e94;hb=aaba0a2ec9ed310785a1e79d627c2530094ce208;hp=3c75ec9e99ecd68baa51be9d1f60eb8e39becb2f;hpb=d4b6f58ba67a40d49a58722a104d2d3ea53a0410;p=rust-lightning diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 3c75ec9e..aa666036 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -106,7 +106,9 @@ impl Readable for ChannelMonitorUpdate { let len: u64 = Readable::read(r)?; let mut updates = Vec::with_capacity(cmp::min(len as usize, MAX_ALLOC_SIZE / ::core::mem::size_of::())); for _ in 0..len { - updates.push(Readable::read(r)?); + if let Some(upd) = MaybeReadable::read(r)? { + updates.push(upd); + } } read_tlv_fields!(r, {}); Ok(Self { update_id, updates }) @@ -270,11 +272,15 @@ struct HolderSignedTx { b_htlc_key: PublicKey, delayed_payment_key: PublicKey, per_commitment_point: PublicKey, - feerate_per_kw: u32, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>, + to_self_value_sat: u64, + feerate_per_kw: u32, } impl_writeable_tlv_based!(HolderSignedTx, { (0, txid, required), + // Note that this is filled in with data from OnchainTxHandler if it's missing. + // For HolderSignedTx objects serialized with 0.0.100+, this should be filled in. + (1, to_self_value_sat, (default_value, u64::max_value())), (2, revocation_key, required), (4, a_htlc_key, required), (6, b_htlc_key, required), @@ -394,13 +400,36 @@ enum OnchainEvent { }, } -impl_writeable_tlv_based!(OnchainEventEntry, { - (0, txid, required), - (2, height, required), - (4, event, required), -}); +impl Writeable for OnchainEventEntry { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { + write_tlv_fields!(writer, { + (0, self.txid, required), + (2, self.height, required), + (4, self.event, required), + }); + Ok(()) + } +} + +impl MaybeReadable for OnchainEventEntry { + fn read(reader: &mut R) -> Result, DecodeError> { + let mut txid = Default::default(); + let mut height = 0; + let mut event = None; + read_tlv_fields!(reader, { + (0, txid, required), + (2, height, required), + (4, event, ignorable), + }); + if let Some(ev) = event { + Ok(Some(Self { txid, height, event: ev })) + } else { + Ok(None) + } + } +} -impl_writeable_tlv_based_enum!(OnchainEvent, +impl_writeable_tlv_based_enum_upgradable!(OnchainEvent, (0, HTLCUpdate) => { (0, source, required), (1, onchain_value_satoshis, option), @@ -409,7 +438,7 @@ impl_writeable_tlv_based_enum!(OnchainEvent, (1, MaturingOutput) => { (0, descriptor, required), }, -;); +); #[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))] #[derive(Clone)] @@ -443,7 +472,7 @@ pub(crate) enum ChannelMonitorUpdateStep { }, } -impl_writeable_tlv_based_enum!(ChannelMonitorUpdateStep, +impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep, (0, LatestHolderCommitmentTXInfo) => { (0, commitment_tx, required), (2, htlc_outputs, vec_type), @@ -467,7 +496,7 @@ impl_writeable_tlv_based_enum!(ChannelMonitorUpdateStep, (5, ShutdownScript) => { (0, scriptpubkey, required), }, -;); +); /// A ChannelMonitor handles chain events (blocks connected and disconnected) and generates /// on-chain transactions to ensure no loss of funds occurs. @@ -844,8 +873,9 @@ impl ChannelMonitor { b_htlc_key: tx_keys.countersignatory_htlc_key, delayed_payment_key: tx_keys.broadcaster_delayed_payment_key, per_commitment_point: tx_keys.per_commitment_point, - feerate_per_kw: trusted_tx.feerate_per_kw(), htlc_outputs: Vec::new(), // There are never any HTLCs in the initial commitment transactions + to_self_value_sat: initial_holder_commitment_tx.to_broadcaster_value_sat(), + feerate_per_kw: trusted_tx.feerate_per_kw(), }; (holder_commitment_tx, trusted_tx.commitment_number()) }; @@ -1399,8 +1429,9 @@ impl ChannelMonitorImpl { b_htlc_key: tx_keys.countersignatory_htlc_key, delayed_payment_key: tx_keys.broadcaster_delayed_payment_key, per_commitment_point: tx_keys.per_commitment_point, - feerate_per_kw: trusted_tx.feerate_per_kw(), htlc_outputs, + to_self_value_sat: holder_commitment_tx.to_broadcaster_value_sat(), + feerate_per_kw: trusted_tx.feerate_per_kw(), } }; self.onchain_tx_handler.provide_latest_holder_tx(holder_commitment_tx); @@ -1888,7 +1919,6 @@ impl ChannelMonitorImpl { L::Target: Logger, { let block_hash = header.block_hash(); - log_trace!(logger, "New best block {} at height {}", block_hash, height); self.best_block = BestBlock::new(block_hash, height); self.transactions_confirmed(header, txdata, height, broadcaster, fee_estimator, logger) @@ -1908,7 +1938,6 @@ impl ChannelMonitorImpl { L::Target: Logger, { let block_hash = header.block_hash(); - log_trace!(logger, "New best block {} at height {}", block_hash, height); if height > self.best_block.height() { self.best_block = BestBlock::new(block_hash, height); @@ -1946,7 +1975,6 @@ impl ChannelMonitorImpl { } let block_hash = header.block_hash(); - log_trace!(logger, "Block {} at height {} connected with {} txn matched", block_hash, height, txn_matched.len()); let mut watch_outputs = Vec::new(); let mut claimable_outpoints = Vec::new(); @@ -2019,6 +2047,7 @@ impl ChannelMonitorImpl { F::Target: FeeEstimator, L::Target: Logger, { + log_trace!(logger, "Processing {} matched transactions for block at height {}.", txn_matched.len(), conf_height); debug_assert!(self.best_block.height() >= conf_height); let should_broadcast = self.should_broadcast_holder_commitment_txn(logger); @@ -2685,14 +2714,15 @@ impl<'a, Signer: Sign, K: KeysInterface> ReadableArgs<&'a K> } } - let prev_holder_signed_commitment_tx = match ::read(reader)? { - 0 => None, - 1 => { - Some(Readable::read(reader)?) - }, - _ => return Err(DecodeError::InvalidValue), - }; - let current_holder_commitment_tx = Readable::read(reader)?; + let mut prev_holder_signed_commitment_tx: Option = + match ::read(reader)? { + 0 => None, + 1 => { + Some(Readable::read(reader)?) + }, + _ => return Err(DecodeError::InvalidValue), + }; + let mut current_holder_commitment_tx: HolderSignedTx = Readable::read(reader)?; let current_counterparty_commitment_number = ::read(reader)?.0; let current_holder_commitment_number = ::read(reader)?.0; @@ -2731,7 +2761,9 @@ impl<'a, Signer: Sign, K: KeysInterface> ReadableArgs<&'a K> let waiting_threshold_conf_len: u64 = Readable::read(reader)?; let mut onchain_events_awaiting_threshold_conf = Vec::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128)); for _ in 0..waiting_threshold_conf_len { - onchain_events_awaiting_threshold_conf.push(Readable::read(reader)?); + if let Some(val) = MaybeReadable::read(reader)? { + onchain_events_awaiting_threshold_conf.push(val); + } } let outputs_to_watch_len: u64 = Readable::read(reader)?; @@ -2747,11 +2779,28 @@ impl<'a, Signer: Sign, K: KeysInterface> ReadableArgs<&'a K> return Err(DecodeError::InvalidValue); } } - let onchain_tx_handler = ReadableArgs::read(reader, keys_manager)?; + let onchain_tx_handler: OnchainTxHandler = ReadableArgs::read(reader, keys_manager)?; let lockdown_from_offchain = Readable::read(reader)?; let holder_tx_signed = Readable::read(reader)?; + if let Some(prev_commitment_tx) = prev_holder_signed_commitment_tx.as_mut() { + let prev_holder_value = onchain_tx_handler.get_prev_holder_commitment_to_self_value(); + if prev_holder_value.is_none() { return Err(DecodeError::InvalidValue); } + if prev_commitment_tx.to_self_value_sat == u64::max_value() { + prev_commitment_tx.to_self_value_sat = prev_holder_value.unwrap(); + } else if prev_commitment_tx.to_self_value_sat != prev_holder_value.unwrap() { + return Err(DecodeError::InvalidValue); + } + } + + let cur_holder_value = onchain_tx_handler.get_cur_holder_commitment_to_self_value(); + if current_holder_commitment_tx.to_self_value_sat == u64::max_value() { + current_holder_commitment_tx.to_self_value_sat = cur_holder_value; + } else if current_holder_commitment_tx.to_self_value_sat != cur_holder_value { + return Err(DecodeError::InvalidValue); + } + read_tlv_fields!(reader, {}); let mut secp_ctx = Secp256k1::new();