Skip to content

Commit

Permalink
Merge #6085: backport: merge bitcoin#21727, bitcoin#22371, bitcoin#21526
Browse files Browse the repository at this point in the history
, bitcoin#23174, bitcoin#23785, bitcoin#23581, bitcoin#23974, bitcoin#22932, bitcoin#24050, bitcoin#24515 (blockstorage backports)

1bf0bf4 merge bitcoin#24515: Only load BlockMan in BlockMan member functions (Kittywhiskers Van Gogh)
5c1eb67 merge bitcoin#24050: Give m_block_index ownership of CBlockIndexes (Kittywhiskers Van Gogh)
c440304 merge bitcoin#22932: Add CBlockIndex lock annotations, guard nStatus/nFile/nDataPos/nUndoPos by cs_main (Kittywhiskers Van Gogh)
e303a4e merge bitcoin#23974: Make blockstorage globals private members of BlockManager (Kittywhiskers Van Gogh)
301163c merge bitcoin#23581: Move BlockManager to node/blockstorage (Kittywhiskers Van Gogh)
732e871 merge bitcoin#23785: Move stuff to ChainstateManager (Kittywhiskers Van Gogh)
b402fd5 merge bitcoin#23174: have LoadBlockIndex account for snapshot use (Kittywhiskers Van Gogh)
a08f2f4 merge bitcoin#21526: UpdateTip/CheckBlockIndex assumeutxo support (Kittywhiskers Van Gogh)
472caa0 merge bitcoin#22371: Move pblocktree global to BlockManager (Kittywhiskers Van Gogh)
d69ca83 merge bitcoin#21727: Move more stuff to blockstorage (Kittywhiskers Van Gogh)
6df927f chore: exclude underscore placeholder from shadowing linter warnings (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Dependent on #6078

  * Dependent on #6074

  * Dependent on #6083

  * Dependent on #6119

  * Dependency for #6138

  * In [bitcoin#24050](bitcoin#24050), `BlockMap` is given ownership of the `CBlockIndex` instance contained within the `unordered_map`. The same has not been done for `PrevBlockMap` as `PrevBlockMap` is populated with `pprev` pointers and doing so seems to break validation logic.

  * Dash has a specific linter for all Dash-specific code present in Core. The introduction of `util/translation.h` into `validation.h` has caused the linter to trigger shadowing warnings due to a conflict between the common use of `_` as a placeholder/throwaway name ([source](https://github.com/dashpay/dash/blob/37e026a038a60313214e01b6aba029809ea7ad39/src/spork.cpp#L44)) and upstream's usage of it to process translatable strings ([source](https://github.com/dashpay/dash/blob/37e026a038a60313214e01b6aba029809ea7ad39/src/util/translation.h#L55-L62)).

    Neither C++17 nor C++20 have an _official_ placeholder/throwaway term or annotation for structured bindings (which cannot use `[[maybe_unused]` or `std::ignore`) but [P2169](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2169r4.pdf) is a proposal put forth to make it the official placeholder, in that light, the linter will silence shadowing warnings involving an underscore.

  ## Breaking Changes

  None expected

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK 1bf0bf4 (with one nit)
  knst:
    utACK 1bf0bf4
  PastaPastaPasta:
    utACK 1bf0bf4

Tree-SHA512: 875fff34fe91916722f017526135697466e521d7179c473a5c0c444e3aa873369019b804dee9f5f795fc7ebed5c2481b5ce2d895b2950782a37de7b098157ad4
  • Loading branch information
PastaPastaPasta committed Jul 23, 2024
2 parents 5e6c86a + 1bf0bf4 commit 1e9694d
Show file tree
Hide file tree
Showing 35 changed files with 1,657 additions and 1,203 deletions.
1 change: 1 addition & 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/chainstate.h \
test/util/index.h \
test/util/logging.h \
test/util/mining.h \
Expand Down
51 changes: 42 additions & 9 deletions src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <consensus/params.h>
#include <flatfile.h>
#include <primitives/block.h>
#include <sync.h>
#include <uint256.h>

#include <vector>
Expand All @@ -34,6 +35,8 @@ static constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME;
*/
static constexpr int64_t MAX_BLOCK_TIME_GAP = 25 * 60;

extern RecursiveMutex cs_main;

class CBlockFileInfo
{
public:
Expand Down Expand Up @@ -124,6 +127,14 @@ enum BlockStatus: uint32_t {
BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,

BLOCK_CONFLICT_CHAINLOCK = 128, //!< conflicts with chainlock system

/**
* If set, this indicates that the block index entry is assumed-valid.
* Certain diagnostics will be skipped in e.g. CheckBlockIndex().
* It almost certainly means that the block's full validation is pending
* on a background chainstate. See `doc/assumeutxo.md`.
*/
BLOCK_ASSUMED_VALID = 256,
};

/** The block chain is a tree shaped structure starting with the
Expand All @@ -147,13 +158,13 @@ class CBlockIndex
int nHeight{0};

//! Which # file this block is stored in (blk?????.dat)
int nFile{0};
int nFile GUARDED_BY(::cs_main){0};

//! Byte offset within blk?????.dat where this block's data is stored
unsigned int nDataPos{0};
unsigned int nDataPos GUARDED_BY(::cs_main){0};

//! Byte offset within rev?????.dat where this block's undo data is stored
unsigned int nUndoPos{0};
unsigned int nUndoPos GUARDED_BY(::cs_main){0};

//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
arith_uint256 nChainWork{};
Expand Down Expand Up @@ -181,7 +192,7 @@ class CBlockIndex
//! load to avoid the block index being spuriously rewound.
//! @sa NeedsRedownload
//! @sa ActivateSnapshot
uint32_t nStatus{0};
uint32_t nStatus GUARDED_BY(::cs_main){0};

//! block header
int32_t nVersion{0};
Expand Down Expand Up @@ -209,7 +220,9 @@ class CBlockIndex
{
}

FlatFilePos GetBlockPos() const {
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{
AssertLockHeld(::cs_main);
FlatFilePos ret;
if (nStatus & BLOCK_HAVE_DATA) {
ret.nFile = nFile;
Expand All @@ -218,7 +231,9 @@ class CBlockIndex
return ret;
}

FlatFilePos GetUndoPos() const {
FlatFilePos GetUndoPos() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{
AssertLockHeld(::cs_main);
FlatFilePos ret;
if (nStatus & BLOCK_HAVE_UNDO) {
ret.nFile = nFile;
Expand Down Expand Up @@ -284,21 +299,38 @@ class CBlockIndex

//! Check whether this block index entry is valid up to the passed validity level.
bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{
AssertLockHeld(::cs_main);
assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
if (nStatus & BLOCK_FAILED_MASK)
return false;
return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
}

//! @returns true if the block is assumed-valid; this means it is queued to be
//! validated by a background chainstate.
bool IsAssumedValid() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{
AssertLockHeld(::cs_main);
return nStatus & BLOCK_ASSUMED_VALID;
}

//! Raise the validity level of this block index entry.
//! Returns true if the validity was changed.
bool RaiseValidity(enum BlockStatus nUpTo)
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{
AssertLockHeld(::cs_main);
assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
if (nStatus & BLOCK_FAILED_MASK)
return false;
if (nStatus & BLOCK_FAILED_MASK) return false;

if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
// If this block had been marked assumed-valid and we're raising
// its validity to a certain point, there is no longer an assumption.
if (nStatus & BLOCK_ASSUMED_VALID && nUpTo >= BLOCK_VALID_SCRIPTS) {
nStatus &= ~BLOCK_ASSUMED_VALID;
}

nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
return true;
}
Expand Down Expand Up @@ -339,6 +371,7 @@ class CDiskBlockIndex : public CBlockIndex

SERIALIZE_METHODS(CDiskBlockIndex, obj)
{
LOCK(::cs_main);
int _nVersion = s.GetVersion();
if (!(s.GetType() & SER_GETHASH)) READWRITE(VARINT_MODE(_nVersion, VarIntMode::NONNEGATIVE_SIGNED));

Expand Down
2 changes: 1 addition & 1 deletion src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool BaseIndex::Init()
if (locator.IsNull()) {
m_best_block_index = nullptr;
} else {
m_best_block_index = m_chainstate->m_blockman.FindForkInGlobalIndex(active_chain, locator);
m_best_block_index = m_chainstate->FindForkInGlobalIndex(locator);
}

// Note: this will latch to true immediately if the user starts up with an empty
Expand Down
2 changes: 1 addition & 1 deletion src/index/coinstatsindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ bool CoinStatsIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* n

{
LOCK(cs_main);
CBlockIndex* iter_tip{m_chainstate->m_blockman.LookupBlockIndex(current_tip->GetBlockHash())};
const CBlockIndex* iter_tip{m_chainstate->m_blockman.LookupBlockIndex(current_tip->GetBlockHash())};
const auto& consensus_params{Params().GetConsensus()};

do {
Expand Down
7 changes: 5 additions & 2 deletions src/index/txindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <index/disktxpos.h>
#include <index/txindex.h>
#include <node/blockstorage.h>
#include <node/ui_interface.h>
#include <shutdown.h>
#include <util/system.h>
Expand Down Expand Up @@ -203,7 +204,7 @@ bool TxIndex::Init()
// Attempt to migrate txindex from the old database to the new one. Even if
// chain_tip is null, the node could be reindexing and we still want to
// delete txindex records in the old database.
if (!m_db->MigrateData(*pblocktree, m_chainstate->m_chain.GetLocator())) {
if (!m_db->MigrateData(*m_chainstate->m_blockman.m_block_tree_db, m_chainstate->m_chain.GetLocator())) {
return false;
}

Expand All @@ -215,7 +216,9 @@ bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
// Exclude genesis block transaction because outputs are not spendable.
if (pindex->nHeight == 0) return true;

CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
CDiskTxPos pos{
WITH_LOCK(::cs_main, return pindex->GetBlockPos()),
GetSizeOfCompactSize(block.vtx.size())};
std::vector<std::pair<uint256, CDiskTxPos>> vPos;
vPos.reserve(block.vtx.size());
for (const auto& tx : block.vtx) {
Expand Down
43 changes: 1 addition & 42 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ void PrepareShutdown(NodeContext& node)
chainstate->ResetCoinsViews();
}
}
pblocktree.reset();
node.chain_helper.reset();
if (node.mnhf_manager) {
node.mnhf_manager->DisconnectManagers();
Expand Down Expand Up @@ -831,47 +830,6 @@ static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex)
}
}

// If we're using -prune with -reindex, then delete block files that will be ignored by the
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
// is missing, do the same here to delete any later block files after a gap. Also delete all
// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
// is in sync with what's actually on disk by the time we start downloading, so that pruning
// works correctly.
static void CleanupBlockRevFiles()
{
std::map<std::string, fs::path> mapBlockFiles;

// Glob all blk?????.dat and rev?????.dat files from the blocks directory.
// Remove the rev files immediately and insert the blk file paths into an
// ordered map keyed by block file index.
LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
fs::path blocksdir = gArgs.GetBlocksDirPath();
for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
if (fs::is_regular_file(*it) &&
it->path().filename().string().length() == 12 &&
it->path().filename().string().substr(8,4) == ".dat")
{
if (it->path().filename().string().substr(0,3) == "blk")
mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path();
else if (it->path().filename().string().substr(0,3) == "rev")
remove(it->path());
}
}

// Remove all block files that aren't part of a contiguous set starting at
// zero by walking the ordered map (keys are block file indices) by
// keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
// start removing block files.
int nContigCounter = 0;
for (const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
if (LocaleIndependentAtoi<int>(item.first) == nContigCounter) {
nContigCounter++;
continue;
}
remove(item.second);
}
}

#if HAVE_SYSTEM
static void StartupNotify(const ArgsManager& args)
{
Expand Down Expand Up @@ -1992,6 +1950,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)

UnloadBlockIndex(node.mempool.get(), chainman);

auto& pblocktree{chainman.m_blockman.m_block_tree_db};
// new CBlockTreeDB tries to delete the existing file, which
// fails if it's still open from the previous loop. Close it first:
pblocktree.reset();
Expand Down
1 change: 1 addition & 0 deletions src/llmq/instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <index/txindex.h>
#include <masternode/sync.h>
#include <net_processing.h>
#include <node/blockstorage.h>
#include <spork.h>
#include <txmempool.h>
#include <util/irange.h>
Expand Down
3 changes: 2 additions & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
return nNewTime - nOldTime;
}

BlockAssembler::Options::Options() {
BlockAssembler::Options::Options()
{
blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
}
Expand Down
4 changes: 2 additions & 2 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3926,7 +3926,7 @@ void PeerManagerImpl::ProcessMessage(
LOCK(cs_main);

// Find the last block the caller has in the main chain
const CBlockIndex* pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
const CBlockIndex* pindex = m_chainman.ActiveChainstate().FindForkInGlobalIndex(locator);

// Send the rest of the chain
if (pindex)
Expand Down Expand Up @@ -4046,7 +4046,7 @@ void PeerManagerImpl::ProcessMessage(
else
{
// Find the last block the caller has in the main chain
pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
pindex = m_chainman.ActiveChainstate().FindForkInGlobalIndex(locator);
if (pindex)
pindex = m_chainman.ActiveChain().Next(pindex);
}
Expand Down
Loading

0 comments on commit 1e9694d

Please sign in to comment.