Skip to content

Commit eff2232

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 5ba7c29 commit eff2232

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,
@@ -1303,8 +1310,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13031310
pub(super) fn update_monitor_ooo(&mut self, mut updates: ChannelMonitorUpdate) -> Result<(), MonitorUpdateError> {
13041311
for update in updates.updates.drain(..) {
13051312
match update {
1306-
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
1307-
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
1313+
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
1314+
if self.lockdown_from_offchain { panic!(); }
1315+
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
1316+
},
13081317
ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
13091318
self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
13101319
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1332,8 +1341,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13321341
}
13331342
for update in updates.updates.drain(..) {
13341343
match update {
1335-
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
1336-
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
1344+
ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
1345+
if self.lockdown_from_offchain { panic!(); }
1346+
self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
1347+
},
13371348
ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
13381349
self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
13391350
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1343,6 +1354,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
13431354
ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } =>
13441355
self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point),
13451356
ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
1357+
self.lockdown_from_offchain = true;
13461358
if should_broadcast {
13471359
self.broadcast_latest_local_commitment_txn(broadcaster);
13481360
} else {
@@ -2483,6 +2495,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
24832495
}
24842496
let onchain_tx_handler = ReadableArgs::read(reader, logger.clone())?;
24852497

2498+
let lockdown_from_offchain = Readable::read(reader)?;
2499+
24862500
Ok((last_block_hash.clone(), ChannelMonitor {
24872501
latest_update_id,
24882502
commitment_transaction_number_obscure_factor,
@@ -2521,6 +2535,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
25212535

25222536
onchain_tx_handler,
25232537

2538+
lockdown_from_offchain,
2539+
25242540
last_block_hash,
25252541
secp_ctx: Secp256k1::new(),
25262542
logger,

0 commit comments

Comments
 (0)