Skip to content

Commit beec57f

Browse files
committed
[Custom Transactions] Define the TxBuilder trait
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.
1 parent b05402a commit beec57f

File tree

5 files changed

+104
-0
lines changed

5 files changed

+104
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ check-cfg = [
6767
"cfg(splicing)",
6868
"cfg(async_payments)",
6969
"cfg(dual_funding)",
70+
"cfg(custom_tx)",
7071
]

ci/ci-tests.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,6 @@ RUSTFLAGS="--cfg=trampoline" cargo test --verbose --color always -p lightning
135135
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
136136
RUSTFLAGS="--cfg=async_payments" cargo test --verbose --color always -p lightning
137137
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
138+
RUSTFLAGS="--cfg=custom_tx" cargo test --verbose --color always -p lightning
139+
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
138140
RUSTFLAGS="--cfg=lsps1_service" cargo test --verbose --color always -p lightning-liquidity

lightning/src/sign/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ use crate::prelude::*;
6868
use crate::sign::ecdsa::EcdsaChannelSigner;
6969
#[cfg(taproot)]
7070
use crate::sign::taproot::TaprootChannelSigner;
71+
#[cfg(custom_tx)]
72+
use crate::sign::tx_builder::SpecTxBuilder;
7173
use crate::types::features::ChannelTypeFeatures;
7274
use crate::util::atomic_counter::AtomicCounter;
7375
use core::convert::TryInto;
@@ -81,6 +83,8 @@ pub(crate) mod type_resolver;
8183
pub mod ecdsa;
8284
#[cfg(taproot)]
8385
pub mod taproot;
86+
#[cfg(custom_tx)]
87+
pub mod tx_builder;
8488

8589
/// Information about a spendable output to a P2WSH script.
8690
///
@@ -816,6 +820,10 @@ pub trait ChannelSigner {
816820
///
817821
/// channel_parameters.is_populated() MUST be true.
818822
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
823+
824+
/// Derive a `TxBuilder`
825+
#[cfg(custom_tx)]
826+
fn derive_tx_builder(&self) -> SpecTxBuilder;
819827
}
820828

821829
/// Specifies the recipient of an invoice.
@@ -1400,6 +1408,11 @@ impl ChannelSigner for InMemorySigner {
14001408
assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
14011409
self.channel_parameters = Some(channel_parameters.clone());
14021410
}
1411+
1412+
#[cfg(custom_tx)]
1413+
fn derive_tx_builder(&self) -> SpecTxBuilder {
1414+
SpecTxBuilder::default()
1415+
}
14031416
}
14041417

14051418
const MISSING_PARAMS_ERR: &'static str =

lightning/src/sign/tx_builder.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//! Defines the `TxBuilder` trait, and the `SpecTxBuilder` type
2+
#![allow(dead_code)]
3+
#![allow(unused_variables)]
4+
5+
use bitcoin::secp256k1::{self, PublicKey, Secp256k1};
6+
use bitcoin::{Amount, Transaction};
7+
8+
use crate::ln::chan_utils::{ChannelTransactionParameters, HTLCOutputInCommitment, TxCreationKeys};
9+
use crate::prelude::*;
10+
11+
/// A trait for types that can build commitment transactions, both for the holder, and the counterparty.
12+
pub trait TxBuilder {
13+
/// Set the counterparty static channel data, including basepoints,
14+
/// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
15+
///
16+
/// This data is static, and will never change for a channel once set.
17+
///
18+
/// channel_parameters.is_populated() MUST be true.
19+
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
20+
/// Build a commitment transaction, and populate the elements of `htlcs` with their output indices.
21+
/// Do not sort `htlcs`; this will be done by the caller as needed.
22+
/// This method will be called only after all the channel parameters have been provided via `provide_channel_parameters`.
23+
fn build_commitment_transaction(
24+
&self, is_holder_tx: bool, commitment_number: u64, per_commitment_point: &PublicKey,
25+
to_broadcaster_value_sat: Amount, to_countersignatory_value_sat: Amount,
26+
trimmed_value_sat: Amount, htlcs: Vec<&mut HTLCOutputInCommitment>,
27+
secp_ctx: &Secp256k1<secp256k1::All>,
28+
) -> Transaction;
29+
}
30+
31+
/// A type that builds commitment transactions according to the Lightning Specification.
32+
#[derive(Clone, Debug, Default)]
33+
pub struct SpecTxBuilder {
34+
channel_parameters: Option<ChannelTransactionParameters>,
35+
}
36+
37+
impl TxBuilder for SpecTxBuilder {
38+
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
39+
assert!(
40+
self.channel_parameters.is_none()
41+
|| self.channel_parameters.as_ref().unwrap() == channel_parameters
42+
);
43+
if self.channel_parameters.is_some() {
44+
// The channel parameters were already set and they match, return early.
45+
return;
46+
}
47+
assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
48+
self.channel_parameters = Some(channel_parameters.clone());
49+
}
50+
fn build_commitment_transaction(
51+
&self, is_holder_tx: bool, commitment_number: u64, per_commitment_point: &PublicKey,
52+
to_broadcaster_value_sat: Amount, to_countersignatory_value_sat: Amount,
53+
trimmed_value_sat: Amount, htlcs: Vec<&mut HTLCOutputInCommitment>,
54+
secp_ctx: &Secp256k1<secp256k1::All>,
55+
) -> Transaction {
56+
let params = if is_holder_tx {
57+
self.channel_parameters.as_ref().unwrap().as_holder_broadcastable()
58+
} else {
59+
self.channel_parameters.as_ref().unwrap().as_counterparty_broadcastable()
60+
};
61+
let keys = TxCreationKeys::from_channel_static_keys(
62+
per_commitment_point,
63+
params.broadcaster_pubkeys(),
64+
params.countersignatory_pubkeys(),
65+
secp_ctx,
66+
);
67+
/*
68+
let (obscured_commitment_transaction_number, txins) =
69+
internal_build_inputs(commitment_number, &params);
70+
let txouts = internal_build_outputs(
71+
&keys,
72+
to_broadcaster_value_sat,
73+
to_countersignatory_value_sat,
74+
htlcs,
75+
&params,
76+
);
77+
make_transaction(obscured_commitment_transaction_number, txins, txouts)
78+
*/
79+
todo!();
80+
}
81+
}

lightning/src/util/test_channel_signer.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use crate::ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSH
1515
use crate::ln::channel_keys::HtlcKey;
1616
use crate::ln::msgs;
1717
use crate::sign::ecdsa::EcdsaChannelSigner;
18+
#[cfg(custom_tx)]
19+
use crate::sign::tx_builder::SpecTxBuilder;
1820
use crate::sign::{ChannelSigner, InMemorySigner};
1921
use crate::types::payment::PaymentPreimage;
2022

@@ -227,6 +229,11 @@ impl ChannelSigner for TestChannelSigner {
227229
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
228230
self.inner.provide_channel_parameters(channel_parameters)
229231
}
232+
233+
#[cfg(custom_tx)]
234+
fn derive_tx_builder(&self) -> SpecTxBuilder {
235+
SpecTxBuilder::default()
236+
}
230237
}
231238

232239
impl EcdsaChannelSigner for TestChannelSigner {

0 commit comments

Comments
 (0)