Pass channel params to sign_counterparty_commitment

Now that channel_value_satoshis has been moved to
ChannelTransactionParameters, pass the entire parameters when calling
each method on EcdsaChannelSigner. This will remove the need for
ChannelSigner::provide_channel_parameters. Instead, the parameters from
the FundingScope will be passed in to each method. This simplifies the
interaction with a ChannelSigner when needing to be called for more than
one FundingScope, which will be the case for pending splices and RBF
attempts.
This commit is contained in:
Jeffrey Czyz 2025-02-20 10:17:40 -06:00
parent dc995eafcd
commit ee72c4a9b4
No known key found for this signature in database
GPG key ID: 3A4E08275D5E96D2
6 changed files with 43 additions and 23 deletions

View file

@ -931,6 +931,11 @@ impl ChannelTransactionParameters {
}
}
/// Returns the counterparty's pubkeys.
pub fn counterparty_pubkeys(&self) -> Option<&ChannelPublicKeys> {
self.counterparty_parameters.as_ref().map(|params| &params.pubkeys)
}
#[cfg(test)]
pub fn test_dummy(channel_value_satoshis: u64) -> Self {
let dummy_keys = ChannelPublicKeys {

View file

@ -4415,7 +4415,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
/// Only allowed after [`FundingScope::channel_transaction_parameters`] is set.
fn get_funding_signed_msg<L: Deref>(
&mut self, logger: &L, counterparty_initial_commitment_tx: CommitmentTransaction
&mut self, channel_parameters: &ChannelTransactionParameters, logger: &L,
counterparty_initial_commitment_tx: CommitmentTransaction,
) -> Option<msgs::FundingSigned> where L::Target: Logger {
let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();
let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction();
@ -4426,7 +4427,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
let signature = match &self.holder_signer {
// TODO (arik): move match into calling method for Taproot
ChannelSignerType::Ecdsa(ecdsa) => ecdsa.sign_counterparty_commitment(
&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx
channel_parameters, &counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx
).ok(),
// TODO (taproot|arik)
#[cfg(taproot)]
@ -4515,7 +4516,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
match self.holder_signer {
// TODO (taproot|arik): move match into calling method for Taproot
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
let channel_parameters = &funding.channel_transaction_parameters;
ecdsa.sign_counterparty_commitment(channel_parameters, &counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
@ -6592,7 +6594,7 @@ impl<SP: Deref> FundedChannel<SP> where
let funding_signed = if self.context.signer_pending_funding && !self.funding.is_outbound() {
let counterparty_keys = self.context.build_remote_transaction_keys(&self.funding);
let counterparty_initial_commitment_tx = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number + 1, &counterparty_keys, false, false, logger).tx;
self.context.get_funding_signed_msg(logger, counterparty_initial_commitment_tx)
self.context.get_funding_signed_msg(&self.funding.channel_transaction_parameters, logger, counterparty_initial_commitment_tx)
} else { None };
// Provide a `channel_ready` message if we need to, but only if we're _not_ still pending
// funding.
@ -8572,6 +8574,7 @@ impl<SP: Deref> FundedChannel<SP> where
}
let res = ecdsa.sign_counterparty_commitment(
&self.funding.channel_transaction_parameters,
&commitment_stats.tx,
commitment_stats.inbound_htlc_preimages,
commitment_stats.outbound_htlc_preimages,
@ -9045,7 +9048,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
let signature = match &self.context.holder_signer {
// TODO (taproot|arik): move match into calling method for Taproot
ChannelSignerType::Ecdsa(ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.context.secp_ctx)
let channel_parameters = &self.funding.channel_transaction_parameters;
ecdsa.sign_counterparty_commitment(channel_parameters, &counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.context.secp_ctx)
.map(|(sig, _)| sig).ok()
},
// TODO (taproot|arik)
@ -9496,7 +9500,9 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
Err(err) => return Err((self, err)),
};
let funding_signed = self.context.get_funding_signed_msg(logger, counterparty_initial_commitment_tx);
let funding_signed = self.context.get_funding_signed_msg(
&self.funding.channel_transaction_parameters, logger, counterparty_initial_commitment_tx
);
log_info!(logger, "{} funding_signed for peer for channel {}",
if funding_signed.is_some() { "Generated" } else { "Waiting for signature on" }, &self.context.channel_id());

View file

@ -771,7 +771,10 @@ fn test_update_fee_that_funder_cannot_afford() {
&mut htlcs,
&local_chan.funding.channel_transaction_parameters.as_counterparty_broadcastable()
);
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), Vec::new(), &secp_ctx).unwrap()
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(
&local_chan.funding.channel_transaction_parameters, &commitment_tx, Vec::new(),
Vec::new(), &secp_ctx,
).unwrap()
};
let commit_signed_msg = msgs::CommitmentSigned {
@ -1514,7 +1517,10 @@ fn test_fee_spike_violation_fails_htlc() {
&mut vec![(accepted_htlc_info, ())],
&local_chan.funding.channel_transaction_parameters.as_counterparty_broadcastable()
);
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), Vec::new(), &secp_ctx).unwrap()
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(
&local_chan.funding.channel_transaction_parameters, &commitment_tx, Vec::new(),
Vec::new(), &secp_ctx,
).unwrap()
};
let commit_signed_msg = msgs::CommitmentSigned {

View file

@ -15,7 +15,7 @@ use crate::types::payment::PaymentPreimage;
#[allow(unused_imports)]
use crate::prelude::*;
use crate::sign::{ChannelSigner, HTLCDescriptor};
use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
@ -53,7 +53,8 @@ pub trait EcdsaChannelSigner: ChannelSigner {
///
/// [`ChannelManager::signer_unblocked`]: crate::ln::channelmanager::ChannelManager::signer_unblocked
fn sign_counterparty_commitment(
&self, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>,
&self, channel_parameters: &ChannelTransactionParameters,
commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>,
outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>,
) -> Result<(Signature, Vec<Signature>), ()>;
/// Creates a signature for a holder's commitment transaction.

View file

@ -1390,15 +1390,16 @@ const MISSING_PARAMS_ERR: &'static str =
impl EcdsaChannelSigner for InMemorySigner {
fn sign_counterparty_commitment(
&self, commitment_tx: &CommitmentTransaction,
_inbound_htlc_preimages: Vec<PaymentPreimage>,
&self, channel_parameters: &ChannelTransactionParameters,
commitment_tx: &CommitmentTransaction, _inbound_htlc_preimages: Vec<PaymentPreimage>,
_outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>,
) -> Result<(Signature, Vec<Signature>), ()> {
let trusted_tx = commitment_tx.trust();
let keys = trusted_tx.keys();
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let counterparty_keys = self.counterparty_pubkeys().expect(MISSING_PARAMS_ERR);
let counterparty_keys =
channel_parameters.counterparty_pubkeys().expect(MISSING_PARAMS_ERR);
let channel_funding_redeemscript =
make_funding_redeemscript(&funding_pubkey, &counterparty_keys.funding_pubkey);
@ -1406,16 +1407,14 @@ impl EcdsaChannelSigner for InMemorySigner {
let commitment_sig = built_tx.sign_counterparty_commitment(
&self.funding_key,
&channel_funding_redeemscript,
self.channel_value_satoshis,
channel_parameters.channel_value_satoshis,
secp_ctx,
);
let commitment_txid = built_tx.txid;
let mut htlc_sigs = Vec::with_capacity(commitment_tx.htlcs().len());
for htlc in commitment_tx.htlcs() {
let channel_parameters = self.get_channel_parameters().expect(MISSING_PARAMS_ERR);
let holder_selected_contest_delay =
self.holder_selected_contest_delay().expect(MISSING_PARAMS_ERR);
let holder_selected_contest_delay = channel_parameters.holder_selected_contest_delay;
let chan_type = &channel_parameters.channel_type_features;
let htlc_tx = chan_utils::build_htlc_transaction(
&commitment_txid,

View file

@ -229,10 +229,11 @@ impl ChannelSigner for TestChannelSigner {
impl EcdsaChannelSigner for TestChannelSigner {
fn sign_counterparty_commitment(
&self, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>,
&self, channel_parameters: &ChannelTransactionParameters,
commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>,
outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>,
) -> Result<(Signature, Vec<Signature>), ()> {
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
self.verify_counterparty_commitment_tx(channel_parameters, commitment_tx, secp_ctx);
{
#[cfg(test)]
@ -266,6 +267,7 @@ impl EcdsaChannelSigner for TestChannelSigner {
Ok(self
.inner
.sign_counterparty_commitment(
channel_parameters,
commitment_tx,
inbound_htlc_preimages,
outbound_htlc_preimages,
@ -530,13 +532,14 @@ impl TaprootChannelSigner for TestChannelSigner {
impl TestChannelSigner {
fn verify_counterparty_commitment_tx<'a, T: secp256k1::Signing + secp256k1::Verification>(
&self, commitment_tx: &'a CommitmentTransaction, secp_ctx: &Secp256k1<T>,
&self, channel_parameters: &ChannelTransactionParameters,
commitment_tx: &'a CommitmentTransaction, secp_ctx: &Secp256k1<T>,
) -> TrustedCommitmentTransaction<'a> {
commitment_tx
.verify(
&self.inner.get_channel_parameters().unwrap().as_counterparty_broadcastable(),
self.inner.counterparty_pubkeys().unwrap(),
self.inner.pubkeys(),
&channel_parameters.as_counterparty_broadcastable(),
channel_parameters.counterparty_pubkeys().unwrap(),
&channel_parameters.holder_pubkeys,
secp_ctx,
)
.expect("derived different per-tx keys or built transaction")