From: Wilmer Paulino Date: Thu, 6 Jul 2023 17:04:50 +0000 (-0700) Subject: Cache HTLC per_commitment_point in descriptor X-Git-Tag: v0.0.116-rc1~5^2~3 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=72c42ee786d11ea1913d2898069f2c6b15285a2a;p=rust-lightning Cache HTLC per_commitment_point in descriptor This allows us to obtain the HTLC input and output from its descriptor without needing to derive the `per_commitment_point` through the signer. --- diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 36e3bc46..1bc16035 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -2632,6 +2632,9 @@ impl ChannelMonitorImpl { channel_parameters: self.onchain_tx_handler.channel_transaction_parameters.clone(), commitment_txid: htlc.commitment_txid, per_commitment_number: htlc.per_commitment_number, + per_commitment_point: self.onchain_tx_handler.signer.get_per_commitment_point( + htlc.per_commitment_number, &self.onchain_tx_handler.secp_ctx, + ), htlc: htlc.htlc, preimage: htlc.preimage, counterparty_sig: htlc.counterparty_sig, diff --git a/lightning/src/events/bump_transaction.rs b/lightning/src/events/bump_transaction.rs index edb146ba..0e3152d7 100644 --- a/lightning/src/events/bump_transaction.rs +++ b/lightning/src/events/bump_transaction.rs @@ -93,6 +93,12 @@ pub struct HTLCDescriptor { pub commitment_txid: Txid, /// The number of the commitment transaction in which the HTLC output lives. pub per_commitment_number: u64, + /// The key tweak corresponding to the number of the commitment transaction in which the HTLC + /// output lives. This tweak is applied to all the basepoints for both parties in the channel to + /// arrive at unique keys per commitment. + /// + /// See for more info. + pub per_commitment_point: PublicKey, /// The details of the HTLC as it appears in the commitment transaction. pub htlc: HTLCOutputInCommitment, /// The preimage, if `Some`, to claim the HTLC output with. If `None`, the timeout path must be @@ -111,17 +117,15 @@ impl HTLCDescriptor { /// Returns the delayed output created as a result of spending the HTLC output in the commitment /// transaction. - pub fn tx_output( - &self, per_commitment_point: &PublicKey, secp: &Secp256k1 - ) -> TxOut { + pub fn tx_output(&self, secp: &Secp256k1) -> TxOut { let channel_params = self.channel_parameters.as_holder_broadcastable(); let broadcaster_keys = channel_params.broadcaster_pubkeys(); let counterparty_keys = channel_params.countersignatory_pubkeys(); let broadcaster_delayed_key = chan_utils::derive_public_key( - secp, per_commitment_point, &broadcaster_keys.delayed_payment_basepoint + secp, &self.per_commitment_point, &broadcaster_keys.delayed_payment_basepoint ); let counterparty_revocation_key = chan_utils::derive_public_revocation_key( - secp, per_commitment_point, &counterparty_keys.revocation_basepoint + secp, &self.per_commitment_point, &counterparty_keys.revocation_basepoint ); chan_utils::build_htlc_output( 0 /* feerate_per_kw */, channel_params.contest_delay(), &self.htlc, @@ -130,20 +134,18 @@ impl HTLCDescriptor { } /// Returns the witness script of the HTLC output in the commitment transaction. - pub fn witness_script( - &self, per_commitment_point: &PublicKey, secp: &Secp256k1 - ) -> Script { + pub fn witness_script(&self, secp: &Secp256k1) -> Script { let channel_params = self.channel_parameters.as_holder_broadcastable(); let broadcaster_keys = channel_params.broadcaster_pubkeys(); let counterparty_keys = channel_params.countersignatory_pubkeys(); let broadcaster_htlc_key = chan_utils::derive_public_key( - secp, per_commitment_point, &broadcaster_keys.htlc_basepoint + secp, &self.per_commitment_point, &broadcaster_keys.htlc_basepoint ); let counterparty_htlc_key = chan_utils::derive_public_key( - secp, per_commitment_point, &counterparty_keys.htlc_basepoint + secp, &self.per_commitment_point, &counterparty_keys.htlc_basepoint ); let counterparty_revocation_key = chan_utils::derive_public_revocation_key( - secp, per_commitment_point, &counterparty_keys.revocation_basepoint + secp, &self.per_commitment_point, &counterparty_keys.revocation_basepoint ); chan_utils::get_htlc_redeemscript_with_explicit_keys( &self.htlc, &ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(), &broadcaster_htlc_key, &counterparty_htlc_key, @@ -696,15 +698,12 @@ where let mut signers = HashMap::new(); let mut must_spend = Vec::with_capacity(htlc_descriptors.len()); for htlc_descriptor in htlc_descriptors { - let signer = signers.entry(htlc_descriptor.channel_keys_id) + signers.entry(htlc_descriptor.channel_keys_id) .or_insert_with(|| self.signer_provider.derive_channel_signer( htlc_descriptor.channel_value_satoshis, htlc_descriptor.channel_keys_id, ) ); - let per_commitment_point = signer.get_per_commitment_point( - htlc_descriptor.per_commitment_number, &self.secp - ); let htlc_input = htlc_descriptor.unsigned_tx_input(); must_spend.push(Input { @@ -716,7 +715,7 @@ where }, }); tx.input.push(htlc_input); - let htlc_output = htlc_descriptor.tx_output(&per_commitment_point, &self.secp); + let htlc_output = htlc_descriptor.tx_output(&self.secp); tx.output.push(htlc_output); } @@ -743,10 +742,7 @@ where let htlc_sig = signer.sign_holder_htlc_transaction( &htlc_tx, idx, htlc_descriptor, &self.secp )?; - let per_commitment_point = signer.get_per_commitment_point( - htlc_descriptor.per_commitment_number, &self.secp - ); - let witness_script = htlc_descriptor.witness_script(&per_commitment_point, &self.secp); + let witness_script = htlc_descriptor.witness_script(&self.secp); htlc_tx.input[idx].witness = htlc_descriptor.tx_input_witness(&htlc_sig, &witness_script); } diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 2a3f5849..4d37f936 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -1781,12 +1781,9 @@ fn do_test_monitor_rebroadcast_pending_claims(anchors: bool) { let signer = nodes[0].keys_manager.derive_channel_keys( descriptor.channel_value_satoshis, &descriptor.channel_keys_id, ); - let per_commitment_point = signer.get_per_commitment_point( - descriptor.per_commitment_number, &secp - ); - tx.output.push(descriptor.tx_output(&per_commitment_point, &secp)); + tx.output.push(descriptor.tx_output(&secp)); let our_sig = signer.sign_holder_htlc_transaction(&mut tx, 0, &descriptor, &secp).unwrap(); - let witness_script = descriptor.witness_script(&per_commitment_point, &secp); + let witness_script = descriptor.witness_script(&secp); tx.input[0].witness = descriptor.tx_input_witness(&our_sig, &witness_script); target_feerate_sat_per_1000_weight as u64 } else { panic!("unexpected event"); }; @@ -1943,10 +1940,6 @@ fn test_yield_anchors_events() { Event::BumpTransaction(BumpTransactionEvent::HTLCResolution { htlc_descriptors, tx_lock_time, .. }) => { assert_eq!(htlc_descriptors.len(), 1); let htlc_descriptor = &htlc_descriptors[0]; - let signer = nodes[0].keys_manager.derive_channel_keys( - htlc_descriptor.channel_value_satoshis, &htlc_descriptor.channel_keys_id - ); - let per_commitment_point = signer.get_per_commitment_point(htlc_descriptor.per_commitment_number, &secp); let mut htlc_tx = Transaction { version: 2, lock_time: tx_lock_time, @@ -1955,15 +1948,18 @@ fn test_yield_anchors_events() { TxIn { ..Default::default() } // Fee input ], output: vec![ - htlc_descriptor.tx_output(&per_commitment_point, &secp), // HTLC output + htlc_descriptor.tx_output(&secp), // HTLC output TxOut { // Fee input change value: Amount::ONE_BTC.to_sat(), script_pubkey: Script::new_op_return(&[]), } ] }; + let signer = nodes[0].keys_manager.derive_channel_keys( + htlc_descriptor.channel_value_satoshis, &htlc_descriptor.channel_keys_id + ); let our_sig = signer.sign_holder_htlc_transaction(&mut htlc_tx, 0, htlc_descriptor, &secp).unwrap(); - let witness_script = htlc_descriptor.witness_script(&per_commitment_point, &secp); + let witness_script = htlc_descriptor.witness_script(&secp); htlc_tx.input[0].witness = htlc_descriptor.tx_input_witness(&our_sig, &witness_script); htlc_txs.push(htlc_tx); }, @@ -2227,12 +2223,8 @@ fn test_anchors_aggregated_revoked_htlc_tx() { assert_eq!(htlc_descriptors.len(), 2); for htlc_descriptor in &htlc_descriptors { assert!(!htlc_descriptor.htlc.offered); - let signer = nodes[1].keys_manager.derive_channel_keys( - htlc_descriptor.channel_value_satoshis, &htlc_descriptor.channel_keys_id - ); - let per_commitment_point = signer.get_per_commitment_point(htlc_descriptor.per_commitment_number, &secp); htlc_tx.input.push(htlc_descriptor.unsigned_tx_input()); - htlc_tx.output.push(htlc_descriptor.tx_output(&per_commitment_point, &secp)); + htlc_tx.output.push(htlc_descriptor.tx_output(&secp)); } descriptors.append(&mut htlc_descriptors); htlc_tx.lock_time = tx_lock_time; @@ -2246,8 +2238,7 @@ fn test_anchors_aggregated_revoked_htlc_tx() { htlc_descriptor.channel_value_satoshis, &htlc_descriptor.channel_keys_id ); let our_sig = signer.sign_holder_htlc_transaction(&htlc_tx, htlc_input_idx, &htlc_descriptor, &secp).unwrap(); - let per_commitment_point = signer.get_per_commitment_point(htlc_descriptor.per_commitment_number, &secp); - let witness_script = htlc_descriptor.witness_script(&per_commitment_point, &secp); + let witness_script = htlc_descriptor.witness_script(&secp); htlc_tx.input[htlc_input_idx].witness = htlc_descriptor.tx_input_witness(&our_sig, &witness_script); } let fee_utxo_sig = { diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 66217de2..c11d47e9 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -1030,15 +1030,12 @@ impl EcdsaChannelSigner for InMemorySigner { &self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1 ) -> Result { - let per_commitment_point = self.get_per_commitment_point( - htlc_descriptor.per_commitment_number, &secp_ctx - ); - let witness_script = htlc_descriptor.witness_script(&per_commitment_point, secp_ctx); + let witness_script = htlc_descriptor.witness_script(secp_ctx); let sighash = &sighash::SighashCache::new(&*htlc_tx).segwit_signature_hash( input, &witness_script, htlc_descriptor.htlc.amount_msat / 1000, EcdsaSighashType::All ).map_err(|_| ())?; let our_htlc_private_key = chan_utils::derive_private_key( - &secp_ctx, &per_commitment_point, &self.htlc_base_key + &secp_ctx, &htlc_descriptor.per_commitment_point, &self.htlc_base_key ); Ok(sign_with_aux_rand(&secp_ctx, &hash_to_message!(sighash), &our_htlc_private_key, &self)) } diff --git a/lightning/src/util/enforcing_trait_impls.rs b/lightning/src/util/enforcing_trait_impls.rs index a9a6e8e0..df0f13bc 100644 --- a/lightning/src/util/enforcing_trait_impls.rs +++ b/lightning/src/util/enforcing_trait_impls.rs @@ -209,9 +209,8 @@ impl EcdsaChannelSigner for EnforcingSigner { &self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1 ) -> Result { - let per_commitment_point = self.get_per_commitment_point(htlc_descriptor.per_commitment_number, secp_ctx); assert_eq!(htlc_tx.input[input], htlc_descriptor.unsigned_tx_input()); - assert_eq!(htlc_tx.output[input], htlc_descriptor.tx_output(&per_commitment_point, secp_ctx)); + assert_eq!(htlc_tx.output[input], htlc_descriptor.tx_output(secp_ctx)); Ok(self.inner.sign_holder_htlc_transaction(htlc_tx, input, htlc_descriptor, secp_ctx).unwrap()) }