Skip to content

Commit af7c292

Browse files
authored
Merge pull request #1828 from lightning-signer/2022-11-non-zero-fee-anchors
Re-add support for non-zero-fee-anchors to chan_utils
2 parents 17e1403 + e6b9694 commit af7c292

File tree

6 files changed

+42
-18
lines changed

6 files changed

+42
-18
lines changed

fuzz/src/full_stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ impl KeysInterface for KeyProvider {
311311
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr]).unwrap(),
312312
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, ctr],
313313
channel_value_satoshis,
314-
[0; 32]
314+
[0; 32],
315315
)
316316
} else {
317317
InMemorySigner::new(
@@ -324,7 +324,7 @@ impl KeysInterface for KeyProvider {
324324
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(),
325325
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr],
326326
channel_value_satoshis,
327-
[0; 32]
327+
[0; 32],
328328
)
329329
})
330330
}

lightning/src/chain/channelmonitor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4044,7 +4044,7 @@ mod tests {
40444044
SecretKey::from_slice(&[41; 32]).unwrap(),
40454045
[41; 32],
40464046
0,
4047-
[0; 32]
4047+
[0; 32],
40484048
);
40494049

40504050
let counterparty_pubkeys = ChannelPublicKeys {
@@ -4065,6 +4065,7 @@ mod tests {
40654065
}),
40664066
funding_outpoint: Some(funding_outpoint),
40674067
opt_anchors: None,
4068+
opt_non_zero_fee_anchors: None,
40684069
};
40694070
// Prune with one old state and a holder commitment tx holding a few overlaps with the
40704071
// old state.

lightning/src/chain/keysinterface.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,8 @@ impl InMemorySigner {
533533
htlc_base_key: SecretKey,
534534
commitment_seed: [u8; 32],
535535
channel_value_satoshis: u64,
536-
channel_keys_id: [u8; 32]) -> InMemorySigner {
536+
channel_keys_id: [u8; 32],
537+
) -> InMemorySigner {
537538
let holder_channel_pubkeys =
538539
InMemorySigner::make_holder_keys(secp_ctx, &funding_key, &revocation_base_key,
539540
&payment_key, &delayed_payment_base_key,
@@ -704,7 +705,8 @@ impl BaseSign for InMemorySigner {
704705

705706
let mut htlc_sigs = Vec::with_capacity(commitment_tx.htlcs().len());
706707
for htlc in commitment_tx.htlcs() {
707-
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw(), self.holder_selected_contest_delay(), htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
708+
let channel_parameters = self.get_channel_parameters();
709+
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw(), self.holder_selected_contest_delay(), htlc, self.opt_anchors(), channel_parameters.opt_non_zero_fee_anchors.is_some(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
708710
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
709711
let htlc_sighashtype = if self.opt_anchors() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
710712
let htlc_sighash = hash_to_message!(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype).unwrap()[..]);
@@ -1035,7 +1037,7 @@ impl KeysManager {
10351037
htlc_base_key,
10361038
commitment_seed,
10371039
channel_value_satoshis,
1038-
params.clone()
1040+
params.clone(),
10391041
)
10401042
}
10411043

lightning/src/ln/chan_utils.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ pub fn make_funding_redeemscript(broadcaster: &PublicKey, countersignatory: &Pub
660660
///
661661
/// Panics if htlc.transaction_output_index.is_none() (as such HTLCs do not appear in the
662662
/// commitment transaction).
663-
pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, contest_delay: u16, htlc: &HTLCOutputInCommitment, opt_anchors: bool, broadcaster_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction {
663+
pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, contest_delay: u16, htlc: &HTLCOutputInCommitment, opt_anchors: bool, use_non_zero_fee_anchors: bool, broadcaster_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction {
664664
let mut txins: Vec<TxIn> = Vec::new();
665665
txins.push(TxIn {
666666
previous_output: OutPoint {
@@ -677,7 +677,7 @@ pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, conte
677677
} else {
678678
htlc_success_tx_weight(opt_anchors)
679679
};
680-
let output_value = if opt_anchors {
680+
let output_value = if opt_anchors && !use_non_zero_fee_anchors {
681681
htlc.amount_msat / 1000
682682
} else {
683683
let total_fee = feerate_per_kw as u64 * weight / 1000;
@@ -765,7 +765,11 @@ pub struct ChannelTransactionParameters {
765765
pub funding_outpoint: Option<chain::transaction::OutPoint>,
766766
/// Are anchors (zero fee HTLC transaction variant) used for this channel. Boolean is
767767
/// serialization backwards-compatible.
768-
pub opt_anchors: Option<()>
768+
pub opt_anchors: Option<()>,
769+
/// Are non-zero-fee anchors are enabled (used in conjuction with opt_anchors)
770+
/// It is intended merely for backwards compatibility with signers that need it.
771+
/// There is no support for this feature in LDK channel negotiation.
772+
pub opt_non_zero_fee_anchors: Option<()>,
769773
}
770774

771775
/// Late-bound per-channel counterparty data used to build transactions.
@@ -820,6 +824,7 @@ impl_writeable_tlv_based!(ChannelTransactionParameters, {
820824
(6, counterparty_parameters, option),
821825
(8, funding_outpoint, option),
822826
(10, opt_anchors, option),
827+
(12, opt_non_zero_fee_anchors, option),
823828
});
824829

825830
/// Static channel fields used to build transactions given per-commitment fields, organized by
@@ -942,7 +947,8 @@ impl HolderCommitmentTransaction {
942947
is_outbound_from_holder: false,
943948
counterparty_parameters: Some(CounterpartyChannelTransactionParameters { pubkeys: channel_pubkeys.clone(), selected_contest_delay: 0 }),
944949
funding_outpoint: Some(chain::transaction::OutPoint { txid: Txid::all_zeros(), index: 0 }),
945-
opt_anchors: None
950+
opt_anchors: None,
951+
opt_non_zero_fee_anchors: None,
946952
};
947953
let mut htlcs_with_aux: Vec<(_, ())> = Vec::new();
948954
let inner = CommitmentTransaction::new_with_auxiliary_htlc_data(0, 0, 0, false, dummy_key.clone(), dummy_key.clone(), keys, 0, &mut htlcs_with_aux, &channel_parameters.as_counterparty_broadcastable());
@@ -1160,6 +1166,8 @@ pub struct CommitmentTransaction {
11601166
htlcs: Vec<HTLCOutputInCommitment>,
11611167
// A boolean that is serialization backwards-compatible
11621168
opt_anchors: Option<()>,
1169+
// Whether non-zero-fee anchors should be used
1170+
opt_non_zero_fee_anchors: Option<()>,
11631171
// A cache of the parties' pubkeys required to construct the transaction, see doc for trust()
11641172
keys: TxCreationKeys,
11651173
// For access to the pre-built transaction, see doc for trust()
@@ -1193,6 +1201,7 @@ impl_writeable_tlv_based!(CommitmentTransaction, {
11931201
(10, built, required),
11941202
(12, htlcs, vec_type),
11951203
(14, opt_anchors, option),
1204+
(16, opt_non_zero_fee_anchors, option),
11961205
});
11971206

11981207
impl CommitmentTransaction {
@@ -1225,9 +1234,18 @@ impl CommitmentTransaction {
12251234
transaction,
12261235
txid
12271236
},
1237+
opt_non_zero_fee_anchors: None,
12281238
}
12291239
}
12301240

1241+
/// Use non-zero fee anchors
1242+
///
1243+
/// (C-not exported) due to move, and also not likely to be useful for binding users
1244+
pub fn with_non_zero_fee_anchors(mut self) -> Self {
1245+
self.opt_non_zero_fee_anchors = Some(());
1246+
self
1247+
}
1248+
12311249
fn internal_rebuild_transaction(&self, keys: &TxCreationKeys, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_funding_key: &PublicKey, countersignatory_funding_key: &PublicKey) -> Result<BuiltCommitmentTransaction, ()> {
12321250
let (obscured_commitment_transaction_number, txins) = Self::internal_build_inputs(self.commitment_number, channel_parameters);
12331251

@@ -1492,7 +1510,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
14921510

14931511
for this_htlc in inner.htlcs.iter() {
14941512
assert!(this_htlc.transaction_output_index.is_some());
1495-
let htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
1513+
let htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), self.opt_non_zero_fee_anchors.is_some(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
14961514

14971515
let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
14981516

@@ -1514,7 +1532,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
15141532
// Further, we should never be provided the preimage for an HTLC-Timeout transaction.
15151533
if this_htlc.offered && preimage.is_some() { unreachable!(); }
15161534

1517-
let mut htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
1535+
let mut htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), self.opt_non_zero_fee_anchors.is_some(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
15181536

15191537
let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
15201538

@@ -1614,7 +1632,8 @@ mod tests {
16141632
is_outbound_from_holder: false,
16151633
counterparty_parameters: Some(CounterpartyChannelTransactionParameters { pubkeys: counterparty_pubkeys.clone(), selected_contest_delay: 0 }),
16161634
funding_outpoint: Some(chain::transaction::OutPoint { txid: Txid::all_zeros(), index: 0 }),
1617-
opt_anchors: None
1635+
opt_anchors: None,
1636+
opt_non_zero_fee_anchors: None,
16181637
};
16191638

16201639
let mut htlcs_with_aux: Vec<(_, ())> = Vec::new();

lightning/src/ln/channel.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,7 @@ impl<Signer: Sign> Channel<Signer> {
10381038
counterparty_parameters: None,
10391039
funding_outpoint: None,
10401040
opt_anchors: if opt_anchors { Some(()) } else { None },
1041+
opt_non_zero_fee_anchors: None
10411042
},
10421043
funding_transaction: None,
10431044

@@ -1383,6 +1384,7 @@ impl<Signer: Sign> Channel<Signer> {
13831384
}),
13841385
funding_outpoint: None,
13851386
opt_anchors: if opt_anchors { Some(()) } else { None },
1387+
opt_non_zero_fee_anchors: None
13861388
},
13871389
funding_transaction: None,
13881390

@@ -3016,7 +3018,7 @@ impl<Signer: Sign> Channel<Signer> {
30163018
if let Some(_) = htlc.transaction_output_index {
30173019
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_stats.feerate_per_kw,
30183020
self.get_counterparty_selected_contest_delay().unwrap(), &htlc, self.opt_anchors(),
3019-
&keys.broadcaster_delayed_payment_key, &keys.revocation_key);
3021+
false, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
30203022

30213023
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
30223024
let htlc_sighashtype = if self.opt_anchors() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
@@ -5743,7 +5745,7 @@ impl<Signer: Sign> Channel<Signer> {
57435745

57445746
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
57455747
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {} in channel {}",
5746-
encode::serialize_hex(&chan_utils::build_htlc_transaction(&counterparty_commitment_txid, commitment_stats.feerate_per_kw, self.get_holder_selected_contest_delay(), htlc, self.opt_anchors(), &counterparty_keys.broadcaster_delayed_payment_key, &counterparty_keys.revocation_key)),
5748+
encode::serialize_hex(&chan_utils::build_htlc_transaction(&counterparty_commitment_txid, commitment_stats.feerate_per_kw, self.get_holder_selected_contest_delay(), htlc, self.opt_anchors(), false, &counterparty_keys.broadcaster_delayed_payment_key, &counterparty_keys.revocation_key)),
57475749
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &counterparty_keys)),
57485750
log_bytes!(counterparty_keys.broadcaster_htlc_key.serialize()),
57495751
log_bytes!(htlc_sig.serialize_compact()[..]), log_bytes!(self.channel_id()));
@@ -7250,7 +7252,7 @@ mod tests {
72507252
// These aren't set in the test vectors:
72517253
[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
72527254
10_000_000,
7253-
[0; 32]
7255+
[0; 32],
72547256
);
72557257

72567258
assert_eq!(signer.pubkeys().funding_pubkey.serialize()[..],
@@ -7368,7 +7370,7 @@ mod tests {
73687370
let ref htlc = htlcs[$htlc_idx];
73697371
let htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, chan.feerate_per_kw,
73707372
chan.get_counterparty_selected_contest_delay().unwrap(),
7371-
&htlc, $opt_anchors, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
7373+
&htlc, $opt_anchors, false, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
73727374
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, $opt_anchors, &keys);
73737375
let htlc_sighashtype = if $opt_anchors { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
73747376
let htlc_sighash = Message::from_slice(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype).unwrap()[..]).unwrap();

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl BaseSign for EnforcingSigner {
157157
for (this_htlc, sig) in trusted_tx.htlcs().iter().zip(&commitment_tx.counterparty_htlc_sigs) {
158158
assert!(this_htlc.transaction_output_index.is_some());
159159
let keys = trusted_tx.keys();
160-
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, trusted_tx.feerate_per_kw(), holder_csv, &this_htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
160+
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, trusted_tx.feerate_per_kw(), holder_csv, &this_htlc, self.opt_anchors(), false, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
161161

162162
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&this_htlc, self.opt_anchors(), &keys);
163163

0 commit comments

Comments
 (0)