Skip to content

Commit fd364d8

Browse files
author
Antoine Riard
committed
Monitor should panic on receiving buggy update sequences
Channel shouldn't send a ChannelForceClosed update followed by a LatestLocalCommitmentTxInfo as it would be a programming error leading to risk of money loss. Force-closing the channel will broadcast the local commitment transaction, if the revocation secret for this one is released after its broadcast, it would allow remote party to claim outputs on this transaction using the revocation path.
1 parent 46f495b commit fd364d8

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,9 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
794794
#[cfg(not(test))]
795795
onchain_tx_handler: OnchainTxHandler<ChanSigner>,
796796

797+
// Used to detect programming bug due to unsafe monitor update sequence { ChannelForceClosed, LatestLocalCommitmentTXInfo }
798+
lockdown_from_offchain: bool,
799+
797800
// We simply modify last_block_hash in Channel's block_connected so that serialization is
798801
// consistent but hopefully the users' copy handles block_connected in a consistent way.
799802
// (we do *not*, however, update them in update_monitor to ensure any local user copies keep
@@ -1053,6 +1056,8 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
10531056
}
10541057
self.onchain_tx_handler.write(writer)?;
10551058

1059+
self.lockdown_from_offchain.write(writer)?;
1060+
10561061
Ok(())
10571062
}
10581063

@@ -1136,6 +1141,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
11361141

11371142
onchain_tx_handler: OnchainTxHandler::new(destination_script.clone(), keys, funding_redeemscript, their_to_self_delay, logger.clone()),
11381143

1144+
lockdown_from_offchain: false,
1145+
11391146
last_block_hash: Default::default(),
11401147
secp_ctx: Secp256k1::new(),
11411148
logger,
@@ -1297,8 +1304,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
12971304
pub(super) fn update_monitor_ooo(&mut self, mut updates: ChannelMonitorUpdate) -> Result<(), MonitorUpdateError> {
12981305
for update in updates.updates.drain(..) {
12991306
match update {
1300-
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
1301-
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
1307+
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
1308+
if self.lockdown_from_offchain { panic!(); }
1309+
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
1310+
},
13021311
ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
13031312
self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
13041313
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1326,8 +1335,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13261335
}
13271336
for update in updates.updates.drain(..) {
13281337
match update {
1329-
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
1330-
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
1338+
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
1339+
if self.lockdown_from_offchain { panic!(); }
1340+
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
1341+
},
13311342
ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
13321343
self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
13331344
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1337,6 +1348,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13371348
ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } =>
13381349
self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point),
13391350
ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
1351+
self.lockdown_from_offchain = true;
13401352
if should_broadcast {
13411353
self.broadcast_latest_local_commitment_txn(broadcaster);
13421354
} else {
@@ -2453,6 +2465,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
24532465
}
24542466
let onchain_tx_handler = ReadableArgs::read(reader, logger.clone())?;
24552467

2468+
let lockdown_from_offchain = Readable::read(reader)?;
2469+
24562470
Ok((last_block_hash.clone(), ChannelMonitor {
24572471
latest_update_id,
24582472
commitment_transaction_number_obscure_factor,
@@ -2491,6 +2505,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
24912505

24922506
onchain_tx_handler,
24932507

2508+
lockdown_from_offchain,
2509+
24942510
last_block_hash,
24952511
secp_ctx: Secp256k1::new(),
24962512
logger,

0 commit comments

Comments
 (0)