Skip to content

Commit adb5dc0

Browse files
Handle error if unable to update monitor on preimage receipt after channel close
If we receive a preimage right as the channel hits the chain, we need to update the corresponding ChannelMonitor with this preimage. However, if updating the ChannelMonitor then fails with a PermanentError, we should send an error to the preimage-sending node.
1 parent e01b7b3 commit adb5dc0

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
695695
// the full block_connected).
696696
last_block_hash: BlockHash,
697697
secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
698+
699+
counterparty_node_id: PublicKey
698700
}
699701

700702
#[cfg(any(test, feature = "fuzztarget"))]
@@ -927,6 +929,7 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
927929

928930
self.lockdown_from_offchain.write(writer)?;
929931
self.holder_tx_signed.write(writer)?;
932+
self.counterparty_node_id.write(writer)?;
930933

931934
Ok(())
932935
}
@@ -938,7 +941,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
938941
counterparty_htlc_base_key: &PublicKey, counterparty_delayed_payment_base_key: &PublicKey,
939942
on_holder_tx_csv: u16, funding_redeemscript: Script, channel_value_satoshis: u64,
940943
commitment_transaction_number_obscure_factor: u64,
941-
initial_holder_commitment_tx: HolderCommitmentTransaction) -> ChannelMonitor<ChanSigner> {
944+
initial_holder_commitment_tx: HolderCommitmentTransaction,
945+
counterparty_node_id: PublicKey) -> ChannelMonitor<ChanSigner> {
942946

943947
assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
944948
let our_channel_close_key_hash = WPubkeyHash::hash(&shutdown_pubkey.serialize());
@@ -1010,6 +1014,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
10101014
lockdown_from_offchain: false,
10111015
holder_tx_signed: false,
10121016

1017+
counterparty_node_id,
1018+
10131019
last_block_hash: Default::default(),
10141020
secp_ctx: Secp256k1::new(),
10151021
}
@@ -1755,7 +1761,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
17551761
source: htlc_update.0,
17561762
monitor_info: MonitorUpdateInfo {
17571763
funding_outpoint: self.funding_info.0,
1758-
latest_monitor_update_id
1764+
latest_monitor_update_id,
1765+
counterparty_node_id: self.counterparty_node_id
17591766
}
17601767
}));
17611768
},
@@ -2029,7 +2036,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
20292036
payment_hash,
20302037
monitor_info: MonitorUpdateInfo {
20312038
funding_outpoint: self.funding_info.0,
2032-
latest_monitor_update_id
2039+
latest_monitor_update_id,
2040+
counterparty_node_id: self.counterparty_node_id
20332041
}
20342042
}));
20352043
}
@@ -2046,7 +2054,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
20462054
payment_hash,
20472055
monitor_info: MonitorUpdateInfo {
20482056
funding_outpoint: self.funding_info.0,
2049-
latest_monitor_update_id
2057+
latest_monitor_update_id,
2058+
counterparty_node_id: self.counterparty_node_id
20502059
}
20512060
}));
20522061
}
@@ -2379,6 +2388,7 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for (BlockHash, ChannelMonitor
23792388

23802389
let lockdown_from_offchain = Readable::read(reader)?;
23812390
let holder_tx_signed = Readable::read(reader)?;
2391+
let counterparty_node_id = Readable::read(reader)?;
23822392

23832393
Ok((last_block_hash.clone(), ChannelMonitor {
23842394
latest_update_id,
@@ -2423,6 +2433,8 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for (BlockHash, ChannelMonitor
24232433
lockdown_from_offchain,
24242434
holder_tx_signed,
24252435

2436+
counterparty_node_id,
2437+
24262438
last_block_hash,
24272439
secp_ctx: Secp256k1::new(),
24282440
}))
@@ -2459,6 +2471,7 @@ mod tests {
24592471
let logger = Arc::new(TestLogger::new());
24602472

24612473
let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2474+
let dummy_counterparty_nodeid = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap());
24622475
let dummy_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
24632476

24642477
let mut preimages = Vec::new();
@@ -2524,7 +2537,7 @@ mod tests {
25242537
(OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
25252538
&PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[44; 32]).unwrap()),
25262539
&PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[45; 32]).unwrap()),
2527-
10, Script::new(), 46, 0, HolderCommitmentTransaction::dummy());
2540+
10, Script::new(), 46, 0, HolderCommitmentTransaction::dummy(), dummy_counterparty_nodeid);
25282541

25292542
monitor.provide_latest_holder_commitment_tx_info(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..10])).unwrap();
25302543
monitor.provide_latest_counterparty_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);

lightning/src/ln/channel.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
15631563
&counterparty_pubkeys.htlc_basepoint, &counterparty_pubkeys.delayed_payment_basepoint,
15641564
self.counterparty_selected_contest_delay, funding_redeemscript.clone(), self.channel_value_satoshis,
15651565
self.get_commitment_transaction_number_obscure_factor(),
1566-
initial_commitment_tx.clone());
1566+
initial_commitment_tx.clone(), self.counterparty_node_id);
15671567

15681568
channel_monitor.provide_latest_counterparty_commitment_tx_info(&counterparty_initial_commitment_tx, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
15691569
channel_monitor
@@ -1627,7 +1627,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
16271627
&counterparty_pubkeys.htlc_basepoint, &counterparty_pubkeys.delayed_payment_basepoint,
16281628
self.counterparty_selected_contest_delay, funding_redeemscript.clone(), self.channel_value_satoshis,
16291629
self.get_commitment_transaction_number_obscure_factor(),
1630-
commitment_tx);
1630+
commitment_tx, self.counterparty_node_id);
16311631

16321632
channel_monitor.provide_latest_counterparty_commitment_tx_info(&counterparty_initial_commitment_tx, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
16331633

@@ -1950,7 +1950,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
19501950
Ok(res) => {
19511951
let mon_info = MonitorUpdateInfo {
19521952
funding_outpoint: self.funding_txo.unwrap(),
1953-
latest_monitor_update_id: self.latest_monitor_update_id
1953+
latest_monitor_update_id: self.latest_monitor_update_id,
1954+
counterparty_node_id: self.counterparty_node_id
19541955
};
19551956
Ok((res, mon_info))
19561957
},

lightning/src/ln/channelmanager.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -707,9 +707,10 @@ macro_rules! maybe_break_monitor_err {
707707
#[derive(Clone, PartialEq)]
708708
pub(crate) struct MonitorUpdateInfo {
709709
pub(crate) funding_outpoint: OutPoint,
710-
pub(crate) latest_monitor_update_id: u64
710+
pub(crate) latest_monitor_update_id: u64,
711+
pub(crate) counterparty_node_id: PublicKey
711712
}
712-
impl_writeable!(MonitorUpdateInfo, 0, { funding_outpoint, latest_monitor_update_id });
713+
impl_writeable!(MonitorUpdateInfo, 0, { funding_outpoint, latest_monitor_update_id, counterparty_node_id });
713714

714715
impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<ChanSigner, M, T, K, F, L>
715716
where M::Target: chain::Watch<Keys=ChanSigner>,
@@ -2157,10 +2158,17 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
21572158
payment_preimage: payment_preimage.clone(),
21582159
}],
21592160
};
2160-
if let Err(_) = self.chain_monitor.update_channel(monitor_update_info.funding_outpoint, preimage_update) {
2161-
// TODO(val): figure out what to do here
2161+
match self.chain_monitor.update_channel(monitor_update_info.funding_outpoint, preimage_update) {
2162+
Err(ChannelMonitorUpdateErr::PermanentFailure) => {
2163+
let err_msg = MsgHandleErrInternal::send_err_msg_no_close("Failed to update channel with preimage".to_owned(), monitor_update_info.funding_outpoint.to_channel_id());
2164+
Err((monitor_update_info.counterparty_node_id, err_msg))
2165+
}
2166+
Err(ChannelMonitorUpdateErr::TemporaryFailure) => {
2167+
let err_msg = MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore("Failed to update channel with preimage".to_owned()), monitor_update_info.funding_outpoint.to_channel_id());
2168+
Err((monitor_update_info.counterparty_node_id, err_msg))
2169+
}
2170+
Ok(()) => Ok(())
21622171
}
2163-
Ok(())
21642172
},
21652173
Err(Some(res)) => Err(res),
21662174
} {

0 commit comments

Comments
 (0)