Skip to content

Commit 4d57ac3

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 3ebb1e6 commit 4d57ac3

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,
@@ -1305,8 +1312,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13051312
pub(super) fn update_monitor_ooo(&mut self, mut updates: ChannelMonitorUpdate) -> Result<(), MonitorUpdateError> {
13061313
for update in updates.updates.drain(..) {
13071314
match update {
1308-
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
1309-
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
1315+
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
1316+
if self.lockdown_from_offchain { panic!(); }
1317+
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
1318+
},
13101319
ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
13111320
self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
13121321
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1334,8 +1343,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13341343
}
13351344
for update in updates.updates.drain(..) {
13361345
match update {
1337-
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
1338-
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
1346+
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
1347+
if self.lockdown_from_offchain { panic!(); }
1348+
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
1349+
},
13391350
ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
13401351
self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
13411352
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1345,6 +1356,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13451356
ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } =>
13461357
self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point),
13471358
ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
1359+
self.lockdown_from_offchain = true;
13481360
if should_broadcast {
13491361
self.broadcast_latest_local_commitment_txn(broadcaster);
13501362
} else {
@@ -2485,6 +2497,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
24852497
}
24862498
let onchain_tx_handler = ReadableArgs::read(reader, logger.clone())?;
24872499

2500+
let lockdown_from_offchain = Readable::read(reader)?;
2501+
24882502
Ok((last_block_hash.clone(), ChannelMonitor {
24892503
latest_update_id,
24902504
commitment_transaction_number_obscure_factor,
@@ -2523,6 +2537,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
25232537

25242538
onchain_tx_handler,
25252539

2540+
lockdown_from_offchain,
2541+
25262542
last_block_hash,
25272543
secp_ctx: Secp256k1::new(),
25282544
logger,

0 commit comments

Comments
 (0)