Skip to content

Commit 9008409

Browse files
tankyleoTheBlueMatt
andcommitted
Create a single P2A anchor on commitment transactions in 0FC channels
Zero-fee commitment channels replace today's existing `to_local_anchor` and `to_remote_anchor` outputs with a single `shared_anchor` output. Co-authored-by: Matt Corallo <[email protected]>
1 parent 9ddd25b commit 9008409

File tree

1 file changed

+38
-8
lines changed

1 file changed

+38
-8
lines changed

lightning/src/ln/chan_utils.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ pub const ANCHOR_INPUT_WITNESS_WEIGHT: u64 = 114;
8989
#[cfg(not(feature = "grind_signatures"))]
9090
pub const ANCHOR_INPUT_WITNESS_WEIGHT: u64 = 115;
9191

92+
/// The P2A scriptpubkey
93+
pub const P2A_SCRIPT: &[u8] = &[0x51, 0x02, 0x4e, 0x73];
94+
95+
/// The maximum value of the P2A anchor
96+
pub const P2A_MAX_VALUE: u64 = 240;
97+
9298
/// The upper bound weight of an HTLC timeout input from a commitment transaction with anchor
9399
/// outputs.
94100
pub const HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT: u64 = 288;
@@ -1232,6 +1238,11 @@ impl<'a> DirectedChannelTransactionParameters<'a> {
12321238
pub fn channel_type_features(&self) -> &'a ChannelTypeFeatures {
12331239
&self.inner.channel_type_features
12341240
}
1241+
1242+
/// The value locked in the channel, denominated in satoshis.
1243+
pub fn channel_value_satoshis(&self) -> u64 {
1244+
self.inner.channel_value_satoshis
1245+
}
12351246
}
12361247

12371248
/// Information needed to build and sign a holder's commitment transaction.
@@ -1637,7 +1648,7 @@ impl CommitmentTransaction {
16371648
let outputs = Self::build_outputs_and_htlcs(&keys, to_broadcaster_value_sat, to_countersignatory_value_sat, &mut nondust_htlcs, channel_parameters);
16381649

16391650
let (obscured_commitment_transaction_number, txins) = Self::build_inputs(commitment_number, channel_parameters);
1640-
let transaction = Self::make_transaction(obscured_commitment_transaction_number, txins, outputs);
1651+
let transaction = Self::make_transaction(obscured_commitment_transaction_number, txins, outputs, channel_parameters);
16411652
let txid = transaction.compute_txid();
16421653
CommitmentTransaction {
16431654
commitment_number,
@@ -1691,6 +1702,8 @@ impl CommitmentTransaction {
16911702
// First rebuild the htlc outputs, note that `outputs` is now the same length as `self.nondust_htlcs`
16921703
let mut outputs = Self::build_htlc_outputs(keys, &self.nondust_htlcs, channel_parameters.channel_type_features());
16931704

1705+
let nondust_htlcs_value_sum_sat = self.nondust_htlcs.iter().map(|htlc| htlc.to_bitcoin_amount()).sum();
1706+
16941707
// Check that the HTLC outputs are sorted by value, script pubkey, and cltv expiry.
16951708
// Note that this only iterates if the length of `outputs` and `self.nondust_htlcs` is >= 2.
16961709
if (1..outputs.len()).into_iter().any(|i| Self::is_left_greater(i, &outputs, &self.nondust_htlcs)) {
@@ -1713,11 +1726,11 @@ impl CommitmentTransaction {
17131726
self.to_broadcaster_value_sat,
17141727
self.to_countersignatory_value_sat,
17151728
channel_parameters,
1716-
!self.nondust_htlcs.is_empty(),
1729+
nondust_htlcs_value_sum_sat,
17171730
insert_non_htlc_output
17181731
);
17191732

1720-
let transaction = Self::make_transaction(obscured_commitment_transaction_number, txins, outputs);
1733+
let transaction = Self::make_transaction(obscured_commitment_transaction_number, txins, outputs, channel_parameters);
17211734
let txid = transaction.compute_txid();
17221735
let built_transaction = BuiltCommitmentTransaction {
17231736
transaction,
@@ -1727,9 +1740,14 @@ impl CommitmentTransaction {
17271740
}
17281741

17291742
#[rustfmt::skip]
1730-
fn make_transaction(obscured_commitment_transaction_number: u64, txins: Vec<TxIn>, outputs: Vec<TxOut>) -> Transaction {
1743+
fn make_transaction(obscured_commitment_transaction_number: u64, txins: Vec<TxIn>, outputs: Vec<TxOut>, channel_parameters: &DirectedChannelTransactionParameters) -> Transaction {
1744+
let version = if channel_parameters.channel_type_features().supports_anchor_zero_fee_commitments() {
1745+
Version::non_standard(3)
1746+
} else {
1747+
Version::TWO
1748+
};
17311749
Transaction {
1732-
version: Version::TWO,
1750+
version,
17331751
lock_time: LockTime::from_consensus(((0x20 as u32) << 8 * 3) | ((obscured_commitment_transaction_number & 0xffffffu64) as u32)),
17341752
input: txins,
17351753
output: outputs,
@@ -1747,7 +1765,8 @@ impl CommitmentTransaction {
17471765
// First build and sort the HTLC outputs.
17481766
// Also sort the HTLC output data in `nondust_htlcs` in the same order.
17491767
let mut outputs = Self::build_sorted_htlc_outputs(keys, nondust_htlcs, channel_parameters.channel_type_features());
1750-
let tx_has_htlc_outputs = !outputs.is_empty();
1768+
1769+
let nondust_htlcs_value_sum_sat = nondust_htlcs.iter().map(|htlc| htlc.to_bitcoin_amount()).sum();
17511770

17521771
// Initialize the transaction output indices; we will update them below when we
17531772
// add the non-htlc transaction outputs.
@@ -1784,7 +1803,7 @@ impl CommitmentTransaction {
17841803
to_broadcaster_value_sat,
17851804
to_countersignatory_value_sat,
17861805
channel_parameters,
1787-
tx_has_htlc_outputs,
1806+
nondust_htlcs_value_sum_sat,
17881807
insert_non_htlc_output
17891808
);
17901809

@@ -1797,7 +1816,7 @@ impl CommitmentTransaction {
17971816
to_broadcaster_value_sat: Amount,
17981817
to_countersignatory_value_sat: Amount,
17991818
channel_parameters: &DirectedChannelTransactionParameters,
1800-
tx_has_htlc_outputs: bool,
1819+
nondust_htlcs_value_sum_sat: Amount,
18011820
mut insert_non_htlc_output: F,
18021821
) where
18031822
F: FnMut(TxOut),
@@ -1807,6 +1826,7 @@ impl CommitmentTransaction {
18071826
let broadcaster_funding_key = &channel_parameters.broadcaster_pubkeys().funding_pubkey;
18081827
let channel_type = channel_parameters.channel_type_features();
18091828
let contest_delay = channel_parameters.contest_delay();
1829+
let tx_has_htlc_outputs = nondust_htlcs_value_sum_sat != Amount::ZERO;
18101830

18111831
if to_countersignatory_value_sat > Amount::ZERO {
18121832
let script = if channel_type.supports_anchors_zero_fee_htlc_tx() {
@@ -1849,6 +1869,16 @@ impl CommitmentTransaction {
18491869
});
18501870
}
18511871
}
1872+
1873+
if channel_type.supports_anchor_zero_fee_commitments() {
1874+
let channel_value_satoshis = Amount::from_sat(channel_parameters.channel_value_satoshis());
1875+
// These subtractions panic on underflow, but this should never happen
1876+
let trimmed_sum_sat = channel_value_satoshis - nondust_htlcs_value_sum_sat - to_broadcaster_value_sat - to_countersignatory_value_sat;
1877+
insert_non_htlc_output(TxOut {
1878+
script_pubkey: ScriptBuf::from_bytes(P2A_SCRIPT.to_vec()),
1879+
value: cmp::min(Amount::from_sat(P2A_MAX_VALUE), trimmed_sum_sat),
1880+
});
1881+
}
18521882
}
18531883

18541884
#[rustfmt::skip]

0 commit comments

Comments
 (0)