aboutsummaryrefslogtreecommitdiff
path: root/src/index
diff options
context:
space:
mode:
Diffstat (limited to 'src/index')
-rw-r--r--src/index/base.cpp45
-rw-r--r--src/index/base.h6
-rw-r--r--src/index/blockfilterindex.cpp2
-rw-r--r--src/index/blockfilterindex.h4
-rw-r--r--src/index/coinstatsindex.cpp44
-rw-r--r--src/index/coinstatsindex.h6
-rw-r--r--src/index/txindex.cpp2
-rw-r--r--src/index/txindex.h2
8 files changed, 67 insertions, 44 deletions
diff --git a/src/index/base.cpp b/src/index/base.cpp
index 8fe30f8960..323547900d 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -5,7 +5,7 @@
#include <chainparams.h>
#include <index/base.h>
#include <node/blockstorage.h>
-#include <node/ui_interface.h>
+#include <node/interface_ui.h>
#include <shutdown.h>
#include <tinyformat.h>
#include <util/syscall_sandbox.h>
@@ -18,8 +18,8 @@ using node::ReadBlockFromDisk;
constexpr uint8_t DB_BEST_BLOCK{'B'};
-constexpr int64_t SYNC_LOG_INTERVAL = 30; // seconds
-constexpr int64_t SYNC_LOCATOR_WRITE_INTERVAL = 30; // seconds
+constexpr auto SYNC_LOG_INTERVAL{30s};
+constexpr auto SYNC_LOCATOR_WRITE_INTERVAL{30s};
template <typename... Args>
static void FatalError(const char* fmt, const Args&... args)
@@ -65,9 +65,9 @@ bool BaseIndex::Init()
LOCK(cs_main);
CChain& active_chain = m_chainstate->m_chain;
if (locator.IsNull()) {
- m_best_block_index = nullptr;
+ SetBestBlockIndex(nullptr);
} else {
- m_best_block_index = m_chainstate->FindForkInGlobalIndex(locator);
+ SetBestBlockIndex(m_chainstate->FindForkInGlobalIndex(locator));
}
m_synced = m_best_block_index.load() == active_chain.Tip();
if (!m_synced) {
@@ -75,11 +75,7 @@ bool BaseIndex::Init()
if (!m_best_block_index) {
// index is not built yet
// make sure we have all block data back to the genesis
- const CBlockIndex* block = active_chain.Tip();
- while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
- block = block->pprev;
- }
- prune_violation = block != active_chain.Genesis();
+ prune_violation = m_chainstate->m_blockman.GetFirstStoredBlock(*active_chain.Tip()) != active_chain.Genesis();
}
// in case the index has a best block set and is not fully synced
// check if we have the required blocks to continue building the index
@@ -134,11 +130,11 @@ void BaseIndex::ThreadSync()
if (!m_synced) {
auto& consensus_params = Params().GetConsensus();
- int64_t last_log_time = 0;
- int64_t last_locator_write_time = 0;
+ std::chrono::steady_clock::time_point last_log_time{0s};
+ std::chrono::steady_clock::time_point last_locator_write_time{0s};
while (true) {
if (m_interrupt) {
- m_best_block_index = pindex;
+ SetBestBlockIndex(pindex);
// No need to handle errors in Commit. If it fails, the error will be already be
// logged. The best way to recover is to continue, as index cannot be corrupted by
// a missed commit to disk for an advanced index state.
@@ -150,7 +146,7 @@ void BaseIndex::ThreadSync()
LOCK(cs_main);
const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
if (!pindex_next) {
- m_best_block_index = pindex;
+ SetBestBlockIndex(pindex);
m_synced = true;
// No need to handle errors in Commit. See rationale above.
Commit();
@@ -164,7 +160,7 @@ void BaseIndex::ThreadSync()
pindex = pindex_next;
}
- int64_t current_time = GetTime();
+ auto current_time{std::chrono::steady_clock::now()};
if (last_log_time + SYNC_LOG_INTERVAL < current_time) {
LogPrintf("Syncing %s with block chain from height %d\n",
GetName(), pindex->nHeight);
@@ -172,7 +168,7 @@ void BaseIndex::ThreadSync()
}
if (last_locator_write_time + SYNC_LOCATOR_WRITE_INTERVAL < current_time) {
- m_best_block_index = pindex;
+ SetBestBlockIndex(pindex->pprev);
last_locator_write_time = current_time;
// No need to handle errors in Commit. See rationale above.
Commit();
@@ -230,10 +226,10 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
// out of sync may be possible but a users fault.
// In case we reorg beyond the pruned depth, ReadBlockFromDisk would
// throw and lead to a graceful shutdown
- m_best_block_index = new_tip;
+ SetBestBlockIndex(new_tip);
if (!Commit()) {
// If commit fails, revert the best block index to avoid corruption.
- m_best_block_index = current_tip;
+ SetBestBlockIndex(current_tip);
return false;
}
@@ -274,7 +270,7 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
}
if (WriteBlock(*block, pindex)) {
- m_best_block_index = pindex;
+ SetBestBlockIndex(pindex);
} else {
FatalError("%s: Failed to write block %s to index",
__func__, pindex->GetBlockHash().ToString());
@@ -381,3 +377,14 @@ IndexSummary BaseIndex::GetSummary() const
summary.best_block_height = m_best_block_index ? m_best_block_index.load()->nHeight : 0;
return summary;
}
+
+void BaseIndex::SetBestBlockIndex(const CBlockIndex* block) {
+ assert(!node::fPruneMode || AllowPrune());
+
+ m_best_block_index = block;
+ if (AllowPrune() && block) {
+ node::PruneLockInfo prune_lock;
+ prune_lock.height_first = block->nHeight;
+ WITH_LOCK(::cs_main, m_chainstate->m_blockman.UpdatePruneLock(GetName(), prune_lock));
+ }
+}
diff --git a/src/index/base.h b/src/index/base.h
index c4a8215bc4..a8f6a18c8d 100644
--- a/src/index/base.h
+++ b/src/index/base.h
@@ -75,6 +75,9 @@ private:
/// to a chain reorganization), the index must halt until Commit succeeds or else it could end up
/// getting corrupted.
bool Commit();
+
+ virtual bool AllowPrune() const = 0;
+
protected:
CChainState* m_chainstate{nullptr};
@@ -103,6 +106,9 @@ protected:
/// Get the name of the index for display in logs.
virtual const char* GetName() const = 0;
+ /// Update the internal best block index as well as the prune lock.
+ void SetBestBlockIndex(const CBlockIndex* block);
+
public:
/// Destructor interrupts sync thread if running and blocks until it exits.
virtual ~BaseIndex();
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index a8e1860481..e7fad8eb64 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -101,7 +101,7 @@ BlockFilterIndex::BlockFilterIndex(BlockFilterType filter_type,
const std::string& filter_name = BlockFilterTypeName(filter_type);
if (filter_name.empty()) throw std::invalid_argument("unknown filter_type");
- fs::path path = gArgs.GetDataDirNet() / "indexes" / "blockfilter" / filter_name;
+ fs::path path = gArgs.GetDataDirNet() / "indexes" / "blockfilter" / fs::u8path(filter_name);
fs::create_directories(path);
m_name = filter_name + " block filter index";
diff --git a/src/index/blockfilterindex.h b/src/index/blockfilterindex.h
index 09c3c78c63..fef8b573e8 100644
--- a/src/index/blockfilterindex.h
+++ b/src/index/blockfilterindex.h
@@ -38,6 +38,8 @@ private:
/** cache of block hash to filter header, to avoid disk access when responding to getcfcheckpt. */
std::unordered_map<uint256, uint256, FilterHeaderHasher> m_headers_cache GUARDED_BY(m_cs_headers_cache);
+ bool AllowPrune() const override { return true; }
+
protected:
bool Init() override;
@@ -62,7 +64,7 @@ public:
bool LookupFilter(const CBlockIndex* block_index, BlockFilter& filter_out) const;
/** Get a single filter header by block. */
- bool LookupFilterHeader(const CBlockIndex* block_index, uint256& header_out);
+ bool LookupFilterHeader(const CBlockIndex* block_index, uint256& header_out) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_headers_cache);
/** Get a range of filters between two heights on a chain. */
bool LookupFilterRange(int start_height, const CBlockIndex* stop_index,
diff --git a/src/index/coinstatsindex.cpp b/src/index/coinstatsindex.cpp
index 69078708f9..687e330fe0 100644
--- a/src/index/coinstatsindex.cpp
+++ b/src/index/coinstatsindex.cpp
@@ -12,10 +12,11 @@
#include <undo.h>
#include <validation.h>
-using node::CCoinsStats;
-using node::GetBogoSize;
+using kernel::CCoinsStats;
+using kernel::GetBogoSize;
+using kernel::TxOutSer;
+
using node::ReadBlockFromDisk;
-using node::TxOutSer;
using node::UndoReadFromDisk;
static constexpr uint8_t DB_BLOCK_HASH{'s'};
@@ -316,28 +317,31 @@ static bool LookUpOne(const CDBWrapper& db, const CBlockIndex* block_index, DBVa
return db.Read(DBHashKey(block_index->GetBlockHash()), result);
}
-bool CoinStatsIndex::LookUpStats(const CBlockIndex* block_index, CCoinsStats& coins_stats) const
+std::optional<CCoinsStats> CoinStatsIndex::LookUpStats(const CBlockIndex* block_index) const
{
+ CCoinsStats stats{Assert(block_index)->nHeight, block_index->GetBlockHash()};
+ stats.index_used = true;
+
DBVal entry;
if (!LookUpOne(*m_db, block_index, entry)) {
- return false;
+ return std::nullopt;
}
- coins_stats.hashSerialized = entry.muhash;
- coins_stats.nTransactionOutputs = entry.transaction_output_count;
- coins_stats.nBogoSize = entry.bogo_size;
- coins_stats.total_amount = entry.total_amount;
- coins_stats.total_subsidy = entry.total_subsidy;
- coins_stats.total_unspendable_amount = entry.total_unspendable_amount;
- coins_stats.total_prevout_spent_amount = entry.total_prevout_spent_amount;
- coins_stats.total_new_outputs_ex_coinbase_amount = entry.total_new_outputs_ex_coinbase_amount;
- coins_stats.total_coinbase_amount = entry.total_coinbase_amount;
- coins_stats.total_unspendables_genesis_block = entry.total_unspendables_genesis_block;
- coins_stats.total_unspendables_bip30 = entry.total_unspendables_bip30;
- coins_stats.total_unspendables_scripts = entry.total_unspendables_scripts;
- coins_stats.total_unspendables_unclaimed_rewards = entry.total_unspendables_unclaimed_rewards;
-
- return true;
+ stats.hashSerialized = entry.muhash;
+ stats.nTransactionOutputs = entry.transaction_output_count;
+ stats.nBogoSize = entry.bogo_size;
+ stats.total_amount = entry.total_amount;
+ stats.total_subsidy = entry.total_subsidy;
+ stats.total_unspendable_amount = entry.total_unspendable_amount;
+ stats.total_prevout_spent_amount = entry.total_prevout_spent_amount;
+ stats.total_new_outputs_ex_coinbase_amount = entry.total_new_outputs_ex_coinbase_amount;
+ stats.total_coinbase_amount = entry.total_coinbase_amount;
+ stats.total_unspendables_genesis_block = entry.total_unspendables_genesis_block;
+ stats.total_unspendables_bip30 = entry.total_unspendables_bip30;
+ stats.total_unspendables_scripts = entry.total_unspendables_scripts;
+ stats.total_unspendables_unclaimed_rewards = entry.total_unspendables_unclaimed_rewards;
+
+ return stats;
}
bool CoinStatsIndex::Init()
diff --git a/src/index/coinstatsindex.h b/src/index/coinstatsindex.h
index 24190ac137..cae052d913 100644
--- a/src/index/coinstatsindex.h
+++ b/src/index/coinstatsindex.h
@@ -9,7 +9,7 @@
#include <crypto/muhash.h>
#include <flatfile.h>
#include <index/base.h>
-#include <node/coinstats.h>
+#include <kernel/coinstats.h>
/**
* CoinStatsIndex maintains statistics on the UTXO set.
@@ -36,6 +36,8 @@ private:
bool ReverseBlock(const CBlock& block, const CBlockIndex* pindex);
+ bool AllowPrune() const override { return true; }
+
protected:
bool Init() override;
@@ -54,7 +56,7 @@ public:
explicit CoinStatsIndex(size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
// Look up stats for a specific block using CBlockIndex
- bool LookUpStats(const CBlockIndex* block_index, node::CCoinsStats& coins_stats) const;
+ std::optional<kernel::CCoinsStats> LookUpStats(const CBlockIndex* block_index) const;
};
/// The global UTXO set hash object.
diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
index e1d807f39a..97c11c4383 100644
--- a/src/index/txindex.cpp
+++ b/src/index/txindex.cpp
@@ -52,7 +52,7 @@ TxIndex::TxIndex(size_t n_cache_size, bool f_memory, bool f_wipe)
: m_db(std::make_unique<TxIndex::DB>(n_cache_size, f_memory, f_wipe))
{}
-TxIndex::~TxIndex() {}
+TxIndex::~TxIndex() = default;
bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
{
diff --git a/src/index/txindex.h b/src/index/txindex.h
index 2bbc602631..ec339abaa1 100644
--- a/src/index/txindex.h
+++ b/src/index/txindex.h
@@ -20,6 +20,8 @@ protected:
private:
const std::unique_ptr<DB> m_db;
+ bool AllowPrune() const override { return false; }
+
protected:
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;