Skip to content

Commit 78fd449

Browse files
committed
rm counterparty_claimable_outpoints from check_spend & use option<vec>
1 parent 7511319 commit 78fd449

File tree

1 file changed

+39
-36
lines changed

1 file changed

+39
-36
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,8 +2771,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27712771
if let Some(txid) = self.current_counterparty_commitment_txid {
27722772
if txid == confirmed_spend_txid {
27732773
if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
2774-
let htlc_outputs: Vec<HTLCOutputInCommitment> = self.counterparty_claimable_outpoints.get(&txid).unwrap_or(&vec![]).iter().map(|(htlc, _)| htlc.clone()).collect();
2775-
claim_htlcs!(*commitment_number, txid, htlc_outputs.as_ref());
2774+
claim_htlcs!(*commitment_number, txid, self.counterparty_claimable_outpoints.get(&txid));
27762775
} else {
27772776
debug_assert!(false);
27782777
log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number");
@@ -2783,8 +2782,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27832782
if let Some(txid) = self.prev_counterparty_commitment_txid {
27842783
if txid == confirmed_spend_txid {
27852784
if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
2786-
let htlc_outputs: Vec<HTLCOutputInCommitment> = self.counterparty_claimable_outpoints.get(&txid).unwrap_or(&vec![]).iter().map(|(htlc, _)| htlc.clone()).collect();
2787-
claim_htlcs!(*commitment_number, txid, htlc_outputs.as_ref());
2785+
claim_htlcs!(*commitment_number, txid, self.counterparty_claimable_outpoints.get(&txid));
27882786
} else {
27892787
debug_assert!(false);
27902788
log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number");
@@ -3237,8 +3235,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32373235
/// Returns packages to claim the revoked output(s), as well as additional outputs to watch and
32383236
/// general information about the output that is to the counterparty in the commitment
32393237
/// transaction.
3240-
fn check_spend_counterparty_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, per_commitment_claimable_outpoints: &Vec<HTLCOutputInCommitment>, logger: &L)
3241-
-> (Vec<PackageTemplate>, TransactionOutputs, CommitmentTxCounterpartyOutputInfo)
3238+
fn check_spend_counterparty_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, per_commitment_option: Option<&Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>>, logger: &L)
3239+
-> (Vec<PackageTemplate>, TransactionOutputs, CommitmentTxCounterpartyOutputInfo)
32423240
where L::Target: Logger {
32433241
// Most secp and related errors trying to create keys means we have no hope of constructing
32443242
// a spend transaction...so we return no transactions to broadcast
@@ -3247,7 +3245,6 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32473245
let mut to_counterparty_output_info = None;
32483246

32493247
let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers!
3250-
let per_commitment_option = self.counterparty_claimable_outpoints.get(&commitment_txid);
32513248

32523249
macro_rules! ignore_error {
32533250
( $thing : expr ) => {
@@ -3281,32 +3278,34 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32813278
}
32823279

32833280
// Then, try to find revoked htlc outputs
3284-
for htlc in per_commitment_claimable_outpoints {
3285-
if let Some(transaction_output_index) = htlc.transaction_output_index {
3286-
if transaction_output_index as usize >= tx.output.len() ||
3281+
if let Some(per_commitment_claimable_data) = per_commitment_option {
3282+
for (htlc, _) in per_commitment_claimable_data {
3283+
if let Some(transaction_output_index) = htlc.transaction_output_index {
3284+
if transaction_output_index as usize >= tx.output.len() ||
32873285
tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
3288-
// per_commitment_data is corrupt or our commitment signing key leaked!
3289-
return (claimable_outpoints, (commitment_txid, watch_outputs),
3290-
to_counterparty_output_info);
3286+
// per_commitment_data is corrupt or our commitment signing key leaked!
3287+
return (claimable_outpoints, (commitment_txid, watch_outputs),
3288+
to_counterparty_output_info);
3289+
}
3290+
let revk_htlc_outp = RevokedHTLCOutput::build(per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, per_commitment_key, htlc.amount_msat / 1000, htlc.clone(), &self.onchain_tx_handler.channel_transaction_parameters.channel_type_features);
3291+
let justice_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, PackageSolvingData::RevokedHTLCOutput(revk_htlc_outp), htlc.cltv_expiry, height);
3292+
claimable_outpoints.push(justice_package);
32913293
}
3292-
let revk_htlc_outp = RevokedHTLCOutput::build(per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, per_commitment_key, htlc.amount_msat / 1000, htlc.clone(), &self.onchain_tx_handler.channel_transaction_parameters.channel_type_features);
3293-
let justice_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, PackageSolvingData::RevokedHTLCOutput(revk_htlc_outp), htlc.cltv_expiry, height);
3294-
claimable_outpoints.push(justice_package);
32953294
}
32963295
}
32973296

32983297
// Last, track onchain revoked commitment transaction and fail backward outgoing HTLCs as payment path is broken
3299-
if !claimable_outpoints.is_empty() || !per_commitment_claimable_outpoints.is_empty() { // ie we're confident this is actually ours
3298+
if !claimable_outpoints.is_empty() || per_commitment_option.is_some() { // ie we're confident this is actually ours
33003299
// We're definitely a counterparty commitment transaction!
33013300
log_error!(logger, "Got broadcast of revoked counterparty commitment transaction, going to generate general spend tx with {} inputs", claimable_outpoints.len());
33023301
for (idx, outp) in tx.output.iter().enumerate() {
33033302
watch_outputs.push((idx as u32, outp.clone()));
33043303
}
33053304
self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number);
33063305

3307-
if let Some(per_commitment_data) = per_commitment_option {
3306+
if let Some(per_commitment_claimable_data) = per_commitment_option {
33083307
fail_unbroadcast_htlcs!(self, "revoked_counterparty", commitment_txid, tx, height,
3309-
block_hash, per_commitment_data.iter().map(|(htlc, htlc_source)|
3308+
block_hash, per_commitment_claimable_data.iter().map(|(htlc, htlc_source)|
33103309
(htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref()))
33113310
), logger);
33123311
} else {
@@ -3319,7 +3318,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33193318
block_hash, [].iter().map(|reference| *reference), logger);
33203319
}
33213320
}
3322-
} else if let Some(per_commitment_data) = per_commitment_option {
3321+
} else if let Some(per_commitment_claimable_data) = per_commitment_option {
33233322
// While this isn't useful yet, there is a potential race where if a counterparty
33243323
// revokes a state at the same time as the commitment transaction for that state is
33253324
// confirmed, and the watchtower receives the block before the user, the user could
@@ -3334,13 +3333,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33343333

33353334
log_info!(logger, "Got broadcast of non-revoked counterparty commitment transaction {}", commitment_txid);
33363335
fail_unbroadcast_htlcs!(self, "counterparty", commitment_txid, tx, height, block_hash,
3337-
per_commitment_data.iter().map(|(htlc, htlc_source)|
3336+
per_commitment_claimable_data.iter().map(|(htlc, htlc_source)|
33383337
(htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref()))
33393338
), logger);
3340-
let per_commitment_htlc_outputs : Vec<HTLCOutputInCommitment> = per_commitment_data.iter().map(|(a, _)| a.clone()).collect();
3341-
// let per_commitment_htlc_outputs = per_commitment_data.iter().map(|&(ref htlc, _)| htlc.clone()).collect();
33423339
let (htlc_claim_reqs, counterparty_output_info) =
3343-
self.get_counterparty_output_claim_info(commitment_number, commitment_txid, Some(tx), per_commitment_htlc_outputs.as_ref());
3340+
self.get_counterparty_output_claim_info(commitment_number, commitment_txid, Some(tx), per_commitment_option);
33443341
to_counterparty_output_info = counterparty_output_info;
33453342
for req in htlc_claim_reqs {
33463343
claimable_outpoints.push(req);
@@ -3351,15 +3348,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33513348
}
33523349

33533350
/// 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>, per_commitment_claimable_outpoints: &Vec<HTLCOutputInCommitment>)
3355-
-> (Vec<PackageTemplate>, CommitmentTxCounterpartyOutputInfo) {
3351+
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>>)>>)
3352+
-> (Vec<PackageTemplate>, CommitmentTxCounterpartyOutputInfo) {
33563353
let mut claimable_outpoints = Vec::new();
33573354
let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None;
33583355

3359-
if per_commitment_claimable_outpoints.is_empty() || self.their_cur_per_commitment_points.is_none(){
3356+
if per_commitment_option.is_none() || self.their_cur_per_commitment_points.is_none() {
33603357
return (claimable_outpoints, to_counterparty_output_info);
33613358
}
33623359
let per_commitment_points = self.their_cur_per_commitment_points.as_ref().unwrap();
3360+
let per_commitment_claimable_data = per_commitment_option.unwrap();
33633361

33643362
let per_commitment_point =
33653363
// If the counterparty commitment tx is the latest valid state, use their latest
@@ -3391,7 +3389,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33913389
}
33923390
}
33933391

3394-
for &ref htlc in per_commitment_claimable_outpoints.iter() {
3392+
for &(ref htlc, _) in per_commitment_claimable_data.iter() {
33953393
if let Some(transaction_output_index) = htlc.transaction_output_index {
33963394
if let Some(transaction) = tx {
33973395
if transaction_output_index as usize >= transaction.output.len() ||
@@ -3574,14 +3572,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35743572
/// Cancels any existing pending claims for a commitment that previously confirmed and has now
35753573
/// been replaced by another.
35763574
pub fn cancel_prev_commitment_claims<L: Deref>(
3577-
&mut self, logger: &L, confirmed_commitment_txid: &Txid, per_commitment_claimable_outpoints: &Vec<HTLCOutputInCommitment>
3575+
&mut self, logger: &L, confirmed_commitment_txid: &Txid, per_commitment_option: Option<&Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>>
35783576
) where L::Target: Logger {
35793577
for (counterparty_commitment_txid, _) in &self.counterparty_commitment_txn_on_chain {
35803578
// Cancel any pending claims for counterparty commitments we've seen confirm.
35813579
if counterparty_commitment_txid == confirmed_commitment_txid {
35823580
continue;
35833581
}
3584-
for htlc in per_commitment_claimable_outpoints {
3582+
for (htlc, _) in per_commitment_option.unwrap_or(&vec![]) {
35853583
log_trace!(logger, "Canceling claims for previously confirmed counterparty commitment {}",
35863584
counterparty_commitment_txid);
35873585
let mut outpoint = BitcoinOutPoint { txid: *counterparty_commitment_txid, vout: 0 };
@@ -3766,16 +3764,20 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37663764
// (except for HTLC transactions for channels with anchor outputs), which is an easy
37673765
// way to filter out any potential non-matching txn for lazy filters.
37683766
let prevout = &tx.input[0].previous_output;
3769-
let per_commitment_claimable_outpoints: Vec<HTLCOutputInCommitment> = self.counterparty_claimable_outpoints.get(&tx.txid()).unwrap_or(&vec![]).iter().map(|(htlc, _)| htlc.clone()).collect();
3767+
37703768
if prevout.txid == self.funding_info.0.txid && prevout.vout == self.funding_info.0.index as u32 {
37713769
let mut balance_spendable_csv = None;
37723770
log_info!(logger, "Channel {} closed by funding output spend in txid {}.",
37733771
&self.channel_id(), txid);
37743772
self.funding_spend_seen = true;
37753773
let mut commitment_tx_to_counterparty_output = None;
3776-
if (tx.input[0].sequence.0 >> 8*3) as u8 == 0x80 && (tx.lock_time.to_consensus_u32() >> 8*3) as u8 == 0x20 {
3774+
3775+
let per_commitment_option = self.counterparty_claimable_outpoints.get(&tx.txid()).map(|x| (x.iter()
3776+
.map(|&(ref a, ref b)| (a.clone(), b.clone())).collect::<Vec<_>>()));
3777+
3778+
if (tx.input[0].sequence.0 >> 8 * 3) as u8 == 0x80 && (tx.lock_time.to_consensus_u32() >> 8 * 3) as u8 == 0x20 {
37773779
let (mut new_outpoints, new_outputs, counterparty_output_idx_sats) =
3778-
self.check_spend_counterparty_transaction(&tx, height, &block_hash, &per_commitment_claimable_outpoints, &logger);
3780+
self.check_spend_counterparty_transaction(&tx, height, &block_hash, per_commitment_option.as_ref(), &logger);
37793781
commitment_tx_to_counterparty_output = counterparty_output_idx_sats;
37803782
if !new_outputs.1.is_empty() {
37813783
watch_outputs.push(new_outputs);
@@ -3785,7 +3787,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37853787
if let Some((mut new_outpoints, new_outputs)) = self.check_spend_holder_transaction(&tx, height, &block_hash, &logger) {
37863788
#[cfg(not(fuzzing))]
37873789
debug_assert!(commitment_tx_to_counterparty_output.is_none(),
3788-
"A commitment transaction matched as both a counterparty and local commitment tx?");
3790+
"A commitment transaction matched as both a counterparty and local commitment tx?");
37893791
if !new_outputs.1.is_empty() {
37903792
watch_outputs.push(new_outputs);
37913793
}
@@ -3794,6 +3796,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37943796
}
37953797
}
37963798
}
3799+
37973800
self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
37983801
txid,
37993802
transaction: Some((*tx).clone()),
@@ -3807,7 +3810,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38073810
// Now that we've detected a confirmed commitment transaction, attempt to cancel
38083811
// pending claims for any commitments that were previously confirmed such that
38093812
// we don't continue claiming inputs that no longer exist.
3810-
self.cancel_prev_commitment_claims(&logger, &txid, &per_commitment_claimable_outpoints);
3813+
self.cancel_prev_commitment_claims(&logger, &txid, per_commitment_option.as_ref());
38113814
}
38123815
}
38133816
if tx.input.len() >= 1 {
@@ -4287,7 +4290,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42874290
}
42884291
}
42894292
if let Some(ref htlc_outputs) = self.counterparty_claimable_outpoints.get(&input.previous_output.txid) {
4290-
scan_commitment!(htlc_outputs.iter().map(|&(ref a, ref b)| (a, (b.as_ref().clone()).map(|boxed| &**boxed))),
4293+
scan_commitment!(htlc_outputs.iter().map(|&(ref a, ref b)| (a, (b.as_ref()).map(|boxed| &**boxed))),
42914294
"counterparty commitment tx", false);
42924295
}
42934296

0 commit comments

Comments
 (0)