Skip to content

Check for timing-out HTLCs in remote unrevoked commitments #284

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

Conversation

TheBlueMatt
Copy link
Collaborator

This is based on #282 and #283 as they all work on similar bits of code.

This resolves a TODO/issue in would_broadcast_at_height where we
will not fail a channel with HTLCs which time out in remote
broadcastable transactions.

Note that it requires a good bit of refactoring, sadly, undoing most of the refactoring I did to get #269 through. Luckily it cleans up state tracking in the process, so that's OK.

@TheBlueMatt TheBlueMatt force-pushed the 2019-01-remote-htlc-timeout-broadcast branch 5 times, most recently from 898433c to ad238e2 Compare January 7, 2019 19:02
Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed for now until 92d8e53

@TheBlueMatt TheBlueMatt force-pushed the 2019-01-remote-htlc-timeout-broadcast branch from 188a3fa to 70499da Compare January 9, 2019 04:48
@TheBlueMatt
Copy link
Collaborator Author

Rebased after dependencies got merged.

Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just review this commit, still ongoing work

@@ -50,11 +50,12 @@ use std::sync::atomic::Ordering;
use std::time::Instant;
use std::mem;

const CHAN_CONFIRM_DEPTH: u32 = 100;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you could even parameterize it, for coming tracking-claims-confirmation, I need to connect only HTLC_FAIL_ANTI__REORG_DELAY blocks, and more will slow down tests

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just the "how many blocks confirm_transaction connects" which is "how many blocks do we need to get a funding_locked". Later connects dont need to connect this many blocks (and dont).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point was we may want to use confirm_transaction for other uses than getting channel confirmation but a macro would be better if I'm lazy enough to write each time the loop confirmation

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohoh, right, yea, would love to see that, but I'll leave that for when something is ready to start using it.

nodes[1].chain_monitor.block_connected_checked(&header, i, &Vec::new(), &Vec::new());
header.prev_blockhash = header.bitcoin_hash();
}
test_txn_broadcast(&nodes[1], &chan, None, if use_dust { HTLCType::NONE } else { HTLCType::SUCCESS });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting ! This means that receiving node isn't incentivized to unilateral close channel as it would lost capability to claim dust HTLCs even being in possession of preimage for them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, we currently dont do the optimal thing and check inbound+outbound+dust+non-dust all the same way, which could be tweaked, but its simpler this way and should be fine at least for now.

Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, apart of the issue raised elsewhere, seems good to me, it may help further stuff to have recombined HTLCOutputInCommitment and HTLCSource.

Side-notes: it could be nice to have warning comments somewhere on distinction between "virtual offchain HTLC" (dust + non-dust) and "physical onchain HTLC" (non-dust) to ease understanding of newcomers of some code parts. And also maybe have a TODO to write advanced tests of gaming of all different delays.

// HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= inbound_cltv - outbound_cltv
// HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= CLTV_EXPIRY_DELTA
let htlc_outbound = $local_tx == htlc.offered;
if ( htlc_outbound && htlc.cltv_expiry + HTLC_FAIL_TIMEOUT_BLOCKS <= height) ||
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: space after opening bracket

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was on purpose to match the next line which has a "!" there, but doesnt really matter.

// inbound_cltv == height + CLTV_CLAIM_BUFFER
// outbound_cltv + HTLC_FAIL_TIMEOUT_BLOCKS + CLTV_CLAIM_BUFER <= inbound_cltv - CLTV_CLAIM_BUFFER
// HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= inbound_cltv - outbound_cltv
// HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= CLTV_EXPIRY_DELTA
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*nit: CLTV_CLAIM_BUFER

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, you mean the missing F? fixed.

