mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
Merge bitcoin/bitcoin#21584: Fix assumeutxo crash due to invalid base_blockhash
fa340b8794
refactor: Avoid magic value of all-zeros in assumeutxo base_blockhash (MarcoFalke)fae33f98e6
Fix assumeutxo crash due to invalid base_blockhash (MarcoFalke)fa5668bfb3
refactor: Use type-safe assumeutxo hash (MarcoFalke)0000007709
refactor: Remove unused code (MarcoFalke)faa921f787
move-only: Add util/hash_type (MarcoFalke) Pull request description: Starting with commitd6af06d68a
, a block hash of all-zeros is invalid and will lead to a crash of the node. Can be tested by cherry-picking the test changes without the other changes. Stack trace (copied from https://github.com/bitcoin/bitcoin/pull/21584#discussion_r612673879): ``` #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x00007ffff583c8b1 in __GI_abort () at abort.c:79 #2 0x00007ffff582c42a in __assert_fail_base (fmt=0x7ffff59b3a38 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x555556c8b450 "!hashBlock.IsNull()", file=file@entry=0x555556c8b464 "txdb.cpp", line=line@entry=89, function=function@entry=0x555556c8b46d "virtual bool CCoinsViewDB::BatchWrite(CCoinsMap &, const uint256 &)") at assert.c:92 #3 0x00007ffff582c4a2 in __GI___assert_fail (assertion=0x555556c8b450 "!hashBlock.IsNull()", file=0x555556c8b464 "txdb.cpp", line=89, function=0x555556c8b46d "virtual bool CCoinsViewDB::BatchWrite(CCoinsMap &, const uint256 &)") at assert.c:101 #4 0x000055555636738b in CCoinsViewDB::BatchWrite (this=0x5555577975c0, mapCoins=std::unordered_map with 110 elements = {...}, hashBlock=...) at txdb.cpp:89 #5 0x00005555564a2e80 in CCoinsViewBacked::BatchWrite (this=0x5555577975f8, mapCoins=std::unordered_map with 110 elements = {...}, hashBlock=...) at coins.cpp:30 #6 0x00005555564a43de in CCoinsViewCache::Flush (this=0x55555778eaf0) at coins.cpp:223 #7 0x00005555563fc11d in ChainstateManager::PopulateAndValidateSnapshot (this=0x55555740b038 <g_chainman>, snapshot_chainstate=..., coins_file=..., metadata=...) at validation.cpp:5422 #8 0x00005555563fab3d in ChainstateManager::ActivateSnapshot (this=0x55555740b038 <g_chainman>, coins_file=..., metadata=..., in_memory=true) at validation.cpp:5299 #9 0x0000555555e8c893 in validation_chainstatemanager_tests::CreateAndActivateUTXOSnapshot<validation_chainstatemanager_tests::chainstatemanager_activate_snapshot::test_method()::$_12>(NodeContext&, boost::filesystem::path, validation_chainstatemanager_tests::chainstatemanager_activate_snapshot::test_method()::$_12) (node=..., root=..., malleation=...) at test/validation_chainstatemanager_tests.cpp:199 #10 0x0000555555e8877a in validation_chainstatemanager_tests::chainstatemanager_activate_snapshot::test_method (this=0x7fffffffc8d0) at test/validation_chainstatemanager_tests.cpp:262 ACKs for top commit: laanwj: Code review re-ACKfa340b8794
jamesob: ACKfa340b8794
([`jamesob/ackr/21584.1.MarcoFalke.fix_assumeutxo_crash_due`](https://github.com/jamesob/bitcoin/tree/ackr/21584.1.MarcoFalke.fix_assumeutxo_crash_due)) Tree-SHA512: c2c4e66c1abfd400ef18a04f22fec1f302f1ff4d27a18050f492f688319deb4ccdd165ff792eee0a1f816e7b69fb64080662b79517ab669e3d26b9eb77802851
This commit is contained in:
commit
ee9befe8b4
10 changed files with 130 additions and 123 deletions
|
@ -246,6 +246,7 @@ BITCOIN_CORE_H = \
|
|||
util/fees.h \
|
||||
util/getuniquepath.h \
|
||||
util/golombrice.h \
|
||||
util/hash_type.h \
|
||||
util/hasher.h \
|
||||
util/macros.h \
|
||||
util/message.h \
|
||||
|
|
|
@ -451,11 +451,11 @@ public:
|
|||
m_assumeutxo_data = MapAssumeutxo{
|
||||
{
|
||||
110,
|
||||
{uint256S("0x1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618"), 110},
|
||||
{AssumeutxoHash{uint256S("0x1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618")}, 110},
|
||||
},
|
||||
{
|
||||
210,
|
||||
{uint256S("0x9c5ed99ef98544b34f8920b6d1802f72ac28ae6e2bd2bd4c316ff10c230df3f2"), 210},
|
||||
{AssumeutxoHash{uint256S("0x9c5ed99ef98544b34f8920b6d1802f72ac28ae6e2bd2bd4c316ff10c230df3f2")}, 210},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -559,9 +559,3 @@ void SelectParams(const std::string& network)
|
|||
SelectBaseParams(network);
|
||||
globalChainParams = CreateChainParams(gArgs, network);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const AssumeutxoData& aud)
|
||||
{
|
||||
o << strprintf("AssumeutxoData(%s, %s)", aud.hash_serialized.ToString(), aud.nChainTx);
|
||||
return o;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <consensus/params.h>
|
||||
#include <primitives/block.h>
|
||||
#include <protocol.h>
|
||||
#include <util/hash_type.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
@ -25,6 +26,10 @@ struct CCheckpointData {
|
|||
}
|
||||
};
|
||||
|
||||
struct AssumeutxoHash : public BaseHash<uint256> {
|
||||
explicit AssumeutxoHash(const uint256& hash) : BaseHash(hash) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds configuration for use during UTXO snapshot load and validation. The contents
|
||||
* here are security critical, since they dictate which UTXO snapshots are recognized
|
||||
|
@ -32,7 +37,7 @@ struct CCheckpointData {
|
|||
*/
|
||||
struct AssumeutxoData {
|
||||
//! The expected hash of the deserialized UTXO set.
|
||||
const uint256 hash_serialized;
|
||||
const AssumeutxoHash hash_serialized;
|
||||
|
||||
//! Used to populate the nChainTx value, which is used during BlockManager::LoadBlockIndex().
|
||||
//!
|
||||
|
@ -41,8 +46,6 @@ struct AssumeutxoData {
|
|||
const unsigned int nChainTx;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const AssumeutxoData& aud);
|
||||
|
||||
using MapAssumeutxo = std::map<int, const AssumeutxoData>;
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
class ChainstateManager;
|
||||
|
||||
/**
|
||||
* A UTXO entry.
|
||||
*
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <script/interpreter.h>
|
||||
#include <uint256.h>
|
||||
#include <util/hash_type.h>
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
@ -18,70 +19,6 @@ class CKeyID;
|
|||
class CScript;
|
||||
struct ScriptHash;
|
||||
|
||||
template<typename HashType>
|
||||
class BaseHash
|
||||
{
|
||||
protected:
|
||||
HashType m_hash;
|
||||
|
||||
public:
|
||||
BaseHash() : m_hash() {}
|
||||
explicit BaseHash(const HashType& in) : m_hash(in) {}
|
||||
|
||||
unsigned char* begin()
|
||||
{
|
||||
return m_hash.begin();
|
||||
}
|
||||
|
||||
const unsigned char* begin() const
|
||||
{
|
||||
return m_hash.begin();
|
||||
}
|
||||
|
||||
unsigned char* end()
|
||||
{
|
||||
return m_hash.end();
|
||||
}
|
||||
|
||||
const unsigned char* end() const
|
||||
{
|
||||
return m_hash.end();
|
||||
}
|
||||
|
||||
operator std::vector<unsigned char>() const
|
||||
{
|
||||
return std::vector<unsigned char>{m_hash.begin(), m_hash.end()};
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return m_hash.ToString();
|
||||
}
|
||||
|
||||
bool operator==(const BaseHash<HashType>& other) const noexcept
|
||||
{
|
||||
return m_hash == other.m_hash;
|
||||
}
|
||||
|
||||
bool operator!=(const BaseHash<HashType>& other) const noexcept
|
||||
{
|
||||
return !(m_hash == other.m_hash);
|
||||
}
|
||||
|
||||
bool operator<(const BaseHash<HashType>& other) const noexcept
|
||||
{
|
||||
return m_hash < other.m_hash;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_hash.size();
|
||||
}
|
||||
|
||||
unsigned char* data() { return m_hash.data(); }
|
||||
const unsigned char* data() const { return m_hash.data(); }
|
||||
};
|
||||
|
||||
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
|
||||
class CScriptID : public BaseHash<uint160>
|
||||
{
|
||||
|
|
|
@ -226,10 +226,8 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
|
|||
|
||||
// Snapshot should refuse to load at this height.
|
||||
BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot(m_node, m_path_root));
|
||||
BOOST_CHECK(chainman.ActiveChainstate().m_from_snapshot_blockhash.IsNull());
|
||||
BOOST_CHECK_EQUAL(
|
||||
chainman.ActiveChainstate().m_from_snapshot_blockhash,
|
||||
chainman.SnapshotBlockhash().value_or(uint256()));
|
||||
BOOST_CHECK(!chainman.ActiveChainstate().m_from_snapshot_blockhash);
|
||||
BOOST_CHECK(!chainman.SnapshotBlockhash());
|
||||
|
||||
// Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
|
||||
// be found.
|
||||
|
@ -260,6 +258,11 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
|
|||
// Coins count is smaller than coins in file
|
||||
metadata.m_coins_count -= 1;
|
||||
}));
|
||||
BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot(
|
||||
m_node, m_path_root, [](CAutoFile& auto_infile, SnapshotMetadata& metadata) {
|
||||
// Wrong hash
|
||||
metadata.m_base_blockhash = uint256::ZERO;
|
||||
}));
|
||||
BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot(
|
||||
m_node, m_path_root, [](CAutoFile& auto_infile, SnapshotMetadata& metadata) {
|
||||
// Wrong hash
|
||||
|
@ -269,9 +272,9 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
|
|||
BOOST_REQUIRE(CreateAndActivateUTXOSnapshot(m_node, m_path_root));
|
||||
|
||||
// Ensure our active chain is the snapshot chainstate.
|
||||
BOOST_CHECK(!chainman.ActiveChainstate().m_from_snapshot_blockhash.IsNull());
|
||||
BOOST_CHECK(!chainman.ActiveChainstate().m_from_snapshot_blockhash->IsNull());
|
||||
BOOST_CHECK_EQUAL(
|
||||
chainman.ActiveChainstate().m_from_snapshot_blockhash,
|
||||
*chainman.ActiveChainstate().m_from_snapshot_blockhash,
|
||||
*chainman.SnapshotBlockhash());
|
||||
|
||||
const AssumeutxoData& au_data = *ExpectedAssumeutxo(snapshot_height, ::Params());
|
||||
|
@ -347,7 +350,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
|
|||
|
||||
// Snapshot blockhash should be unchanged.
|
||||
BOOST_CHECK_EQUAL(
|
||||
chainman.ActiveChainstate().m_from_snapshot_blockhash,
|
||||
*chainman.ActiveChainstate().m_from_snapshot_blockhash,
|
||||
loaded_snapshot_blockhash);
|
||||
}
|
||||
|
||||
|
|
|
@ -135,11 +135,11 @@ BOOST_AUTO_TEST_CASE(test_assumeutxo)
|
|||
}
|
||||
|
||||
const auto out110 = *ExpectedAssumeutxo(110, *params);
|
||||
BOOST_CHECK_EQUAL(out110.hash_serialized, uint256S("1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618"));
|
||||
BOOST_CHECK_EQUAL(out110.hash_serialized.ToString(), "1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618");
|
||||
BOOST_CHECK_EQUAL(out110.nChainTx, (unsigned int)110);
|
||||
|
||||
const auto out210 = *ExpectedAssumeutxo(210, *params);
|
||||
BOOST_CHECK_EQUAL(out210.hash_serialized, uint256S("9c5ed99ef98544b34f8920b6d1802f72ac28ae6e2bd2bd4c316ff10c230df3f2"));
|
||||
BOOST_CHECK_EQUAL(out210.hash_serialized.ToString(), "9c5ed99ef98544b34f8920b6d1802f72ac28ae6e2bd2bd4c316ff10c230df3f2");
|
||||
BOOST_CHECK_EQUAL(out210.nChainTx, (unsigned int)210);
|
||||
}
|
||||
|
||||
|
|
72
src/util/hash_type.h
Normal file
72
src/util/hash_type.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) 2020-2021 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_UTIL_HASH_TYPE_H
|
||||
#define BITCOIN_UTIL_HASH_TYPE_H
|
||||
|
||||
template <typename HashType>
|
||||
class BaseHash
|
||||
{
|
||||
protected:
|
||||
HashType m_hash;
|
||||
|
||||
public:
|
||||
BaseHash() : m_hash() {}
|
||||
explicit BaseHash(const HashType& in) : m_hash(in) {}
|
||||
|
||||
unsigned char* begin()
|
||||
{
|
||||
return m_hash.begin();
|
||||
}
|
||||
|
||||
const unsigned char* begin() const
|
||||
{
|
||||
return m_hash.begin();
|
||||
}
|
||||
|
||||
unsigned char* end()
|
||||
{
|
||||
return m_hash.end();
|
||||
}
|
||||
|
||||
const unsigned char* end() const
|
||||
{
|
||||
return m_hash.end();
|
||||
}
|
||||
|
||||
operator std::vector<unsigned char>() const
|
||||
{
|
||||
return std::vector<unsigned char>{m_hash.begin(), m_hash.end()};
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return m_hash.ToString();
|
||||
}
|
||||
|
||||
bool operator==(const BaseHash<HashType>& other) const noexcept
|
||||
{
|
||||
return m_hash == other.m_hash;
|
||||
}
|
||||
|
||||
bool operator!=(const BaseHash<HashType>& other) const noexcept
|
||||
{
|
||||
return !(m_hash == other.m_hash);
|
||||
}
|
||||
|
||||
bool operator<(const BaseHash<HashType>& other) const noexcept
|
||||
{
|
||||
return m_hash < other.m_hash;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_hash.size();
|
||||
}
|
||||
|
||||
unsigned char* data() { return m_hash.data(); }
|
||||
const unsigned char* data() const { return m_hash.data(); }
|
||||
};
|
||||
|
||||
#endif // BITCOIN_UTIL_HASH_TYPE_H
|
|
@ -1158,7 +1158,7 @@ void CoinsViews::InitCache()
|
|||
m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
|
||||
}
|
||||
|
||||
CChainState::CChainState(CTxMemPool& mempool, BlockManager& blockman, uint256 from_snapshot_blockhash)
|
||||
CChainState::CChainState(CTxMemPool& mempool, BlockManager& blockman, std::optional<uint256> from_snapshot_blockhash)
|
||||
: m_mempool(mempool),
|
||||
m_blockman(blockman),
|
||||
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
|
||||
|
@ -1169,8 +1169,8 @@ void CChainState::InitCoinsDB(
|
|||
bool should_wipe,
|
||||
std::string leveldb_name)
|
||||
{
|
||||
if (!m_from_snapshot_blockhash.IsNull()) {
|
||||
leveldb_name += "_" + m_from_snapshot_blockhash.ToString();
|
||||
if (m_from_snapshot_blockhash) {
|
||||
leveldb_name += "_" + m_from_snapshot_blockhash->ToString();
|
||||
}
|
||||
|
||||
m_coins_views = std::make_unique<CoinsViews>(
|
||||
|
@ -3877,7 +3877,7 @@ bool CVerifyDB::VerifyDB(
|
|||
int reportDone = 0;
|
||||
LogPrintf("[0%%]..."); /* Continued */
|
||||
|
||||
bool is_snapshot_cs = !chainstate.m_from_snapshot_blockhash.IsNull();
|
||||
const bool is_snapshot_cs{!chainstate.m_from_snapshot_blockhash};
|
||||
|
||||
for (pindex = chainstate.m_chain.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
|
||||
const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
|
||||
|
@ -4458,8 +4458,8 @@ std::string CChainState::ToString()
|
|||
{
|
||||
CBlockIndex* tip = m_chain.Tip();
|
||||
return strprintf("Chainstate [%s] @ height %d (%s)",
|
||||
m_from_snapshot_blockhash.IsNull() ? "ibd" : "snapshot",
|
||||
tip ? tip->nHeight : -1, tip ? tip->GetBlockHash().ToString() : "null");
|
||||
m_from_snapshot_blockhash ? "snapshot" : "ibd",
|
||||
tip ? tip->nHeight : -1, tip ? tip->GetBlockHash().ToString() : "null");
|
||||
}
|
||||
|
||||
bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
|
||||
|
@ -4662,10 +4662,10 @@ double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pin
|
|||
return std::min<double>(pindex->nChainTx / fTxTotal, 1.0);
|
||||
}
|
||||
|
||||
std::optional<uint256> ChainstateManager::SnapshotBlockhash() const {
|
||||
std::optional<uint256> ChainstateManager::SnapshotBlockhash() const
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
if (m_active_chainstate != nullptr &&
|
||||
!m_active_chainstate->m_from_snapshot_blockhash.IsNull()) {
|
||||
if (m_active_chainstate && m_active_chainstate->m_from_snapshot_blockhash) {
|
||||
// If a snapshot chainstate exists, it will always be our active.
|
||||
return m_active_chainstate->m_from_snapshot_blockhash;
|
||||
}
|
||||
|
@ -4688,9 +4688,9 @@ std::vector<CChainState*> ChainstateManager::GetAll()
|
|||
return out;
|
||||
}
|
||||
|
||||
CChainState& ChainstateManager::InitializeChainstate(CTxMemPool& mempool, const uint256& snapshot_blockhash)
|
||||
CChainState& ChainstateManager::InitializeChainstate(CTxMemPool& mempool, const std::optional<uint256>& snapshot_blockhash)
|
||||
{
|
||||
bool is_snapshot = !snapshot_blockhash.IsNull();
|
||||
bool is_snapshot = snapshot_blockhash.has_value();
|
||||
std::unique_ptr<CChainState>& to_modify =
|
||||
is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate;
|
||||
|
||||
|
@ -4815,6 +4815,26 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
|
|||
|
||||
uint256 base_blockhash = metadata.m_base_blockhash;
|
||||
|
||||
CBlockIndex* snapshot_start_block = WITH_LOCK(::cs_main, return m_blockman.LookupBlockIndex(base_blockhash));
|
||||
|
||||
if (!snapshot_start_block) {
|
||||
// Needed for GetUTXOStats and ExpectedAssumeutxo to determine the height and to avoid a crash when base_blockhash.IsNull()
|
||||
LogPrintf("[snapshot] Did not find snapshot start blockheader %s\n",
|
||||
base_blockhash.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
int base_height = snapshot_start_block->nHeight;
|
||||
auto maybe_au_data = ExpectedAssumeutxo(base_height, ::Params());
|
||||
|
||||
if (!maybe_au_data) {
|
||||
LogPrintf("[snapshot] assumeutxo height in snapshot metadata not recognized " /* Continued */
|
||||
"(%d) - refusing to load snapshot\n", base_height);
|
||||
return false;
|
||||
}
|
||||
|
||||
const AssumeutxoData& au_data = *maybe_au_data;
|
||||
|
||||
COutPoint outpoint;
|
||||
Coin coin;
|
||||
const uint64_t coins_count = metadata.m_coins_count;
|
||||
|
@ -4905,15 +4925,6 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
|
|||
|
||||
assert(coins_cache.GetBestBlock() == base_blockhash);
|
||||
|
||||
CBlockIndex* snapshot_start_block = WITH_LOCK(::cs_main, return m_blockman.LookupBlockIndex(base_blockhash));
|
||||
|
||||
if (!snapshot_start_block) {
|
||||
// Needed for GetUTXOStats to determine the height
|
||||
LogPrintf("[snapshot] Did not find snapshot start blockheader %s\n",
|
||||
base_blockhash.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
CCoinsStats stats{CoinStatsHashType::HASH_SERIALIZED};
|
||||
auto breakpoint_fnc = [] { /* TODO insert breakpoint here? */ };
|
||||
|
||||
|
@ -4927,19 +4938,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
|
|||
}
|
||||
|
||||
// Assert that the deserialized chainstate contents match the expected assumeutxo value.
|
||||
|
||||
int base_height = snapshot_start_block->nHeight;
|
||||
auto maybe_au_data = ExpectedAssumeutxo(base_height, ::Params());
|
||||
|
||||
if (!maybe_au_data) {
|
||||
LogPrintf("[snapshot] assumeutxo height in snapshot metadata not recognized " /* Continued */
|
||||
"(%d) - refusing to load snapshot\n", base_height);
|
||||
return false;
|
||||
}
|
||||
|
||||
const AssumeutxoData& au_data = *maybe_au_data;
|
||||
|
||||
if (stats.hashSerialized != au_data.hash_serialized) {
|
||||
if (AssumeutxoHash{stats.hashSerialized} != au_data.hash_serialized) {
|
||||
LogPrintf("[snapshot] bad snapshot content hash: expected %s, got %s\n",
|
||||
au_data.hash_serialized.ToString(), stats.hashSerialized.ToString());
|
||||
return false;
|
||||
|
|
|
@ -553,7 +553,7 @@ public:
|
|||
//! CChainState instances.
|
||||
BlockManager& m_blockman;
|
||||
|
||||
explicit CChainState(CTxMemPool& mempool, BlockManager& blockman, uint256 from_snapshot_blockhash = uint256());
|
||||
explicit CChainState(CTxMemPool& mempool, BlockManager& blockman, std::optional<uint256> from_snapshot_blockhash = std::nullopt);
|
||||
|
||||
/**
|
||||
* Initialize the CoinsViews UTXO set database management data structures. The in-memory
|
||||
|
@ -584,9 +584,9 @@ public:
|
|||
/**
|
||||
* The blockhash which is the base of the snapshot this chainstate was created from.
|
||||
*
|
||||
* IsNull() if this chainstate was not created from a snapshot.
|
||||
* std::nullopt if this chainstate was not created from a snapshot.
|
||||
*/
|
||||
const uint256 m_from_snapshot_blockhash{};
|
||||
const std::optional<uint256> m_from_snapshot_blockhash;
|
||||
|
||||
/**
|
||||
* The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
|
||||
|
@ -866,7 +866,7 @@ public:
|
|||
// constructor
|
||||
//! @param[in] snapshot_blockhash If given, signify that this chainstate
|
||||
//! is based on a snapshot.
|
||||
CChainState& InitializeChainstate(CTxMemPool& mempool, const uint256& snapshot_blockhash = uint256())
|
||||
CChainState& InitializeChainstate(CTxMemPool& mempool, const std::optional<uint256>& snapshot_blockhash = std::nullopt)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
|
||||
|
||||
//! Get all chainstates currently being used.
|
||||
|
|
Loading…
Add table
Reference in a new issue