Skip to content

Commit 6c29de6

Browse files
author
Antoine Riard
committed
Remove duplicata of broadcast txn from ChannelMonitor
Previously, if new ouputs were found to be watched as part of channel operations, the block was rescan which triggers again parser and generation of transactions already issued. This commit first modifies the test framework without altering further ChannelMonitor. ChannelMonitor refactoring is introduced in a latter commit.
1 parent 9a02115 commit 6c29de6

File tree

4 files changed

+109
-95
lines changed

4 files changed

+109
-95
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,11 +1772,11 @@ impl ChannelMonitor {
17721772
let mut inputs_info = Vec::new();
17731773

17741774
macro_rules! sign_input {
1775-
($sighash_parts: expr, $input: expr, $amount: expr, $preimage: expr) => {
1775+
($sighash_parts: expr, $input: expr, $amount: expr, $preimage: expr, $idx: expr) => {
17761776
{
17771777
let (sig, redeemscript, htlc_key) = match self.key_storage {
17781778
Storage::Local { ref htlc_base_key, .. } => {
1779-
let htlc = &per_commitment_option.unwrap()[$input.sequence as usize].0;
1779+
let htlc = &per_commitment_option.unwrap()[$idx as usize].0;
17801780
let redeemscript = chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
17811781
let sighash = hash_to_message!(&$sighash_parts.sighash_all(&$input, &redeemscript, $amount)[..]);
17821782
let htlc_key = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &htlc_base_key));
@@ -1805,19 +1805,20 @@ impl ChannelMonitor {
18051805
}
18061806
if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
18071807
if htlc.offered {
1808-
let input = TxIn {
1808+
let mut input = TxIn {
18091809
previous_output: BitcoinOutPoint {
18101810
txid: commitment_txid,
18111811
vout: transaction_output_index,
18121812
},
18131813
script_sig: Script::new(),
1814-
sequence: idx as u32, // reset to 0xfffffffd in sign_input
1814+
sequence: idx as u32, // reset to 0xfffffffd before sign_input
18151815
witness: Vec::new(),
18161816
};
18171817
if htlc.cltv_expiry > height + CLTV_SHARED_CLAIM_BUFFER {
1818+
input.sequence = 0xff_ff_ff_fd;
18181819
inputs.push(input);
18191820
inputs_desc.push(if htlc.offered { InputDescriptors::OfferedHTLC } else { InputDescriptors::ReceivedHTLC });
1820-
inputs_info.push((payment_preimage, tx.output[transaction_output_index as usize].value, htlc.cltv_expiry));
1821+
inputs_info.push((payment_preimage, tx.output[transaction_output_index as usize].value, htlc.cltv_expiry, idx));
18211822
total_value += tx.output[transaction_output_index as usize].value;
18221823
} else {
18231824
let mut single_htlc_tx = Transaction {
@@ -1833,8 +1834,10 @@ impl ChannelMonitor {
18331834
let height_timer = Self::get_height_timer(height, htlc.cltv_expiry);
18341835
let mut used_feerate;
18351836
if subtract_high_prio_fee!(self, fee_estimator, single_htlc_tx.output[0].value, predicted_weight, used_feerate) {
1837+
let idx = single_htlc_tx.input[0].sequence;
1838+
single_htlc_tx.input[0].sequence = 0xff_ff_ff_fd;
18361839
let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
1837-
let (redeemscript, htlc_key) = sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.0.to_vec());
1840+
let (redeemscript, htlc_key) = sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.0.to_vec(), idx);
18381841
assert!(predicted_weight >= single_htlc_tx.get_weight());
18391842
spendable_outputs.push(SpendableOutputDescriptor::StaticOutput {
18401843
outpoint: BitcoinOutPoint { txid: single_htlc_tx.txid(), vout: 0 },
@@ -1881,8 +1884,10 @@ impl ChannelMonitor {
18811884
let height_timer = Self::get_height_timer(height, htlc.cltv_expiry);
18821885
let mut used_feerate;
18831886
if subtract_high_prio_fee!(self, fee_estimator, timeout_tx.output[0].value, predicted_weight, used_feerate) {
1887+
let idx = timeout_tx.input[0].sequence;
1888+
timeout_tx.input[0].sequence = 0xff_ff_ff_fd;
18841889
let sighash_parts = bip143::SighashComponents::new(&timeout_tx);
1885-
let (redeemscript, htlc_key) = sign_input!(sighash_parts, timeout_tx.input[0], htlc.amount_msat / 1000, vec![0]);
1890+
let (redeemscript, htlc_key) = sign_input!(sighash_parts, timeout_tx.input[0], htlc.amount_msat / 1000, vec![0], idx);
18861891
assert!(predicted_weight >= timeout_tx.get_weight());
18871892
//TODO: track SpendableOutputDescriptor
18881893
log_trace!(self, "Outpoint {}:{} is being being claimed, if it doesn't succeed, a bumped claiming txn is going to be broadcast at height {}", timeout_tx.input[0].previous_output.txid, timeout_tx.input[0].previous_output.vout, height_timer);
@@ -1934,7 +1939,7 @@ impl ChannelMonitor {
19341939
let height_timer = Self::get_height_timer(height, soonest_timelock);
19351940
let spend_txid = spend_tx.txid();
19361941
for (input, info) in spend_tx.input.iter_mut().zip(inputs_info.iter()) {
1937-
let (redeemscript, htlc_key) = sign_input!(sighash_parts, input, info.1, (info.0).0.to_vec());
1942+
let (redeemscript, htlc_key) = sign_input!(sighash_parts, input, info.1, (info.0).0.to_vec(), info.3);
19381943
log_trace!(self, "Outpoint {}:{} is being being claimed, if it doesn't succeed, a bumped claiming txn is going to be broadcast at height {}", input.previous_output.txid, input.previous_output.vout, height_timer);
19391944
per_input_material.insert(input.previous_output, InputMaterial::RemoteHTLC { script: redeemscript, key: htlc_key, preimage: Some(*(info.0)), amount: info.1, locktime: 0});
19401945
match self.claimable_outpoints.entry(input.previous_output) {
@@ -2872,7 +2877,6 @@ impl ChannelMonitor {
28722877
for per_outp_material in cached_claim_datas.per_input_material.values() {
28732878
match per_outp_material {
28742879
&InputMaterial::Revoked { ref script, ref is_htlc, ref amount, .. } => {
2875-
log_trace!(self, "Is HLTC ? {}", is_htlc);
28762880
inputs_witnesses_weight += Self::get_witnesses_weight(if !is_htlc { &[InputDescriptors::RevokedOutput] } else if HTLCType::scriptlen_to_htlctype(script.len()) == Some(HTLCType::OfferedHTLC) { &[InputDescriptors::RevokedOfferedHTLC] } else if HTLCType::scriptlen_to_htlctype(script.len()) == Some(HTLCType::AcceptedHTLC) { &[InputDescriptors::RevokedReceivedHTLC] } else { unreachable!() });
28772881
amt += *amount;
28782882
},

lightning/src/ln/functional_test_utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use std::cell::RefCell;
3434
use std::rc::Rc;
3535
use std::sync::{Arc, Mutex};
3636
use std::mem;
37+
use std::collections::HashSet;
3738

3839
pub const CHAN_CONFIRM_DEPTH: u32 = 100;
3940
pub fn confirm_transaction(notifier: &chaininterface::BlockNotifier, chain: &chaininterface::ChainWatchInterfaceUtil, tx: &Transaction, chan_id: u32) {
@@ -851,7 +852,7 @@ pub fn create_network(node_count: usize, node_config: &[Option<UserConfig>]) ->
851852
let feeest = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 });
852853
let chain_monitor = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&logger)));
853854
let block_notifier = Arc::new(chaininterface::BlockNotifier::new(chain_monitor.clone()));
854-
let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())});
855+
let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), broadcasted_txn: Mutex::new(HashSet::new())});
855856
let mut seed = [0; 32];
856857
rng.fill_bytes(&mut seed);
857858
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet, Arc::clone(&logger)));

0 commit comments

Comments
 (0)