#36002 txindex: allow running in pruned mode

full analysis

https://github.com/bitcoin/bitcoin/pull/36002 · andrewtoth · +371/-86 in 23 files, 7 commits · labels: none

Goal

  • Allow pruned nodes to run txindex without keeping full raw block history on disk
  • Let users look up transaction block hashes and fetch missing blocks on demand
  • Enable indexing on already pruned nodes without redownloading past history

This pull request removes the restriction preventing -txindex from running alongside -prune. It leverages the block-hash indexing introduced in #35531 so lookups for pruned transactions return the block hashes where the transactions reside, allowing users to fetch those blocks via getblockfrompeer. It also permits starting a partial transaction index on an already-pruned node and exposes the index starting height in getindexinfo.

Problem: Historically, users who needed -txindex were forced to run full archival nodes because txindex stored physical block file offsets and could not tolerate pruned block files. Users with limited disk space who only wanted an index of recent blocks or needed to look up which historical block contained a transaction could not use pruning.

Category: Indexes (#2 of 7)

P2 · new feature

  • P2 because it unlocks transaction indexing for users unable to store full block data
  • Removes a long-standing barrier for resource-constrained node operators
  • Delivers durable value by letting indexes start on already pruned nodes

Lifts a major long-standing restriction where running -prune alongside -txindex was disallowed. This enables resource-constrained node operators to run a transaction index and pinpoint missing historical blocks on demand.

Membership: Modifies BaseIndex and TxIndex to allow running under block pruning and starting from a non-genesis height.

Factors: security/stability 0, bug 0, performance 0, user value 2, leverage 1

Category: RPC / REST / ZMQ (#28 of 52)

P3 · new feature

  • P3 because it returns missing block hashes so callers can retrieve blocks via RPC
  • Provides transparency on partial indexes by reporting starting height in getindexinfo

Adapts RPC and REST responses to provide context and candidate block hashes when transaction lookups fail due to pruning, and adds first_block_height to getindexinfo.

Membership: Modifies getrawtransaction, gettxoutproof, REST /tx, and getindexinfo to handle pruned block responses and report first_block_height.

Factors: security/stability 0, bug 0, performance 0, user value 1, leverage 0

Reviewability: Ready

  • Ready to review
  • The author is actively addressing questions and CI is passing

The code is clean, CI is passing, and changes addressing earlier reviewer suggestions have been pushed.

Author status: Active; incorporated suggestions for partial index support and recently rebased.

Open concerns:

  • arejula27 suggested combining BaseIndex::AllowPrune() and BaseIndex::AllowPartialHistory() into a single enum to formalize their dependency.
  • arejula27 asked whether candidate pruned block hashes should be returned as structured RPC data rather than embedded in an error string.

Resolved concerns:

  • ajtowns and mzumsande asked about enabling txindex on an already pruned node; author updated the PR to support partial indexing starting from the earliest available block.

Agreement: Strong

  • Strong concept support for enabling txindex on pruned nodes
  • Enthusiastic concept approval (l0rinc)
  • Concept approval with discussion on partial history disk usage (ajtowns)
  • Suggests returning structured RPC data and unifying index state enums (arejula27)

Strong concept consensus across multiple reviewers; author already integrated initial feedback on partial indexing.

Four contributors and maintainers voiced strong concept support. The open suggestions from arejula27 concern interface polish rather than blocking objections.

  • l0rinc: 'Big concept ACK'
  • ajtowns: 'Concept ACK, looks okay to me at first glance.'
  • arejula27: 'Concept ACK. I'm excited about this PR and I love the idea and the approach.'

Objections: none enumerated.

Support:

  • l0rinc: Big concept ACK on allowing txindex in pruned mode.
  • ajtowns: Concept ACK, noted it makes sense for nodes wanting local block-explorer setups with bounded disk.
  • arejula27: Concept ACK, excited about being able to fetch missing blocks on demand via getblockfrompeer.

Participants: l0rinc (support), ajtowns (support), mzumsande (support), arejula27 (support)

State derived from the lists: substantive support, no open objection (l0rinc, ajtowns, arejula27)

Review verdicts (DrahtBot): 0

Files

210 lines under test/bench/ci.

  • test/functional/feature_txindex_prune.py +150/-0
  • src/test/txindex_tests.cpp +39/-6
  • src/rpc/rawtransaction.cpp +15/-19
  • src/index/tx_lookup_result.h +31/-0
  • src/index/txindex.cpp +19/-12
  • src/index/txindex.h +10/-13
  • src/node/transaction.cpp +11/-10
  • src/index/base.cpp +17/-1
  • src/rpc/util.cpp +17/-0
  • src/rpc/txoutproof.cpp +11/-5
  • src/rest.cpp +11/-4
  • src/init.cpp +10/-3
  • src/index/base.h +9/-0
  • src/rpc/util.h +8/-0
  • src/node/transaction.h +4/-3
  • test/functional/feature_index_prune.py +2/-2
  • test/functional/feature_pruning.py +0/-4
  • src/qt/bitcoinstrings.cpp +1/-1
  • src/rpc/node.cpp +2/-0
  • test/functional/feature_assumeutxo.py +1/-1
  • test/functional/interface_rest.py +1/-1
  • test/functional/rpc_misc.py +1/-1
  • test/functional/test_runner.py +1/-0

Card

This PR enables running Bitcoin Core's transaction index (txindex) on pruned nodes, removing a longstanding mutual exclusion between -txindex and -prune. Because txindex entries record containing block hashes rather than file offsets, lookups for pruned transactions can identify the missing block hash, allowing external callers to fetch the block via getblockfrompeer and retry. It also adds support for building a partial txindex on a node that was already pruned prior to index startup. There is strong concept agreement from multiple reviewers, with current review focusing on code structure in BaseIndex and RPC response formatting.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T21:45, confidence high, input hash 945e4820b72908a6