Skip to content

Commit b45a1b0

Browse files
author
Antoine Riard
committed
Add block_disconnecting tests to cancel HTLC failure updates
1 parent 092c677 commit b45a1b0

File tree

3 files changed

+104
-3
lines changed

3 files changed

+104
-3
lines changed

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ impl<'a> MoneyLossDetector<'a> {
208208
if self.height > 0 && (self.max_height < 6 || self.height >= self.max_height - 6) {
209209
self.height -= 1;
210210
let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
211-
self.manager.block_disconnected(&header, height);
212-
self.monitor.block_disconnected(&header, height);
211+
self.manager.block_disconnected(&header, self.height);
212+
self.monitor.block_disconnected(&header, self.height);
213213
let removal_height = self.height;
214214
self.txids_confirmed.retain(|_, height| {
215215
removal_height != *height

src/ln/functional_test_utils.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use util::logger::Logger;
1515
use util::config::UserConfig;
1616

1717
use bitcoin::util::hash::{BitcoinHash, Sha256dHash};
18-
use bitcoin::blockdata::block::BlockHeader;
18+
use bitcoin::blockdata::block::{BlockHeader, Block};
1919
use bitcoin::blockdata::transaction::{Transaction, TxOut};
2020
use bitcoin::network::constants::Network;
2121

@@ -55,6 +55,20 @@ pub fn connect_blocks(chain: &chaininterface::ChainWatchInterfaceUtil, depth: u3
5555
}
5656
}
5757

58+
pub fn disconnect_blocks(chain: &chaininterface::ChainWatchInterfaceUtil, depth: u32, height: u32, parent: bool, prev_blockhash: Sha256dHash) {
59+
let mut header = BlockHeader { version: 0x2000000, prev_blockhash: if parent { prev_blockhash } else { Default::default() }, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
60+
let mut blocks = Vec::new();
61+
for _ in 0..depth {
62+
blocks.push(Block { header, txdata: Vec::new() });
63+
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
64+
}
65+
let mut height = height;
66+
for block in blocks.pop() {
67+
chain.block_disconnected(&block, height);
68+
height -= 1;
69+
}
70+
}
71+
5872
pub struct Node {
5973
pub chain_monitor: Arc<chaininterface::ChainWatchInterfaceUtil>,
6074
pub tx_broadcaster: Arc<test_utils::TestBroadcaster>,

src/ln/functional_tests.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5187,3 +5187,90 @@ fn test_failure_delay_dust_htlc_local_commitment() {
51875187
do_test_failure_delay_dust_htlc_local_commitment(true);
51885188
do_test_failure_delay_dust_htlc_local_commitment(false);
51895189
}
5190+
5191+
fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) {
5192+
5193+
let nodes = create_network(2);
5194+
let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
5195+
5196+
let bs_dust_limit = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().our_dust_limit_satoshis;
5197+
5198+
let (payment_preimage_1, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000);
5199+
let (payment_preimage_2, payment_hash_2) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
5200+
5201+
let as_commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
5202+
let bs_commitment_tx = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
5203+
5204+
if revoked {
5205+
let (payment_preimage_3, payment_hash_3) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
5206+
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_3);
5207+
let events = nodes[0].node.get_and_clear_pending_events();
5208+
assert_eq!(events.len(), 1);
5209+
match events[0] {
5210+
Event::PaymentReceived { payment_hash, .. } => {
5211+
assert_eq!(payment_hash, payment_hash_3);
5212+
},
5213+
_ => panic!("Unexpected event"),
5214+
}
5215+
}
5216+
println!("Before, A channels {}", nodes[0].node.list_channels().len());
5217+
5218+
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
5219+
let header_2 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
5220+
let timeout_tx;
5221+
if local {
5222+
nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&as_commitment_tx[0]], &[1; 1]);
5223+
timeout_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone();
5224+
assert_eq!(timeout_tx.input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
5225+
nodes[0].chain_monitor.block_connected_checked(&header_2, 1, &[&timeout_tx], &[1; 1]);
5226+
} else {
5227+
nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&bs_commitment_tx[0]], &[1; 1]);
5228+
timeout_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone();
5229+
assert_eq!(timeout_tx.input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
5230+
nodes[0].chain_monitor.block_connected_checked(&header_2, 1, &[&timeout_tx], &[1; 1]);
5231+
}
5232+
println!("After 2 block connected, A channels {}", nodes[0].node.list_channels().len());
5233+
5234+
let events = nodes[0].node.get_and_clear_pending_msg_events();
5235+
assert_eq!(events.len(), 1);
5236+
match events[0] {
5237+
MessageSendEvent::BroadcastChannelUpdate { .. } => {},
5238+
_ => panic!("Unexpected event"),
5239+
}
5240+
5241+
assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
5242+
connect_blocks(&nodes[0].chain_monitor, 3, 2, true, header.bitcoin_hash());
5243+
assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
5244+
5245+
disconnect_blocks(&nodes[0].chain_monitor, 3, 5, true, header.bitcoin_hash());
5246+
nodes[0].chain_monitor.block_disconnected(&Block { header: header_2, txdata: vec![timeout_tx] }, 2);
5247+
nodes[0].chain_monitor.block_disconnected(&Block { header, txdata: vec![if local { as_commitment_tx[0].clone() } else { bs_commitment_tx[0].clone() }] }, 1);
5248+
assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
5249+
5250+
println!("After 5 disconnected, A channels {}", nodes[0].node.list_channels().len());
5251+
//claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1);
5252+
//claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_2);
5253+
5254+
//let events = nodes[0].get_and_clear_pending_events();
5255+
//assert_eq!(events.len(), 2);
5256+
//let mut first_claimed = false;
5257+
//for event in events {
5258+
// match event {
5259+
// Event::PaymentReceived { payment_hash, .. } => {
5260+
// if payment_hash == payment_hash_1 {
5261+
// assert!(!first_claimed);
5262+
// first_claimed = true;
5263+
// } else {
5264+
// assert_eq!(payment_hash, payment_hash_2);
5265+
// }
5266+
// }
5267+
// _ => panic!("Unexpected event"),
5268+
// }
5269+
//}
5270+
}
5271+
5272+
#[test]
5273+
fn test_sweep_outbound_htlc_failure_update() {
5274+
//do_test_sweep_outbound_htlc_failure_update(false, true);
5275+
do_test_sweep_outbound_htlc_failure_update(false, false);
5276+
}

0 commit comments

Comments
 (0)