Skip to content

Commit 87b8aca

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 3f96d12 commit 87b8aca

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

Comments
 (0)