7#include <chainparams.h>
37#include <boost/test/unit_test.hpp>
51 db.WriteBestBlock(batch, locator);
60 std::pair<uint64_t, uint64_t> salt;
67 std::vector<txindex::BlockTxPosition> positions;
70 for (it->Seek(key); it->Valid() && it->GetKey(key) && key.hash_prefix ==
prefix; it->Next()) {
71 positions.push_back(key.pos);
80 BOOST_REQUIRE(block_index);
81 return {block_index->nFile, block_index->nDataPos};
86 const auto result{
txindex.FindTx(txid)};
87 BOOST_REQUIRE(result);
89 return result->block_hash;
95 BOOST_REQUIRE(block_index);
97 BOOST_REQUIRE(chainman.
ActiveChainstate().InvalidateBlock(state, block_index));
105 {{0, 0},
"00000000"},
106 {{1, 2},
"01000002"},
107 {{10'000'000, 123},
"83e1ac0000007b"},
108 {{456, 3'999'999},
"82483d08ff"},
111 for (
const auto& [position, encoded] : test_vectors) {
122 "78010203040501000002");
132 Txid{
"1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"}),
142 for (
const auto& txn : m_coinbase_txns) {
153 for (
const auto& txn : genesis_block.
vtx) {
158 for (
const auto& txn : m_coinbase_txns) {
159 LookupTx(
txindex, txn->GetHash());
163 for (
int i = 0; i < 10; i++) {
165 std::vector<CMutableTransaction> no_txns;
166 const CBlock& block = CreateAndProcessBlock(no_txns, coinbase_script_pub_key);
192 const Txid fake_txid{m_coinbase_txns.back()->GetHash()};
193 const Txid target_txid{m_coinbase_txns.front()->GetHash()};
197 BOOST_REQUIRE(fake_prefix != target_prefix);
200 const auto fake_bucket{BucketPositions(
db, fake_prefix)};
201 BOOST_REQUIRE_EQUAL(fake_bucket.size(), 1U);
208 const auto target_bucket{BucketPositions(
db, target_prefix)};
209 BOOST_REQUIRE_EQUAL(target_bucket.size(), 2U);
213 LookupTx(
txindex, target_txid);
233 const Txid legacy_txid{m_coinbase_txns.front()->GetHash()};
250 const auto bucket{BucketPositions(
db,
prefix)};
251 BOOST_REQUIRE(!bucket.empty());
254 LookupTx(
txindex, legacy_txid);
267 CBlockLocator legacy_locator{{legacy_hash}}, new_locator{{new_hash}};
299 const uint256 stale_block_hash{CreateAndProcessBlock({unique_mtx}, coinbase_script).GetHash()};
300 BOOST_REQUIRE(
txindex.BlockUntilSyncedToCurrentChain());
306 const auto original_bucket{BucketPositions(
db,
prefix)};
307 BOOST_REQUIRE_EQUAL(original_bucket.size(), 1U);
313 BOOST_REQUIRE(
txindex.BlockUntilSyncedToCurrentChain());
320 BOOST_REQUIRE(stale_index);
326 const uint256 branch_block_hash{CreateAndProcessBlock({unique_mtx},
CScript() <<
OP_TRUE).GetHash()};
327 CreateAndProcessBlock({}, coinbase_script);
328 BOOST_REQUIRE(
txindex.BlockUntilSyncedToCurrentChain());
342 BOOST_REQUIRE(
txindex.BlockUntilSyncedToCurrentChain());
348 const auto reorg_bucket{BucketPositions(
db,
prefix)};
349 BOOST_REQUIRE_EQUAL(reorg_bucket.size(), 2U);
350 BOOST_CHECK(reorg_bucket.front() == original_bucket.front());
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
int64_t CAmount
Amount in satoshis (Can be negative)
constexpr CAmount COIN
The amount of satoshis in one BTC.
void InvalidateBlock(ChainstateManager &chainman, const uint256 block_hash)
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
fs::path GetDataDirNet() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get data directory path with appended network identifier.
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
uint256 GetBlockHash() const
bool Contains(const CBlockIndex &index) const
Efficiently check whether a block is present in this chain.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
const CBlock & GenesisBlock() const
Batch of changes queued to be written to a CDBWrapper.
bool Read(const K &key, V &value) const
CDBIterator * NewIterator()
void Erase(const K &key, bool fSync=false)
void WriteBatch(CDBBatch &batch, bool fSync=false)
void Write(const K &key, const V &value, bool fSync=false)
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
const Txid & GetHash() const LIFETIMEBOUND
bool PreciousBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(void SetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(voi ResetBlockFailureFlags)(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as precious and reorganize.
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
Chainstate & ActiveChainstate() const
Alternatives to CurrentChainstate() used by older code to query latest chainstate information without...
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
Double ended buffer combining vector and stream-like interfaces.
A custom weaker variant of SipHash-1-3 without padding, and supporting "jumbo" inputs.
TxIndex is used to look up transactions included in the blockchain by hash.
static CBlockLocator ReadBestBlock(const TxIndex &txindex)
static CDBWrapper & GetDB(const TxIndex &txindex)
static void WriteBestBlock(const TxIndex &txindex, const CBlockLocator &locator)
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
BOOST_AUTO_TEST_SUITE_END()
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
std::unique_ptr< Chain > MakeChain(node::NodeContext &node)
Return implementation of Chain interface.
const std::string DB_TXID_HASH_SALT
constexpr std::array< std::byte, 0 > EMPTY_VALUE
Empty value of a hashed txindex row, whose position is encoded in its key.
TxHashKeyPrefix CreateKeyPrefix(const SipHasher13UJ &hasher, const Txid &txid)
constexpr uint32_t BLOCK_HEADER_SIZE
Serialized size of a block header, the offset of the first byte after it.
std::pair< uint8_t, uint256 > LegacyTxKey(const Txid &txid)
Key of a legacy (pre-hashing) txindex row: the full txid under the 't' prefix.
#define BOOST_CHECK(expr)
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::vector< unsigned char > ToByteVector(const T &in)
uint64_t GetSerializeSize(const T &t)
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
A mutable version of CTransaction.
Application-specific storage settings.
fs::path path
Location in the filesystem where leveldb data will be stored.
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
std::unique_ptr< ChainstateManager > chainman
Key for looking up the hash of the block with the given sequence number.
The location of a transaction: the sequence number of the block that contains it and the transaction'...
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
BOOST_AUTO_TEST_CASE(txindex_position_encoding)