Page MenuHomePhabricator

D12279.id35836.diff
No OneTemporary

D12279.id35836.diff

diff --git a/src/blockindex.h b/src/blockindex.h
--- a/src/blockindex.h
+++ b/src/blockindex.h
@@ -205,6 +205,10 @@
return nStatus.isValid(nUpTo);
}
+ //! @returns true if the block is assumed-valid; this means it is queued
+ //! to be validated by a background chainstate.
+ bool IsAssumedValid() const { return nStatus.isAssumedValid(); }
+
//! Raise the validity level of this block index entry.
//! Returns true if the validity was changed.
bool RaiseValidity(enum BlockValidity nUpTo) {
@@ -217,6 +221,12 @@
return false;
}
+ // 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 (IsAssumedValid() && nUpTo >= BlockValidity::SCRIPTS) {
+ nStatus = nStatus.withClearedAssumedValidFlags();
+ }
+
nStatus = nStatus.withValidity(nUpTo);
return true;
}
diff --git a/src/blockstatus.h b/src/blockstatus.h
--- a/src/blockstatus.h
+++ b/src/blockstatus.h
@@ -40,6 +40,14 @@
// Mask used to check for parked blocks.
static const uint32_t PARKED_MASK = PARKED_FLAG | PARKED_PARENT_FLAG;
+ /**
+ * 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.
+ */
+ static const uint32_t ASSUMED_VALID_FLAG = 0x200;
+
public:
explicit constexpr BlockStatus() : status(0) {}
@@ -99,6 +107,15 @@
return getValidity() >= nUpTo;
}
+ bool isAssumedValid() const { return status & ASSUMED_VALID_FLAG; }
+ BlockStatus withAssumedValid(bool assumed_valid = true) const {
+ return BlockStatus((status & ~ASSUMED_VALID_FLAG) |
+ (assumed_valid ? ASSUMED_VALID_FLAG : 0));
+ }
+ BlockStatus withClearedAssumedValidFlags() const {
+ return BlockStatus(status & ~ASSUMED_VALID_FLAG);
+ }
+
bool isInvalid() const { return status & INVALID_MASK; }
BlockStatus withClearedFailureFlags() const {
return BlockStatus(status & ~INVALID_MASK);
diff --git a/src/test/blockindex_tests.cpp b/src/test/blockindex_tests.cpp
--- a/src/test/blockindex_tests.cpp
+++ b/src/test/blockindex_tests.cpp
@@ -420,4 +420,47 @@
}
}
+BOOST_AUTO_TEST_CASE(index_assumevalid_tests) {
+ CBlockIndex index;
+
+ // Test against all validity values
+ std::set<BlockValidity> validityValues{
+ BlockValidity::UNKNOWN, BlockValidity::RESERVED,
+ BlockValidity::TREE, BlockValidity::TRANSACTIONS,
+ BlockValidity::CHAIN, BlockValidity::SCRIPTS};
+ std::set<bool> boolValues = {false, true};
+ for (BlockValidity validityFrom : validityValues) {
+ for (bool withAssumedValid : boolValues) {
+ index.nStatus = BlockStatus()
+ .withValidity(validityFrom)
+ .withAssumedValid(withAssumedValid);
+ BOOST_CHECK_EQUAL(index.nStatus.isAssumedValid(),
+ index.IsAssumedValid());
+ BOOST_CHECK_EQUAL(index.IsAssumedValid(), withAssumedValid);
+
+ for (BlockValidity validityUpTo : validityValues) {
+ // Test RaiseValidity()
+ bool raisedValidity = index.RaiseValidity(validityUpTo);
+ if (validityFrom < validityUpTo) {
+ BOOST_CHECK(raisedValidity);
+ BOOST_CHECK_EQUAL(index.nStatus.getValidity(),
+ validityUpTo);
+ if (validityUpTo < BlockValidity::SCRIPTS) {
+ BOOST_CHECK_EQUAL(index.IsAssumedValid(),
+ withAssumedValid);
+ } else {
+ // If a block had been marked assumed-valid and
+ // we're raising its validity to a certain point,
+ // there is no longer an assumption.
+ BOOST_CHECK(!index.IsAssumedValid());
+ }
+ } else {
+ // Validity not raised, so no change to assumed-validity
+ BOOST_CHECK(!raisedValidity);
+ BOOST_CHECK_EQUAL(index.IsAssumedValid(), withAssumedValid);
+ }
+ }
+ }
+ }
+}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/fuzz/chain.cpp b/src/test/fuzz/chain.cpp
--- a/src/test/fuzz/chain.cpp
+++ b/src/test/fuzz/chain.cpp
@@ -59,6 +59,7 @@
bool has_failed_parent = fuzzed_data_provider.ConsumeBool();
bool is_parked = fuzzed_data_provider.ConsumeBool();
bool has_parked_parent = fuzzed_data_provider.ConsumeBool();
+ bool is_assumed_valid = fuzzed_data_provider.ConsumeBool();
const BlockStatus block_status =
base.withValidity(block_validity)
.withData(has_data)
@@ -66,7 +67,8 @@
.withFailed(has_failed)
.withFailedParent(has_failed_parent)
.withParked(is_parked)
- .withParkedParent(has_parked_parent);
+ .withParkedParent(has_parked_parent)
+ .withAssumedValid(is_assumed_valid);
assert(block_status.hasData() == has_data);
assert(block_status.hasUndo() == has_undo);
@@ -74,6 +76,7 @@
assert(block_status.hasFailedParent() == has_failed_parent);
assert(block_status.isParked() == is_parked);
assert(block_status.hasParkedParent() == has_parked_parent);
+ assert(block_status.isAssumedValid() == is_assumed_valid);
assert(block_status.isInvalid() == has_failed || has_failed_parent);
const BlockStatus valid_block = block_status.withClearedFailureFlags();
@@ -85,6 +88,10 @@
block_status.withClearedParkedFlags();
assert(!unparked_block.isOnParkedChain());
+ const BlockStatus unassumed_valid_block =
+ block_status.withClearedAssumedValidFlags();
+ assert(!unassumed_valid_block.isAssumedValid());
+
if (!block_status.isValid()) {
continue;
}
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -6091,6 +6091,21 @@
}
index->nChainTx =
index->pprev ? index->pprev->nChainTx + index->nTx : 1;
+
+ // Mark unvalidated block index entries beneath the snapshot base block
+ // as assumed-valid.
+ if (!index->IsValid(BlockValidity::SCRIPTS)) {
+ // This flag will be removed once the block is fully validated by a
+ // background chainstate.
+ index->nStatus = index->nStatus.withAssumedValid();
+ }
+
+ setDirtyBlockIndex.insert(index);
+ // Changes to the block index will be flushed to disk after this call
+ // returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is
+ // called, since we've added a snapshot chainstate and therefore will
+ // have to downsize the IBD chainstate, which will result in a call to
+ // `FlushStateToDisk(ALWAYS)`.
}
assert(index);

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 1, 12:41 (11 m, 27 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5186847
Default Alt Text
D12279.id35836.diff (7 KB)

Event Timeline