Skip to content

Commit

Permalink
[Custom Transactions] Define the TxBuilder trait
Browse files Browse the repository at this point in the history
This commit defines the `TxBuilder` trait to give users the ability to
customize the build of the lightning commitment transactions.

The `TxBuilder` trait has a single method,
`build_commitment_transaction`, which builds the commitment transaction,
and populates the output indices of the HTLCs passed in. Note that the
method itself does not impose any sorting.
  • Loading branch information
tankyleo committed Feb 20, 2025
1 parent b05402a commit beec57f
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@ check-cfg = [
"cfg(splicing)",
"cfg(async_payments)",
"cfg(dual_funding)",
"cfg(custom_tx)",
]
2 changes: 2 additions & 0 deletions ci/ci-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,6 @@ RUSTFLAGS="--cfg=trampoline" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=async_payments" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=custom_tx" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=lsps1_service" cargo test --verbose --color always -p lightning-liquidity
13 changes: 13 additions & 0 deletions lightning/src/sign/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ use crate::prelude::*;
use crate::sign::ecdsa::EcdsaChannelSigner;
#[cfg(taproot)]
use crate::sign::taproot::TaprootChannelSigner;
#[cfg(custom_tx)]
use crate::sign::tx_builder::SpecTxBuilder;
use crate::types::features::ChannelTypeFeatures;
use crate::util::atomic_counter::AtomicCounter;
use core::convert::TryInto;
Expand All @@ -81,6 +83,8 @@ pub(crate) mod type_resolver;
pub mod ecdsa;
#[cfg(taproot)]
pub mod taproot;
#[cfg(custom_tx)]
pub mod tx_builder;

/// Information about a spendable output to a P2WSH script.
///
Expand Down Expand Up @@ -816,6 +820,10 @@ pub trait ChannelSigner {
///
/// channel_parameters.is_populated() MUST be true.
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);

/// Derive a `TxBuilder`
#[cfg(custom_tx)]
fn derive_tx_builder(&self) -> SpecTxBuilder;
}

/// Specifies the recipient of an invoice.
Expand Down Expand Up @@ -1400,6 +1408,11 @@ impl ChannelSigner for InMemorySigner {
assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
self.channel_parameters = Some(channel_parameters.clone());
}

#[cfg(custom_tx)]
fn derive_tx_builder(&self) -> SpecTxBuilder {
SpecTxBuilder::default()
}
}

const MISSING_PARAMS_ERR: &'static str =
Expand Down
81 changes: 81 additions & 0 deletions lightning/src/sign/tx_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! Defines the `TxBuilder` trait, and the `SpecTxBuilder` type
#![allow(dead_code)]
#![allow(unused_variables)]

use bitcoin::secp256k1::{self, PublicKey, Secp256k1};
use bitcoin::{Amount, Transaction};

use crate::ln::chan_utils::{ChannelTransactionParameters, HTLCOutputInCommitment, TxCreationKeys};
use crate::prelude::*;

/// A trait for types that can build commitment transactions, both for the holder, and the counterparty.
pub trait TxBuilder {
/// Set the counterparty static channel data, including basepoints,
/// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
///
/// This data is static, and will never change for a channel once set.
///
/// channel_parameters.is_populated() MUST be true.
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
/// Build a commitment transaction, and populate the elements of `htlcs` with their output indices.
/// Do not sort `htlcs`; this will be done by the caller as needed.
/// This method will be called only after all the channel parameters have been provided via `provide_channel_parameters`.
fn build_commitment_transaction(
&self, is_holder_tx: bool, commitment_number: u64, per_commitment_point: &PublicKey,
to_broadcaster_value_sat: Amount, to_countersignatory_value_sat: Amount,
trimmed_value_sat: Amount, htlcs: Vec<&mut HTLCOutputInCommitment>,
secp_ctx: &Secp256k1<secp256k1::All>,
) -> Transaction;
}

/// A type that builds commitment transactions according to the Lightning Specification.
#[derive(Clone, Debug, Default)]
pub struct SpecTxBuilder {
channel_parameters: Option<ChannelTransactionParameters>,
}

impl TxBuilder for SpecTxBuilder {
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
assert!(
self.channel_parameters.is_none()
|| self.channel_parameters.as_ref().unwrap() == channel_parameters
);
if self.channel_parameters.is_some() {
// The channel parameters were already set and they match, return early.
return;
}
assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
self.channel_parameters = Some(channel_parameters.clone());
}
fn build_commitment_transaction(
&self, is_holder_tx: bool, commitment_number: u64, per_commitment_point: &PublicKey,
to_broadcaster_value_sat: Amount, to_countersignatory_value_sat: Amount,
trimmed_value_sat: Amount, htlcs: Vec<&mut HTLCOutputInCommitment>,
secp_ctx: &Secp256k1<secp256k1::All>,
) -> Transaction {
let params = if is_holder_tx {
self.channel_parameters.as_ref().unwrap().as_holder_broadcastable()
} else {
self.channel_parameters.as_ref().unwrap().as_counterparty_broadcastable()
};
let keys = TxCreationKeys::from_channel_static_keys(
per_commitment_point,
params.broadcaster_pubkeys(),
params.countersignatory_pubkeys(),
secp_ctx,
);
/*
let (obscured_commitment_transaction_number, txins) =
internal_build_inputs(commitment_number, &params);
let txouts = internal_build_outputs(
&keys,
to_broadcaster_value_sat,
to_countersignatory_value_sat,
htlcs,
&params,
);
make_transaction(obscured_commitment_transaction_number, txins, txouts)
*/
todo!();
}
}
7 changes: 7 additions & 0 deletions lightning/src/util/test_channel_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use crate::ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSH
use crate::ln::channel_keys::HtlcKey;
use crate::ln::msgs;
use crate::sign::ecdsa::EcdsaChannelSigner;
#[cfg(custom_tx)]
use crate::sign::tx_builder::SpecTxBuilder;
use crate::sign::{ChannelSigner, InMemorySigner};
use crate::types::payment::PaymentPreimage;

Expand Down Expand Up @@ -227,6 +229,11 @@ impl ChannelSigner for TestChannelSigner {
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
self.inner.provide_channel_parameters(channel_parameters)
}

#[cfg(custom_tx)]
fn derive_tx_builder(&self) -> SpecTxBuilder {
SpecTxBuilder::default()
}
}

impl EcdsaChannelSigner for TestChannelSigner {
Expand Down

0 comments on commit beec57f

Please sign in to comment.