// aka outbound_cltv + HTLC_FAIL_TIMEOUT_BLOCKS == height - CLTV_CLAIM_BUFFER
// inbound_cltv == height + CLTV_CLAIM_BUFFER
// outbound_cltv + HTLC_FAIL_TIMEOUT_BLOCKS + CLTV_CLAIM_BUFER <= inbound_cltv - CLTV_CLAIM_BUFFER
// HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= inbound_cltv - outbound_cltv
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay to be a little bit clearer, maybe you could have a line there : "Or we want outbound_cltv inferior or equal to inbound_cltv" and at the end we have "inbound_ctlv - outbound_cltv " that we set at 72 so have a comment "IMPRESCRIPTIBLE_SAFE_DELAY == 57". Maybe also update stuff in channel_manager.rs L338 CLTV_EXPIRY_DELTA = IMPRESCRIPTIBLE_SAFE_DELAY + HTLC_FAIL_TIMEOUT_BLOCKS + 2 * CLTV_CLAIM_BUFFER or at least its comment.
(Hmm in fact worth have a clean commit on const delay to clarify relations between all of them when things stabilize there)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really confused, where did you get IMPRESCRIPTIBLE_SAFE_DELAY/57? I added another line to the algebra noting the check in ChannelManager is inbound_cltv - outbound_cltv >= CLTV_EXPIRY_DELTA.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLTV_EXPIRY_DELTA = 6 * 12 (ChannelManager L338)
HTLC_FAIL_TIMEOUT_BLOCKS = 3 (ChannelMonitor L298)
CLTV_CLAIM_BUFFER = 6 (ChannelMonitor L294)
IMPRESCRIPTIBLE_SAFE_DELAY = CLTV_EXPIRY_DELTA - HTLC_FAIL_TIMEOUT_BLOCKS - 2 * CLTV_CLAIM_BUFFER
So with current config values we have IMPRESCRIPTIBLE_SAFE_DELAY == 57 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm still not entire sure what "IMPRESCRIPTABLE" means in this context, and not entirely sure this makes sense as a separate constant? Its just an implied requirement that we have to make sure is true even as we change constants.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From IRC:

<BlueMatt> ariard: I have no idea what "IMPRESCRITABLE" means
<ariard> BlueMatt: oh that a term I get from civil law, which means that a right can't be trespass, encroach, compress
<ariard> in context, I would to mean that we should be sure that we have a minimal safe delay we can't fuckup we substraction of HTLC_FAIL_TIMEOUT and CLTV_CLAIM_BUFFER
<BlueMatt> I mean so why not just leave it as "CHECK_CLTV_EXPIRY_SANITY_2"
<BlueMatt> in channelmanager
<BlueMatt> we'll already fail compile if that fails
<BlueMatt> (cause we'll be trying to set a negative number into a u32 const)
<ariard> Ah yes that what CHECK_CLTV_EXPIRY_SANITY is doing, same idea,, well don't have it in mind when I reviewed, maybe add a comment in would_broacast_height which references it too
<BlueMatt> k
<BlueMatt> is that sufficient or should I do something else before merge?
<ariard> All fine, just looked on your last comments, nothing to add

}
}
let non_dust_htlc_count = htlcs_included.len();
htlcs_included.append(&mut unincluded_htlc_sources);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: hey if you append unincluded_htlc does htlcs_included is still meaningful?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, that was unclear. I guess my change to call "unincluded_htlc_sources"->"included_dust_htlcs" makes it more clear? I consider dust HTLCs "included" since they effect the to_self/remote outputs and are distinct from HTLCs which were not included due to being in a state where we dont care about them.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay if you consider them included because of them being part of miner fee maybe add a hint about it in function comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment describing return value to build_commitment_transaction, which was completely absent previously.

We really shouldn't have split out the with-source HTLCs from the
in-transaction HTLCs when we added back-failing, and will need
almost all of the info in HTLCOutputInCommitment for each HTLC to
fix would_broadcast_at_height, so this is a first step at
recombining them.
@TheBlueMatt TheBlueMatt force-pushed the 2019-01-remote-htlc-timeout-broadcast branch from 70499da to 4156afd Compare January 11, 2019 21:40
This simplifies a few things, deduplicates a some small memory
overhead, and, most importantly, is a first step to fixing
would_broadcast_at_height.
This resolves a TODO/issue in would_broadcast_at_height where we
will not fail a channel with HTLCs which time out in remote
broadcastable transactions.
@TheBlueMatt TheBlueMatt force-pushed the 2019-01-remote-htlc-timeout-broadcast branch from 4156afd to 54f112c Compare January 13, 2019 17:59
@TheBlueMatt TheBlueMatt force-pushed the 2019-01-remote-htlc-timeout-broadcast branch from 54f112c to f065a62 Compare January 13, 2019 18:12
@TheBlueMatt TheBlueMatt merged commit 301f91e into lightningdevkit:master Jan 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants