indexes, refactor: Remove CBlockIndex* uses in index WriteBlock methods

Replace WriteBlock method with CustomAppend and pass BlockInfo struct
instead of CBlockIndex* pointer

This commit does not change behavior in any way.
This commit is contained in:
Ryan Ofsky 2022-01-17 20:33:16 -05:00
parent bef4e405f3
commit dc971be083
9 changed files with 45 additions and 33 deletions

View file

@ -884,6 +884,7 @@ libbitcoinkernel_la_SOURCES = \
flatfile.cpp \
fs.cpp \
hash.cpp \
kernel/chain.cpp \
kernel/checks.cpp \
kernel/coinstats.cpp \
kernel/context.cpp \

View file

@ -5,6 +5,7 @@
#include <chainparams.h>
#include <index/base.h>
#include <interfaces/chain.h>
#include <kernel/chain.h>
#include <node/blockstorage.h>
#include <node/context.h>
#include <node/interface_ui.h>
@ -180,12 +181,15 @@ void BaseIndex::ThreadSync()
}
CBlock block;
interfaces::BlockInfo block_info = kernel::MakeBlockInfo(pindex);
if (!ReadBlockFromDisk(block, pindex, consensus_params)) {
FatalError("%s: Failed to read block %s from disk",
__func__, pindex->GetBlockHash().ToString());
return;
} else {
block_info.data = &block;
}
if (!WriteBlock(block, pindex)) {
if (!CustomAppend(block_info)) {
FatalError("%s: Failed to write block %s to index database",
__func__, pindex->GetBlockHash().ToString());
return;
@ -273,8 +277,8 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
return;
}
}
if (WriteBlock(*block, pindex)) {
interfaces::BlockInfo block_info = kernel::MakeBlockInfo(pindex, block.get());
if (CustomAppend(block_info)) {
SetBestBlockIndex(pindex);
} else {
FatalError("%s: Failed to write block %s to index",

View file

@ -97,7 +97,7 @@ protected:
[[nodiscard]] virtual bool CustomInit(const std::optional<interfaces::BlockKey>& block) { return true; }
/// Write update index entries for a newly connected block.
virtual bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) { return true; }
[[nodiscard]] virtual bool CustomAppend(const interfaces::BlockInfo& block) { return true; }
/// Virtual method called internally by Commit that can be overridden to atomically
/// commit more index state.

View file

@ -9,6 +9,7 @@
#include <index/blockfilterindex.h>
#include <node/blockstorage.h>
#include <util/system.h>
#include <validation.h>
using node::UndoReadFromDisk;
@ -214,22 +215,25 @@ size_t BlockFilterIndex::WriteFilterToDisk(FlatFilePos& pos, const BlockFilter&
return data_size;
}
bool BlockFilterIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
bool BlockFilterIndex::CustomAppend(const interfaces::BlockInfo& block)
{
CBlockUndo block_undo;
uint256 prev_header;
if (pindex->nHeight > 0) {
if (block.height > 0) {
// pindex variable gives indexing code access to node internals. It
// will be removed in upcoming commit
const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash));
if (!UndoReadFromDisk(block_undo, pindex)) {
return false;
}
std::pair<uint256, DBVal> read_out;
if (!m_db->Read(DBHeightKey(pindex->nHeight - 1), read_out)) {
if (!m_db->Read(DBHeightKey(block.height - 1), read_out)) {
return false;
}
uint256 expected_block_hash = pindex->pprev->GetBlockHash();
uint256 expected_block_hash = *Assert(block.prev_hash);
if (read_out.first != expected_block_hash) {
return error("%s: previous block header belongs to unexpected block %s; expected %s",
__func__, read_out.first.ToString(), expected_block_hash.ToString());
@ -238,18 +242,18 @@ bool BlockFilterIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex
prev_header = read_out.second.header;
}
BlockFilter filter(m_filter_type, block, block_undo);
BlockFilter filter(m_filter_type, *Assert(block.data), block_undo);
size_t bytes_written = WriteFilterToDisk(m_next_filter_pos, filter);
if (bytes_written == 0) return false;
std::pair<uint256, DBVal> value;
value.first = pindex->GetBlockHash();
value.first = block.hash;
value.second.hash = filter.GetHash();
value.second.header = filter.ComputeHeader(prev_header);
value.second.pos = m_next_filter_pos;
if (!m_db->Write(DBHeightKey(pindex->nHeight), value)) {
if (!m_db->Write(DBHeightKey(block.height), value)) {
return false;
}

View file

@ -45,7 +45,7 @@ protected:
bool CommitInternal(CDBBatch& batch) override;
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;
bool CustomAppend(const interfaces::BlockInfo& block) override;
bool Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip) override;

View file

@ -111,24 +111,27 @@ CoinStatsIndex::CoinStatsIndex(std::unique_ptr<interfaces::Chain> chain, size_t
m_db = std::make_unique<CoinStatsIndex::DB>(path / "db", n_cache_size, f_memory, f_wipe);
}
bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
bool CoinStatsIndex::CustomAppend(const interfaces::BlockInfo& block)
{
CBlockUndo block_undo;
const CAmount block_subsidy{GetBlockSubsidy(pindex->nHeight, Params().GetConsensus())};
const CAmount block_subsidy{GetBlockSubsidy(block.height, Params().GetConsensus())};
m_total_subsidy += block_subsidy;
// Ignore genesis block
if (pindex->nHeight > 0) {
if (block.height > 0) {
// pindex variable gives indexing code access to node internals. It
// will be removed in upcoming commit
const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash));
if (!UndoReadFromDisk(block_undo, pindex)) {
return false;
}
std::pair<uint256, DBVal> read_out;
if (!m_db->Read(DBHeightKey(pindex->nHeight - 1), read_out)) {
if (!m_db->Read(DBHeightKey(block.height - 1), read_out)) {
return false;
}
uint256 expected_block_hash{pindex->pprev->GetBlockHash()};
uint256 expected_block_hash{*Assert(block.prev_hash)};
if (read_out.first != expected_block_hash) {
LogPrintf("WARNING: previous block header belongs to unexpected block %s; expected %s\n",
read_out.first.ToString(), expected_block_hash.ToString());
@ -140,12 +143,13 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
}
// TODO: Deduplicate BIP30 related code
bool is_bip30_block{(pindex->nHeight == 91722 && pindex->GetBlockHash() == uint256S("0x00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e")) ||
(pindex->nHeight == 91812 && pindex->GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f"))};
bool is_bip30_block{(block.height == 91722 && block.hash == uint256S("0x00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e")) ||
(block.height == 91812 && block.hash == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f"))};
// Add the new utxos created from the block
for (size_t i = 0; i < block.vtx.size(); ++i) {
const auto& tx{block.vtx.at(i)};
assert(block.data);
for (size_t i = 0; i < block.data->vtx.size(); ++i) {
const auto& tx{block.data->vtx.at(i)};
// Skip duplicate txid coinbase transactions (BIP30).
if (is_bip30_block && tx->IsCoinBase()) {
@ -156,7 +160,7 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
for (uint32_t j = 0; j < tx->vout.size(); ++j) {
const CTxOut& out{tx->vout[j]};
Coin coin{out, pindex->nHeight, tx->IsCoinBase()};
Coin coin{out, block.height, tx->IsCoinBase()};
COutPoint outpoint{tx->GetHash(), j};
// Skip unspendable coins
@ -212,7 +216,7 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
m_total_unspendables_unclaimed_rewards += unclaimed_rewards;
std::pair<uint256, DBVal> value;
value.first = pindex->GetBlockHash();
value.first = block.hash;
value.second.transaction_output_count = m_transaction_output_count;
value.second.bogo_size = m_bogo_size;
value.second.total_amount = m_total_amount;
@ -232,7 +236,7 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
// Intentionally do not update DB_MUHASH here so it stays in sync with
// DB_BEST_BLOCK, and the index is not corrupted if there is an unclean shutdown.
return m_db->Write(DBHeightKey(pindex->nHeight), value);
return m_db->Write(DBHeightKey(block.height), value);
}
static bool CopyHeightIndexToHashIndex(CDBIterator& db_it, CDBBatch& batch,

View file

@ -43,7 +43,7 @@ protected:
bool CommitInternal(CDBBatch& batch) override;
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;
bool CustomAppend(const interfaces::BlockInfo& block) override;
bool Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip) override;

View file

@ -54,17 +54,16 @@ TxIndex::TxIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size,
TxIndex::~TxIndex() = default;
bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
bool TxIndex::CustomAppend(const interfaces::BlockInfo& block)
{
// Exclude genesis block transaction because outputs are not spendable.
if (pindex->nHeight == 0) return true;
if (block.height == 0) return true;
CDiskTxPos pos{
WITH_LOCK(::cs_main, return pindex->GetBlockPos()),
GetSizeOfCompactSize(block.vtx.size())};
assert(block.data);
CDiskTxPos pos({block.file_number, block.data_pos}, GetSizeOfCompactSize(block.data->vtx.size()));
std::vector<std::pair<uint256, CDiskTxPos>> vPos;
vPos.reserve(block.vtx.size());
for (const auto& tx : block.vtx) {
vPos.reserve(block.data->vtx.size());
for (const auto& tx : block.data->vtx) {
vPos.emplace_back(tx->GetHash(), pos);
pos.nTxOffset += ::GetSerializeSize(*tx, CLIENT_VERSION);
}

View file

@ -23,7 +23,7 @@ private:
bool AllowPrune() const override { return false; }
protected:
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;
bool CustomAppend(const interfaces::BlockInfo& block) override;
BaseIndex::DB& GetDB() const override;