@@ -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