Recover possible transaction in conflicted cache when RBF #4561
+229
−22
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What problem does this PR solve?
When we replace some transactions in RBF, some old transactions may be okay to be recovered, since there are no conflicts after removing transactions.
If we don't recover these transactions, it may introduce a scenario of a possible cycling attack in lightning network.
In the Lightning Network, the flow of funds across multiple hops is achieved through HTLCs. If an intermediate node discovers that the subsequent node has not acted as agreed, it can issue a timeout transaction, and after a certain waiting period, reclaim its own funds.
Assume A -> B -> C, where the attacker controls both A and C, and attempts to prevent B's timeout transaction from being confirmed on-chain while stealing B's money through a preimage transaction.
The attack method can be described as follows:
B1 is a transaction that is prepared to spend B0. B0 has already been included in a block, and B1 is in the transaction pool. Here, B1 is a timeout transaction.
A1 and A2 are two chained transactions that are prepared to spend A0. A0 has already been included in a block, and A1 and A2 are in the transaction pool.
Construct a B2 transaction, which spends B0 and A1.
As long as B2’s feerate is higher than B1's and A2's, it will evict B1 and A2 from the transaction:
Construct an A3 transaction, which spends A0 and has a feerate higher than A1's and B2's. It will evict A1 and B2 from the transaction pool:
In this way, both B1 and B2 will disappear from the transaction pool. By carefully timing the submission of the transactions, B2 will also not be broadcast to the network.
More reference:
https://blog.satsbridge.com/lightning-replacement-cycling-attack-explained-45636e41bc6f
https://twitter.com/mononautical/status/1715736832950825224
What is changed and how it works?
What's Changed:
Add
conflicts_outputs_cache
to track the relationship ofinput -> tx
in RBF, then add possible transactions into the verify pool, so that they may be recovered.This PR is based on the
new-verify
branch, one reason is we can not recursively callsubmit_entry
in async. Another reason isnew-verify
's worker-consumer model is more suitable for retrying submit transactions.Related changes
owner/repo
:Check List
Tests
Side effects
Release note