Skip to content

Commit

Permalink
Merge pull request dashpay#5501 from kwvg/assumeutxo5
Browse files Browse the repository at this point in the history
  • Loading branch information
PastaPastaPasta authored Aug 2, 2023
2 parents d914bf2 + cc9dcdd commit 0b8e501
Show file tree
Hide file tree
Showing 37 changed files with 1,383 additions and 181 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ BITCOIN_CORE_H = \
i2p.h \
index/base.h \
index/blockfilterindex.h \
index/coinstatsindex.h \
index/disktxpos.h \
index/txindex.h \
indirectmap.h \
Expand Down Expand Up @@ -408,6 +409,7 @@ libbitcoin_server_a_SOURCES = \
i2p.cpp \
index/base.cpp \
index/blockfilterindex.cpp \
index/coinstatsindex.cpp \
index/txindex.cpp \
init.cpp \
governance/governance.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ BITCOIN_TESTS =\
test/cachemap_tests.cpp \
test/cachemultimap_tests.cpp \
test/coins_tests.cpp \
test/coinstatsindex_tests.cpp \
test/compilerbug_tests.cpp \
test/compress_tests.cpp \
test/crypto_tests.cpp \
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.test_util.include
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ EXTRA_LIBRARIES += \

TEST_UTIL_H = \
test/util/blockfilter.h \
test/util/index.h \
test/util/logging.h \
test/util/mining.h \
test/util/net.h \
Expand All @@ -21,6 +22,7 @@ libtest_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAG
libtest_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libtest_util_a_SOURCES = \
test/util/blockfilter.cpp \
test/util/index.cpp \
test/util/logging.cpp \
test/util/mining.cpp \
test/util/net.cpp \
Expand Down
2 changes: 1 addition & 1 deletion src/bench/block_assemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static void AssembleBlock(benchmark::Bench& bench)

for (const auto& txr : txs) {
TxValidationState state;
bool ret{::AcceptToMemoryPool(::ChainstateActive(), *test_setup.m_node.mempool, state, txr, false /* bypass_limits */, /* nAbsurdFee */ 0)};
bool ret{::AcceptToMemoryPool(test_setup.m_node.chainman->ActiveChainstate(), *test_setup.m_node.mempool, state, txr, false /* bypass_limits */, /* nAbsurdFee */ 0)};
assert(ret);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/bench/duplicate_inputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ static void DuplicateInputs(benchmark::Bench& bench)
CMutableTransaction coinbaseTx{};
CMutableTransaction naughtyTx{};

CBlockIndex* pindexPrev = ::ChainActive().Tip();
assert(std::addressof(::ChainActive()) == std::addressof(test_setup.m_node.chainman->ActiveChain()));
CBlockIndex* pindexPrev = test_setup.m_node.chainman->ActiveChain().Tip();
assert(pindexPrev != nullptr);
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());
block.nNonce = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/muhash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,6 @@ MuHash3072& MuHash3072::Insert(Span<const unsigned char> in) noexcept {
}

MuHash3072& MuHash3072::Remove(Span<const unsigned char> in) noexcept {
m_numerator.Divide(ToNum3072(in));
m_denominator.Multiply(ToNum3072(in));
return *this;
}
48 changes: 27 additions & 21 deletions src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,33 +59,34 @@ bool BaseIndex::Init()
}

LOCK(cs_main);
CChain& active_chain = m_chainstate->m_chain;
if (locator.IsNull()) {
m_best_block_index = nullptr;
} else {
m_best_block_index = g_chainman.m_blockman.FindForkInGlobalIndex(::ChainActive(), locator);
m_best_block_index = m_chainstate->m_blockman.FindForkInGlobalIndex(active_chain, locator);
}
m_synced = m_best_block_index.load() == ::ChainActive().Tip();
m_synced = m_best_block_index.load() == active_chain.Tip();
if (!m_synced) {
bool prune_violation = false;
if (!m_best_block_index) {
// index is not built yet
// make sure we have all block data back to the genesis
const CBlockIndex* block = ::ChainActive().Tip();
const CBlockIndex* block = active_chain.Tip();
while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
block = block->pprev;
}
prune_violation = block != ::ChainActive().Genesis();
prune_violation = block != 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
else {
const CBlockIndex* block_to_test = m_best_block_index.load();
if (!ChainActive().Contains(block_to_test)) {
if (!active_chain.Contains(block_to_test)) {
// if the bestblock is not part of the mainchain, find the fork
// and make sure we have all data down to the fork
block_to_test = ::ChainActive().FindFork(block_to_test);
block_to_test = active_chain.FindFork(block_to_test);
}
const CBlockIndex* block = ::ChainActive().Tip();
const CBlockIndex* block = active_chain.Tip();
prune_violation = true;
// check backwards from the tip if we have all block data until we reach the indexes bestblock
while (block_to_test && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
Expand All @@ -97,28 +98,26 @@ bool BaseIndex::Init()
}
}
if (prune_violation) {
// throw error and graceful shutdown if we can't build the index
FatalError("%s: %s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)", __func__, GetName());
return false;
return InitError(strprintf(Untranslated("%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"), GetName()));
}
}
return true;
}

