Skip to content

[draft] Address-to-Utxo Index Proof-of-Concept#5

Draft
optout21 wants to merge 2 commits into
masterfrom
2604-address-utxo-index-proto
Draft

[draft] Address-to-Utxo Index Proof-of-Concept#5
optout21 wants to merge 2 commits into
masterfrom
2604-address-utxo-index-proto

Conversation

@optout21

Copy link
Copy Markdown
Owner

Address-to-Utxo Index Proof-of-Concept

Background

Bitcoin Core maintains the current set of UTXOs. This is especially important for input validation.

The UTXO set is indexed by outpoint (TXID + vout number, unique key), and contains the actual transaction output. It is stored on disk (LevelDB), but also cached in memory (as it changes often).

A non-primary usage of the UTXO set is searching for UTXOs for a given address (or addresses), through the 'scantxoutset' RPC command. This is possible only through a full search: 'scantxoutset' iterates throught the whole set, and looks for matching outputs.

Address-based UTXO search can be sped up significantly using an address index.

Typical size. As of BH 946000, April 2026, the UTXO set size is about 165 million UTXOs, taking up about 11 GiB on disk.

Overview

An extra index going from the output script of an UTXO to the UTXO and its outpoint can speed up significantly output-script-based UTXO lookup.

The index supports the following operations efficiently:

  • Add or remove an (outpoint, UTXO) pair
  • Look of the set of (outpoint, UTXO) where the script pubkey of the UTXO matches a given one.

Analysis

Pros:

  • offer significant higher speed in the specific use case
  • has relatively low storage requirement
  • fast to rebuild
  • compatible with pruned nodes

Cons:

  • benefit only a specific use case
  • has high maintainence (frequent index updates)
  • does not solve general address-to-TXO or address-to-TX needs

Design Choices

Contents. The contents of the index can be:

  • the UTXO itself, or
  • the outpoint, and the UTXO can be looked up from the CoinsDB.
    With the first option the outpoint would have to be stored as well, and it has higher storage requirement, but it is faster.
    For the PoC the second option was chosen.

Data structure. An output script can have many UTXOs. Therefore a map of vectors is used.

Key. The key can is the output script, but for efficiency, a hash of it should be used. A small hash can be used, as collisions are not a problem, as multiple entries per key have to be stored anyhow (as described above).
For the PoC a very simple, 3-byte hash is used. The intentionally small hash minimizes the key count in the map.

Update/rebuild strategy.
The index can be always kept up-to-date (in sync with the CoinsDB), or re-built occasionally.

Further Ideas

Address-to-TXO or Address-to-TXID or Address-to-Block index. Would be much bigger size (much more TXOs than UTXOs). Expensive to rebuild. Limited on pruned node.

Support for Electrum-API-style script pubkey hash as search criteria.

Proof of Concept implementation

The implementation a very rough PoC, showing the basic implementation, and allowing some benchmarking.
It is concentrated to the src/rpc/blockchain.cpp file, used in FindScriptPubKey().
The map is in-memory map locally. The map is built on first need, and reused afterwards.

For key hash a very simple solution is used, 3 bytes are simply taken from the middle of the output script. A better script (siphash?) should be used.

Limitations:

  • hash with bad distribution (most bytes don't affect the hash)
  • no persistent storage
  • the map is not updated (not kept up-to-date)
  • Aggressive Locking

Results

On Signet, with 65.6M UTXOs:

  • Key count in the map: 9.2M (with 7 per key on avg.)
  • index build time ~100 secs
  • Search in the built index: ~0.02 sec

@optout21 optout21 force-pushed the 2604-address-utxo-index-proto branch from c275f11 to 251db7c Compare April 28, 2026 13:59
@optout21

Copy link
Copy Markdown
Owner Author

TODO:

  • CI fix
  • Add measurement on mainnet
  • better internal hash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant