Skip to content

Commit 7326334

Browse files
authored
Merge pull request #3057 from G8XSU/2024-05-08-claimable-persist-3049
Minimize reads to counterparty_claimable_outpoints
2 parents c9de650 + 1690c66 commit 7326334

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,8 +2431,8 @@ macro_rules! fail_unbroadcast_htlcs {
24312431
debug_assert_eq!($commitment_tx_confirmed.txid(), $commitment_txid_confirmed);
24322432

24332433
macro_rules! check_htlc_fails {
2434-
($txid: expr, $commitment_tx: expr) => {
2435-
if let Some(ref latest_outpoints) = $self.counterparty_claimable_outpoints.get($txid) {
2434+
($txid: expr, $commitment_tx: expr, $per_commitment_outpoints: expr) => {
2435+
if let Some(ref latest_outpoints) = $per_commitment_outpoints {
24362436
for &(ref htlc, ref source_option) in latest_outpoints.iter() {
24372437
if let &Some(ref source) = source_option {
24382438
// Check if the HTLC is present in the commitment transaction that was
@@ -2492,10 +2492,10 @@ macro_rules! fail_unbroadcast_htlcs {
24922492
}
24932493
}
24942494
if let Some(ref txid) = $self.current_counterparty_commitment_txid {
2495-
check_htlc_fails!(txid, "current");
2495+
check_htlc_fails!(txid, "current", $self.counterparty_claimable_outpoints.get(txid));
24962496
}
24972497
if let Some(ref txid) = $self.prev_counterparty_commitment_txid {
2498-
check_htlc_fails!(txid, "previous");
2498+
check_htlc_fails!(txid, "previous", $self.counterparty_claimable_outpoints.get(txid));
24992499
}
25002500
} }
25012501
}
@@ -2764,15 +2764,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27642764
// If the channel is force closed, try to claim the output from this preimage.
27652765
// First check if a counterparty commitment transaction has been broadcasted:
27662766
macro_rules! claim_htlcs {
2767-
($commitment_number: expr, $txid: expr) => {
2768-
let (htlc_claim_reqs, _) = self.get_counterparty_output_claim_info($commitment_number, $txid, None);
2767+
($commitment_number: expr, $txid: expr, $htlcs: expr) => {
2768+
let (htlc_claim_reqs, _) = self.get_counterparty_output_claim_info($commitment_number, $txid, None, $htlcs);
27692769
self.onchain_tx_handler.update_claims_view_from_requests(htlc_claim_reqs, self.best_block.height, self.best_block.height, broadcaster, fee_estimator, logger);
27702770
}
27712771
}
27722772
if let Some(txid) = self.current_counterparty_commitment_txid {
27732773
if txid == confirmed_spend_txid {
27742774
if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
2775-
claim_htlcs!(*commitment_number, txid);
2775+
claim_htlcs!(*commitment_number, txid, self.counterparty_claimable_outpoints.get(&txid));
27762776
} else {
27772777
debug_assert!(false);
27782778
log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number");
@@ -2783,7 +2783,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27832783
if let Some(txid) = self.prev_counterparty_commitment_txid {
27842784
if txid == confirmed_spend_txid {
27852785
if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
2786-
claim_htlcs!(*commitment_number, txid);
2786+
claim_htlcs!(*commitment_number, txid, self.counterparty_claimable_outpoints.get(&txid));
27872787
} else {
27882788
debug_assert!(false);
27892789
log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number");
@@ -3280,8 +3280,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32803280
}
32813281

32823282
// Then, try to find revoked htlc outputs
3283-
if let Some(ref per_commitment_data) = per_commitment_option {
3284-
for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() {
3283+
if let Some(per_commitment_claimable_data) = per_commitment_option {
3284+
for (htlc, _) in per_commitment_claimable_data {
32853285
if let Some(transaction_output_index) = htlc.transaction_output_index {
32863286
if transaction_output_index as usize >= tx.output.len() ||
32873287
tx.output[transaction_output_index as usize].value != htlc.to_bitcoin_amount() {
@@ -3305,9 +3305,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33053305
}
33063306
self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number);
33073307

3308-
if let Some(per_commitment_data) = per_commitment_option {
3308+
if let Some(per_commitment_claimable_data) = per_commitment_option {
33093309
fail_unbroadcast_htlcs!(self, "revoked_counterparty", commitment_txid, tx, height,
3310-
block_hash, per_commitment_data.iter().map(|(htlc, htlc_source)|
3310+
block_hash, per_commitment_claimable_data.iter().map(|(htlc, htlc_source)|
33113311
(htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref()))
33123312
), logger);
33133313
} else {
@@ -3320,7 +3320,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33203320
block_hash, [].iter().map(|reference| *reference), logger);
33213321
}
33223322
}
3323-
} else if let Some(per_commitment_data) = per_commitment_option {
3323+
} else if let Some(per_commitment_claimable_data) = per_commitment_option {
33243324
// While this isn't useful yet, there is a potential race where if a counterparty
33253325
// revokes a state at the same time as the commitment transaction for that state is
33263326
// confirmed, and the watchtower receives the block before the user, the user could
@@ -3335,12 +3335,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33353335

33363336
log_info!(logger, "Got broadcast of non-revoked counterparty commitment transaction {}", commitment_txid);
33373337
fail_unbroadcast_htlcs!(self, "counterparty", commitment_txid, tx, height, block_hash,
3338-
per_commitment_data.iter().map(|(htlc, htlc_source)|
3338+
per_commitment_claimable_data.iter().map(|(htlc, htlc_source)|
33393339
(htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref()))
33403340
), logger);
3341-
33423341
let (htlc_claim_reqs, counterparty_output_info) =
3343-
self.get_counterparty_output_claim_info(commitment_number, commitment_txid, Some(tx));
3342+
self.get_counterparty_output_claim_info(commitment_number, commitment_txid, Some(tx), per_commitment_option);
33443343
to_counterparty_output_info = counterparty_output_info;
33453344
for req in htlc_claim_reqs {
33463345
claimable_outpoints.push(req);
@@ -3351,12 +3350,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33513350
}
33523351

33533352
/// Returns the HTLC claim package templates and the counterparty output info
3354-
fn get_counterparty_output_claim_info(&self, commitment_number: u64, commitment_txid: Txid, tx: Option<&Transaction>)
3353+
fn get_counterparty_output_claim_info(&self, commitment_number: u64, commitment_txid: Txid, tx: Option<&Transaction>, per_commitment_option: Option<&Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>>)
33553354
-> (Vec<PackageTemplate>, CommitmentTxCounterpartyOutputInfo) {
33563355
let mut claimable_outpoints = Vec::new();
33573356
let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None;
33583357

3359-
let htlc_outputs = match self.counterparty_claimable_outpoints.get(&commitment_txid) {
3358+
let per_commitment_claimable_data = match per_commitment_option {
33603359
Some(outputs) => outputs,
33613360
None => return (claimable_outpoints, to_counterparty_output_info),
33623361
};
@@ -3395,7 +3394,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33953394
}
33963395
}
33973396

3398-
for (_, &(ref htlc, _)) in htlc_outputs.iter().enumerate() {
3397+
for &(ref htlc, _) in per_commitment_claimable_data.iter() {
33993398
if let Some(transaction_output_index) = htlc.transaction_output_index {
34003399
if let Some(transaction) = tx {
34013400
if transaction_output_index as usize >= transaction.output.len() ||
@@ -3585,6 +3584,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35853584
if counterparty_commitment_txid == confirmed_commitment_txid {
35863585
continue;
35873586
}
3587+
// If we have generated claims for counterparty_commitment_txid earlier, we can rely on always
3588+
// having claim related htlcs for counterparty_commitment_txid in counterparty_claimable_outpoints.
35883589
for (htlc, _) in self.counterparty_claimable_outpoints.get(counterparty_commitment_txid).unwrap_or(&vec![]) {
35893590
log_trace!(logger, "Canceling claims for previously confirmed counterparty commitment {}",
35903591
counterparty_commitment_txid);
@@ -4220,9 +4221,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42204221
}
42214222

42224223
macro_rules! check_htlc_valid_counterparty {
4223-
($counterparty_txid: expr, $htlc_output: expr) => {
4224-
if let Some(txid) = $counterparty_txid {
4225-
for &(ref pending_htlc, ref pending_source) in self.counterparty_claimable_outpoints.get(&txid).unwrap() {
4224+
($htlc_output: expr, $per_commitment_data: expr) => {
4225+
for &(ref pending_htlc, ref pending_source) in $per_commitment_data {
42264226
if pending_htlc.payment_hash == $htlc_output.payment_hash && pending_htlc.amount_msat == $htlc_output.amount_msat {
42274227
if let &Some(ref source) = pending_source {
42284228
log_claim!("revoked counterparty commitment tx", false, pending_htlc, true);
@@ -4231,7 +4231,6 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42314231
}
42324232
}
42334233
}
4234-
}
42354234
}
42364235
}
42374236

@@ -4248,9 +4247,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42484247
// resolve the source HTLC with the original sender.
42494248
payment_data = Some(((*source).clone(), htlc_output.payment_hash, htlc_output.amount_msat));
42504249
} else if !$holder_tx {
4251-
check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid, htlc_output);
4250+
if let Some(current_counterparty_commitment_txid) = &self.current_counterparty_commitment_txid {
4251+
check_htlc_valid_counterparty!(htlc_output, self.counterparty_claimable_outpoints.get(current_counterparty_commitment_txid).unwrap());
4252+
}
42524253
if payment_data.is_none() {
4253-
check_htlc_valid_counterparty!(self.prev_counterparty_commitment_txid, htlc_output);
4254+
if let Some(prev_counterparty_commitment_txid) = &self.prev_counterparty_commitment_txid {
4255+
check_htlc_valid_counterparty!(htlc_output, self.counterparty_claimable_outpoints.get(prev_counterparty_commitment_txid).unwrap());
4256+
}
42544257
}
42554258
}
42564259
if payment_data.is_none() {
@@ -4288,7 +4291,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42884291
}
42894292
}
42904293
if let Some(ref htlc_outputs) = self.counterparty_claimable_outpoints.get(&input.previous_output.txid) {
4291-
scan_commitment!(htlc_outputs.iter().map(|&(ref a, ref b)| (a, (b.as_ref().clone()).map(|boxed| &**boxed))),
4294+
scan_commitment!(htlc_outputs.iter().map(|&(ref a, ref b)| (a, b.as_ref().map(|boxed| &**boxed))),
42924295
"counterparty commitment tx", false);
42934296
}
42944297

0 commit comments

Comments
 (0)