Skip to content

Commit 383bd90

Browse files
author
Antoine Riard
committed
Add test of claiming HTLC-Timeout outputs based on a revoked commitment
tx
1 parent 3e149b1 commit 383bd90

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

src/ln/channelmanager.rs

+32-16
Original file line numberDiff line numberDiff line change
@@ -3089,9 +3089,11 @@ mod tests {
30893089

30903090
#[derive(PartialEq)]
30913091
enum HTLCType { NONE, TIMEOUT, SUCCESS }
3092-
fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
3092+
#[derive(PartialEq)]
3093+
enum PenaltyType { NONE, HTLC }
3094+
fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction), commitment_tx: Option<Transaction>, revoked_tx: Option<Transaction>, has_htlc_tx: HTLCType, has_penalty_tx: PenaltyType) -> Vec<Transaction> {
30933095
let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
3094-
assert!(node_txn.len() >= if commitment_tx.is_some() { 0 } else { 1 } + if has_htlc_tx == HTLCType::NONE { 0 } else { 1 });
3096+
assert!(node_txn.len() >= if has_htlc_tx == HTLCType::NONE { 0 } else { 1 } + if has_penalty_tx == PenaltyType::NONE { 0 } else { 1 });
30953097

30963098
let mut res = Vec::with_capacity(2);
30973099

@@ -3107,7 +3109,9 @@ mod tests {
31073109
}
31083110
}
31093111
}
3110-
assert_eq!(res.len(), 1);
3112+
if !revoked_tx.is_some() && !(has_penalty_tx == PenaltyType::HTLC) {
3113+
assert_eq!(res.len(), 1);
3114+
}
31113115

31123116
if has_htlc_tx != HTLCType::NONE {
31133117
for tx in node_txn.iter() {
@@ -3126,6 +3130,20 @@ mod tests {
31263130
}
31273131
assert_eq!(res.len(), 2);
31283132
}
3133+
3134+
if has_penalty_tx == PenaltyType::HTLC {
3135+
let revoked_tx = revoked_tx.unwrap();
3136+
for tx in node_txn.iter() {
3137+
if tx.input.len() == 1 && tx.input[0].previous_output.txid == revoked_tx.txid() {
3138+
let mut funding_tx_map = HashMap::new();
3139+
funding_tx_map.insert(revoked_tx.txid(), revoked_tx.clone());
3140+
tx.verify(&funding_tx_map).unwrap();
3141+
res.push(tx.clone());
3142+
break;
3143+
}
3144+
}
3145+
assert_eq!(res.len(), 1);
3146+
}
31293147
node_txn.clear();
31303148
res
31313149
}
@@ -3203,10 +3221,10 @@ mod tests {
32033221
// Simple case with no pending HTLCs:
32043222
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true);
32053223
{
3206-
let mut node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
3224+
let mut node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, None, HTLCType::NONE, PenaltyType::NONE);
32073225
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
32083226
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
3209-
test_txn_broadcast(&nodes[0], &chan_1, None, HTLCType::NONE);
3227+
test_txn_broadcast(&nodes[0], &chan_1, None, None, HTLCType::NONE, PenaltyType::NONE);
32103228
}
32113229
get_announce_close_broadcast_events(&nodes, 0, 1);
32123230
assert_eq!(nodes[0].node.list_channels().len(), 0);
@@ -3218,10 +3236,10 @@ mod tests {
32183236
// Simple case of one pending HTLC to HTLC-Timeout
32193237
nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true);
32203238
{
3221-
let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
3239+
let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, None, HTLCType::TIMEOUT, PenaltyType::NONE);
32223240
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
32233241
nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
3224-
test_txn_broadcast(&nodes[2], &chan_2, None, HTLCType::NONE);
3242+
test_txn_broadcast(&nodes[2], &chan_2, None, None, HTLCType::NONE, PenaltyType::NONE);
32253243
}
32263244
get_announce_close_broadcast_events(&nodes, 1, 2);
32273245
assert_eq!(nodes[1].node.list_channels().len(), 0);
@@ -3255,7 +3273,7 @@ mod tests {
32553273
// HTLC-Timeout and a nodes[3] claim against it (+ its own announces)
32563274
nodes[2].node.peer_disconnected(&nodes[3].node.get_our_node_id(), true);
32573275
{
3258-
let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::TIMEOUT);
3276+
let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, None, HTLCType::TIMEOUT, PenaltyType::NONE);
32593277

32603278
// Claim the payment on nodes[3], giving it knowledge of the preimage
32613279
claim_funds!(nodes[3], nodes[2], payment_preimage_1);
@@ -3280,9 +3298,9 @@ mod tests {
32803298
nodes[3].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
32813299
}
32823300

3283-
let node_txn = test_txn_broadcast(&nodes[3], &chan_4, None, HTLCType::TIMEOUT);
3301+
let node_txn = test_txn_broadcast(&nodes[3], &chan_4, None, None, HTLCType::TIMEOUT, PenaltyType::NONE);
32843302

3285-
// Claim the payment on nodes[3], giving it knowledge of the preimage
3303+
// Claim the payment on nodes[4], giving it knowledge of the preimage
32863304
claim_funds!(nodes[4], nodes[3], payment_preimage_2);
32873305

32883306
header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
@@ -3292,7 +3310,7 @@ mod tests {
32923310
nodes[4].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
32933311
}
32943312

3295-
test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS);
3313+
test_txn_broadcast(&nodes[4], &chan_4, None, None, HTLCType::SUCCESS, PenaltyType::NONE);
32963314

32973315
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
32983316
nodes[4].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, TEST_FINAL_CLTV - 5);
@@ -3327,15 +3345,13 @@ mod tests {
33273345
node_txn[0].verify(&funding_tx_map).unwrap();
33283346
node_txn.swap_remove(0);
33293347
}
3330-
test_txn_broadcast(&nodes[1], &chan_5, None, HTLCType::NONE);
3348+
test_txn_broadcast(&nodes[1], &chan_5, None, None, HTLCType::NONE, PenaltyType::NONE);
33313349

33323350
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
3333-
let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT);
3351+
let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), None, HTLCType::TIMEOUT, PenaltyType::NONE);
33343352
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
33353353
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[1].clone()] }, 1);
3336-
3337-
//TODO: At this point nodes[1] should claim the revoked HTLC-Timeout output, but that's
3338-
//not yet implemented in ChannelMonitor
3354+
test_txn_broadcast(&nodes[1], &chan_5, None, Some(node_txn[1].clone()), HTLCType::NONE, PenaltyType::HTLC);
33393355
}
33403356
get_announce_close_broadcast_events(&nodes, 0, 1);
33413357
assert_eq!(nodes[0].node.list_channels().len(), 0);

0 commit comments

Comments
 (0)