Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#ifndef BITCOIN_INDEX_TXINDEX_KEY_H6#define BITCOIN_INDEX_TXINDEX_KEY_H8#include <consensus/consensus.h>9#include <crypto/siphash.h>10#include <primitives/transaction_identifier.h>11#include <serialize.h>12#include <uint256.h>14#include <array>15#include <cstddef>16#include <cstdint>17#include <ios>18#include <string>19#include <utility>21namespace txindex {22/*23* Database layout:24*25* ['x', hash prefix, block seq, tx offset] -> (empty)26* ['s', block seq] -> block hash27* ['h', block hash] -> block seq28* ["next_block_seq"] -> next block seq to assign29* ["txid_hash_salt"] -> txid hasher salt30* ["best_block_v2"] -> current sync locator31* ['t', txid] -> legacy CDiskTxPos32* ['B'] -> legacy sync locator33*/35constexpr uint8_t DB_TXINDEX_HASHED{'x'};36constexpr uint8_t DB_BLOCK_SEQ{'s'};37constexpr uint8_t DB_BLOCK_HASH{'h'};38inline const std::string DB_NEXT_BLOCK_SEQ{"next_block_seq"};39inline const std::string DB_TXID_HASH_SALT{"txid_hash_salt"};40inline const std::string DB_BEST_BLOCK_V2{"best_block_v2"};41//! Prefix of a legacy (pre-hashing) txindex row.42constexpr uint8_t DB_TXINDEX{'t'};44//! Empty value of a hashed txindex row, whose position is encoded in its key.45inline constexpr std::array<std::byte, 0> EMPTY_VALUE{};47//! Serialized size of a block header, the offset of the first byte after it.48constexpr uint32_t BLOCK_HEADER_SIZE{80};50//! The location of a transaction: the sequence number of the block that contains it51//! and the transaction's serialized byte offset from the start of that block52//! (including the header), so the on-disk position is simply53//! block_data_pos + tx_offset_in_block.54//!55struct BlockTxPosition {56uint32_t block_seq{0};57uint32_t tx_offset_in_block{0};59friend bool operator==(const BlockTxPosition&, const BlockTxPosition&) = default;61// tx_offset is encoded in 3-byte big-endian integer.62// This can hold up to 16,777,216, which is >4x the maximum 4 million block weight position63static constexpr uint32_t TX_OFFSET_SIZE{3};64static_assert(MAX_BLOCK_SERIALIZED_SIZE <= BigEndianFormatter<TX_OFFSET_SIZE>::MAX);66SERIALIZE_METHODS(BlockTxPosition, obj)67{68READWRITE(VARINT(obj.block_seq),69Using<BigEndianFormatter<TX_OFFSET_SIZE>>(obj.tx_offset_in_block));70}71};73//! Key for looking up the hash of the block with the given sequence number.74struct BlockSeqKey {75uint32_t block_seq{0};77SERIALIZE_METHODS(BlockSeqKey, obj)78{79uint8_t prefix{DB_BLOCK_SEQ};80READWRITE(prefix);81if (ser_action.ForRead() && prefix != DB_BLOCK_SEQ) throw std::ios_base::failure("Invalid format for txindex block seq key");82READWRITE(VARINT(obj.block_seq));83}84};86//! Key for looking up the sequence number assigned to the block with the given hash.87struct BlockHashKey {88uint256 block_hash;90SERIALIZE_METHODS(BlockHashKey, obj)91{92uint8_t prefix{DB_BLOCK_HASH};93READWRITE(prefix);94if (ser_action.ForRead() && prefix != DB_BLOCK_HASH) throw std::ios_base::failure("Invalid format for txindex block hash key");95READWRITE(obj.block_hash);96}97};99constexpr int HASH_PREFIX_SIZE{5};100using TxHashKeyPrefix = uint64_t;102inline TxHashKeyPrefix CreateKeyPrefix(const SipHasher13UJ& hasher, const Txid& txid)103{104return hasher.Hash(txid.ToUint256()) >> (8 * (sizeof(TxHashKeyPrefix) - HASH_PREFIX_SIZE));105}107struct DBKey {108TxHashKeyPrefix hash_prefix{0};109BlockTxPosition pos;111SERIALIZE_METHODS(DBKey, obj)112{113uint8_t prefix{DB_TXINDEX_HASHED};114READWRITE(prefix);115if (ser_action.ForRead() && prefix != DB_TXINDEX_HASHED) throw std::ios_base::failure("Invalid format for txindex DB key");116READWRITE(Using<BigEndianFormatter<HASH_PREFIX_SIZE>>(obj.hash_prefix), obj.pos);117}118};120//! Key of a legacy (pre-hashing) txindex row: the full txid under the 't' prefix.121inline std::pair<uint8_t, uint256> LegacyTxKey(const Txid& txid)122{123return {DB_TXINDEX, txid.ToUint256()};124}126} // namespace txindex128#endif // BITCOIN_INDEX_TXINDEX_KEY_H