-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
sweep: group pinnable and non-pinnable inputs separately #9427
Comments
We did this in LDK in the latest release (I assume that's where @morehouse saw this). One subtle issue, though, is an HTLC can become pinnable once it (gets close to) expiring as suddenly both parties can claim it. Thus it's useful to track the pinnable state rather than making it fixed. |
@TheBlueMatt Will transactions actually relay with an |
They will not, no, indeed, for non-revoked transactions its really only an issue after expiry. If you do this for expired counterparty broadcasts, though, it needs consideration. |
Hi @yyforyongyu @morehouse is this issue being worked on? If not, I would love to take it up. |
I wonder if this is still needed given that we now always retry failed inputs immediately?
Thanks for the interest! However I'd recommend looking into some of the good first issues before diving into this one. |
That doesn't fix the issue. If a low-feerate package is pinned in our mempool, our broadcast will fail with a "not-enough-fees" error, which AFAIK doesn't allow us to remove only the pinned inputs. Additionally, mempools can be partitioned, which means we wouldn't even know about the pin. Once we have all channels using zero-fee commitments plus all HTLC transactions are v3, then we could potentially batch HTLC-Timeouts with HTLC-Successes and not worry about pinning. But it will probably be several years before we can deprecate and remove anchor channels completely. |
I think it depends on what happens in the following block - if the pinning tx confirms, we'd remove the input and sweep the rest; otherwise, we'd just move the fee func to the next position and perform a potential fee bump. This fee bump may or may not replace the pinning tx, tho I think it's irrelevant here as we only stick to the budget? |
Another thought: if an attacker wants to steal funds, they will just make sure their target HTLCs are pinnable. So grouping pinnable and non-pinnable inputs separately doesn't really reduce the attack surface. If anything, the separate grouping would help against accidental "pinning" where an honest peer is doing lots of batching. In that case we'd be able to claim the non-pinnable inputs separately at a minimal fee rate and could be sure their deadlines wouldn't be missed. This would reduce the potential damage of the accidental pin. The main question then is whether this scenario occurs often enough in practice to justify the grouping change. We've already seen this accidental pinning with anchors, so we should at least fix that by removing anchor sweeping. But for HTLC-Timeouts accidental pinning seems much less likely. |
Depending on your force-close timing and the specific attack, avoiding batching both HTLC preimage claims and HTLC timeout claims is a really good defense in depth. If you imagine some attack that relies on providing a preimage and then pinning on-chain HTLC preimage claims this can be great. Splitting claims into pinnable and not-pinnable also doesn't materially increase your total cost, whereas trying to avoid these kinds of attacks more generally requires much more aggressive splitting. |
I thought through this some more, and I agree. This sort of pinning attack against batched claims requires a pin to be maintained for a much shorter period of time, so it's worth having the extra defense for this case. Assume a topology like this
To pull off this batched pin the attacker would do something like:
This sort of attack is more complicated than a straightforward pin for the full CLTV delta, but it also means the attacker only needs to pin for ~10 blocks rather than ~80 blocks. |
The sweeper currently has no concept of pinnable and unpinnable inputs, so HTLC-Timeout (pinnable) and HTLC-Success (not pinnable) inputs can be aggregated into the same transaction if they have the same deadline. As a result, the HTLC-Success inputs effectively become pinnable too.
Another example of this is expired anchors (pinnable) being aggregated with HTLC-Success (not pinnable), though this could also be solved by removing expired anchor sweeping.
I think @yyforyongyu's proposed "sweeper groups" would be all we need to properly implement this.
The text was updated successfully, but these errors were encountered: