Skip to content

Commit 85c03c1

Browse files
Antoine RiardTheBlueMatt
authored andcommitted
Add test_bump_txn_sanitize_tracking_maps
Extend test visibility of claim-tracking maps to do so. Cover both "If 2 claimable-outpoint-spending txn are in 1 block, clean up properly" and "Clean up claimable_outpoints when pending_claim_requests is cleaned" fix commits in same patchset.
1 parent 0150b1f commit 85c03c1

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ enum OnchainEvent {
513513

514514
/// Higher-level cache structure needed to re-generate bumped claim txn if needed
515515
#[derive(Clone, PartialEq)]
516-
struct ClaimTxBumpMaterial {
516+
pub struct ClaimTxBumpMaterial {
517517
// At every block tick, used to check if pending claiming tx is taking too
518518
// much time for confirmation and we need to bump it.
519519
height_timer: u32,
@@ -621,6 +621,9 @@ pub struct ChannelMonitor {
621621
// Key is identifier of the pending claim request, i.e the txid of the initial claiming transaction generated by
622622
// us and is immutable until all outpoint of the claimable set are post-anti-reorg-delay solved.
623623
// Entry is cache of elements need to generate a bumped claiming transaction (see ClaimTxBumpMaterial)
624+
#[cfg(test)] // Used in functional_test to verify sanitization
625+
pub pending_claim_requests: HashMap<Sha256dHash, ClaimTxBumpMaterial>,
626+
#[cfg(not(test))]
624627
pending_claim_requests: HashMap<Sha256dHash, ClaimTxBumpMaterial>,
625628

626629
// Used to link outpoints claimed in a connected block to a pending claim request.
@@ -629,6 +632,9 @@ pub struct ChannelMonitor {
629632
// is txid of the initial claiming transaction and is immutable until outpoint is
630633
// post-anti-reorg-delay solved, confirmaiton_block is used to erase entry if
631634
// block with output gets disconnected.
635+
#[cfg(test)] // Used in functional_test to verify sanitization
636+
pub claimable_outpoints: HashMap<BitcoinOutPoint, (Sha256dHash, u32)>,
637+
#[cfg(not(test))]
632638
claimable_outpoints: HashMap<BitcoinOutPoint, (Sha256dHash, u32)>,
633639

634640
// Used to track onchain events, i.e transactions parts of channels confirmed on chain, on which

lightning/src/ln/functional_tests.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6762,3 +6762,49 @@ fn test_set_outpoints_partial_claiming() {
67626762
node_txn.clear();
67636763
}
67646764
}
6765+
6766+
#[test]
6767+
fn test_bump_txn_sanitize_tracking_maps() {
6768+
// Sanitizing pendning_claim_request and claimable_outpoints used to be buggy,
6769+
// verify we clean then right after expiration of ANTI_REORG_DELAY.
6770+
6771+
let nodes = create_network(2, &[None, None]);
6772+
6773+
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, LocalFeatures::new(), LocalFeatures::new());
6774+
// Lock HTLC in both directions
6775+
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9_000_000).0;
6776+
route_payment(&nodes[1], &vec!(&nodes[0])[..], 9_000_000).0;
6777+
6778+
let revoked_local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
6779+
assert_eq!(revoked_local_txn[0].input.len(), 1);
6780+
assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid());
6781+
6782+
// Revoke local commitment tx
6783+
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 9_000_000);
6784+
6785+
// Broadcast set of revoked txn on A
6786+
let header_128 = connect_blocks(&nodes[0].block_notifier, 128, 0, false, Default::default());
6787+
let header_129 = BlockHeader { version: 0x20000000, prev_blockhash: header_128, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
6788+
nodes[0].block_notifier.block_connected(&Block { header: header_129, txdata: vec![revoked_local_txn[0].clone()] }, 129);
6789+
check_closed_broadcast!(nodes[0]);
6790+
let penalty_txn = {
6791+
let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
6792+
assert_eq!(node_txn.len(), 7);
6793+
check_spends!(node_txn[0], revoked_local_txn[0].clone());
6794+
check_spends!(node_txn[1], revoked_local_txn[0].clone());
6795+
check_spends!(node_txn[2], revoked_local_txn[0].clone());
6796+
let penalty_txn = vec![node_txn[0].clone(), node_txn[1].clone(), node_txn[2].clone()];
6797+
node_txn.clear();
6798+
penalty_txn
6799+
};
6800+
let header_130 = BlockHeader { version: 0x20000000, prev_blockhash: header_129.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
6801+
nodes[0].block_notifier.block_connected(&Block { header: header_130, txdata: penalty_txn }, 130);
6802+
connect_blocks(&nodes[0].block_notifier, 5, 130, false, header_130.bitcoin_hash());
6803+
{
6804+
let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap();
6805+
if let Some(monitor) = monitors.get(&OutPoint::new(chan.3.txid(), 0)) {
6806+
assert!(monitor.pending_claim_requests.is_empty());
6807+
assert!(monitor.claimable_outpoints.is_empty());
6808+
}
6809+
}
6810+
}

0 commit comments

Comments
 (0)