static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev, CChain& chain) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);

if (!pindex_prev) {
return ::ChainActive().Genesis();
return chain.Genesis();
}

const CBlockIndex* pindex = ::ChainActive().Next(pindex_prev);
const CBlockIndex* pindex = chain.Next(pindex_prev);
if (pindex) {
return pindex;
}

return ::ChainActive().Next(::ChainActive().FindFork(pindex_prev));
return chain.Next(chain.FindFork(pindex_prev));
}

void BaseIndex::ThreadSync()
Expand All @@ -141,7 +140,7 @@ void BaseIndex::ThreadSync()

{
LOCK(cs_main);
const CBlockIndex* pindex_next = NextSyncBlock(pindex);
const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
if (!pindex_next) {
m_best_block_index = pindex;
m_synced = true;
Expand Down Expand Up @@ -204,7 +203,12 @@ bool BaseIndex::Commit()
bool BaseIndex::CommitInternal(CDBBatch& batch)
{
LOCK(cs_main);
GetDB().WriteBestBlock(batch, ::ChainActive().GetLocator(m_best_block_index));
// Don't commit anything if we haven't indexed any block yet
// (this could happen if init is interrupted).
if (m_best_block_index == nullptr) {
return false;
}
GetDB().WriteBestBlock(batch, m_chainstate->m_chain.GetLocator(m_best_block_index));
return true;
}

Expand Down Expand Up @@ -280,7 +284,7 @@ void BaseIndex::ChainStateFlushed(const CBlockLocator& locator)
const CBlockIndex* locator_tip_index;
{
LOCK(cs_main);
locator_tip_index = g_chainman.m_blockman.LookupBlockIndex(locator_tip_hash);
locator_tip_index = m_chainstate->m_blockman.LookupBlockIndex(locator_tip_hash);
}

if (!locator_tip_index) {
Expand Down Expand Up @@ -321,7 +325,7 @@ bool BaseIndex::BlockUntilSyncedToCurrentChain() const
// Skip the queue-draining stuff if we know we're caught up with
// ::ChainActive().Tip().
LOCK(cs_main);
const CBlockIndex* chain_tip = ::ChainActive().Tip();
const CBlockIndex* chain_tip = m_chainstate->m_chain.Tip();
const CBlockIndex* best_block_index = m_best_block_index.load();
if (best_block_index->GetAncestor(chain_tip->nHeight) == chain_tip) {
return true;
Expand All @@ -338,18 +342,20 @@ void BaseIndex::Interrupt()
m_interrupt();
}

void BaseIndex::Start()
bool BaseIndex::Start(CChainState& active_chainstate)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
m_chainstate = &active_chainstate;
// Need to register this ValidationInterface before running Init(), so that
// callbacks are not missed if Init sets m_synced to true.
RegisterValidationInterface(this);
if (!Init()) {
FatalError("%s: %s failed to initialize", __func__, GetName());
return;
return false;
}

m_thread_sync = std::thread(&TraceThread<std::function<void()>>, GetName(),
std::bind(&BaseIndex::ThreadSync, this));
return true;
}

void BaseIndex::Stop()
Expand Down
14 changes: 9 additions & 5 deletions src/index/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <validationinterface.h>

class CBlockIndex;
class CChainState;

struct IndexSummary {
std::string name;
Expand Down Expand Up @@ -40,10 +41,10 @@ class BaseIndex : public CValidationInterface
DB(const fs::path& path, size_t n_cache_size,
bool f_memory = false, bool f_wipe = false, bool f_obfuscate = false);

/// Read block locator of the chain that the txindex is in sync with.
/// Read block locator of the chain that the index is in sync with.
bool ReadBestBlock(CBlockLocator& locator) const;

/// Write block locator of the chain that the txindex is in sync with.
/// Write block locator of the chain that the index is in sync with.
void WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator);
};

Expand Down Expand Up @@ -75,14 +76,17 @@ class BaseIndex : public CValidationInterface
/// to a chain reorganization), the index must halt until Commit succeeds or else it could end up
/// getting corrupted.
bool Commit();

protected:
CChainState* m_chainstate{nullptr};

void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;

void ChainStateFlushed(const CBlockLocator& locator) override;

const CBlockIndex* CurrentIndex() { return m_best_block_index.load(); };

/// Initialize internal state from the database and block index.
virtual bool Init();
[[nodiscard]] virtual bool Init();

/// Write update index entries for a newly connected block.
virtual bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) { return true; }
Expand Down Expand Up @@ -115,7 +119,7 @@ class BaseIndex : public CValidationInterface

/// Start initializes the sync state and registers the instance as a
/// ValidationInterface so that it stays in sync with blockchain updates.
void Start();
[[nodiscard]] bool Start(CChainState& active_chainstate);

/// Stops the instance from staying in sync with blockchain updates.
void Stop();
Expand Down
Loading

0 comments on commit 0b8e501

Please sign in to comment.