-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
v3 transaction policy for anti-pinning #28948
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. |
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.
Would be good to have some fuzzing for the new policy rules. Maybe amending the existing fuzz targets (tx_pool, tx_package_eval) to include v3 txs is enough? A standalone harness for the new rules would probably also be good regardless.
Changed tx_pool and tx_package_eval fuzzer to sometimes create v3 transactions, and check v3 invariants at the end of each iteration. |
|
I don’t think adopting cluster limits instead of max ancestors / descendants limits change anything for V3 packages. What matters is the overall weight limit of the package (4000 WU for a child), as this limit draws an anti-pinning security bound on the lowest off-chain payment that one can afford to burn as an absolute fee . Limit to be evaluated in function of network mempools congestion. Removing the absolute fee replacement rules I think would simplify current pinning analysis - though sounds this is beyond the scope of this proposal. |
82d683e
to
d9ebb11
Compare
CI is green. I've added a rule for maximum sigops and updated the doc. |
Pushed to address @instagibbs review and make v3 not-yet-standard. |
i’m not sure if the adversary injects malicious package A in target’s mempool, and package B in other network mempools.
thanks interesting to test both NTA and “loophole” pinnings on this branch described earlier to t-bast here
sure package relay fixes this, less sure even if you add package RBF if you combine with some leeway given by 1000vb limit
no, if we follow this line of reasoning imo it’s like saying it’s okay to have IPsec or TLS shipping with weak crypto primitives
i broke enough time LN spec dev stuff to take their technical opinions at their fair prices.
the CPFP carveout rule can be removed with or without v3, its security benefits quasi-null in my opinion.
@sdaftuar do you have a lightning node running somewhere on signet (maybe instagibbs has some v3 CLN branch) ? |
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. Left some comments that are just nits, nothing that I think needs to be addressed unless you have to fix more things anyway.
Will do another round of testing shortly...
ACK 29029df In addition to my code review and running a slightly earlier version of this branch on a year's worth of historical data, I also did a bunch of mutation testing to confirm code coverage for every component of the new logic (found one block that I think is unreachable, which I commented on above, but doesn't seem like an issue either way). |
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.
looks like if I revert TX_MAX_STANDARD_VERSION to 3, all unit/functional tests pass?
ACK 29029df modulo that
I suppose my change at https://github.com/bitcoin/bitcoin/pull/28948/files#diff-cc0c6a9039a1c9fe38b8a21fe28391fffbac9b8531dfda0f658919a9f74b46baR793 is partially to blame. I made it I'm working on a followup to address the comments, and can incorporate if I need to retouch. |
ACK 29029df |
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.
Post merge ACK
@sdaftuar @achow101 @instagibbs Congrats guys to ACK and merge a +1100 LoC PR a Friday evening with still standing objections on the very heart of the PR. I think there is medium difficulty follow-up to this PR to make pinning far harder to exploit. |
I'll let people decide for themselves our professionalism or lack thereof. I asked hundreds of comments ago to stop You are also free to lobby different projects to not use these primitives moving forward and push As was noted already: We're nearing feature freeze, which means if we miss the window the rebasing would continue To end a positive note, I'm looking forward to iterative improvements,
and leveraging a totally ordered mempool in interesting ways beyond. |
6b161cb [test] second child of a v3 tx can be replaced individually (glozow) 5c998a6 [refactor] use MAX_PUBKEYS_PER_MULTISIG instead of magic numbers in test (glozow) a934642 [test] PackageV3Checks with inheritance violation in mempool ancestor (glozow) 63b62e1 [doc] fix docs and comments from v3 (glozow) Pull request description: Addresses final comments from #28948: - thread at #28948 (comment), using ismaelsadeeq@87fc7f0 with some modifications - #28948 (comment) - #28948 (comment) - #28948 (comment) - #28948 (comment) - #28948 (comment) - #28948 (comment) - #28948 (comment) - #28948 (comment) ACKs for top commit: instagibbs: ACK 6b161cb sdaftuar: utACK 6b161cb Tree-SHA512: 584fce7810f4d704ee6ab51fdc7d42bab342140cae3d076f89b5e1966dd1dd8293cb25b3121e41a4dcd65f9d4a735102b9ab2e90f98aa770b84e21f4d35d63d3
I maintain your review and the ones of @sdaftuar and @achow101 are lacking professionalism. For a PR which is called "anti-pinning" (it's all in the title), there has been no substantial answer on my concerns that it does not address neither rbf rule3 pinning (the 1000 vbyte rule limit offers to give a way, see "loophole" scenario exposed above), neither topological-based scenario at the tx-relay network level (NTA one), and that actually "hard" limits are a source of "no-one-fits-all" bargainging for use-cases operations (as we have seen with On the review process itself and calling to stop using this PR to debate the robustness of the mitigation, this is insulting and a flagrant proof of your lack of system engineering culture. When software engineers are designing new cryptopgraphic primtives or kernel mechanism (e.g linux The current design and review mentality you're exposing and I understanding you're advocating has been proven multiple times a source of potential security failures (e.g On the remark that people who find this useful and want to, they can use it, which I understanding that LN maintainers or anyone else (e.g exchange batching) are free to level up their bitcoin use-cases with nversion=3 semantics. Sadly one has to be very realistic and observe that LN security track record is not great. When you're doing adversarial reviews on financial software you cannot trust the incentives of the developers "in defense", as they have always a moral interest to claim attack X or attack Y is "mitigated", playing some kind of security theater. Finally, on the call of approaching feature freeze, this is neither a convicining argument in my eyes. In critical system design, development and maintenance there is a social phenomena called process fatigue. Namely, when engineers are getting in front of some deadlines after lengthy work cycles, they are rushing to deliver a technical project, provoking downstream major failure (e.g known historic example is Space Shuttle Challenger disaster). There is no magical reason that Bitcoin Core review process is not affected by such phenomena of "process fatigue" and as such when there is no review consensus on security-first contribution in one of the part of the codebaee like the mempool, practical wisdom would recommend to delay it to the next release cycle. This is better than yet-another "poor hot fixes" in production were we have to mobilize half-of the engineering, vendors and users ecosystem time, and jeopardize their funds. To conclude your answer is a poor one sustaining my precedent accusation of lacking professionalism. You're still free to communicate any example or demonstration infrastructure running with v3 semantics that I can target with demo pinning attacks. And as such back up your Bitcoin Core technical review with your credibility and reputation, in a skin-in-the-game approach. |
@glozow are you still interested if I do a proof-of-concept bitcoin core branch or idea draft of a) moving the “package limit” on the use-case side and b) make it dynamic (in the limit of absolute core DoS robustness) ? I think it can be backup in future bip331 changes. v3 is your work and this is your PR making anti-pinning claims after-all. |
did it with #29448 |
@@ -694,6 +696,7 @@ libbitcoin_common_a_SOURCES = \ | |||
netbase.cpp \ | |||
net_permissions.cpp \ | |||
outputtype.cpp \ | |||
policy/v3_policy.cpp \ |
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.
Considering the current code organisation, I can't see any reasons to include policy/v3_policy.cpp
into the libbitcoin_common
library. Both its symbols, i.e., SingleV3Checks
and PackageV3Checks
are referenced in the validation.cpp
only. As such, policy/v3_policy.cpp
inclusion into the libbitcoin_node
library is enough.
/** Helper for PackageV3Checks: Returns a vector containing the indices of transactions (within | ||
* package) that are direct parents of ptx. */ | ||
std::vector<size_t> FindInPackageParents(const Package& package, const CTransactionRef& ptx) | ||
{ | ||
std::vector<size_t> in_package_parents; | ||
|
||
std::set<Txid> possible_parents; | ||
for (auto &input : ptx->vin) { | ||
possible_parents.insert(input.prevout.hash); | ||
} | ||
|
||
for (size_t i{0}; i < package.size(); ++i) { | ||
const auto& tx = package.at(i); | ||
// We assume the package is sorted, so that we don't need to continue | ||
// looking past the transaction itself. | ||
if (&(*tx) == &(*ptx)) break; | ||
if (possible_parents.count(tx->GetHash())) { | ||
in_package_parents.push_back(i); | ||
} | ||
} | ||
return in_package_parents; | ||
} | ||
|
||
/** Helper for PackageV3Checks, storing info for a mempool or package parent. */ | ||
struct ParentInfo { | ||
/** Txid used to identify this parent by prevout */ | ||
const Txid& m_txid; | ||
/** Wtxid used for debug string */ | ||
const Wtxid& m_wtxid; | ||
/** nVersion used to check inheritance of v3 and non-v3 */ | ||
decltype(CTransaction::nVersion) m_version; | ||
/** If parent is in mempool, whether it has any descendants in mempool. */ | ||
bool m_has_mempool_descendant; | ||
|
||
ParentInfo() = delete; | ||
ParentInfo(const Txid& txid, const Wtxid& wtxid, decltype(CTransaction::nVersion) version, bool has_mempool_descendant) : | ||
m_txid{txid}, m_wtxid{wtxid}, m_version{version}, | ||
m_has_mempool_descendant{has_mempool_descendant} | ||
{} | ||
}; |
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.
nit: This stuff can be placed into a anonymous namespace.
See SF.22: Use an unnamed (anonymous) namespace for all internal/non-exported entities.
See #27463 for overall package relay tracking.
Delving Bitcoin discussion thread: https://delvingbitcoin.org/t/v3-transaction-policy-for-anti-pinning/340
Delving Bitcoin discussion for LN usage: https://delvingbitcoin.org/t/lightning-transactions-with-v3-and-ephemeral-anchors/418
Rationale:
V3 policy is for "Priority Transactions." [3][4] It allows users to opt in to more restrictive topological limits for shared transactions, in exchange for the more robust fee-bumping abilities that offers. Even though we don't have cluster limits, we are able to treat these transactions as having as having a maximum cluster size of 2.
Immediate benefits:
This also enables some other cool things (again see #27463 for overall roadmap):
[1]: Original mailing list post and discussion about RBF pinning problems https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019817.html
[2]: A FAQ is "we need this for cluster mempool, but is this still necessary afterwards?" There are some pinning issues that are fixed here and not fully fixed in cluster mempool, so we will still want this or something similar afterward.
[3]: Mailing list post for v3 https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html
[4]: Original PR #25038 also contains a lot of the discussion
[5]: https://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393/7
[6]: https://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393#the-cpfp-carveout-rule-can-no-longer-be-supported-12