-
Notifications
You must be signed in to change notification settings - Fork 406
Add channel_monitor_claim_revoked_commitment_tx test #184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add channel_monitor_claim_revoked_commitment_tx test #184
Conversation
src/ln/channelmanager.rs
Outdated
/// Tests that the given node has broadcast a claim transaction against the provided revoked | ||
/// HTLC transaction. | ||
/// Tests that the given node has broadcast a claim transaction against the provided | ||
/// HTLC transaction issued from a revoked commitment tx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properly speaking, does a HTLC transaction is revoked ? It's more the broadcasting of a revoked commitment tx which "nullify" the chain of following transactions, seems to me
src/ln/channelmanager.rs
Outdated
|
||
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); | ||
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); | ||
assert_eq!(node_txn.len(), 4); // ChannelManager is broadcasting last_local_commitment_txn.. and revocation tx is broacasted twice as block has been re-scanned. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As described in force_close, ChannelManager is also broadcasting the last_local_commitment_txn, which is normal. But revocation tx which is generated and broadcasted again due to block re-scanning seems really a performance bottleneck?
src/ln/channelmanager.rs
Outdated
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); | ||
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); | ||
assert_eq!(node_txn.len(), 4); // ChannelManager is broadcasting last_local_commitment_txn.. and revocation tx is broacasted twice as block has been re-scanned. | ||
assert_eq!(node_txn[0].input.len(), 2); //TODO: really should be 4 when we implement to_local and to_remote via revocation key claiming |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still thinking to more assert, but how to identify specifically htlc input scripts?
94235ea
to
7e2fd5a
Compare
This 2 tests are covering claiming of htlc outputs from a revoked commitment tx, both case where they can shared a tx and case where they can't due to timeout. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I think we should be a bit more aggressive with these tests. Better to be aggressive (with lots of comments) and change the tests later if we tweak how txn get created than have a bug in on-chain claiming.
src/ln/channelmanager.rs
Outdated
let _payment_preimage_2 = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3000000).0; | ||
|
||
// Get the will-be-revoked local txn from node[0] | ||
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.iter().next().unwrap().1.last_local_commitment_txn.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that chan_1.3 is the channel_id, so you can do a get(chan_1.3).unwrap() here for a bit more readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, updated
src/ln/channelmanager.rs
Outdated
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; | ||
|
||
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); | ||
test_txn_broadcast(&nodes[0], &chan_1, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really care what nodes[0] did here? It misbehaved (broadcasted an old local commitment state, so is probably gonna lose its money on revocation claims).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was thinking of the comment, check_spend_revoked_transaction channel_monitor l 1338, maybe we want to implement it and substitute it to check_spend_local_transaction internally for specially handling revoked tx from us.
Seems check_spend_revoked_transaction is no longer news ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted the test_txn_broadcast
src/ln/channelmanager.rs
Outdated
|
||
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); | ||
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); | ||
assert_eq!(node_txn.len(), 4); // ChannelManager is broadcasting 2 last_local_commitment_txn..and revocation tx is broacasted twice as block has been re-scanned. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, can we test what the 4 txn look like, then to be much tighter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, add asserts based on witness script, txid, number of inputs.
src/ln/channelmanager.rs
Outdated
assert_eq!(nodes[0].node.list_channels().len(), 0); | ||
assert_eq!(nodes[1].node.list_channels().len(), 0); | ||
|
||
let chan_2 = create_announced_chan_between_nodes(&nodes, 2, 3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, if the tests are completely separate I'd prefer we make a new test. This means fewer channel_update/channel_announcement handles and also lets rust run them in paralell. I previously didn't but going forward would be nice to keep tests smaller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Splitted as of 080d5df
src/ln/channelmanager.rs
Outdated
// Rebalance the network to generate htlc in the two directions | ||
send_payment(&nodes[2], &vec!(&nodes[3])[..], 8000000); | ||
// node[2] is gonna to revoke an old state thus node[3] should be able to claim both offered/received HTLC outputs on top of commitment tx, but this | ||
// time as two different claim transactions as we're gonna to timeout htlc with given a high current heigh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: heigh -> height.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thks
src/ln/channelmanager.rs
Outdated
assert_eq!(node_txn[1].input.len(), 1); | ||
|
||
let mut funding_tx_map = HashMap::new(); | ||
funding_tx_map.insert(revoked_local_txn[0].txid(), revoked_local_txn[0].clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this test looks like it would pass whether the tx here were claiming the revoked normal output or the revoked HTLC output. We should test that later txn claim a different output in the revoked_local_txn[0], at least, if not be more aggressive with what all of the txn here look like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes add assert based on witness_script. Note: we can't assume which one is the htlc offered/received first as of using HashMap internally.
7e2fd5a
to
2f41481
Compare
let witness_script_1 = node_txn[0].clone().input[0].witness.pop().unwrap(); | ||
let witness_script_2 = node_txn[0].clone().input[1].witness.pop().unwrap(); | ||
if witness_script_1.len() > 133 { | ||
assert_eq!(witness_script_1.len(), 138); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason to get accepted HTLC script of 138 bytes instead of BOLT 3 139 bytes ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be 139 in prod but because the block height being used as locktime here is < 2^15 (but more than 2^7) its 138.
2f41481
to
080d5df
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just re-reviewed first test for now.
src/ln/channelmanager.rs
Outdated
assert_eq!(node_txn[3].input.len(), 2); | ||
node_txn[3].verify(&revoked_tx_map).unwrap(); | ||
|
||
assert_eq!(node_txn[0].txid(), node_txn[3].txid()); // justice tx is duplicated due to block re-scanning |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should just be able to assert node_txn[0], node_txn[3], no? The witnesses should also be identical.
let witness_script_1 = node_txn[0].clone().input[0].witness.pop().unwrap(); | ||
let witness_script_2 = node_txn[0].clone().input[1].witness.pop().unwrap(); | ||
if witness_script_1.len() > 133 { | ||
assert_eq!(witness_script_1.len(), 138); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be 139 in prod but because the block height being used as locktime here is < 2^15 (but more than 2^7) its 138.
src/ln/channelmanager.rs
Outdated
} | ||
|
||
assert_eq!(node_txn[1].input.len(), 1); | ||
let witness_script = node_txn[1].clone().input[0].witness.pop().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just assert the input prevout is the funding tx?
src/ln/channelmanager.rs
Outdated
assert_eq!(witness_script.len(), 71); // Spending funding tx unique txoutput, tx broadcasted by ChannelManager | ||
|
||
assert_eq!(node_txn[2].input.len(), 1); | ||
let witness_script = node_txn[2].clone().input[0].witness.pop().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we check that its spending the same as revoked_tx_map (and has a unique outpoint that wasnt in one of the others)?
080d5df
to
622c958
Compare
622c958
to
f1f9ead
Compare
Rebased, updated with comments, also add more asserts in remaining test based on last review pass. |
New tests look good, but found a bug that needs to be fixed first. Can you review #199 (which includes this rebased)? |
Fix simple to_local revoked output claim and rebase #184
Test htlc outputs shared claim case
Following discussion in #137 on testing htlc outputs claiming.
Note that I didn't clean the TODO in channel_monitor, I'm also gonna add this specific case here.