Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/index/addressindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
constexpr uint8_t DB_ADDRESSINDEX{'a'};
constexpr uint8_t DB_ADDRESSUNSPENTINDEX{'u'};

std::unique_ptr<AddressIndex> g_addressindex;

AddressIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) :
BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "addressindex", n_cache_size, f_memory, f_wipe)
{
Expand Down
3 changes: 0 additions & 3 deletions src/index/addressindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,4 @@ class AddressIndex final : public BaseIndex
std::vector<CAddressUnspentIndexEntry>& entries, const bool height_sort = false) const;
};

/// Global AddressIndex instance
extern std::unique_ptr<AddressIndex> g_addressindex;

#endif // BITCOIN_INDEX_ADDRESSINDEX_H
2 changes: 0 additions & 2 deletions src/index/spentindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

constexpr uint8_t DB_SPENTINDEX{'p'};

std::unique_ptr<SpentIndex> g_spentindex;

SpentIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) :
BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "spentindex", n_cache_size, f_memory, f_wipe)
{
Expand Down
3 changes: 0 additions & 3 deletions src/index/spentindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,4 @@ class SpentIndex final : public BaseIndex
bool GetSpentInfo(const CSpentIndexKey& key, CSpentIndexValue& value) const;
};

/// Global SpentIndex instance
extern std::unique_ptr<SpentIndex> g_spentindex;

#endif // BITCOIN_INDEX_SPENTINDEX_H
2 changes: 0 additions & 2 deletions src/index/timestampindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

constexpr uint8_t DB_TIMESTAMPINDEX{'s'};

std::unique_ptr<TimestampIndex> g_timestampindex;

TimestampIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) :
BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "timestampindex", n_cache_size, f_memory, f_wipe)
{
Expand Down
3 changes: 0 additions & 3 deletions src/index/timestampindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,4 @@ class TimestampIndex final : public BaseIndex
bool GetBlockHashes(uint32_t high, uint32_t low, std::vector<uint256>& hashes) const;
};

/// Global TimestampIndex instance
extern std::unique_ptr<TimestampIndex> g_timestampindex;

