From: Matt Corallo Date: Thu, 19 Mar 2020 23:15:06 +0000 (-0400) Subject: Fail to deserialize ChannelManager if it is ahead of any monitor(s) X-Git-Tag: v0.0.12~96^2~1 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=492983f54fb035d5c46db25078fabc1518bdaa28;p=rust-lightning Fail to deserialize ChannelManager if it is ahead of any monitor(s) If any monitors are out of sync with the Channel, we previously closed the channel, but we should really only do that if the monitor is ahead of the channel, opting to call the whole thing invalid if the channel is ahead of the monitor. --- diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index cde40ee32..1afce1f7b 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -3470,10 +3470,17 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De let funding_txo = channel.get_funding_txo().ok_or(DecodeError::InvalidValue)?; funding_txo_set.insert(funding_txo.clone()); if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) { - if channel.get_cur_local_commitment_transaction_number() != monitor.get_cur_local_commitment_number() || - channel.get_revoked_remote_commitment_transaction_number() != monitor.get_min_seen_secret() || - channel.get_cur_remote_commitment_transaction_number() != monitor.get_cur_remote_commitment_number() || - channel.get_latest_monitor_update_id() != monitor.get_latest_update_id() { + if channel.get_cur_local_commitment_transaction_number() < monitor.get_cur_local_commitment_number() || + channel.get_revoked_remote_commitment_transaction_number() < monitor.get_min_seen_secret() || + channel.get_cur_remote_commitment_transaction_number() < monitor.get_cur_remote_commitment_number() || + channel.get_latest_monitor_update_id() > monitor.get_latest_update_id() { + // If the channel is ahead of the monitor, return InvalidValue: + return Err(DecodeError::InvalidValue); + } else if channel.get_cur_local_commitment_transaction_number() > monitor.get_cur_local_commitment_number() || + channel.get_revoked_remote_commitment_transaction_number() > monitor.get_min_seen_secret() || + channel.get_cur_remote_commitment_transaction_number() > monitor.get_cur_remote_commitment_number() || + channel.get_latest_monitor_update_id() < monitor.get_latest_update_id() { + // But if the channel is behind of the monitor, close the channel: let (_, _, mut new_failed_htlcs) = channel.force_shutdown(true); failed_htlcs.append(&mut new_failed_htlcs); monitor.broadcast_latest_local_commitment_txn(&args.tx_broadcaster);