Skip to content

Commit cc55553

Browse files
committed
Use correct to_remote script in counterparty commitments
While our commitment transactions did use the correct `to_remote` script, the `ChannelMonitor`'s was not as it is tracked separately. This would lead to users never receiving an `Event::SpendableOutputs` with a `StaticPaymentOutput` descriptor to claim the funds. Luckily, any users affected which had channel closures confirmed by a counterparty commitment just need to replay the closing transaction to receive the event.
1 parent 1ac53ed commit cc55553

File tree

3 files changed

+28
-12
lines changed

3 files changed

+28
-12
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@
2222
2323
use bitcoin::blockdata::block::BlockHeader;
2424
use bitcoin::blockdata::transaction::{OutPoint as BitcoinOutPoint, TxOut, Transaction};
25-
use bitcoin::blockdata::script::{Script, Builder};
26-
use bitcoin::blockdata::opcodes;
25+
use bitcoin::blockdata::script::Script;
2726

2827
use bitcoin::hashes::Hash;
2928
use bitcoin::hashes::sha256::Hash as Sha256;
30-
use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
29+
use bitcoin::hash_types::{Txid, BlockHash};
3130

3231
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
3332
use bitcoin::secp256k1::{SecretKey, PublicKey};
@@ -1141,8 +1140,9 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
11411140
best_block: BestBlock, counterparty_node_id: PublicKey) -> ChannelMonitor<Signer> {
11421141

11431142
assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
1144-
let payment_key_hash = WPubkeyHash::hash(&keys.pubkeys().payment_point.serialize());
1145-
let counterparty_payment_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_key_hash[..]).into_script();
1143+
let counterparty_payment_script = chan_utils::get_counterparty_payment_script(
1144+
&channel_parameters.channel_type_features, &keys.pubkeys().payment_point
1145+
);
11461146

11471147
let counterparty_channel_parameters = channel_parameters.counterparty_parameters.as_ref().unwrap();
11481148
let counterparty_delayed_payment_base_key = counterparty_channel_parameters.pubkeys.delayed_payment_basepoint;
@@ -2236,6 +2236,7 @@ macro_rules! fail_unbroadcast_htlcs {
22362236

22372237
#[cfg(test)]
22382238
pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec<u8> {
2239+
use bitcoin::blockdata::opcodes;
22392240
let mut ret = [opcodes::all::OP_NOP.to_u8(); 136];
22402241
ret[131] = opcodes::all::OP_DROP.to_u8();
22412242
ret[132] = opcodes::all::OP_DROP.to_u8();

lightning/src/ln/chan_utils.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use bitcoin::util::address::Payload;
1919
use bitcoin::hashes::{Hash, HashEngine};
2020
use bitcoin::hashes::sha256::Hash as Sha256;
2121
use bitcoin::hashes::ripemd160::Hash as Ripemd160;
22-
use bitcoin::hash_types::{Txid, PubkeyHash};
22+
use bitcoin::hash_types::{Txid, PubkeyHash, WPubkeyHash};
2323

2424
use crate::chain::chaininterface::fee_for_weight;
2525
use crate::chain::package::WEIGHT_REVOKED_OUTPUT;
@@ -556,6 +556,16 @@ pub fn get_revokeable_redeemscript(revocation_key: &PublicKey, contest_delay: u1
556556
res
557557
}
558558

559+
/// Returns the script for the counterparty's output on a holder's commitment transaction based on
560+
/// the channel type.
561+
pub fn get_counterparty_payment_script(channel_type_features: &ChannelTypeFeatures, payment_key: &PublicKey) -> Script {
562+
if channel_type_features.supports_anchors_zero_fee_htlc_tx() {
563+
get_to_countersignatory_with_anchors_redeemscript(payment_key).to_v0_p2wsh()
564+
} else {
565+
Script::new_v0_p2wpkh(&WPubkeyHash::hash(&payment_key.serialize()))
566+
}
567+
}
568+
559569
/// Information about an HTLC as it appears in a commitment transaction
560570
#[derive(Clone, Debug, PartialEq, Eq)]
561571
pub struct HTLCOutputInCommitment {

lightning/src/ln/monitor_tests.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
//! Further functional tests which test blockchain reorganizations.
1111
12-
use crate::sign::EcdsaChannelSigner;
12+
use crate::sign::{EcdsaChannelSigner, SpendableOutputDescriptor};
1313
use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS, Balance};
1414
use crate::chain::transaction::OutPoint;
1515
use crate::chain::chaininterface::{LowerBoundedFeeEstimator, compute_feerate_sat_per_1000_weight};
@@ -2230,16 +2230,21 @@ fn test_anchors_aggregated_revoked_htlc_tx() {
22302230

22312231
assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
22322232
let spendable_output_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
2233-
assert_eq!(spendable_output_events.len(), 2);
2234-
for event in spendable_output_events.iter() {
2235-
if let Event::SpendableOutputs { outputs, channel_id } = event {
2233+
assert_eq!(spendable_output_events.len(), 4);
2234+
for event in spendable_output_events {
2235+
if let Event::SpendableOutputs { mut outputs, channel_id } = event {
22362236
assert_eq!(outputs.len(), 1);
22372237
assert!(vec![chan_b.2, chan_a.2].contains(&channel_id.unwrap()));
2238+
let spendable_output = outputs.pop().unwrap();
22382239
let spend_tx = nodes[0].keys_manager.backing.spend_spendable_outputs(
2239-
&[&outputs[0]], Vec::new(), Script::new_op_return(&[]), 253, None, &Secp256k1::new(),
2240+
&[&spendable_output], Vec::new(), Script::new_op_return(&[]), 253, None, &Secp256k1::new(),
22402241
).unwrap();
22412242

2242-
check_spends!(spend_tx, revoked_claim_transactions.get(&spend_tx.input[0].previous_output.txid).unwrap());
2243+
if let SpendableOutputDescriptor::StaticPaymentOutput(descriptor) = &spendable_output {
2244+
check_spends!(spend_tx, &revoked_commitment_a, &revoked_commitment_b);
2245+
} else {
2246+
check_spends!(spend_tx, revoked_claim_transactions.get(&spend_tx.input[0].previous_output.txid).unwrap());
2247+
}
22432248
} else {
22442249
panic!("unexpected event");
22452250
}

0 commit comments

Comments
 (0)