Commit 37c4c20
perf(rpc): answer gettxoutproof from the txindex instead of scanning the chain
Called without a block hash, the handler deep-copied every BlockRecord, then
loaded, deserialized and hashed every block on the chain to answer one call.
At tip that is roughly a million block loads, almost all of them discarded --
unbounded work for one authenticated RPC call, which stalls the node and evicts
everything else from cache while it runs.
Context.indexer already knows which block confirms a txid. Resolve the
confirming height, build the proof from that block alone, and take the same
route Bitcoin Core does: it requires the block hash unless txindex is enabled.
The scan is kept whole as proof_from_records. It is the fallback whenever the
index cannot answer -- no indexer, an unresolved or stale row, a pruned body, or
a candidate block that does not hold every wanted txid -- and it is the oracle
the equivalence tests compare against. That last fallback is not belt and
braces: BIP30 duplicate coinbase txids mean a txid can confirm in more than one
block, so a block chosen from a single txid is a candidate, never a verdict.
IndexerLike gains resolve_transaction_height, defaulting to Ok(None), so every
existing implementation keeps compiling and no caller may drop its fallback.
Measured on an idle machine, both arms in one Criterion run over one fixture:
21.118 ms -> 32.983 us for the scan worst case, and within noise of each other
for its best case, because the index arm is flat at 28-33 us regardless of
position. Extrapolating the scan's 10.56 us per record to a mainnet-sized chain
gives about 10 seconds per call, and that is a floor -- fixture blocks hold 8
small transactions where real ones hold thousands. See
docs/benchmarks/gettxoutproof.md.
The twelve tests were audited by mutation rather than trusted for being green.
That audit found the three crates/index tests were not running at all, because
their module is gated on a feature the crate does not enable by default, and
that one of them passed vacuously when both resolvers returned None. Both are
fixed here.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent a157e09 commit 37c4c20
6 files changed
Lines changed: 805 additions & 25 deletions
File tree
- crates
- index/src
- rpc
- benches
- src/handlers
- docs/benchmarks
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
436 | 436 | | |
437 | 437 | | |
438 | 438 | | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
439 | 473 | | |
440 | 474 | | |
441 | 475 | | |
| |||
1442 | 1476 | | |
1443 | 1477 | | |
1444 | 1478 | | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
1445 | 1493 | | |
1446 | 1494 | | |
1447 | 1495 | | |
| |||
1594 | 1642 | | |
1595 | 1643 | | |
1596 | 1644 | | |
| 1645 | + | |
| 1646 | + | |
| 1647 | + | |
| 1648 | + | |
| 1649 | + | |
| 1650 | + | |
| 1651 | + | |
| 1652 | + | |
1597 | 1653 | | |
1598 | 1654 | | |
1599 | 1655 | | |
| |||
1961 | 2017 | | |
1962 | 2018 | | |
1963 | 2019 | | |
| 2020 | + | |
| 2021 | + | |
| 2022 | + | |
| 2023 | + | |
| 2024 | + | |
| 2025 | + | |
| 2026 | + | |
| 2027 | + | |
| 2028 | + | |
| 2029 | + | |
| 2030 | + | |
| 2031 | + | |
| 2032 | + | |
| 2033 | + | |
| 2034 | + | |
| 2035 | + | |
| 2036 | + | |
| 2037 | + | |
| 2038 | + | |
| 2039 | + | |
| 2040 | + | |
| 2041 | + | |
| 2042 | + | |
| 2043 | + | |
| 2044 | + | |
| 2045 | + | |
| 2046 | + | |
| 2047 | + | |
| 2048 | + | |
| 2049 | + | |
| 2050 | + | |
| 2051 | + | |
| 2052 | + | |
| 2053 | + | |
| 2054 | + | |
| 2055 | + | |
| 2056 | + | |
| 2057 | + | |
| 2058 | + | |
| 2059 | + | |
| 2060 | + | |
| 2061 | + | |
| 2062 | + | |
| 2063 | + | |
| 2064 | + | |
| 2065 | + | |
| 2066 | + | |
| 2067 | + | |
| 2068 | + | |
| 2069 | + | |
| 2070 | + | |
| 2071 | + | |
| 2072 | + | |
| 2073 | + | |
| 2074 | + | |
| 2075 | + | |
| 2076 | + | |
| 2077 | + | |
| 2078 | + | |
| 2079 | + | |
| 2080 | + | |
| 2081 | + | |
| 2082 | + | |
| 2083 | + | |
| 2084 | + | |
1964 | 2085 | | |
1965 | 2086 | | |
1966 | 2087 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
0 commit comments