p2p: never check tx rejections by txid #33066

pull glozow wants to merge 1 commits into bitcoin:master from glozow:2025-07-wtxid-only-rej changing 7 files +50 −224
  1. glozow commented at 8:47 pm on July 25, 2025: member

    Main motivation of this PR is to enable #32379 without creating a censorship problem where the attacker sends a witness-stripped version of a transaction to cause us to reject its child. It does this by removing all queries to the rejection caches by txid.

    TLDR, this PR removes the logic that stops us from attempting orphan resolution when parents are found in the rejection filter. It removes the rejection cache filtering part of all txid-based tx requests. In practice, this seems to only be used for orphan resolution because everybody supports wtxidrelay.

    Background: We have 2 bloom filters for remembering transactions that we’ve rejected so we don’t redownload them, RecentRejectsFilter and RecentRejectsReconsiderableFilter. This lets us save a little bit of bandwidth on rejected transactions, particularly if we have policy differences. It’s not designed to stop attackers from wasting our download bandwidth, as they can create as many policy-invalid transactions with different witnesses as they want. We generally only put wtxids and not txids in them (see #18044), except for these cases: (A) When we specifically know that the rejection reason is not due to the witness (B) When the transaction has no witness, so its txid == wtxid (C) (With #32379) When the transaction’s witness has been stripped, so txid == wtxid

    “Will this increase bandwidth usage?” We check the filters to decide whether to send a getdata for an inv, whether we should validate a tx we just downloaded, and whether we should keep an orphan: we look the missing parents up by (prevout) txid and throw the orphan away if its parents were already rejected. That means there are very few cases where we save bandwidth by finding a txid in the filter. I collected some stats over a couple of weeks:

    • When we receive an announcement by txid (i.e. the peer does not support BIP339 wtxidrelay) and somehow the txid is already in the filter (see cases ABC)
      • On my node, I’m seeing 100% of peers support wtxidrelay. Bitcoin Core has been doing this since ~5 years ago. I’m sure there are some nodes that don’t do it, but it’ll probably be rare that we are surrounded by txidrelay peers and that we have a policy difference causing us to reject the transaction that they all send us.
    • When an orphan parent has been placed in the rejection cache (see cases ABC)
      • On my node, orphan parent fetching is only 3.64% of my transaction requests. I also set mempoolexpiry to 1 hour to try to artificially increase orphan rates, though I don’t know whether the effect is significant.
      • 93.77% of all transactions I receive have witnesses (includes accepted and rejected ones). 96.20% of the orphan parents I fetched had witnesses.
      • I actually haven’t found any cases of already-rejected parent txids in the past week, but the number of nonsegwit orphan parents is just so tiny - a few dozen requests per day.
  2. [p2p] never check rejections by txid in AlreadyHaveTx
    While this may result in some wasted bandwidth for orphans that have
    invalid non-witness parents, we expect this case to be rare. Allows us
    to cache witness-stripped transactions in recent rejections without
    worrying about blocking 1p1cs.
    86a03b167f
  3. DrahtBot added the label P2P on Jul 25, 2025
  4. DrahtBot commented at 8:47 pm on July 25, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33066.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept ACK darosior, cedwies

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #32941 (p2p: TxOrphanage revamp cleanups by glozow)
    • #29060 (Policy: Report reason inputs are non standard by ismaelsadeeq)

    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.

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • In p2p_invalid_tx.py:
      “causes erase its transactions” -> “causes it to erase its transactions” [missing “it to” for grammatical clarity]

    No other typos were found.

    drahtbot_id_4_m

  5. glozow commented at 8:47 pm on July 25, 2025: member
  6. darosior commented at 9:27 pm on July 25, 2025: member
    Concept ACK
  7. cedwies commented at 10:40 pm on July 25, 2025: none

    Built PR 33066 on macOS 14 (Apple Silicon) with CMake + Ninja, Debug.

    • unit tests: 141/141 pass, 9 min wall time

    what I checked: ‒ AlreadyHaveTx(): tx-id path now skips both reject filters; wtx-id path unchanged.
    ‒ MempoolRejectedTx(): parent-txid rejection bail-out removed → orphans kept even if parents sit in a reject cache ‒ updated tests (expected_behaviors table + orphan-handling cases) run green.

    Question (still wrapping my head around this): MempoolRejectedTx still inserts a tx-id into RecentRejectsFilter for TX_INPUTS_NOT_STANDARD, but After this patch AlreadyHaveTx no longer consults the filter by tx-id. Is that entry now redundant, or do other call-sites still depend on it?

    (Second review, so no (N)ACK yet. just confirming I understand the (PR) flow.)


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-07-26 12:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me