Skip to content

Commit 9d9a745

Browse files
committed
assumeutxo: Remove BLOCK_ASSUMED_VALID flag
Flag adds complexity and is not currently used for anything.
1 parent ef174e9 commit 9d9a745

File tree

5 files changed

+17
-71
lines changed

5 files changed

+17
-71
lines changed

doc/design/assumeutxo.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,12 @@ The utility script
5151

5252
## Design notes
5353

54-
- A new block index `nStatus` flag is introduced, `BLOCK_ASSUMED_VALID`, to mark block
55-
index entries that are required to be assumed-valid by a chainstate created
56-
from a UTXO snapshot. This flag is used as a way to modify certain
57-
CheckBlockIndex() logic to account for index entries that are pending validation by a
58-
chainstate running asynchronously in the background.
59-
6054
- The concept of UTXO snapshots is treated as an implementation detail that lives
6155
behind the ChainstateManager interface. The external presentation of the changes
6256
required to facilitate the use of UTXO snapshots is the understanding that there are
63-
now certain regions of the chain that can be temporarily assumed to be valid (using
64-
the nStatus flag mentioned above). In certain cases, e.g. wallet rescanning, this is
65-
very similar to dealing with a pruned chain.
57+
now certain regions of the chain that can be temporarily assumed to be valid.
58+
In certain cases, e.g. wallet rescanning, this is very similar to dealing with
59+
a pruned chain.
6660

6761
Logic outside ChainstateManager should try not to know about snapshots, instead
6862
preferring to work in terms of more general states like assumed-valid.

src/chain.h

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,8 @@ enum BlockStatus : uint32_t {
128128

129129
BLOCK_OPT_WITNESS = 128, //!< block data in blk*.dat was received with a witness-enforcing client
130130

131-
/**
132-
* If ASSUMED_VALID is set, it means that this block has not been validated
133-
* and has validity status less than VALID_SCRIPTS. Also that it may have
134-
* descendant blocks with VALID_SCRIPTS set, because they can be validated
135-
* based on an assumeutxo snapshot.
136-
*
137-
* When an assumeutxo snapshot is loaded, the ASSUMED_VALID flag is added to
138-
* unvalidated blocks at the snapshot height and below. Then, as the background
139-
* validation progresses, and these blocks are validated, the ASSUMED_VALID
140-
* flags are removed. See `doc/design/assumeutxo.md` for details.
141-
*
142-
* This flag is only used to implement checks in CheckBlockIndex() and
143-
* should not be used elsewhere.
144-
*/
145-
BLOCK_ASSUMED_VALID = 256,
131+
BLOCK_STATUS_RESERVED = 256, //!< Unused flag that was previously set on assumeutxo snapshot blocks and their
132+
//!< ancestors before they were validated, and unset when they were validated.
146133
};
147134

