mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-02 01:36:13 +00:00
The index is now initialized after the setup phase (chain generation and txs creation), since it doesn't participate on it at all. This improves readability and splits setup from what we actually want to check. This also adds a check after Sync() to verify the index best block hash matches the tip, so we know it fully synced before checking the processed data. This will help catching errors as Sync() could have aborted prematurely. As a happy side effect, the SyncWithValidationInterfaceQueue() call at the end of the test is no longer needed and has been removed.
76 lines
3.0 KiB
C++
76 lines
3.0 KiB
C++
// Copyright (c) The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <index/txospenderindex.h>
|
|
#include <test/util/setup_common.h>
|
|
#include <validation.h>
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
BOOST_AUTO_TEST_SUITE(txospenderindex_tests)
|
|
|
|
BOOST_FIXTURE_TEST_CASE(txospenderindex_initial_sync, TestChain100Setup)
|
|
{
|
|
// Setup phase:
|
|
// Mine blocks for coinbase maturity, so we can spend some coinbase outputs in the test.
|
|
const CScript& coinbase_script = m_coinbase_txns[0]->vout[0].scriptPubKey;
|
|
for (int i = 0; i < 10; i++) CreateAndProcessBlock({}, coinbase_script);
|
|
|
|
// Spend 10 outputs
|
|
std::vector<COutPoint> spent(10);
|
|
std::vector<CMutableTransaction> spender(spent.size());
|
|
for (size_t i = 0; i < spent.size(); i++) {
|
|
// Outpoint
|
|
auto coinbase_tx = m_coinbase_txns[i];
|
|
spent[i] = COutPoint(coinbase_tx->GetHash(), 0);
|
|
|
|
// Spending tx
|
|
spender[i].version = 1;
|
|
spender[i].vin.resize(1);
|
|
spender[i].vin[0].prevout.hash = spent[i].hash;
|
|
spender[i].vin[0].prevout.n = spent[i].n;
|
|
spender[i].vout.resize(1);
|
|
spender[i].vout[0].nValue = coinbase_tx->GetValueOut();
|
|
spender[i].vout[0].scriptPubKey = coinbase_script;
|
|
|
|
// Sign
|
|
std::vector<unsigned char> vchSig;
|
|
const uint256 hash = SignatureHash(coinbase_script, spender[i], 0, SIGHASH_ALL, 0, SigVersion::BASE);
|
|
BOOST_REQUIRE(coinbaseKey.Sign(hash, vchSig));
|
|
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
|
spender[i].vin[0].scriptSig << vchSig;
|
|
}
|
|
|
|
// Generate and ensure block has been fully processed
|
|
const uint256 tip_hash = CreateAndProcessBlock(spender, coinbase_script).GetHash();
|
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
|
BOOST_CHECK_EQUAL(WITH_LOCK(::cs_main, return m_node.chainman->ActiveTip()->GetBlockHash()), tip_hash);
|
|
|
|
// Now we concluded the setup phase, run index
|
|
TxoSpenderIndex txospenderindex(interfaces::MakeChain(m_node), 1 << 20, true);
|
|
BOOST_REQUIRE(txospenderindex.Init());
|
|
BOOST_CHECK(!txospenderindex.BlockUntilSyncedToCurrentChain()); // false when not synced
|
|
BOOST_CHECK_NE(txospenderindex.GetSummary().best_block_hash, tip_hash);
|
|
|
|
// Transaction should not be found in the index before it is synced.
|
|
for (const auto& outpoint : spent) {
|
|
BOOST_CHECK(!txospenderindex.FindSpender(outpoint).value());
|
|
}
|
|
|
|
txospenderindex.Sync();
|
|
BOOST_CHECK_EQUAL(txospenderindex.GetSummary().best_block_hash, tip_hash);
|
|
|
|
for (size_t i = 0; i < spent.size(); i++) {
|
|
const auto tx_spender{txospenderindex.FindSpender(spent[i])};
|
|
BOOST_REQUIRE(tx_spender.has_value());
|
|
BOOST_REQUIRE(tx_spender->has_value());
|
|
BOOST_CHECK_EQUAL((*tx_spender)->tx->GetHash(), spender[i].GetHash());
|
|
BOOST_CHECK_EQUAL((*tx_spender)->block_hash, tip_hash);
|
|
}
|
|
|
|
txospenderindex.Stop();
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|