@@ -16463,6 +16463,108 @@ mod tests {
1646316463 assert_eq!(decoded_chan.context.holding_cell_htlc_updates, holding_cell_htlc_updates);
1646416464 }
1646516465
16466+ #[cfg(ldk_test_vectors)]
16467+ #[rustfmt::skip]
16468+ macro_rules! test_commitment_common {
16469+ ( $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, {
16470+ $( { $htlc_idx: expr, $counterparty_htlc_sig_hex: expr, $htlc_sig_hex: expr, $htlc_tx_hex: expr } ), *
16471+ } ) => { {
16472+ let commitment_data = $chan.context.build_commitment_transaction(&$chan.funding,
16473+ 0xffffffffffff - 42, &$per_commitment_point, true, false, &$logger);
16474+ let commitment_tx = commitment_data.tx;
16475+ let trusted_tx = commitment_tx.trust();
16476+ let unsigned_tx = trusted_tx.built_transaction();
16477+ let redeemscript = $chan.funding.get_funding_redeemscript();
16478+ let counterparty_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_sig_hex).unwrap()[..]).unwrap();
16479+ let sighash = unsigned_tx.get_sighash_all(&redeemscript, $chan.funding.get_value_satoshis());
16480+ log_trace!($logger, "unsigned_tx = {}", serialize(&unsigned_tx.transaction).as_hex());
16481+ assert!($secp_ctx.verify_ecdsa(&sighash, &counterparty_signature, $chan.funding.counterparty_funding_pubkey()).is_ok(), "verify counterparty commitment sig");
16482+
16483+ let mut per_htlc: Vec<(HTLCOutputInCommitment, Option<Signature>)> = Vec::new();
16484+ per_htlc.clear(); // Don't warn about excess mut for no-HTLC calls
16485+ let mut counterparty_htlc_sigs = Vec::new();
16486+ counterparty_htlc_sigs.clear(); // Don't warn about excess mut for no-HTLC calls
16487+ $({
16488+ let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16489+ per_htlc.push((commitment_tx.nondust_htlcs()[$htlc_idx].clone(), Some(remote_signature)));
16490+ counterparty_htlc_sigs.push(remote_signature);
16491+ })*
16492+ assert_eq!(commitment_tx.nondust_htlcs().len(), per_htlc.len());
16493+
16494+ let holder_commitment_tx = HolderCommitmentTransaction::new(
16495+ commitment_tx.clone(),
16496+ counterparty_signature,
16497+ counterparty_htlc_sigs,
16498+ &$holder_pubkeys.funding_pubkey,
16499+ $chan.funding.counterparty_funding_pubkey()
16500+ );
16501+ let holder_sig = $signer.sign_holder_commitment(&$chan.funding.channel_transaction_parameters, &holder_commitment_tx, &$secp_ctx).unwrap();
16502+ assert_eq!(Signature::from_der(&<Vec<u8>>::from_hex($sig_hex).unwrap()[..]).unwrap(), holder_sig, "holder_sig");
16503+
16504+ let funding_redeemscript = $chan.funding.get_funding_redeemscript();
16505+ let tx = holder_commitment_tx.add_holder_sig(&funding_redeemscript, holder_sig);
16506+ assert_eq!(serialize(&tx)[..], <Vec<u8>>::from_hex($tx_hex).unwrap()[..], "tx");
16507+
16508+ // ((htlc, counterparty_sig), (index, holder_sig))
16509+ let mut htlc_counterparty_sig_iter = holder_commitment_tx.counterparty_htlc_sigs.iter();
16510+
16511+ $({
16512+ log_trace!($logger, "verifying htlc {}", $htlc_idx);
16513+ let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16514+
16515+ let ref htlc = commitment_tx.nondust_htlcs()[$htlc_idx];
16516+ let keys = commitment_tx.trust().keys();
16517+ let mut htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, $chan.context.feerate_per_kw,
16518+ $chan.funding.get_counterparty_selected_contest_delay().unwrap(),
16519+ &htlc, $channel_type_features, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
16520+ let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, $channel_type_features, &keys);
16521+ let htlc_sighashtype = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
16522+ 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());
16523+ assert!($secp_ctx.verify_ecdsa(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key.to_public_key()).is_ok(), "verify counterparty htlc sig");
16524+
16525+ let mut preimage: Option<PaymentPreimage> = None;
16526+ if !htlc.offered {
16527+ for i in 0..5 {
16528+ let out = PaymentHash(Sha256::hash(&[i; 32]).to_byte_array());
16529+ if out == htlc.payment_hash {
16530+ preimage = Some(PaymentPreimage([i; 32]));
16531+ }
16532+ }
16533+
16534+ assert!(preimage.is_some());
16535+ }
16536+
16537+ let htlc_counterparty_sig = htlc_counterparty_sig_iter.next().unwrap();
16538+ let htlc_holder_sig = $signer.sign_holder_htlc_transaction(&htlc_tx, 0, &HTLCDescriptor {
16539+ channel_derivation_parameters: ChannelDerivationParameters {
16540+ value_satoshis: $chan.funding.get_value_satoshis(),
16541+ keys_id: $chan.context.channel_keys_id,
16542+ transaction_parameters: $chan.funding.channel_transaction_parameters.clone(),
16543+ },
16544+ commitment_txid: trusted_tx.txid(),
16545+ per_commitment_number: trusted_tx.commitment_number(),
16546+ per_commitment_point: trusted_tx.per_commitment_point(),
16547+ feerate_per_kw: trusted_tx.negotiated_feerate_per_kw(),
16548+ htlc: htlc.clone(),
16549+ preimage: preimage.clone(),
16550+ counterparty_sig: *htlc_counterparty_sig,
16551+ }, &$secp_ctx).unwrap();
16552+ let num_anchors = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { 2 } else { 0 };
16553+ assert_eq!(htlc.transaction_output_index, Some($htlc_idx + num_anchors), "output index");
16554+
16555+ let signature = Signature::from_der(&<Vec<u8>>::from_hex($htlc_sig_hex).unwrap()[..]).unwrap();
16556+ assert_eq!(signature, htlc_holder_sig, "htlc sig");
16557+ htlc_tx.input[0].witness = chan_utils::build_htlc_input_witness(
16558+ &htlc_holder_sig, htlc_counterparty_sig, &preimage, &htlc_redeemscript,
16559+ $channel_type_features,
16560+ );
16561+ log_trace!($logger, "htlc_tx = {}", serialize(&htlc_tx).as_hex());
16562+ assert_eq!(serialize(&htlc_tx)[..], <Vec<u8>>::from_hex($htlc_tx_hex).unwrap()[..], "htlc tx");
16563+ })*
16564+ assert!(htlc_counterparty_sig_iter.next().is_none());
16565+ } }
16566+ }
16567+
1646616568 #[cfg(ldk_test_vectors)]
1646716569 #[test]
1646816570 #[rustfmt::skip]
@@ -16551,117 +16653,18 @@ mod tests {
1655116653 macro_rules! test_commitment {
1655216654 ( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $($remain:tt)* ) => {
1655316655 chan.funding.channel_transaction_parameters.channel_type_features = ChannelTypeFeatures::only_static_remote_key();
16554- test_commitment_common!($counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::only_static_remote_key(), $($remain)*);
16656+ 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)*);
1655516657 };
1655616658 }
1655716659
1655816660 macro_rules! test_commitment_with_anchors {
1655916661 ( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $($remain:tt)* ) => {
1656016662 chan.funding.channel_transaction_parameters.channel_type_features = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
16561- test_commitment_common!($counterparty_sig_hex, $sig_hex, $tx_hex, &ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(), $($remain)*);
16663+ 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)*);
1656216664 };
1656316665 }
1656416666
1656516667 #[rustfmt::skip]
16566- macro_rules! test_commitment_common {
16567- ( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $channel_type_features: expr, {
16568- $( { $htlc_idx: expr, $counterparty_htlc_sig_hex: expr, $htlc_sig_hex: expr, $htlc_tx_hex: expr } ), *
16569- } ) => { {
16570- let commitment_data = chan.context.build_commitment_transaction(&chan.funding,
16571- 0xffffffffffff - 42, &per_commitment_point, true, false, &logger);
16572- let commitment_tx = commitment_data.tx;
16573- let trusted_tx = commitment_tx.trust();
16574- let unsigned_tx = trusted_tx.built_transaction();
16575- let redeemscript = chan.funding.get_funding_redeemscript();
16576- let counterparty_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_sig_hex).unwrap()[..]).unwrap();
16577- let sighash = unsigned_tx.get_sighash_all(&redeemscript, chan.funding.get_value_satoshis());
16578- log_trace!(logger, "unsigned_tx = {}", serialize(&unsigned_tx.transaction).as_hex());
16579- assert!(secp_ctx.verify_ecdsa(&sighash, &counterparty_signature, chan.funding.counterparty_funding_pubkey()).is_ok(), "verify counterparty commitment sig");
16580-
16581- let mut per_htlc: Vec<(HTLCOutputInCommitment, Option<Signature>)> = Vec::new();
16582- per_htlc.clear(); // Don't warn about excess mut for no-HTLC calls
16583- let mut counterparty_htlc_sigs = Vec::new();
16584- counterparty_htlc_sigs.clear(); // Don't warn about excess mut for no-HTLC calls
16585- $({
16586- let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16587- per_htlc.push((commitment_tx.nondust_htlcs()[$htlc_idx].clone(), Some(remote_signature)));
16588- counterparty_htlc_sigs.push(remote_signature);
16589- })*
16590- assert_eq!(commitment_tx.nondust_htlcs().len(), per_htlc.len());
16591-
16592- let holder_commitment_tx = HolderCommitmentTransaction::new(
16593- commitment_tx.clone(),
16594- counterparty_signature,
16595- counterparty_htlc_sigs,
16596- &holder_pubkeys.funding_pubkey,
16597- chan.funding.counterparty_funding_pubkey()
16598- );
16599- let holder_sig = signer.sign_holder_commitment(&chan.funding.channel_transaction_parameters, &holder_commitment_tx, &secp_ctx).unwrap();
16600- assert_eq!(Signature::from_der(&<Vec<u8>>::from_hex($sig_hex).unwrap()[..]).unwrap(), holder_sig, "holder_sig");
16601-
16602- let funding_redeemscript = chan.funding.get_funding_redeemscript();
16603- let tx = holder_commitment_tx.add_holder_sig(&funding_redeemscript, holder_sig);
16604- assert_eq!(serialize(&tx)[..], <Vec<u8>>::from_hex($tx_hex).unwrap()[..], "tx");
16605-
16606- // ((htlc, counterparty_sig), (index, holder_sig))
16607- let mut htlc_counterparty_sig_iter = holder_commitment_tx.counterparty_htlc_sigs.iter();
16608-
16609- $({
16610- log_trace!(logger, "verifying htlc {}", $htlc_idx);
16611- let remote_signature = Signature::from_der(&<Vec<u8>>::from_hex($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
16612-
16613- let ref htlc = commitment_tx.nondust_htlcs()[$htlc_idx];
16614- let keys = commitment_tx.trust().keys();
16615- let mut htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, chan.context.feerate_per_kw,
16616- chan.funding.get_counterparty_selected_contest_delay().unwrap(),
16617- &htlc, $channel_type_features, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
16618- let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, $channel_type_features, &keys);
16619- let htlc_sighashtype = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
16620- 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());
16621- assert!(secp_ctx.verify_ecdsa(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key.to_public_key()).is_ok(), "verify counterparty htlc sig");
16622-
16623- let mut preimage: Option<PaymentPreimage> = None;
16624- if !htlc.offered {
16625- for i in 0..5 {
16626- let out = PaymentHash(Sha256::hash(&[i; 32]).to_byte_array());
16627- if out == htlc.payment_hash {
16628- preimage = Some(PaymentPreimage([i; 32]));
16629- }
16630- }
16631-
16632- assert!(preimage.is_some());
16633- }
16634-
16635- let htlc_counterparty_sig = htlc_counterparty_sig_iter.next().unwrap();
16636- let htlc_holder_sig = signer.sign_holder_htlc_transaction(&htlc_tx, 0, &HTLCDescriptor {
16637- channel_derivation_parameters: ChannelDerivationParameters {
16638- value_satoshis: chan.funding.get_value_satoshis(),
16639- keys_id: chan.context.channel_keys_id,
16640- transaction_parameters: chan.funding.channel_transaction_parameters.clone(),
16641- },
16642- commitment_txid: trusted_tx.txid(),
16643- per_commitment_number: trusted_tx.commitment_number(),
16644- per_commitment_point: trusted_tx.per_commitment_point(),
16645- feerate_per_kw: trusted_tx.negotiated_feerate_per_kw(),
16646- htlc: htlc.clone(),
16647- preimage: preimage.clone(),
16648- counterparty_sig: *htlc_counterparty_sig,
16649- }, &secp_ctx).unwrap();
16650- let num_anchors = if $channel_type_features.supports_anchors_zero_fee_htlc_tx() { 2 } else { 0 };
16651- assert_eq!(htlc.transaction_output_index, Some($htlc_idx + num_anchors), "output index");
16652-
16653- let signature = Signature::from_der(&<Vec<u8>>::from_hex($htlc_sig_hex).unwrap()[..]).unwrap();
16654- assert_eq!(signature, htlc_holder_sig, "htlc sig");
16655- htlc_tx.input[0].witness = chan_utils::build_htlc_input_witness(
16656- &htlc_holder_sig, htlc_counterparty_sig, &preimage, &htlc_redeemscript,
16657- $channel_type_features,
16658- );
16659- log_trace!(logger, "htlc_tx = {}", serialize(&htlc_tx).as_hex());
16660- assert_eq!(serialize(&htlc_tx)[..], <Vec<u8>>::from_hex($htlc_tx_hex).unwrap()[..], "htlc tx");
16661- })*
16662- assert!(htlc_counterparty_sig_iter.next().is_none());
16663- } }
16664- }
1666516668
1666616669 // anchors: simple commitment tx with no HTLCs and single anchor
1666716670 test_commitment_with_anchors!("30440220655bf909fb6fa81d086f1336ac72c97906dce29d1b166e305c99152d810e26e1022051f577faa46412c46707aaac46b65d50053550a66334e00a44af2706f27a8658",
0 commit comments