-
Notifications
You must be signed in to change notification settings - Fork 38.7k
rpc: allow submitpackage to be called outside of regtest #27609
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
|
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. |
|
Concept ACK |
instagibbs
left a comment
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.
concept ACK
ec025db to
179749e
Compare
|
Added a release note and addressed #27609 (comment) |
|
Concept ACK - when you get a chance, can you put together a backport PR for |
7bb06e2 to
5201396
Compare
|
Had a chat with @sdaftuar offline about how safe this RPC is for a miner to expose. He gave an example of a "parent pays for child" package that is currently handled poorly, and a small fix to prevent it. I've added the small fix and a test that contains an example. Imagine a diamond shape and mempool minfeerate is 5sat/vB: On master, what we'll do is reject each individual transaction, but end up accepting the full package. The child is just below the mempool min feerate and is likely to be evicted later in You can perhaps submit the same transactions via The small change is to reject any package in which the child has a lower feerate than the package feerate. So we reject all of the transactions. |
|
note that the 💎 issue still exists in #26711 , where the ultimate subpackage(including the child) would let everything in. with the fix, hopefully, now every sub-package that is let in the mempool must have a child that pays |
Yeah. Rebasing it on top of this. |
|
without #26711 we are still letting things into mempool that are possibly problematic, no? |
You're right. Every time we think about it a bit longer, another not-quite-ideal edge case comes up. Especially with full mempools and eviction being something to consider. I think it was too early to open this. I've pushed a change to disallow any dependency between parents, which is where all these stupid edge cases come from (but is probably not a common use case).
With the "tree only" topology requirement I feel more comfortable having this branch exist, but still don't think this is something to merge yet / backport. If anybody saw this PR and got excited they could maybe run this, but I'm going to close this PR. @instagibbs thanks for your comments, I'm incorporating them into #26711! |
5201396 to
9ad2c71
Compare
|
IsChildWithParentsTree <---- is this originally what the V3 topo looked like? |
Yep exactly. 1 child multiple parents. Parents can't spend each other. You can use this for batch-bumping commitment transactions, for example. |
Do you think this is not ready to merge / backport yet because of the unexpected edge cases that showed up with the previous, less restrictive iteration, leading to the expectation that something might show up for "tree only" too? Or is there already a known issue for "tree only"? I am looking at this from a Lightning perspective. Not being able to get that presigned commitment transaction and htlc sweep in before cltv expiry is bad and something that may not be so difficult to exploit for an attacker. Of course this PR only allows acceptance of a package over rpc, but at least it would allow miners to open up an alternative endpoint for vulnerable lightning node operators to submit their packages to. |
Short answer: I don't know of any issues with the "child-with-parents tree only" topology. It was actually made specifically for Lightning. The current RPC is restricted to child-with-parents topology. However, it doesn't work for all child-with-parent packages as it doesn't handle parents spending each other properly. This is one of the reasons it was regtest-only. This, among other things, was going to be fixed in #26711, after which it would be ok to build the p2p changes (and thus make sense to submitpackage outside of regtest). Given current events, multiple people reached out about a miner opening up submitpackage to make "package relay without the relay" available for lightning today. So I made this PR, thinking it was "good enough" for this use case and RPC is a trusted interface anyway. But after talking through the edge cases more with others, particularly about a miner opening this as a public API, I became convinced that this is unsafe and we should wait until #26711. It didn't seem right to quickly add commits that avoided specific edge cases, as there are just so many of them. #26711 would not make sense to rush or backport. But I already opened this PR, so I wanted to at least push a branch that I don't believe is unsafe. Hence the "tree only" which avoids the edge cases but covers Lightning since AFAIK you won't make commitment transactions that spend each other. I do not recommend running a patch, but if you decide to do so, use this branch with trees only. |
|
re:topology restrictions beyond generalized ancestor packages, is the thought to restrict the typologies at a higher level, vs AcceptMultipleTransactions? Noticed this branch is restricting at RPC layer. I presume it would also require tree structure in #26711 ? |
I'm curious, what's the worst-case failure here? Is it that a participating miner's mempool gets screwed up? or that replacement may not happen properly? or that pinning becomes an issue? In other words, I'm wondering if the failure is tolerable in the sense that the damage would be contained to the user trying to submit a dumb (or "not topoolgically sensical") package? I was enthusiastic about a small change that would open up this functionality for emergency use to, say, facilitate closing a channel whose commitment tx no longer is admissable to a high-fee mempool, but things have gotten complicated and I'm now having a tough time following. Still down to review, just wondering if theoretical edge cases are getting in the way of good functionality. |
No tree-only in #26711, the hope is to handle ancestor packages so we can do ancestor package relay. We can do it 💪
The worst case is the miner accepts transactions they actually should reject. Yes, if you're using this for fee-bumping commitment transactions, you're not going to submit any of these edge-casey packages. |
That's true. For anchor commitments I think it is the case that all outputs except the anchors (main balance outputs and htlcs) are timelocked CSV 1, so they aren't even available until after confirmation. |
If I understood the various threads here and in other prs correctly, I think the consequence of this is that the mempool will be sub-optimal and lead to a block template that earns fewer fees for the miner exposing the endpoint? If this would happen, I suppose the miner can always close the endpoint again and wait for the next release that is more strict on the "child-with-parents tree only" packages (while also allowing different topologies). The upside is that the edge case is identified at that point. But also this is only a theoretical possibility, because it might be that there are no edges cases with "child-with-parents tree only"? Not sure if this is provable somehow. If there would be an edge case, I think it would need to be filtered out by #26711 (assuming that PR fixes it all). Maybe that is a way to come up with that edge case - try to find a "child-with-parents tree only" that would pass this PR, but not be able to pass the validation in #26711? When looking at #26711 though, it seems that with testing all sub-packages, it is only relaxing things rather than restricting it further compared to this PR. I also wanted to share two other thoughts:
|
Many edge cases exist when parents in a child-with-parents package can spend each other. However, this pattern should also be uncommon in normal use cases.
3358135 to
5b878be
Compare
|
Rebased.
It doesn't seem like people are strongly against / have use cases hindered by the |
|
Concept ACK and Approach ACK (regarding the We want to provide a safer interface for miners who may currently be reached-out to for accepting packages before package relay is available. We want to avoid introducing a footgun with this command, where using it could get a miner's mempool to refuse transactions it would otherwise accept (either because it was filled with suboptimal transactions which wouldn't get evicted or because the minfeerate was artificially bumped more than necessary). There is a few arguments in this thread along the line of "this situation can already be reached by using multiple Moreover it seems there is at the moment only interest in transmitting very specific packages out of band, Lightning commitment transaction + a fee-paying child and Lightning HTLC sweep transaction + a fee-paying child. Given recent bugs, the remaining uncertainty and the proximity to the release i think we should definitely keep the |
|
Concept ACK having this exposed - in general even simple packages with a parent and a child where the parent has too low a fee to reach the mempool will propagate reasonably - many nodes don't actually ever hit their mempool min fee because all their peers do it for them, so they sit right below 300MB usage and don't ever go over and set a min fee. Some miners likely run unlimited mempools (or, if they don't, they can mine on a small mempool and use this rpc to submit packages from an unlimited mempool node sitting next to it). Thus, for those with lots of peers, there's some nontrivial probability of packages actually making it to miners even if they wouldn't accept it on P2P, thus exposing this is a quite useful even without the P2P parts. |
|
ACK 5b878be Nothing much changed from last time. Tree topology will be useful for most people that will be submitting locally(one parent and one child often), and it's a quite trivial check that we can back out later. Did some very basic testing on mainnet. |
|
Concept ACK |
dergoegge
left a comment
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.
Code review ACK 5b878be
Code and docs look good to me. Didn't do any testing.
|
Given that I understood right, that any package where the child has a lower feerate than the package feerate is rejected: Concept ACK, Approach ACK, will start reviewing today. |
ajtowns
left a comment
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.
ACK 5b878be
Did some basic tests and it worked as expected. Some nits noted that could be addressed in a followup.
| /** Context-free check that a package IsChildWithParents() and none of the parents depend on each | ||
| * other (the package is a "tree"). | ||
| */ | ||
| bool IsChildWithParentsTree(const Package& 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.
Seems like this would be better as:
class Package {
public:
std::vector<CTransactionRef> txs;
bool IsChildWithParentsTree() const;
...
};| - A new RPC, `submitpackage`, has been added. It can be used to submit a list of raw hex | ||
| transactions to the mempool to be evaluated as a package using consensus and mempool policy rules. | ||
| These policies include package CPFP, allowing a child with high fees to bump a parent below the | ||
| mempool minimum feerate (but not minimum relay feerate). |
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.
"current mempool minimum feerate" might make it a bit clearer that this is the dynamic level, not the fixed 1sat/vb level?
I don't think that's the case. You can |
The child transaction should be rejected, but not the entire package. |
|
As I understand it:
So I think this isn't quite accurate:
The only way you get a child with a lower feerate than the package, is if a parent has a higher feerate than the child and the package, but in that case the parent will have already been accepted, and the package will become smaller, and this is repeated until the child does have the highest feerate in the package. (Personally I'm not overly concerned about the risk of not having optimal txs (particularly at the bottom of the mempool) -- you can already get similar behaviour by (eg) having a public node with 300MB maxmempool and a private node with 500MB maxmempool that only receives txs from your public node (thus mostly ensuring its minfee stays at 0; perhaps add a short mempool expiry, too), then manually adding the txs in question to your mempool, and using your mempool to generate blocks, etc. It's an experimantal rpc, so if you don't like how it ends up working, that's fine; wait 'til it's not experimental before using it. Just my opinion, YMMV of course) |
ariard
left a comment
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.
Code Review ACK 5b878be. Though didn’t manually test the PR.
I think you have few high-level concerns if submitpackage is exposed by mining pools or block templates builders (e.g transaction “accelerators”) or other substantial transaction-relay full-nodes :
- it can be maliciously leveraged to broadcast a high-fee, low-feerate pinning package of LN commitment transaction + child still above the dynamic mempool min fee blocking a honest high-fee, high-feerate single commitment tx to propagate and confirm
- it can be used to throw high-fee low feerate packages in your competitors mining pools to block single high ancestor score individual transaction propagating and as such downgrade their total income
- it can be used by p2p deanonymization attackers to fingerprint network mempools and observe altered transaction-relay propagation to discover tx-relay topology (I guess similar to the old TxProbe strategy)
If correct, I think all those concerns are more transient “swallowing the bullet” style until full p2p packages is deployed. On the other hand, it’s good to have early testing in limited production of the package acceptance logic, so I would say it’s an equilibrium.
I don’t think if those concerns are correct they warrants withholding landing this PR, though I believe releases notes or doc/policy/packages.md could be extended accordingly as follow-up to say what it is relevant in function of each submitpackage deployment.
| RBF is not supported. Refer to doc/policy/packages.md for more details on package policies | ||
| and limitations. | ||
|
|
||
| - This RPC is experimental. Its interface may change. |
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.
“policies and limitations” can change if sounds more robust and consistent with future p2p support i think
| std::unordered_set<uint256, SaltedTxidHasher> parent_txids; | ||
| std::transform(package.cbegin(), package.cend() - 1, std::inserter(parent_txids, parent_txids.end()), | ||
| [](const auto& ptx) { return ptx->GetHash(); }); | ||
| // Each parent must not have an input who is one of the other parents. |
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.
from my understanding a child input conflicting with a parent input is checked later on in ProcessNewPackage / AcceptPackage / `CheckPackage
| "This RPC is experimental and the interface may be unstable. Refer to doc/policy/packages.md for documentation on package policies.\n" | ||
| "Warning: until package relay is in use, successful submission does not mean the transaction will propagate to other nodes on the network.\n" | ||
| "Currently, each transaction is broadcasted individually after submission, which means they must meet other nodes' feerate requirements alone.\n" | ||
| "Warning: successful submission does not mean the transactions will propagate throughout the network.\n" |
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.
could say the integrality of the transactions, to convey the idea than transactions might propagate partially e.g only the parents not child
|
ACK 5b878be |
Summary: ``` Permit (restricted topology) submitpackage RPC outside of regtest. [...] This RPC should be safe but still experimental - interface may change, not all features (e.g. package RBF) are implemented, etc. If a miner wants to expose this to people, they can effectively use "package relay" before the p2p changes are implemented. However, please note this is not package relay; transactions submitted this way will not relay to other nodes if the feerates are below their mempool min fee. Users should put this behind some kind of rate limit or permissions. ``` Backport of [[bitcoin/bitcoin#27609 | core#27609]]. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK Reviewed By: #bitcoin_abc, PiRK Differential Revision: https://reviews.bitcoinabc.org/D16490
Summary: ``` Permit (restricted topology) submitpackage RPC outside of regtest. [...] This RPC should be safe but still experimental - interface may change, not all features (e.g. package RBF) are implemented, etc. If a miner wants to expose this to people, they can effectively use "package relay" before the p2p changes are implemented. However, please note this is not package relay; transactions submitted this way will not relay to other nodes if the feerates are below their mempool min fee. Users should put this behind some kind of rate limit or permissions. ``` Backport of [[bitcoin/bitcoin#27609 | core#27609]]. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK Reviewed By: #bitcoin_abc, PiRK Differential Revision: https://reviews.bitcoinabc.org/D16490
|
fwiw, people who like this may also like #31385 |
Permit (restricted topology) submitpackage RPC outside of regtest. Suggested in #26933 (comment)
This RPC should be safe but still experimental - interface may change, not all features (e.g. package RBF) are implemented, etc. If a miner wants to expose this to people, they can effectively use "package relay" before the p2p changes are implemented. However, please note this is not package relay; transactions submitted this way will not relay to other nodes if the feerates are below their mempool min fee. Users should put this behind some kind of rate limit or permissions.