Skip to content

Commit 2b92b08

Browse files
committed
ln/test: move commitment check macro out of outbound test
To be used in the commits that follow for zero fee commitment test vectors.
1 parent ec0b969 commit 2b92b08

File tree

1 file changed

+104
-101
lines changed

1 file changed

+104
-101
lines changed

lightning/src/ln/channel.rs

Lines changed: 104 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -16496,6 +16496,108 @@ mod tests {
1649616496
assert_eq!(decoded_chan.context.holding_cell_htlc_updates, holding_cell_htlc_updates);
1649716497
}
1649816498

16499+
#[cfg(ldk_test_vectors)]
16500+
#[rustfmt::skip]
16501+
macro_rules! test_commitment_common {
16502+
( $chan: expr, $logger: expr, $secp_ctx: expr, $signer: expr, $holder_pubkeys: expr, $per_commitment_point: expr, $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $channel_type_features: expr, {
16503+
$( { $htlc_idx: expr, $counterparty_htlc_sig_hex: expr, $htlc_sig_hex: expr, $htlc_tx_hex: expr } ), *
16504+
} ) => { {
16505+
let commitment_data = $chan.context.build_commitment_transaction(&$chan.funding,
16506+
0xffffffffffff - 42, &$per_commitment_point, true, false, &$logger);
16507+
let commitment_tx = commitment_data.tx;
16508+
let trusted_tx = commitment_tx.trust();
16509+
let unsigned_tx = trusted_tx.built_transaction();
16510+
let redeemscript = $chan.funding.get_funding_redeemscript();
16511+
let counterparty_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_sig_hex).unwrap()[..]).unwrap();
16512+
let sighash = unsigned_tx.get_sighash_all(&redeemscript, $chan.funding.get_value_satoshis());
16513+
log_trace!($logger, "unsigned_tx = {}", serialize(&unsigned_tx.transaction).as_hex());
16514+
assert!($secp_ctx.verify_ecdsa(&sighash, &counterparty_signature, $chan.funding.counterparty_funding_pubkey()).is_ok(), "verify counterparty commitment sig");
16515+
16516+
let mut per_htlc: Vec<(HTLCOutputInCommitment, Option<Signature>)> = Vec::new();
16517+
per_htlc.clear(); // Don't warn about excess mut for no-HTLC calls
16518+
let mut counterparty_htlc_sigs = Vec::new();
16519+
counterparty_htlc_sigs.clear(); // Don't warn about excess mut for no-HTLC calls
16520+
$({
16521+
let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16522+
per_htlc.push((commitment_tx.nondust_htlcs()[$htlc_idx].clone(), Some(remote_signature)));
16523+
counterparty_htlc_sigs.push(remote_signature);
16524+
})*
16525+
assert_eq!(commitment_tx.nondust_htlcs().len(), per_htlc.len());
16526+
16527+
let holder_commitment_tx = HolderCommitmentTransaction::new(
16528+
commitment_tx.clone(),
16529+
counterparty_signature,
16530+
counterparty_htlc_sigs,
16531+
&$holder_pubkeys.funding_pubkey,
16532+
$chan.funding.counterparty_funding_pubkey()
16533+
);
16534+
let holder_sig = $signer.sign_holder_commitment(&$chan.funding.channel_transaction_parameters, &holder_commitment_tx, &$secp_ctx).unwrap();
16535+
assert_eq!(Signature::from_der(&<Vec<u8>>::from_hex($sig_hex).unwrap()[..]).unwrap(), holder_sig, "holder_sig");
16536+
16537+
let funding_redeemscript = $chan.funding.get_funding_redeemscript();
16538+
let tx = holder_commitment_tx.add_holder_sig(&funding_redeemscript, holder_sig);
16539+
assert_eq!(serialize(&tx)[..], <Vec<u8>>::from_hex($tx_hex).unwrap()[..], "tx");
16540+
16541+
// ((htlc, counterparty_sig), (index, holder_sig))
16542+
let mut htlc_counterparty_sig_iter = holder_commitment_tx.counterparty_htlc_sigs.iter();
16543+
16544+
$({
16545+
log_trace!($logger, "verifying htlc {}", $htlc_idx);
16546+
let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16547+
16548+
let ref htlc = commitment_tx.nondust_htlcs()[$htlc_idx];
16549+
let keys = commitment_tx.trust().keys();
16550+
let mut htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, $chan.context.feerate_per_kw,
16551+
$chan.funding.get_counterparty_selected_contest_delay().unwrap(),
16552+
&htlc, $channel_type_features, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
16553+
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, $channel_type_features, &keys);
16554+
let htlc_sighashtype = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
16555+
let htlc_sighash = Message::from_digest(sighash::SighashCache::new(&htlc_tx).p2wsh_signature_hash(0, &htlc_redeemscript, htlc.to_bitcoin_amount(), htlc_sighashtype).unwrap().as_raw_hash().to_byte_array());
16556+
assert!($secp_ctx.verify_ecdsa(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key.to_public_key()).is_ok(), "verify counterparty htlc sig");
16557+
16558+
let mut preimage: Option<PaymentPreimage> = None;
16559+
if !htlc.offered {
16560+
for i in 0..5 {
16561+
let out = PaymentHash(Sha256::hash(&[i; 32]).to_byte_array());
16562+
if out == htlc.payment_hash {
16563+
preimage = Some(PaymentPreimage([i; 32]));
16564+
}
16565+
}
16566+
16567+
assert!(preimage.is_some());
16568+
}
16569+
16570+
let htlc_counterparty_sig = htlc_counterparty_sig_iter.next().unwrap();
16571+
let htlc_holder_sig = $signer.sign_holder_htlc_transaction(&htlc_tx, 0, &HTLCDescriptor {
16572+
channel_derivation_parameters: ChannelDerivationParameters {
16573+
value_satoshis: $chan.funding.get_value_satoshis(),
16574+
keys_id: $chan.context.channel_keys_id,
16575+
transaction_parameters: $chan.funding.channel_transaction_parameters.clone(),
16576+
},
16577+
commitment_txid: trusted_tx.txid(),
16578+
per_commitment_number: trusted_tx.commitment_number(),
16579+
per_commitment_point: trusted_tx.per_commitment_point(),
16580+
feerate_per_kw: trusted_tx.negotiated_feerate_per_kw(),
16581+
htlc: htlc.clone(),
16582+
preimage: preimage.clone(),
16583+
counterparty_sig: *htlc_counterparty_sig,
16584+
}, &$secp_ctx).unwrap();
16585+
let num_anchors = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { 2 } else { 0 };
16586+
assert_eq!(htlc.transaction_output_index, Some($htlc_idx + num_anchors), "output index");
16587+
16588+
let signature = Signature::from_der(&<Vec<u8>>::from_hex($htlc_sig_hex).unwrap()[..]).unwrap();
16589+
assert_eq!(signature, htlc_holder_sig, "htlc sig");
16590+
htlc_tx.input[0].witness = chan_utils::build_htlc_input_witness(
16591+
&htlc_holder_sig, htlc_counterparty_sig, &preimage, &htlc_redeemscript,
16592+
$channel_type_features,
16593+
);
16594+
log_trace!($logger, "htlc_tx = {}", serialize(&htlc_tx).as_hex());
16595+
assert_eq!(serialize(&htlc_tx)[..], <Vec<u8>>::from_hex($htlc_tx_hex).unwrap()[..], "htlc tx");
16596+
})*
16597+
assert!(htlc_counterparty_sig_iter.next().is_none());
16598+
} }
16599+
}
16600+
1649916601
#[cfg(ldk_test_vectors)]
1650016602
#[test]
1650116603
#[rustfmt::skip]
@@ -16584,117 +16686,18 @@ mod tests {
1658416686
macro_rules! test_commitment {
1658516687
( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $($remain:tt)* ) => {
1658616688
chan.funding.channel_transaction_parameters.channel_type_features = ChannelTypeFeatures::only_static_remote_key();
16587-
test_commitment_common!($counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::only_static_remote_key(), $($remain)*);
16689+
test_commitment_common!(chan, logger, secp_ctx, signer, holder_pubkeys, per_commitment_point, $counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::only_static_remote_key(), $($remain)*);
1658816690
};
1658916691
}
1659016692

1659116693
macro_rules! test_commitment_with_anchors {
1659216694
( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $($remain:tt)* ) => {
1659316695
chan.funding.channel_transaction_parameters.channel_type_features = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
16594-
test_commitment_common!($counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(), $($remain)*);
16696+
test_commitment_common!(chan, logger, secp_ctx, signer, holder_pubkeys, per_commitment_point, $counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(), $($remain)*);
1659516697
};
1659616698
}
1659716699

1659816700
#[rustfmt::skip]
16599-
macro_rules! test_commitment_common {
16600-
( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $channel_type_features: expr, {
16601-
$( { $htlc_idx: expr, $counterparty_htlc_sig_hex: expr, $htlc_sig_hex: expr, $htlc_tx_hex: expr } ), *
16602-
} ) => { {
16603-
let commitment_data = chan.context.build_commitment_transaction(&chan.funding,
16604-
0xffffffffffff - 42, &per_commitment_point, true, false, &logger);
16605-
let commitment_tx = commitment_data.tx;
16606-
let trusted_tx = commitment_tx.trust();
16607-
let unsigned_tx = trusted_tx.built_transaction();
16608-
let redeemscript = chan.funding.get_funding_redeemscript();
16609-
let counterparty_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_sig_hex).unwrap()[..]).unwrap();
16610-
let sighash = unsigned_tx.get_sighash_all(&redeemscript, chan.funding.get_value_satoshis());
16611-
log_trace!(logger, "unsigned_tx = {}", serialize(&unsigned_tx.transaction).as_hex());
16612-
assert!(secp_ctx.verify_ecdsa(&sighash, &counterparty_signature, chan.funding.counterparty_funding_pubkey()).is_ok(), "verify counterparty commitment sig");
16613-
16614-
let mut per_htlc: Vec<(HTLCOutputInCommitment, Option<Signature>)> = Vec::new();
16615-
per_htlc.clear(); // Don't warn about excess mut for no-HTLC calls
16616-
let mut counterparty_htlc_sigs = Vec::new();
16617-
counterparty_htlc_sigs.clear(); // Don't warn about excess mut for no-HTLC calls
16618-
$({
16619-
let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16620-
per_htlc.push((commitment_tx.nondust_htlcs()[$htlc_idx].clone(), Some(remote_signature)));
16621-
counterparty_htlc_sigs.push(remote_signature);
16622-
})*
16623-
assert_eq!(commitment_tx.nondust_htlcs().len(), per_htlc.len());
16624-
16625-
let holder_commitment_tx = HolderCommitmentTransaction::new(
16626-
commitment_tx.clone(),
16627-
counterparty_signature,
16628-
counterparty_htlc_sigs,
16629-
&holder_pubkeys.funding_pubkey,
16630-
chan.funding.counterparty_funding_pubkey()
16631-
);
16632-
let holder_sig = signer.sign_holder_commitment(&chan.funding.channel_transaction_parameters, &holder_commitment_tx, &secp_ctx).unwrap();
16633-
assert_eq!(Signature::from_der(&<Vec<u8>>::from_hex($sig_hex).unwrap()[..]).unwrap(), holder_sig, "holder_sig");
16634-
16635-
let funding_redeemscript = chan.funding.get_funding_redeemscript();
16636-
let tx = holder_commitment_tx.add_holder_sig(&funding_redeemscript, holder_sig);
16637-
assert_eq!(serialize(&tx)[..], <Vec<u8>>::from_hex($tx_hex).unwrap()[..], "tx");
16638-
16639-
// ((htlc, counterparty_sig), (index, holder_sig))
16640-
let mut htlc_counterparty_sig_iter = holder_commitment_tx.counterparty_htlc_sigs.iter();
16641-
16642-
$({
16643-
log_trace!(logger, "verifying htlc {}", $htlc_idx);
16644-
let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16645-
16646-
let ref htlc = commitment_tx.nondust_htlcs()[$htlc_idx];
16647-
let keys = commitment_tx.trust().keys();
16648-
let mut htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, chan.context.feerate_per_kw,
16649-
chan.funding.get_counterparty_selected_contest_delay().unwrap(),
16650-
&htlc, $channel_type_features, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
16651-
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, $channel_type_features, &keys);
16652-
let htlc_sighashtype = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
16653-
let htlc_sighash = Message::from_digest(sighash::SighashCache::new(&htlc_tx).p2wsh_signature_hash(0, &htlc_redeemscript, htlc.to_bitcoin_amount(), htlc_sighashtype).unwrap().as_raw_hash().to_byte_array());
16654-
assert!(secp_ctx.verify_ecdsa(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key.to_public_key()).is_ok(), "verify counterparty htlc sig");
16655-
16656-
let mut preimage: Option<PaymentPreimage> = None;
16657-
if !htlc.offered {
16658-
for i in 0..5 {
16659-
let out = PaymentHash(Sha256::hash(&[i; 32]).to_byte_array());
16660-
if out == htlc.payment_hash {
16661-
preimage = Some(PaymentPreimage([i; 32]));
16662-
}
16663-
}
16664-
16665-
assert!(preimage.is_some());
16666-
}
16667-
16668-
let htlc_counterparty_sig = htlc_counterparty_sig_iter.next().unwrap();
16669-
let htlc_holder_sig = signer.sign_holder_htlc_transaction(&htlc_tx, 0, &HTLCDescriptor {
16670-
channel_derivation_parameters: ChannelDerivationParameters {
16671-
value_satoshis: chan.funding.get_value_satoshis(),
16672-
keys_id: chan.context.channel_keys_id,
16673-
transaction_parameters: chan.funding.channel_transaction_parameters.clone(),
16674-
},
16675-
commitment_txid: trusted_tx.txid(),
16676-
per_commitment_number: trusted_tx.commitment_number(),
16677-
per_commitment_point: trusted_tx.per_commitment_point(),
16678-
feerate_per_kw: trusted_tx.negotiated_feerate_per_kw(),
16679-
htlc: htlc.clone(),
16680-
preimage: preimage.clone(),
16681-
counterparty_sig: *htlc_counterparty_sig,
16682-
}, &secp_ctx).unwrap();
16683-
let num_anchors = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { 2 } else { 0 };
16684-
assert_eq!(htlc.transaction_output_index, Some($htlc_idx + num_anchors), "output index");
16685-
16686-
let signature = Signature::from_der(&<Vec<u8>>::from_hex($htlc_sig_hex).unwrap()[..]).unwrap();
16687-
assert_eq!(signature, htlc_holder_sig, "htlc sig");
16688-
htlc_tx.input[0].witness = chan_utils::build_htlc_input_witness(
16689-
&htlc_holder_sig, htlc_counterparty_sig, &preimage, &htlc_redeemscript,
16690-
$channel_type_features,
16691-
);
16692-
log_trace!(logger, "htlc_tx = {}", serialize(&htlc_tx).as_hex());
16693-
assert_eq!(serialize(&htlc_tx)[..], <Vec<u8>>::from_hex($htlc_tx_hex).unwrap()[..], "htlc tx");
16694-
})*
16695-
assert!(htlc_counterparty_sig_iter.next().is_none());
16696-
} }
16697-
}
1669816701

1669916702
// anchors: simple commitment tx with no HTLCs and single anchor
1670016703
test_commitment_with_anchors!("30440220655bf909fb6fa81d086f1336ac72c97906dce29d1b166e305c99152d810e26e1022051f577faa46412c46707aaac46b65d50053550a66334e00a44af2706f27a8658",

0 commit comments

Comments
 (0)