Skip to content

Commit 622c958

Browse files
author
Antoine Riard
committed
Test htlc outputs single tx claim due to timeout case
1 parent 9de4f1a commit 622c958

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

src/ln/channelmanager.rs

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3480,7 +3480,7 @@ mod tests {
34803480
assert_eq!(node_txn[3].input.len(), 2);
34813481
node_txn[3].verify(&revoked_tx_map).unwrap();
34823482

3483-
assert_eq!(node_txn[0].txid(), node_txn[3].txid()); // justice tx is duplicated due to block re-scanning
3483+
assert_eq!(node_txn[0], node_txn[3]); // justice tx is duplicated due to block re-scanning
34843484

34853485
let witness_script_1 = node_txn[0].clone().input[0].witness.pop().unwrap();
34863486
let witness_script_2 = node_txn[0].clone().input[1].witness.pop().unwrap();
@@ -3493,12 +3493,87 @@ mod tests {
34933493
}
34943494

34953495
assert_eq!(node_txn[1].input.len(), 1);
3496-
let witness_script = node_txn[1].clone().input[0].witness.pop().unwrap();
3497-
assert_eq!(witness_script.len(), 71); // Spending funding tx unique txoutput, tx broadcasted by ChannelManager
3496+
assert_eq!(node_txn[1].input[0].previous_output.txid, chan_1.3.txid()); //Spending funding tx unique txouput, tx broadcasted by ChannelManager
34983497

34993498
assert_eq!(node_txn[2].input.len(), 1);
35003499
let witness_script = node_txn[2].clone().input[0].witness.pop().unwrap();
3501-
assert_eq!(witness_script.len(), 133); //Spending a offered htlc output
3500+
assert_eq!(witness_script.len(), 133); //Spending an offered htlc output
3501+
assert_eq!(node_txn[2].input[0].previous_output.txid, node_txn[1].txid());
3502+
assert_ne!(node_txn[2].input[0].previous_output.txid, node_txn[0].input[0].previous_output.txid);
3503+
assert_ne!(node_txn[2].input[0].previous_output.txid, node_txn[0].input[1].previous_output.txid);
3504+
3505+
}
3506+
get_announce_close_broadcast_events(&nodes, 0, 1);
3507+
assert_eq!(nodes[0].node.list_channels().len(), 0);
3508+
assert_eq!(nodes[1].node.list_channels().len(), 0);
3509+
}
3510+
3511+
#[test]
3512+
fn claim_htlc_outputs_single_tx() {
3513+
// Node revoked old state, htlcs have timed out, claim each of them in separated justice tx
3514+
3515+
let nodes = create_network(2);
3516+
3517+
let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
3518+
3519+
// Rebalance the network to generate htlc in the two directions
3520+
send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
3521+
// node[0] is gonna to revoke an old state thus node[1] should be able to claim both offered/received HTLC outputs on top of commitment tx, but this
3522+
// time as two different claim transactions as we're gonna to timeout htlc with given a high current height
3523+
let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
3524+
let _payment_preimage_2 = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3000000).0;
3525+
3526+
// Get the will-be-revoked local txn from node[0]
3527+
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
3528+
3529+
//Revoke the old state
3530+
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1);
3531+
3532+
{
3533+
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
3534+
3535+
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 200);
3536+
3537+
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 200);
3538+
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
3539+
assert_eq!(node_txn.len(), 10); // ChannelManager : 2, ChannelMontitor: 8 (2 revocation htlc tx, 1 local commitment tx + 1 htlc timeout tx) * 2 (block-rescan)
3540+
3541+
assert_eq!(node_txn[0], node_txn[6]);
3542+
assert_eq!(node_txn[1], node_txn[7]);
3543+
assert_eq!(node_txn[2], node_txn[8]);
3544+
assert_eq!(node_txn[3], node_txn[9]);
3545+
assert_eq!(node_txn[2], node_txn[4]); //local commitment tx + htlc timeout tx broadcated by ChannelManger
3546+
assert_eq!(node_txn[3], node_txn[5]);
3547+
3548+
assert_eq!(node_txn[0].input.len(), 1);
3549+
assert_eq!(node_txn[1].input.len(), 1);
3550+
3551+
let mut revoked_tx_map = HashMap::new();
3552+
revoked_tx_map.insert(revoked_local_txn[0].txid(), revoked_local_txn[0].clone());
3553+
node_txn[0].verify(&revoked_tx_map).unwrap();
3554+
node_txn[1].verify(&revoked_tx_map).unwrap();
3555+
3556+
let witness_script_1 = node_txn[0].clone().input[0].witness.pop().unwrap();
3557+
let witness_script_2 = node_txn[1].clone().input[0].witness.pop().unwrap();
3558+
if witness_script_1.len() > 133 {
3559+
assert_eq!(witness_script_1.len(), 138);
3560+
assert_eq!(witness_script_2.len(), 133);
3561+
} else {
3562+
assert_eq!(witness_script_1.len(), 133);
3563+
assert_eq!(witness_script_2.len(), 138);
3564+
}
3565+
3566+
let mut funding_tx_map = HashMap::new();
3567+
funding_tx_map.insert(chan_1.3.txid(), chan_1.3.clone());
3568+
node_txn[2].verify(&funding_tx_map).unwrap();
3569+
assert_eq!(node_txn[2].input.len(), 1);
3570+
3571+
assert_eq!(node_txn[3].input.len(), 1);
3572+
let witness_script = node_txn[3].clone().input[0].witness.pop().unwrap();
3573+
assert_eq!(witness_script.len(), 133); //Spending an offered htlc output
3574+
assert_eq!(node_txn[3].input[0].previous_output.txid, node_txn[2].txid());
3575+
assert_ne!(node_txn[3].input[0].previous_output.txid, node_txn[0].input[0].previous_output.txid);
3576+
assert_ne!(node_txn[3].input[0].previous_output.txid, node_txn[1].input[0].previous_output.txid);
35023577

35033578
}
35043579
get_announce_close_broadcast_events(&nodes, 0, 1);

src/ln/channelmonitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ impl ChannelMonitor {
10591059
};
10601060
let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
10611061
sign_input!(sighash_parts, single_htlc_tx.input[0], Some(idx), htlc.amount_msat / 1000);
1062-
txn_to_broadcast.push(single_htlc_tx); // TODO: This is not yet tested in ChannelManager!
1062+
txn_to_broadcast.push(single_htlc_tx);
10631063
}
10641064
}
10651065
}

0 commit comments

Comments
 (0)