Skip to content

Commit 33b745f

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 6016101 commit 33b745f

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
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;
@@ -2263,6 +2263,7 @@ macro_rules! fail_unbroadcast_htlcs {
22632263

22642264
#[cfg(test)]
22652265
pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec<u8> {
2266+
use bitcoin::blockdata::opcodes;
22662267
let mut ret = [opcodes::all::OP_NOP.to_u8(); 136];
22672268
ret[131] = opcodes::all::OP_DROP.to_u8();
22682269
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: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,16 +2287,20 @@ fn test_anchors_aggregated_revoked_htlc_tx() {
22872287

22882288
assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
22892289
let spendable_output_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
2290-
assert_eq!(spendable_output_events.len(), 2);
2291-
for event in spendable_output_events.iter() {
2290+
assert_eq!(spendable_output_events.len(), 4);
2291+
for event in spendable_output_events {
22922292
if let Event::SpendableOutputs { outputs, channel_id } = event {
22932293
assert_eq!(outputs.len(), 1);
22942294
assert!(vec![chan_b.2, chan_a.2].contains(&channel_id.unwrap()));
22952295
let spend_tx = nodes[0].keys_manager.backing.spend_spendable_outputs(
22962296
&[&outputs[0]], Vec::new(), Script::new_op_return(&[]), 253, None, &Secp256k1::new(),
22972297
).unwrap();
22982298

2299-
check_spends!(spend_tx, revoked_claim_transactions.get(&spend_tx.input[0].previous_output.txid).unwrap());
2299+
if let SpendableOutputDescriptor::StaticPaymentOutput(_) = &outputs[0] {
2300+
check_spends!(spend_tx, &revoked_commitment_a, &revoked_commitment_b);
2301+
} else {
2302+
check_spends!(spend_tx, revoked_claim_transactions.get(&spend_tx.input[0].previous_output.txid).unwrap());
2303+
}
23002304
} else {
23012305
panic!("unexpected event");
23022306
}

0 commit comments

Comments
 (0)