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
Cluster size 2 package rbf #28984
base: master
Are you sure you want to change the base?
Cluster size 2 package rbf #28984
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
38ce2cb
to
5b216db
Compare
Added this to the tracking issue |
57e5fc7
to
56848f9
Compare
56848f9
to
be9d163
Compare
src/policy/rbf.cpp
Outdated
const CFeeRate replacement_miner_score(replacement_fees, replacement_vsize); | ||
|
||
for (const auto& entry : direct_conflicts) { | ||
const bool conflict_is_v3{entry->GetSharedTx()->nVersion == 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.
this can't be hit yet; post-v3 it can. I can remove this, or leave a note, or both. It makes some package rbfs more useful
(edit: it's used in #29001 functional tests )
7aee728
to
1d859b0
Compare
So thinking conceptually about this, I'm most concerned by the new I think there are two issues with this approach:
Even though the current RBF logic is broken already, I'd prefer to avoid adding on to that while rolling out the package RBF implementation, just so that users don't get used to some kinds of replacements working that really shouldn't be. So I was wondering, can we deal with this by just restricting the topology of what we allow a package RBF to conflict with? Let's say we allow a replacement if the conflict set consists of either (1) a single transaction with no ancestors (and of course no descendants, since any descendants would be in the conflict set as well), or (2) two transactions that are in a parent-child topology, and that have no other in-mempool ancestors (or descendants, of course). In those situations, the maximum miner score you would have to consider is either the individual feerate of the parent tx or the ancestor feerate of the child, so the new logic should work perfectly. |
After offline discussion with @sdaftuar , I've worked on a set of prospective changes and pushed them to this branch as follow-on commits. Key change is that we will now only allow package RBF when the conflicted transactions are all in "clusters" of up to size 2. This allows us to calculate mining scores for each conflicted transaction, which means that post-cluster mempool, if we did this right, IIUC, the behavior should match with more general package RBF. |
f9ce967
to
385b6ca
Compare
722d1a5
to
7fd321d
Compare
7fd321d
to
ce3a662
Compare
rebased due to conflict |
While I wouldn't trust myself to correctly code-review this PR, I'd be happy to work on e2e tests that would leverage this for lightning channels fee-bumping (based on eclair) if it can help validate the logic and get this PR merged. I'd like to highlight again how important this feature is for lightning (and probably for many other L2 protocols on top of bitcoin today). This is the critical step that allows us to mitigate pinning of a commitment transaction, and guarantee that we're able to set the fees of our commitment package to a value that should ensure timely confirmation. |
sorry forgot to link #30072 here, added to OP |
ce3a662
to
d412681
Compare
rebased on latest #30072 |
2fd34ba Add sanity checks for various ATMPArgs booleans (Greg Sanders) 20d8936 [refactor] make some members MemPoolAccept-wide (glozow) cbbfe71 cpfp carveout is excluded in packages (glozow) 69f7ab0 Add m_allow_sibling_eviction as separate ATMPArgs flag (Greg Sanders) 57ee302 Add description for m_test_accept (Greg Sanders) Pull request description: First few commits of #28984 to set the stage for the package RBF logic. These refactors are preparation for evaluating an RBF in a multi-proposed-transaction context instead of only a single proposed transaction. Also, carveouts and sibling evictions only should work in single RBF cases so add logic to preclude multi-tx cases in the future. No behavior changes aside from bailing earlier from failed carve-outs. ACKs for top commit: glozow: reACK 2fd34ba via range-diff sr-gi: utACK [2fd34ba](2fd34ba) theStack: re-ACK 2fd34ba Tree-SHA512: 5071c5b8d9b8d2c9faa278c8c4df31de288cb407a68e4d55544c588caff6c86160cce7825453549c6ed69e29d9ccb5ee2d4a518b18f563bfb12f2ced073fe42a
d412681
to
d05e350
Compare
rebased on master 🚀 |
@@ -91,7 +91,6 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v | |||
const auto parent_info = [&] { | |||
if (mempool_ancestors.size() > 0) { | |||
auto& mempool_parent = *mempool_ancestors.begin(); | |||
Assume(mempool_parent->GetCountWithDescendants() == 1); |
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.
My comment is just about the commit message for this commit, not this line of code (sorry):
Relax assumptions aabout in-mempool children of in-mempool
"aabout" --> "about"
TxA (in mempool) <- TxB' (in package, conflicts with TxB) <-
TxD (in package)
s/TxD/TxC/ ?
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.
fixed
src/validation.cpp
Outdated
direct_conflict_iters.merge(ws.m_iters_conflicting); | ||
} | ||
|
||
for (const auto& ws : workspaces) { |
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.
Seems weird to loop through all the workspaces, when GetEntriesForConflicts
is doing all the work that needs to be done on the first invocation? Maybe just invoke once with the child's txid, as is done further down?
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.
right this is just a logging arg; probably should clean that up to just take Wtxid
in future work. re-arranged and passed in child workspace now
src/validation.cpp
Outdated
} | ||
|
||
// If the package has in-mempool ancestors, we won't consider a package RBF | ||
// since it would result in a cluster larger than 2 |
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 you just add a comment here that references the comment on line 1520, as a reminder that we can't relax this without revisiting how we track available inputs when processing a package?
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.
made an attempt at a grepp-able cautionary note
Relax assumptions about in-mempool children of in-mempool parents. With package RBF, we will allow a package of size 2 with conflicts on its parent and reconsider the parent if its fee is insufficient on its own. Consider: TxA (in mempool) <- TxB (in mempool) TxA (in mempool) <- TxB' (in package, conflicts with TxB) <- TxC (in package) If TxB' fails to RBF TxB due to insufficient feerate, the package TxB' + TxC will be considered. PackageV3Checks called on TxB' will see an in-mempool parent TxA, and see the in-mempool child TxB. We cannot assume there is no in-mempool sibling, rather detect it and fail normally. Prior to package RBF, this would have failed on the first conflict in package.
Support package RBF where the conflicting package would result in a mempool cluster of size two, and each of its direct conflicts are also part of an up-to-size-2 mempool cluster. This restricted topology allows for exact calculation of miner scores for each side of the equation, reducing the surface area for new pins, or incentive-incompatible replacements. This allows wallets to create simple CPFP packages that can fee bump other simple CPFP packages. This, leveraged with other restrictions such as V3 transactions, can create pin-resistant applications. Future package RBF relaxations can be considered when appropriate. Co-authored-by: glozow <gloriajzhao@gmail.com> Co-authored-by: Greg Sanders <gsanders87@gmail.com>
d05e350
to
cddd60e
Compare
cddd60e
to
7b74cbf
Compare
Allows any 2 transaction package with no in-mempool ancestors to do package RBF when directly conflicting with other mempool clusters of size two or less.
Proposed validation steps:
Post-cluster mempool this will likely be expanded to general package rbf, but this is what we can safely support today.