ZmnSCPxj [ARCHIVE] on Nostr: 📅 Original date posted:2020-10-23 📝 Original message: Good morning t-bast, > > ...
📅 Original date posted:2020-10-23
📝 Original message:
Good morning t-bast,
> > And in this case C earns.
>
> > Can C delay the refund to D to after the grace period even if D settled the HTLC quickly?
>
> Yes C earns, but D has misbehaved. As a final recipient, D isn't dependent on anyone downstream.
> An honest D should settle the HTLC before the `grace_period` ends. If D chooses to hold the HTLC
> for a while, then it's fair that he pays C for this.
Okay, now let us consider the case where the supposedly-delaying party is not the final destination.
So, suppose D indicates to C that it should fail the HTLC.
In this case, C cannot immediately propagate the `update_fail_htlc` upstream, since the latest commitment transaction for the C<->D channel still contains the HTLC.
In addition, our state machine is hand-over-hand, i.e. there is a small window where there are two valid commitment transactions.
What happens is we sign the next commitment transaction and *then* revoke the previous one.
So I think C can only safely propagate its own upstream `update_fail_htlc` once it receives the `revoke_and_ack` from D.
So the time measured for the grace period between C and D should be from C sending `update_add_htlc` to C receiving `revoke_and_ack` from D, in case the HTLC fails.
This is the time period that D is allowed to consume, and if it exceeds the grace period, it is penalized.
(In this situation, it is immaterial if D is the destination: C cannot know this fact.)
So let us diagram this better:
C D
|----update_add_htlc--->| ---
|---commitment_signed-->| ^
|<----revoke_and_ack----| |
|<--commitment_signed---| |
|-----revoke_and_ack--->| |
| | grace period
|<--update_fail_htlc----| |
|<--commitment_signed---| |
|-----revoke_and_ack--->| |
|---commitment_signed-->| v <--- grief point!
|<----revoke_and_ack----| ---
(somebody *else* better make sure my understanding of the state machine is correct!)
C can trivially grief D here, making it look like D is delaying, by delaying its own `commitment_signed` containing the *removal* of the HTLC.
D cannot send its own `revoke_and_ack` until it receives the signature for its own next commitment, as if it did so, it would lose the ability to close the channel unilaterally; it has to wait for C to send the `commitment_signed`.
Thus, it seems to me that C can grief D here.
The question is: does the above C-can-grief-D matter?
I think D does have a defense against C griefing in the above case:
* If the time between D->`update_fail_htlc`->C and the corresponding C->`commitment_signed`->D becomes too long:
* D drops the channel onchain.
* The dropped commitment tx still contains the HTLC, since it is the "previous" commitment that D happens to hold that has not yet had the `update_fail_htlc` committed.
If D performs the above, then C is forced to wait *even longer* (it has to wait out the HTLC timelock) before it can safely propagate the `update_fail_htlc`: D could be fooling with it and actually knows the preimage and claim it onchain, so C for its own safety *must* wait out the onchain timelock.
Does that make sense?
Does it sensibly protect against this griefing?
Is it too much of a punishment and could potentially hurt D more than it hurts C if C is a heavily-connected node that will not miss the channel while D has fewer channels and opened the C<->D channel in the first place?
--
For success case `update_fulfill_htlc`, I believe C can immediately propagate this back to its upstream since it can now.
Thus, in that case, we can stop the timer at the `update_fulfill_htlc`.
So at least for the *end point* of the grace period, I think the end point should be:
* If the HTLC failed:
* When both participants have sent `revoke_and_ack`.
* If the HTLC succeeded:
* When the downstream participant has sent `update_fulfill_htlc`.
For the *start point*, it seems the C->`commitment_signed`->D containing the HTLC would work as the start point.
In particular, it seems to me that C can also deliberately defer its own C->`revoke_and_ack`->D:
C D
|----update_add_htlc--->|
|---commitment_signed-->| ---
|<----revoke_and_ack----| ^
|<--commitment_signed---| |
|-----revoke_and_ack--->| | <--- grief point!
| | grace period
|<--update_fail_htlc----| |
|<--commitment_signed---| |
|-----revoke_and_ack--->| |
|---commitment_signed-->| v
|<----revoke_and_ack----| ---
(If D deliberately delays, then it is penalized, so we should consider the case where C attempts to trigger the reverse case).
D cannot safely fulfill the HTLC until after the previous commitment transactions of *both* sides have been revoked ("irrevocably committed" state).
So D can use the same defense, I think: if C is taking too long to send the `revoke_and_ack` pointed at above, it drops the channel onchain with the HTLC instantiated (which is why the *start time* has to be the C->`commitment_signed`->D that contains the new HTLC).
Thus the D grace period has two smaller grace periods that D imposes on C, using the threat of channel drop to protect against the C-side griefing.
Sorry for dropping into details already but so far this is the only griefing attack I can think of right now.
Regards,
ZmnSCPxj
Published at
2023-06-09 13:01:17Event JSON
{
"id": "bfc4a5ddeee357b2b314612402378b67fae3ab57cc8721388add36e8bc2fcadb",
"pubkey": "4505072744a9d3e490af9262bfe38e6ee5338a77177b565b6b37730b63a7b861",
"created_at": 1686315677,
"kind": 1,
"tags": [
[
"e",
"2e5ffd65d86c5774dbb4381933898049e781bd6e8719e31c24e98ee704e67d6e",
"",
"root"
],
[
"e",
"01bbfa214ab73ac3aa2014fe901f2c557d84fa349f940b6f819bcb2824bfb015",
"",
"reply"
],
[
"p",
"ec3fb08b335b94aace30d13181f2ad0280df9bc34f1a99832c4e2da8fb125eb3"
]
],
"content": "📅 Original date posted:2020-10-23\n📝 Original message:\nGood morning t-bast,\n\n\n\u003e \u003e And in this case C earns.\n\u003e\n\u003e \u003e Can C delay the refund to D to after the grace period even if D settled the HTLC quickly?\n\u003e\n\u003e Yes C earns, but D has misbehaved. As a final recipient, D isn't dependent on anyone downstream.\n\u003e An honest D should settle the HTLC before the `grace_period` ends. If D chooses to hold the HTLC\n\u003e for a while, then it's fair that he pays C for this.\n\n\nOkay, now let us consider the case where the supposedly-delaying party is not the final destination.\n\nSo, suppose D indicates to C that it should fail the HTLC.\nIn this case, C cannot immediately propagate the `update_fail_htlc` upstream, since the latest commitment transaction for the C\u003c-\u003eD channel still contains the HTLC.\n\nIn addition, our state machine is hand-over-hand, i.e. there is a small window where there are two valid commitment transactions.\nWhat happens is we sign the next commitment transaction and *then* revoke the previous one.\n\nSo I think C can only safely propagate its own upstream `update_fail_htlc` once it receives the `revoke_and_ack` from D.\n\nSo the time measured for the grace period between C and D should be from C sending `update_add_htlc` to C receiving `revoke_and_ack` from D, in case the HTLC fails.\nThis is the time period that D is allowed to consume, and if it exceeds the grace period, it is penalized.\n\n(In this situation, it is immaterial if D is the destination: C cannot know this fact.)\n\nSo let us diagram this better:\n\n C D\n |----update_add_htlc---\u003e| ---\n |---commitment_signed--\u003e| ^\n |\u003c----revoke_and_ack----| |\n |\u003c--commitment_signed---| |\n |-----revoke_and_ack---\u003e| |\n | | grace period\n |\u003c--update_fail_htlc----| |\n |\u003c--commitment_signed---| |\n |-----revoke_and_ack---\u003e| |\n |---commitment_signed--\u003e| v \u003c--- grief point!\n |\u003c----revoke_and_ack----| ---\n\n(somebody *else* better make sure my understanding of the state machine is correct!)\n\nC can trivially grief D here, making it look like D is delaying, by delaying its own `commitment_signed` containing the *removal* of the HTLC.\nD cannot send its own `revoke_and_ack` until it receives the signature for its own next commitment, as if it did so, it would lose the ability to close the channel unilaterally; it has to wait for C to send the `commitment_signed`.\n\nThus, it seems to me that C can grief D here.\n\nThe question is: does the above C-can-grief-D matter?\n\nI think D does have a defense against C griefing in the above case:\n\n* If the time between D-\u003e`update_fail_htlc`-\u003eC and the corresponding C-\u003e`commitment_signed`-\u003eD becomes too long:\n * D drops the channel onchain.\n * The dropped commitment tx still contains the HTLC, since it is the \"previous\" commitment that D happens to hold that has not yet had the `update_fail_htlc` committed.\n\nIf D performs the above, then C is forced to wait *even longer* (it has to wait out the HTLC timelock) before it can safely propagate the `update_fail_htlc`: D could be fooling with it and actually knows the preimage and claim it onchain, so C for its own safety *must* wait out the onchain timelock.\n\nDoes that make sense?\nDoes it sensibly protect against this griefing?\nIs it too much of a punishment and could potentially hurt D more than it hurts C if C is a heavily-connected node that will not miss the channel while D has fewer channels and opened the C\u003c-\u003eD channel in the first place?\n\n--\n\nFor success case `update_fulfill_htlc`, I believe C can immediately propagate this back to its upstream since it can now.\nThus, in that case, we can stop the timer at the `update_fulfill_htlc`.\n\nSo at least for the *end point* of the grace period, I think the end point should be:\n\n* If the HTLC failed:\n * When both participants have sent `revoke_and_ack`.\n* If the HTLC succeeded:\n * When the downstream participant has sent `update_fulfill_htlc`.\n\nFor the *start point*, it seems the C-\u003e`commitment_signed`-\u003eD containing the HTLC would work as the start point.\nIn particular, it seems to me that C can also deliberately defer its own C-\u003e`revoke_and_ack`-\u003eD:\n\n C D\n |----update_add_htlc---\u003e|\n |---commitment_signed--\u003e| ---\n |\u003c----revoke_and_ack----| ^\n |\u003c--commitment_signed---| |\n |-----revoke_and_ack---\u003e| | \u003c--- grief point!\n | | grace period\n |\u003c--update_fail_htlc----| |\n |\u003c--commitment_signed---| |\n |-----revoke_and_ack---\u003e| |\n |---commitment_signed--\u003e| v\n |\u003c----revoke_and_ack----| ---\n\n(If D deliberately delays, then it is penalized, so we should consider the case where C attempts to trigger the reverse case).\nD cannot safely fulfill the HTLC until after the previous commitment transactions of *both* sides have been revoked (\"irrevocably committed\" state).\nSo D can use the same defense, I think: if C is taking too long to send the `revoke_and_ack` pointed at above, it drops the channel onchain with the HTLC instantiated (which is why the *start time* has to be the C-\u003e`commitment_signed`-\u003eD that contains the new HTLC).\n\nThus the D grace period has two smaller grace periods that D imposes on C, using the threat of channel drop to protect against the C-side griefing.\n\n\n\nSorry for dropping into details already but so far this is the only griefing attack I can think of right now.\n\n\n\nRegards,\nZmnSCPxj",
"sig": "de106e8c0ecb0fe2bf81342b5980ec60c079bd3154e6ce8e7678e0b9389ea8973101825cddc4803c130e99605e32c1372c0eecad10b9543c3ece06a90fe8205f"
}