From 06f5930b64f479add335bb479acba0197585d7f7 Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Sat, 7 Dec 2024 00:37:27 +0000 Subject: [PATCH] Let `ChannelSigner` set `to_remote` scriptpubkey This allows the `to_remote` output to easily be changed according to the features of the channel, or the evolution of the LN specification. `to_remote` could even be set to completely arbitrary scripts if compatibility with the formal LN spec is not required. Builders of `CommitmentTransaction` now ask a `ChannelSigner` for the appropriate `to_remote` script to use, and then pass the script to the `CommitmentTransaction` constructor. External signers now provide the expected `to_remote` script to the `verify` call of `CommitmentTransaction`. --- lightning/src/chain/channelmonitor.rs | 14 ++++-- lightning/src/ln/chan_utils.rs | 60 +++++++++++++---------- lightning/src/ln/channel.rs | 19 +++++-- lightning/src/ln/functional_tests.rs | 20 ++++++-- lightning/src/sign/mod.rs | 22 ++++++++- lightning/src/util/test_channel_signer.rs | 13 ++++- 6 files changed, 105 insertions(+), 43 deletions(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 1e1fee0eabd..bd2f5e1be20 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -1331,7 +1331,7 @@ impl ChannelMonitor { ChannelMonitor { inner: Mutex::new(imp) } } - pub(crate) fn new(secp_ctx: Secp256k1, keys: Signer, shutdown_script: Option, + pub(crate) fn new(secp_ctx: Secp256k1, mut keys: Signer, shutdown_script: Option, on_counterparty_tx_csv: u16, destination_script: &Script, funding_info: (OutPoint, ScriptBuf), channel_parameters: &ChannelTransactionParameters, holder_pays_commitment_tx_fee: bool, funding_redeemscript: ScriptBuf, channel_value_satoshis: u64, @@ -1339,11 +1339,11 @@ impl ChannelMonitor { initial_holder_commitment_tx: HolderCommitmentTransaction, best_block: BestBlock, counterparty_node_id: PublicKey, channel_id: ChannelId, ) -> ChannelMonitor { + + keys.provide_channel_parameters(channel_parameters); assert!(commitment_transaction_number_obscure_factor <= (1 << 48)); - let counterparty_payment_script = chan_utils::get_counterparty_payment_script( - &channel_parameters.channel_type_features, &keys.pubkeys().payment_point - ); + let counterparty_payment_script = keys.get_counterparty_payment_script(true); let counterparty_channel_parameters = channel_parameters.counterparty_parameters.as_ref().unwrap(); let counterparty_delayed_payment_base_key = counterparty_channel_parameters.pubkeys.delayed_payment_basepoint; @@ -3398,9 +3398,13 @@ impl ChannelMonitorImpl { &broadcaster_keys, &countersignatory_keys, &self.onchain_tx_handler.secp_ctx); let channel_parameters = &self.onchain_tx_handler.channel_transaction_parameters.as_counterparty_broadcastable(); + let counterparty_txout = TxOut { + script_pubkey: self.counterparty_payment_script.clone(), + value: Amount::from_sat(to_countersignatory_value), + }; CommitmentTransaction::new_with_auxiliary_htlc_data(commitment_number, - to_broadcaster_value, to_countersignatory_value, broadcaster_funding_key, + to_broadcaster_value, counterparty_txout, broadcaster_funding_key, countersignatory_funding_key, keys, feerate_per_kw, &mut nondust_htlcs, channel_parameters) } diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index ae76308f0ce..3896eab96c3 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -20,7 +20,6 @@ use bitcoin::sighash::EcdsaSighashType; use bitcoin::transaction::Version; use bitcoin::hashes::{Hash, HashEngine}; -use bitcoin::hashes::hash160::Hash as Hash160; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::ripemd160::Hash as Ripemd160; use bitcoin::hash_types::Txid; @@ -1135,7 +1134,13 @@ impl HolderCommitmentTransaction { for _ in 0..htlcs.len() { counterparty_htlc_sigs.push(dummy_sig); } - let inner = CommitmentTransaction::new_with_auxiliary_htlc_data(0, 0, 0, dummy_key.clone(), dummy_key.clone(), keys, 0, htlcs, &channel_parameters.as_counterparty_broadcastable()); + let channel_parameters = channel_parameters.as_counterparty_broadcastable(); + let counterparty_payment_script = get_counterparty_payment_script(&channel_parameters.channel_type_features(), &channel_parameters.countersignatory_pubkeys().payment_point); + let counterparty_txout = TxOut { + script_pubkey: counterparty_payment_script, + value: Amount::ZERO, + }; + let inner = CommitmentTransaction::new_with_auxiliary_htlc_data(0, 0, counterparty_txout, dummy_key.clone(), dummy_key.clone(), keys, 0, htlcs, &channel_parameters); htlcs.sort_by_key(|htlc| htlc.0.transaction_output_index); HolderCommitmentTransaction { inner, @@ -1445,12 +1450,12 @@ impl CommitmentTransaction { /// Only include HTLCs that are above the dust limit for the channel. /// /// This is not exported to bindings users due to the generic though we likely should expose a version without - pub fn new_with_auxiliary_htlc_data(commitment_number: u64, to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, broadcaster_funding_key: PublicKey, countersignatory_funding_key: PublicKey, keys: TxCreationKeys, feerate_per_kw: u32, htlcs_with_aux: &mut Vec<(HTLCOutputInCommitment, T)>, channel_parameters: &DirectedChannelTransactionParameters) -> CommitmentTransaction { + pub fn new_with_auxiliary_htlc_data(commitment_number: u64, to_broadcaster_value_sat: u64, to_countersignatory_txout: TxOut, broadcaster_funding_key: PublicKey, countersignatory_funding_key: PublicKey, keys: TxCreationKeys, feerate_per_kw: u32, htlcs_with_aux: &mut Vec<(HTLCOutputInCommitment, T)>, channel_parameters: &DirectedChannelTransactionParameters) -> CommitmentTransaction { let to_broadcaster_value_sat = Amount::from_sat(to_broadcaster_value_sat); - let to_countersignatory_value_sat = Amount::from_sat(to_countersignatory_value_sat); + let to_countersignatory_value_sat = to_countersignatory_txout.value; // Sort outputs and populate output indices while keeping track of the auxiliary data - let (outputs, htlcs) = Self::internal_build_outputs(&keys, to_broadcaster_value_sat, to_countersignatory_value_sat, htlcs_with_aux, channel_parameters, &broadcaster_funding_key, &countersignatory_funding_key).unwrap(); + let (outputs, htlcs) = Self::internal_build_outputs(&keys, to_broadcaster_value_sat, to_countersignatory_txout, htlcs_with_aux, channel_parameters, &broadcaster_funding_key, &countersignatory_funding_key).unwrap(); let (obscured_commitment_transaction_number, txins) = Self::internal_build_inputs(commitment_number, channel_parameters); let transaction = Self::make_transaction(obscured_commitment_transaction_number, txins, outputs); @@ -1479,11 +1484,15 @@ impl CommitmentTransaction { self } - fn internal_rebuild_transaction(&self, keys: &TxCreationKeys, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_funding_key: &PublicKey, countersignatory_funding_key: &PublicKey) -> Result { + fn internal_rebuild_transaction(&self, keys: &TxCreationKeys, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_funding_key: &PublicKey, countersignatory_funding_key: &PublicKey, to_countersignatory_spk: ScriptBuf) -> Result { let (obscured_commitment_transaction_number, txins) = Self::internal_build_inputs(self.commitment_number, channel_parameters); + let to_countersignatory_txout = TxOut { + script_pubkey: to_countersignatory_spk, + value: self.to_countersignatory_value_sat, + }; let mut htlcs_with_aux = self.htlcs.iter().map(|h| (h.clone(), ())).collect(); - let (outputs, _) = Self::internal_build_outputs(keys, self.to_broadcaster_value_sat, self.to_countersignatory_value_sat, &mut htlcs_with_aux, channel_parameters, broadcaster_funding_key, countersignatory_funding_key)?; + let (outputs, _) = Self::internal_build_outputs(keys, self.to_broadcaster_value_sat, to_countersignatory_txout, &mut htlcs_with_aux, channel_parameters, broadcaster_funding_key, countersignatory_funding_key)?; let transaction = Self::make_transaction(obscured_commitment_transaction_number, txins, outputs); let txid = transaction.compute_txid(); @@ -1507,23 +1516,14 @@ impl CommitmentTransaction { // - initial sorting of outputs / HTLCs in the constructor, in which case T is auxiliary data the // caller needs to have sorted together with the HTLCs so it can keep track of the output index // - building of a bitcoin transaction during a verify() call, in which case T is just () - fn internal_build_outputs(keys: &TxCreationKeys, to_broadcaster_value_sat: Amount, to_countersignatory_value_sat: Amount, htlcs_with_aux: &mut Vec<(HTLCOutputInCommitment, T)>, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_funding_key: &PublicKey, countersignatory_funding_key: &PublicKey) -> Result<(Vec, Vec), ()> { - let countersignatory_pubkeys = channel_parameters.countersignatory_pubkeys(); + fn internal_build_outputs(keys: &TxCreationKeys, to_broadcaster_value_sat: Amount, to_countersignatory_txout: TxOut, htlcs_with_aux: &mut Vec<(HTLCOutputInCommitment, T)>, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_funding_key: &PublicKey, countersignatory_funding_key: &PublicKey) -> Result<(Vec, Vec), ()> { let contest_delay = channel_parameters.contest_delay(); let mut txouts: Vec<(TxOut, Option<&mut HTLCOutputInCommitment>)> = Vec::new(); - if to_countersignatory_value_sat > Amount::ZERO { - let script = if channel_parameters.channel_type_features().supports_anchors_zero_fee_htlc_tx() { - get_to_countersignatory_with_anchors_redeemscript(&countersignatory_pubkeys.payment_point).to_p2wsh() - } else { - ScriptBuf::new_p2wpkh(&Hash160::hash(&countersignatory_pubkeys.payment_point.serialize()).into()) - }; + if to_countersignatory_txout.value > Amount::ZERO { txouts.push(( - TxOut { - script_pubkey: script.clone(), - value: to_countersignatory_value_sat, - }, + to_countersignatory_txout.clone(), None, )) } @@ -1555,7 +1555,7 @@ impl CommitmentTransaction { )); } - if to_countersignatory_value_sat > Amount::ZERO || !htlcs_with_aux.is_empty() { + if to_countersignatory_txout.value > Amount::ZERO || !htlcs_with_aux.is_empty() { let anchor_script = get_anchor_redeemscript(countersignatory_funding_key); txouts.push(( TxOut { @@ -1680,14 +1680,14 @@ impl CommitmentTransaction { /// /// An external validating signer must call this method before signing /// or using the built transaction. - pub fn verify(&self, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_keys: &ChannelPublicKeys, countersignatory_keys: &ChannelPublicKeys, secp_ctx: &Secp256k1) -> Result { + pub fn verify(&self, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_keys: &ChannelPublicKeys, countersignatory_keys: &ChannelPublicKeys, secp_ctx: &Secp256k1, to_countersignatory_spk: ScriptBuf) -> Result { // This is the only field of the key cache that we trust let per_commitment_point = self.keys.per_commitment_point; let keys = TxCreationKeys::from_channel_static_keys(&per_commitment_point, broadcaster_keys, countersignatory_keys, secp_ctx); if keys != self.keys { return Err(()); } - let tx = self.internal_rebuild_transaction(&keys, channel_parameters, &broadcaster_keys.funding_pubkey, &countersignatory_keys.funding_pubkey)?; + let tx = self.internal_rebuild_transaction(&keys, channel_parameters, &broadcaster_keys.funding_pubkey, &countersignatory_keys.funding_pubkey, to_countersignatory_spk)?; if self.built.transaction != tx.transaction || self.built.txid != tx.txid { return Err(()); } @@ -1894,11 +1894,11 @@ pub fn get_commitment_transaction_number_obscure_factor( mod tests { use super::{CounterpartyCommitmentSecrets, ChannelPublicKeys}; use crate::chain; - use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment}; + use crate::ln::chan_utils::{get_counterparty_payment_script, get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment}; use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1}; use crate::util::test_utils; use crate::sign::{ChannelSigner, SignerProvider}; - use bitcoin::{Network, Txid, ScriptBuf, CompressedPublicKey}; + use bitcoin::{Amount, TxOut, Network, Txid, ScriptBuf, CompressedPublicKey}; use bitcoin::hashes::Hash; use bitcoin::hex::FromHex; use crate::types::payment::PaymentHash; @@ -1957,12 +1957,20 @@ mod tests { } fn build(&mut self, to_broadcaster_sats: u64, to_countersignatory_sats: u64) -> CommitmentTransaction { + let channel_parameters = self.channel_parameters.as_holder_broadcastable(); + let counterparty_payment_script = get_counterparty_payment_script(&channel_parameters.channel_type_features(), &channel_parameters.countersignatory_pubkeys().payment_point); + let counterparty_txout = TxOut { + script_pubkey: counterparty_payment_script, + value: Amount::from_sat(to_countersignatory_sats), + }; CommitmentTransaction::new_with_auxiliary_htlc_data( - self.commitment_number, to_broadcaster_sats, to_countersignatory_sats, + self.commitment_number, + to_broadcaster_sats, + counterparty_txout, self.holder_funding_pubkey.clone(), self.counterparty_funding_pubkey.clone(), self.keys.clone(), self.feerate_per_kw, - &mut self.htlcs_with_aux, &self.channel_parameters.as_holder_broadcastable() + &mut self.htlcs_with_aux, &channel_parameters, ) } } diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 32e81cabda0..cd07142da65 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -15,7 +15,7 @@ use bitcoin::sighash; use bitcoin::sighash::EcdsaSighashType; use bitcoin::consensus::encode; use bitcoin::absolute::LockTime; -use bitcoin::Weight; +use bitcoin::{TxOut, Weight}; use bitcoin::hashes::Hash; use bitcoin::hashes::sha256::Hash as Sha256; @@ -1609,8 +1609,7 @@ trait InitialRemoteCommitmentReceiver where SP::Target: SignerProvide let funding_txo_script = funding_redeemscript.to_p2wsh(); let obscure_factor = get_commitment_transaction_number_obscure_factor(&context.get_holder_pubkeys().payment_point, &context.get_counterparty_pubkeys().payment_point, context.is_outbound()); let shutdown_script = context.shutdown_scriptpubkey.clone().map(|script| script.into_inner()); - let mut monitor_signer = signer_provider.derive_channel_signer(context.channel_value_satoshis, context.channel_keys_id); - monitor_signer.provide_channel_parameters(&context.channel_transaction_parameters); + let monitor_signer = signer_provider.derive_channel_signer(context.channel_value_satoshis, context.channel_keys_id); let channel_monitor = ChannelMonitor::new(context.secp_ctx.clone(), monitor_signer, shutdown_script, context.get_holder_selected_contest_delay(), &context.destination_script, (funding_txo, funding_txo_script), @@ -3165,9 +3164,14 @@ impl ChannelContext where SP::Target: SignerProvider { let channel_parameters = if local { self.channel_transaction_parameters.as_holder_broadcastable() } else { self.channel_transaction_parameters.as_counterparty_broadcastable() }; + let counterparty_payment_script = self.holder_signer.as_ref().get_counterparty_payment_script(!local); + let counterparty_txout = TxOut { + script_pubkey: counterparty_payment_script, + value: Amount::from_sat(value_to_b as u64), + }; let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(commitment_number, value_to_a as u64, - value_to_b as u64, + counterparty_txout, funding_pubkey_a, funding_pubkey_b, keys.clone(), @@ -10839,6 +10843,7 @@ mod tests { use crate::ln::channel::{HTLCOutputInCommitment ,TxCreationKeys}; use crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint}; use crate::ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters}; + use crate::sign::type_resolver::ChannelSignerType; use crate::util::logger::Logger; use crate::sync::Arc; use core::str::FromStr; @@ -10912,6 +10917,9 @@ mod tests { macro_rules! test_commitment { ( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $($remain:tt)* ) => { chan.context.channel_transaction_parameters.channel_type_features = ChannelTypeFeatures::only_static_remote_key(); + let mut holder_signer = keys_provider.derive_channel_signer(chan.context.channel_value_satoshis, chan.context.channel_keys_id); + holder_signer.provide_channel_parameters(&chan.context.channel_transaction_parameters); + chan.context.holder_signer = ChannelSignerType::Ecdsa(holder_signer); test_commitment_common!($counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::only_static_remote_key(), $($remain)*); }; } @@ -10919,6 +10927,9 @@ mod tests { macro_rules! test_commitment_with_anchors { ( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $($remain:tt)* ) => { chan.context.channel_transaction_parameters.channel_type_features = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(); + let mut holder_signer = keys_provider.derive_channel_signer(chan.context.channel_value_satoshis, chan.context.channel_keys_id); + holder_signer.provide_channel_parameters(&chan.context.channel_transaction_parameters); + chan.context.holder_signer = ChannelSignerType::Ecdsa(holder_signer); test_commitment_common!($counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(), $($remain)*); }; } diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index dc8edacb85e..c069534ca9f 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -766,16 +766,22 @@ fn test_update_fee_that_funder_cannot_afford() { |phase| if let ChannelPhase::Funded(chan) = phase { Some(chan) } else { None } ).flatten().unwrap(); let local_chan_signer = local_chan.get_signer(); + let channel_parameters = local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable(); + let counterparty_payment_script = local_chan_signer.as_ref().get_counterparty_payment_script(true); + let counterparty_txout = TxOut { + script_pubkey: counterparty_payment_script, + value: Amount::from_sat(channel_value - push_sats - commit_tx_fee_msat(non_buffer_feerate + 4, 0, &channel_type_features) / 1000), + }; let mut htlcs: Vec<(HTLCOutputInCommitment, ())> = vec![]; let commitment_tx = CommitmentTransaction::new_with_auxiliary_htlc_data( INITIAL_COMMITMENT_NUMBER - 1, push_sats, - channel_value - push_sats - commit_tx_fee_msat(non_buffer_feerate + 4, 0, &channel_type_features) / 1000, + counterparty_txout, local_funding, remote_funding, commit_tx_keys.clone(), non_buffer_feerate + 4, &mut htlcs, - &local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable() + &channel_parameters, ); local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), Vec::new(), &secp_ctx).unwrap() }; @@ -1517,15 +1523,21 @@ fn test_fee_spike_violation_fails_htlc() { |phase| if let ChannelPhase::Funded(chan) = phase { Some(chan) } else { None } ).flatten().unwrap(); let local_chan_signer = local_chan.get_signer(); + let channel_parameters = local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable(); + let counterparty_payment_script = local_chan_signer.as_ref().get_counterparty_payment_script(true); + let counterparty_txout = TxOut { + script_pubkey: counterparty_payment_script, + value: Amount::from_sat(local_chan_balance), + }; let commitment_tx = CommitmentTransaction::new_with_auxiliary_htlc_data( commitment_number, 95000, - local_chan_balance, + counterparty_txout, local_funding, remote_funding, commit_tx_keys.clone(), feerate_per_kw, &mut vec![(accepted_htlc_info, ())], - &local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable() + &channel_parameters, ); local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), Vec::new(), &secp_ctx).unwrap() }; diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index ed4f296b783..979e8fe61a4 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -42,8 +42,8 @@ use crate::chain::transaction::OutPoint; use crate::crypto::utils::{hkdf_extract_expand_twice, sign, sign_with_aux_rand}; use crate::ln::chan_utils; use crate::ln::chan_utils::{ - get_revokeable_redeemscript, make_funding_redeemscript, ChannelPublicKeys, - ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction, + get_counterparty_payment_script, get_revokeable_redeemscript, make_funding_redeemscript, + ChannelPublicKeys, ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction, }; use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI; @@ -795,6 +795,14 @@ pub trait ChannelSigner { /// /// channel_parameters.is_populated() MUST be true. fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters); + + /// Returns the scriptpubkey that should be placed in the `to_remote` output of commitment + /// transactions. Assumes the signer has already been given the channel parameters via + /// `provide_channel_parameters`. + /// + /// If `to_self` is set, return the `to_remote` script pubkey for the counterparty's commitment + /// transaction, otherwise, for the local party's. + fn get_counterparty_payment_script(&self, to_self: bool) -> ScriptBuf; } /// Specifies the recipient of an invoice. @@ -1379,6 +1387,16 @@ impl ChannelSigner for InMemorySigner { assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated"); self.channel_parameters = Some(channel_parameters.clone()); } + + fn get_counterparty_payment_script(&self, to_self: bool) -> ScriptBuf { + let params = if to_self { + self.channel_parameters.as_ref().unwrap().as_counterparty_broadcastable() + } else { + self.channel_parameters.as_ref().unwrap().as_holder_broadcastable() + }; + let payment_point = ¶ms.countersignatory_pubkeys().payment_point; + get_counterparty_payment_script(params.channel_type_features(), payment_point) + } } const MISSING_PARAMS_ERR: &'static str = diff --git a/lightning/src/util/test_channel_signer.rs b/lightning/src/util/test_channel_signer.rs index f3ef4dc1557..7dcb722ef86 100644 --- a/lightning/src/util/test_channel_signer.rs +++ b/lightning/src/util/test_channel_signer.rs @@ -25,6 +25,7 @@ use crate::sync::{Mutex, Arc}; use bitcoin::transaction::Transaction; use bitcoin::hashes::Hash; use bitcoin::sighash; +use bitcoin::ScriptBuf; use bitcoin::sighash::EcdsaSighashType; use bitcoin::secp256k1; @@ -212,6 +213,10 @@ impl ChannelSigner for TestChannelSigner { fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) { self.inner.provide_channel_parameters(channel_parameters) } + + fn get_counterparty_payment_script(&self, to_self: bool) -> ScriptBuf { + self.inner.get_counterparty_payment_script(to_self) + } } impl EcdsaChannelSigner for TestChannelSigner { @@ -415,16 +420,20 @@ impl Writeable for TestChannelSigner { impl TestChannelSigner { fn verify_counterparty_commitment_tx<'a, T: secp256k1::Signing + secp256k1::Verification>(&self, commitment_tx: &'a CommitmentTransaction, secp_ctx: &Secp256k1) -> TrustedCommitmentTransaction<'a> { + let counterparty_spk = self.get_counterparty_payment_script(true); commitment_tx.verify( &self.inner.get_channel_parameters().unwrap().as_counterparty_broadcastable(), - self.inner.counterparty_pubkeys().unwrap(), self.inner.pubkeys(), secp_ctx + self.inner.counterparty_pubkeys().unwrap(), self.inner.pubkeys(), secp_ctx, + counterparty_spk, ).expect("derived different per-tx keys or built transaction") } fn verify_holder_commitment_tx<'a, T: secp256k1::Signing + secp256k1::Verification>(&self, commitment_tx: &'a CommitmentTransaction, secp_ctx: &Secp256k1) -> TrustedCommitmentTransaction<'a> { + let counterparty_spk = self.get_counterparty_payment_script(false); commitment_tx.verify( &self.inner.get_channel_parameters().unwrap().as_holder_broadcastable(), - self.inner.pubkeys(), self.inner.counterparty_pubkeys().unwrap(), secp_ctx + self.inner.pubkeys(), self.inner.counterparty_pubkeys().unwrap(), secp_ctx, + counterparty_spk, ).expect("derived different per-tx keys or built transaction") } }