148135
/** The block chain is a tree shaped structure starting with the
@@ -316,14 +303,6 @@ class CBlockIndex
316303
return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
317304
}
318305

319-
//! @returns true if the block is assumed-valid; this means it is queued to be
320-
//! validated by a background chainstate.
321-
bool IsAssumedValid() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
322-
{
323-
AssertLockHeld(::cs_main);
324-
return nStatus & BLOCK_ASSUMED_VALID;
325-
}
326-
327306
//! Raise the validity level of this block index entry.
328307
//! Returns true if the validity was changed.
329308
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
@@ -333,12 +312,6 @@ class CBlockIndex
333312
if (nStatus & BLOCK_FAILED_MASK) return false;
334313

335314
if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
336-
// If this block had been marked assumed-valid and we're raising
337-
// its validity to a certain point, there is no longer an assumption.
338-
if (nStatus & BLOCK_ASSUMED_VALID && nUpTo >= BLOCK_VALID_SCRIPTS) {
339-
nStatus &= ~BLOCK_ASSUMED_VALID;
340-
}
341-
342315
nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
343316
return true;
344317
}

src/test/validation_chainstatemanager_tests.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,6 @@ struct SnapshotTestSetup : TestChain100Setup {
276276
BOOST_CHECK_EQUAL(
277277
*node::ReadSnapshotBaseBlockhash(found),
278278
*chainman.SnapshotBlockhash());
279-
280-
// Ensure that the genesis block was not marked assumed-valid.
281-
BOOST_CHECK(!chainman.ActiveChain().Genesis()->IsAssumedValid());
282279
}
283280

284281
const auto& au_data = ::Params().AssumeutxoForHeight(snapshot_height);
@@ -410,7 +407,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, SnapshotTestSetup)
410407
//! - First, verify that setBlockIndexCandidates is as expected when using a single,
411408
//! fully-validating chainstate.
412409
//!
413-
//! - Then mark a region of the chain BLOCK_ASSUMED_VALID and introduce a second chainstate
410+
//! - Then mark a region of the chain as missing data and introduce a second chainstate
414411
//! that will tolerate assumed-valid blocks. Run LoadBlockIndex() and ensure that the first
415412
//! chainstate only contains fully validated blocks and the other chainstate contains all blocks,
416413
//! except those marked assume-valid, because those entries don't HAVE_DATA.
@@ -421,7 +418,6 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
421418
Chainstate& cs1 = chainman.ActiveChainstate();
422419

423420
int num_indexes{0};
424-
int num_assumed_valid{0};
425421
// Blocks in range [assumed_valid_start_idx, last_assumed_valid_idx) will be
426422
// marked as assumed-valid and not having data.
427423
const int expected_assumed_valid{20};
@@ -456,37 +452,30 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
456452
reload_all_block_indexes();
457453
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), 1);
458454

459-
// Mark some region of the chain assumed-valid, and remove the HAVE_DATA flag.
455+
// Reset some region of the chain's nStatus, removing the HAVE_DATA flag.
460456
for (int i = 0; i <= cs1.m_chain.Height(); ++i) {
461457
LOCK(::cs_main);
462458
auto index = cs1.m_chain[i];
463459

464-
// Blocks with heights in range [91, 110] are marked ASSUMED_VALID
460+
// Blocks with heights in range [91, 110] are marked as missing data.
465461
if (i < last_assumed_valid_idx && i >= assumed_valid_start_idx) {
466-
index->nStatus = BlockStatus::BLOCK_VALID_TREE | BlockStatus::BLOCK_ASSUMED_VALID;
462+
index->nStatus = BlockStatus::BLOCK_VALID_TREE;
467463
index->nTx = 0;
468464
index->nChainTx = 0;
469465
}
470466

471467
++num_indexes;
472-
if (index->IsAssumedValid()) ++num_assumed_valid;
473468

474469
// Note the last fully-validated block as the expected validated tip.
475470
if (i == (assumed_valid_start_idx - 1)) {
476471
validated_tip = index;
477-
BOOST_CHECK(!index->IsAssumedValid());
478472
}
479473
// Note the last assumed valid block as the snapshot base
480474
if (i == last_assumed_valid_idx - 1) {
481475
assumed_base = index;
482-
BOOST_CHECK(index->IsAssumedValid());
483-
} else if (i == last_assumed_valid_idx) {
484-
BOOST_CHECK(!index->IsAssumedValid());
485476
}
486477
}
487478

488-
BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid);
489-
490479
// Note: cs2's tip is not set when ActivateExistingSnapshot is called.
491480
Chainstate& cs2 = WITH_LOCK(::cs_main,
492481
return chainman.ActivateExistingSnapshot(*assumed_base->phashBlock));

src/validation.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5048,7 +5048,6 @@ void ChainstateManager::CheckBlockIndex()
50485048
CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not), since assumeutxo snapshot if used.
50495049
CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not), since assumeutxo snapshot if used.
50505050
CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not), since assumeutxo snapshot if used.
5051-
CBlockIndex* pindexFirstAssumeValid = nullptr; // Oldest ancestor of pindex which has BLOCK_ASSUMED_VALID
50525051

50535052
// After checking an assumeutxo snapshot block, reset pindexFirst pointers
50545053
// to earlier blocks that have not been downloaded or validated yet, so
@@ -5068,7 +5067,6 @@ void ChainstateManager::CheckBlockIndex()
50685067

50695068
while (pindex != nullptr) {
50705069
nNodes++;
5071-
if (pindexFirstAssumeValid == nullptr && pindex->nStatus & BLOCK_ASSUMED_VALID) pindexFirstAssumeValid = pindex;
50725070
if (pindexFirstInvalid == nullptr && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
50735071
if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
50745072
pindexFirstMissing = pindex;
@@ -5115,7 +5113,7 @@ void ChainstateManager::CheckBlockIndex()
51155113
if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
51165114
}
51175115
if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5118-
if (pindex->IsAssumedValid()) {
5116+
if (snap_base && snap_base->GetAncestor(pindex->nHeight) == pindex) {
51195117
// Assumed-valid blocks should connect to the main chain.
51205118
assert((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE);
51215119
}
@@ -5271,7 +5269,6 @@ void ChainstateManager::CheckBlockIndex()
52715269
if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = nullptr;
52725270
if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = nullptr;
52735271
if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = nullptr;
5274-
if (pindex == pindexFirstAssumeValid) pindexFirstAssumeValid = nullptr;
52755272
// Find our parent.
52765273
CBlockIndex* pindexPar = pindex->pprev;
52775274
// Find which child we just visited.
@@ -5757,22 +5754,14 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
57575754
// Fake various pieces of CBlockIndex state:
57585755
CBlockIndex* index = nullptr;
57595756

5760-
// Don't make any modifications to the genesis block.
5761-
// This is especially important because we don't want to erroneously
5762-
// apply BLOCK_ASSUMED_VALID to genesis, which would happen if we didn't skip
5763-
// it here (since it apparently isn't BLOCK_VALID_SCRIPTS).
5757+
// Don't make any modifications to the genesis block since it shouldn't be
5758+
// neccessary, and since the genesis block doesn't have normal flags like
5759+
// BLOCK_VALID_SCRIPTS set.
57645760
constexpr int AFTER_GENESIS_START{1};
57655761

57665762
for (int i = AFTER_GENESIS_START; i <= snapshot_chainstate.m_chain.Height(); ++i) {
57675763
index = snapshot_chainstate.m_chain[i];
57685764

5769-
// Mark unvalidated block index entries beneath the snapshot base block as assumed-valid.
5770-
if (!index->IsValid(BLOCK_VALID_SCRIPTS)) {
5771-
// This flag will be removed once the block is fully validated by a
5772-
// background chainstate.
5773-
index->nStatus |= BLOCK_ASSUMED_VALID;
5774-
}
5775-
57765765
// Fake BLOCK_OPT_WITNESS so that Chainstate::NeedsRedownload()
57775766
// won't ask to rewind the entire assumed-valid chain on startup.
57785767
if (DeploymentActiveAt(*index, *this, Consensus::DEPLOYMENT_SEGWIT)) {

src/validation.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,10 @@ class Chainstate
583583
const CBlockIndex* SnapshotBase() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
584584

585585
/**
586-
* The set of all CBlockIndex entries with either BLOCK_VALID_TRANSACTIONS (for
587-
* itself and all ancestors) *or* BLOCK_ASSUMED_VALID (if using background
588-
* chainstates) and as good as our current tip or better. Entries may be failed,
586+
* The set of all CBlockIndex entries that have as much work as our current
587+
* tip or more, and transaction data needed to be validated (with
588+
* BLOCK_VALID_TRANSACTIONS for each block and its parents back to the
589+
* genesis block or an assumeutxo snapshot block). Entries may be failed,
589590
* though, and pruning nodes may be missing the data for the block.
590591
*/
591592
std::set<CBlockIndex*, node::CBlockIndexWorkComparator> setBlockIndexCandidates;

0 commit comments

Comments
 (0)