#endif // BITCOIN_INDEX_TIMESTAMPINDEX_H
42 changes: 21 additions & 21 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,14 @@ void Interrupt(NodeContext& node)
if (g_txindex) {
g_txindex->Interrupt();
}
if (g_addressindex) {
g_addressindex->Interrupt();
if (node.address_index) {
node.address_index->Interrupt();
}
if (g_timestampindex) {
g_timestampindex->Interrupt();
if (node.timestamp_index) {
node.timestamp_index->Interrupt();
}
if (g_spentindex) {
g_spentindex->Interrupt();
if (node.spent_index) {
node.spent_index->Interrupt();
}
ForEachBlockFilterIndex([](BlockFilterIndex& index) { index.Interrupt(); });
if (g_coin_stats_index) {
Expand Down Expand Up @@ -396,17 +396,17 @@ void PrepareShutdown(NodeContext& node)
g_txindex->Stop();
g_txindex.reset();
}
if (g_addressindex) {
g_addressindex->Stop();
g_addressindex.reset();
if (node.address_index) {
node.address_index->Stop();
node.address_index.reset();
}
if (g_timestampindex) {
g_timestampindex->Stop();
g_timestampindex.reset();
if (node.timestamp_index) {
node.timestamp_index->Stop();
node.timestamp_index.reset();
}
if (g_spentindex) {
g_spentindex->Stop();
g_spentindex.reset();
if (node.spent_index) {
node.spent_index->Stop();
node.spent_index.reset();
}
if (g_coin_stats_index) {
g_coin_stats_index->Stop();
Expand Down Expand Up @@ -2199,22 +2199,22 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}

if (args.GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX)) {
g_addressindex = std::make_unique<AddressIndex>(interfaces::MakeChain(node), cache_sizes.address_index, false, fReindex);
if (!g_addressindex->Start()) {
node.address_index = std::make_unique<AddressIndex>(interfaces::MakeChain(node), cache_sizes.address_index, false, fReindex);
if (!node.address_index->Start()) {
return false;
}
}

if (args.GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX)) {
g_timestampindex = std::make_unique<TimestampIndex>(interfaces::MakeChain(node), cache_sizes.timestamp_index, false, fReindex);
if (!g_timestampindex->Start()) {
node.timestamp_index = std::make_unique<TimestampIndex>(interfaces::MakeChain(node), cache_sizes.timestamp_index, false, fReindex);
if (!node.timestamp_index->Start()) {
return false;
}
}

if (args.GetBoolArg("-spentindex", DEFAULT_SPENTINDEX)) {
g_spentindex = std::make_unique<SpentIndex>(interfaces::MakeChain(node), cache_sizes.spent_index, false, fReindex);
if (!g_spentindex->Start()) {
node.spent_index = std::make_unique<SpentIndex>(interfaces::MakeChain(node), cache_sizes.spent_index, false, fReindex);
if (!node.spent_index->Start()) {
return false;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/kernel/mempool_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ struct MemPoolOptions {
std::optional<unsigned> max_datacarrier_bytes{DEFAULT_ACCEPT_DATACARRIER ? std::optional{MAX_OP_RETURN_RELAY} : std::nullopt};
bool permit_bare_multisig{DEFAULT_PERMIT_BAREMULTISIG};
bool require_standard{true};
bool address_index_enabled{false};
bool spent_index_enabled{false};
MemPoolLimits limits{};
};
} // namespace kernel
Expand Down
3 changes: 3 additions & 0 deletions src/node/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include <scheduler.h>
#include <txmempool.h>
#include <validation.h>
#include <index/addressindex.h>
#include <index/spentindex.h>
#include <index/timestampindex.h>
Comment on lines +19 to +21

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: Resolve the temporary BaseIndex dependency before adding direct index cycles

These concrete index includes are required to destroy the new unique_ptr members, but they combine with BaseIndex::Start() dereferencing m_chain->context() to create three new direct cycles through node/context. These differ from the existing temporary cycles, where the return edge to an index passes through net_processing, and the PR adds permanent Dash lint exceptions for them. The comment in src/index/base.cpp already identifies its NodeContext access as temporary pending bitcoin#24230. Resolve that dependency first, use an ownership structure that does not require these direct includes, or defer this migration instead of expanding the circular-dependency allowlist. The <node/context.h> include in index/base.cpp cannot simply be removed because line 404 requires the complete NodeContext definition.

source: ['claude']

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is being litigated in the PR-level thread (see the discussion with knst), so just the short version here: the new node/context -> index/* edges are destructor-instantiation includes with no calls behind them, and every one of these cycles — including the pre-existing txindex entry — depends on the single index/base -> node/context edge from BaseIndex::Start(), which is exactly what bitcoin#24230 removes. When that lands and is backported, all four allowlist entries drop out together. Deferring NodeContext ownership until then would keep the Dash indexes global for no benefit, since 24230 moves sync logic, not ownership.


🤖 Posted autonomously by Claude on behalf of pasta.


#include <active/context.h>
#include <chainlock/chainlock.h>
Expand Down
7 changes: 7 additions & 0 deletions src/node/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <memory>
#include <vector>

class AddressIndex;
class ArgsManager;
class BanMan;
class CActiveMasternodeManager;
Expand All @@ -35,6 +36,8 @@ class CSporkManager;
class CTxMemPool;
class NetGroupManager;
class PeerManager;
class SpentIndex;
class TimestampIndex;
struct ActiveContext;
struct LLMQContext;

Expand Down Expand Up @@ -109,6 +112,10 @@ struct NodeContext {
std::unique_ptr<ActiveContext> active_ctx;
std::unique_ptr<LLMQContext> llmq_ctx;
std::unique_ptr<llmq::ObserverContext> observer_ctx;
//! Dash indexes
std::unique_ptr<AddressIndex> address_index;
std::unique_ptr<SpentIndex> spent_index;
std::unique_ptr<TimestampIndex> timestamp_index;

//! Declare default constructor and destructor that are not inline, so code
//! instantiating the NodeContext struct doesn't need to #include class
Expand Down
6 changes: 6 additions & 0 deletions src/node/mempool_args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include <node/mempool_args.h>

#include <index/addressindex.h>
#include <index/spentindex.h>

#include <kernel/mempool_limits.h>
#include <kernel/mempool_options.h>

Expand Down Expand Up @@ -92,5 +95,8 @@ std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& argsman, con

ApplyArgsManOptions(argsman, mempool_opts.limits);

mempool_opts.address_index_enabled = argsman.GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
mempool_opts.spent_index_enabled = argsman.GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);

return std::nullopt;
}
14 changes: 8 additions & 6 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <evo/chainhelper.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
#include <index/spentindex.h>
#include <index/timestampindex.h>
#include <index/txindex.h>
#include <kernel/coinstats.h>
Expand Down Expand Up @@ -83,7 +84,7 @@ static GlobalMutex cs_blockchange;
static std::condition_variable cond_blockchange;
static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);

extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, const CTxMemPool& mempool, const Chainstate& active_chainstate, const chainlock::Chainlocks& chainlocks, const llmq::CInstantSendManager& isman, UniValue& entry, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS);
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, const CTxMemPool& mempool, const Chainstate& active_chainstate, const chainlock::Chainlocks& chainlocks, const llmq::CInstantSendManager& isman, const SpentIndex* spent_index, UniValue& entry, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS);

/* Calculate the difficulty for a given block index.
*/
Expand Down Expand Up @@ -553,19 +554,20 @@ static RPCHelpMan getblockhashes()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
if (!g_timestampindex) {
const NodeContext& node = EnsureAnyNodeContext(request.context);
if (!node.timestamp_index) {
throw JSONRPCError(RPC_MISC_ERROR, "Timestamp index is not enabled. Start with -timestampindex to enable.");
}

if (!g_timestampindex->BlockUntilSyncedToCurrentChain()) {
throw JSONRPCError(RPC_MISC_ERROR, strprintf("Timestamp index is syncing. Current height: %d", g_timestampindex->GetSummary().best_block_height));
if (!node.timestamp_index->BlockUntilSyncedToCurrentChain()) {
throw JSONRPCError(RPC_MISC_ERROR, strprintf("Timestamp index is syncing. Current height: %d", node.timestamp_index->GetSummary().best_block_height));
}

unsigned int high = request.params[0].getInt<int>();
unsigned int low = request.params[1].getInt<int>();
std::vector<uint256> blockHashes;

if (!g_timestampindex->GetBlockHashes(high, low, blockHashes)) {
if (!node.timestamp_index->GetBlockHashes(high, low, blockHashes)) {
throw JSONRPCError(RPC_MISC_ERROR, "Failed to read timestamp index.");
}

Expand Down Expand Up @@ -2474,7 +2476,7 @@ static RPCHelpMan getspecialtxes()
case 2 :
{
UniValue objTx(UniValue::VOBJ);
TxToJSON(*tx, blockhash, mempool, chainman.ActiveChainstate(), *node.chainlocks, *llmq_ctx.isman, objTx);
TxToJSON(*tx, blockhash, mempool, chainman.ActiveChainstate(), *node.chainlocks, *llmq_ctx.isman, node.spent_index.get(), objTx);
result.push_back(objTx);
break;
}
Expand Down
Loading
Loading