Skip to content

Commit 33b4d48

Browse files
committed
indexes, refactor: Pass Chain interface instead of CChainState class to indexes
Passing abstract Chain interface will let indexes run in separate processes. This commit does not change behavior in any way.
1 parent a0b5b4a commit 33b4d48

15 files changed

+58
-33
lines changed

src/index/base.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
#include <chainparams.h>
66
#include <index/base.h>
7+
#include <interfaces/chain.h>
78
#include <node/blockstorage.h>
9+
#include <node/context.h>
810
#include <node/interface_ui.h>
911
#include <shutdown.h>
1012
#include <tinyformat.h>
@@ -49,6 +51,9 @@ void BaseIndex::DB::WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator
4951
batch.Write(DB_BEST_BLOCK, locator);
5052
}
5153

54+
BaseIndex::BaseIndex(std::unique_ptr<interfaces::Chain> chain)
55+
: m_chain{std::move(chain)} {}
56+
5257
BaseIndex::~BaseIndex()
5358
{
5459
Interrupt();
@@ -346,9 +351,11 @@ void BaseIndex::Interrupt()
346351
m_interrupt();
347352
}
348353

349-
bool BaseIndex::Start(CChainState& active_chainstate)
354+
bool BaseIndex::Start()
350355
{
351-
m_chainstate = &active_chainstate;
356+
// m_chainstate member gives indexing code access to node internals. It is
357+
// removed in followup https://github.com/bitcoin/bitcoin/pull/24230
358+
m_chainstate = &m_chain->context()->chainman->ActiveChainstate();
352359
// Need to register this ValidationInterface before running Init(), so that
353360
// callbacks are not missed if Init sets m_synced to true.
354361
RegisterValidationInterface(this);

src/index/base.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
#define BITCOIN_INDEX_BASE_H
77

88
#include <dbwrapper.h>
9+
#include <interfaces/chain.h>
910
#include <threadinterrupt.h>
1011
#include <validationinterface.h>
1112

1213
class CBlock;
1314
class CBlockIndex;
1415
class CChainState;
16+
namespace interfaces {
17+
class Chain;
18+
} // namespace interfaces
1519

1620
struct IndexSummary {
1721
std::string name;
@@ -79,6 +83,7 @@ class BaseIndex : public CValidationInterface
7983
virtual bool AllowPrune() const = 0;
8084

8185
protected:
86+
std::unique_ptr<interfaces::Chain> m_chain;
8287
CChainState* m_chainstate{nullptr};
8388

8489
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;
@@ -110,6 +115,7 @@ class BaseIndex : public CValidationInterface
110115
void SetBestBlockIndex(const CBlockIndex* block);
111116

112117
public:
118+
BaseIndex(std::unique_ptr<interfaces::Chain> chain);
113119
/// Destructor interrupts sync thread if running and blocks until it exits.
114120
virtual ~BaseIndex();
115121

@@ -124,7 +130,7 @@ class BaseIndex : public CValidationInterface
124130

125131
/// Start initializes the sync state and registers the instance as a
126132
/// ValidationInterface so that it stays in sync with blockchain updates.
127-
[[nodiscard]] bool Start(CChainState& active_chainstate);
133+
[[nodiscard]] bool Start();
128134

129135
/// Stops the instance from staying in sync with blockchain updates.
130136
void Stop();

src/index/blockfilterindex.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ struct DBHashKey {
9494

9595
static std::map<BlockFilterType, BlockFilterIndex> g_filter_indexes;
9696

97-
BlockFilterIndex::BlockFilterIndex(BlockFilterType filter_type,
97+
BlockFilterIndex::BlockFilterIndex(std::unique_ptr<interfaces::Chain> chain, BlockFilterType filter_type,
9898
size_t n_cache_size, bool f_memory, bool f_wipe)
99-
: m_filter_type(filter_type)
99+
: BaseIndex(std::move(chain)), m_filter_type(filter_type)
100100
{
101101
const std::string& filter_name = BlockFilterTypeName(filter_type);
102102
if (filter_name.empty()) throw std::invalid_argument("unknown filter_type");
@@ -467,12 +467,12 @@ void ForEachBlockFilterIndex(std::function<void (BlockFilterIndex&)> fn)
467467
for (auto& entry : g_filter_indexes) fn(entry.second);
468468
}
469469

470-
bool InitBlockFilterIndex(BlockFilterType filter_type,
470+
bool InitBlockFilterIndex(std::function<std::unique_ptr<interfaces::Chain>()> make_chain, BlockFilterType filter_type,
471471
size_t n_cache_size, bool f_memory, bool f_wipe)
472472
{
473473
auto result = g_filter_indexes.emplace(std::piecewise_construct,
474474
std::forward_as_tuple(filter_type),
475-
std::forward_as_tuple(filter_type,
475+
std::forward_as_tuple(make_chain(), filter_type,
476476
n_cache_size, f_memory, f_wipe));
477477
return result.second;
478478
}

src/index/blockfilterindex.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class BlockFilterIndex final : public BaseIndex
5555

5656
public:
5757
/** Constructs the index, which becomes available to be queried. */
58-
explicit BlockFilterIndex(BlockFilterType filter_type,
58+
explicit BlockFilterIndex(std::unique_ptr<interfaces::Chain> chain, BlockFilterType filter_type,
5959
size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
6060

6161
BlockFilterType GetFilterType() const { return m_filter_type; }
@@ -88,7 +88,7 @@ void ForEachBlockFilterIndex(std::function<void (BlockFilterIndex&)> fn);
8888
* Initialize a block filter index for the given type if one does not already exist. Returns true if
8989
* a new index is created and false if one has already been initialized.
9090
*/
91-
bool InitBlockFilterIndex(BlockFilterType filter_type,
91+
bool InitBlockFilterIndex(std::function<std::unique_ptr<interfaces::Chain>()> make_chain, BlockFilterType filter_type,
9292
size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
9393

9494
/**

src/index/coinstatsindex.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ struct DBHashKey {
102102

103103
std::unique_ptr<CoinStatsIndex> g_coin_stats_index;
104104

105-
CoinStatsIndex::CoinStatsIndex(size_t n_cache_size, bool f_memory, bool f_wipe)
105+
CoinStatsIndex::CoinStatsIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size, bool f_memory, bool f_wipe)
106+
: BaseIndex(std::move(chain))
106107
{
107108
fs::path path{gArgs.GetDataDirNet() / "indexes" / "coinstats"};
108109
fs::create_directories(path);

src/index/coinstatsindex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class CoinStatsIndex final : public BaseIndex
5353

5454
public:
5555
// Constructs the index, which becomes available to be queried.
56-
explicit CoinStatsIndex(size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
56+
explicit CoinStatsIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
5757

5858
// Look up stats for a specific block using CBlockIndex
5959
std::optional<kernel::CCoinsStats> LookUpStats(const CBlockIndex* block_index) const;

src/index/txindex.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ bool TxIndex::DB::WriteTxs(const std::vector<std::pair<uint256, CDiskTxPos>>& v_
4848
return WriteBatch(batch);
4949
}
5050

51-
TxIndex::TxIndex(size_t n_cache_size, bool f_memory, bool f_wipe)
52-
: m_db(std::make_unique<TxIndex::DB>(n_cache_size, f_memory, f_wipe))
51+
TxIndex::TxIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size, bool f_memory, bool f_wipe)
52+
: BaseIndex(std::move(chain)), m_db(std::make_unique<TxIndex::DB>(n_cache_size, f_memory, f_wipe))
5353
{}
5454

5555
TxIndex::~TxIndex() = default;

src/index/txindex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class TxIndex final : public BaseIndex
3131

3232
public:
3333
/// Constructs the index, which becomes available to be queried.
34-
explicit TxIndex(size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
34+
explicit TxIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
3535

3636
// Destructor is declared because this class contains a unique_ptr to an incomplete type.
3737
virtual ~TxIndex() override;

src/init.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,22 +1594,22 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15941594
return InitError(*error);
15951595
}
15961596

1597-
g_txindex = std::make_unique<TxIndex>(cache_sizes.tx_index, false, fReindex);
1598-
if (!g_txindex->Start(chainman.ActiveChainstate())) {
1597+
g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, fReindex);
1598+
if (!g_txindex->Start()) {
15991599
return false;
16001600
}
16011601
}
16021602

16031603
for (const auto& filter_type : g_enabled_filter_types) {
1604-
InitBlockFilterIndex(filter_type, cache_sizes.filter_index, false, fReindex);
1605-
if (!GetBlockFilterIndex(filter_type)->Start(chainman.ActiveChainstate())) {
1604+
InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, fReindex);
1605+
if (!GetBlockFilterIndex(filter_type)->Start()) {
16061606
return false;
16071607
}
16081608
}
16091609

16101610
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
1611-
g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex);
1612-
if (!g_coin_stats_index->Start(chainman.ActiveChainstate())) {
1611+
g_coin_stats_index = std::make_unique<CoinStatsIndex>(interfaces::MakeChain(node), /* cache size */ 0, false, fReindex);
1612+
if (!g_coin_stats_index->Start()) {
16131613
return false;
16141614
}
16151615
}

src/interfaces/chain.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ class Chain
304304

305305
//! Return true if an assumed-valid chain is in use.
306306
virtual bool hasAssumedValidChain() = 0;
307+
308+
//! Get internal node context. Useful for testing, but not
309+
//! accessible across processes.
310+
virtual node::NodeContext* context() { return nullptr; }
307311
};
308312

309313
//! Interface to let node manage chain clients (wallets, or maybe tools for

0 commit comments

Comments
 (0)