Auto merge of #4770 - nuttycom:fastsync, r=nuttycom
Add -ibdskiptxverification flag to allow faster synchronization. Subsumes #4037
This commit is contained in:
commit
b076c8dfc5
|
@ -78,4 +78,12 @@ namespace Checkpoints {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool IsAncestorOfLastCheckpoint(const CCheckpointData& data, const CBlockIndex* pindex)
|
||||
{
|
||||
CBlockIndex *pindexLastCheckpoint = GetLastCheckpoint(data);
|
||||
return pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Checkpoints
|
||||
|
|
|
@ -27,6 +27,7 @@ CBlockIndex* GetLastCheckpoint(const CCheckpointData& data);
|
|||
|
||||
double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true);
|
||||
|
||||
bool IsAncestorOfLastCheckpoint(const CCheckpointData& data, const CBlockIndex* pindex);
|
||||
} //namespace Checkpoints
|
||||
|
||||
#endif // BITCOIN_CHECKPOINTS_H
|
||||
|
|
|
@ -32,7 +32,7 @@ TEST(CheckBlock, VersionTooLow) {
|
|||
|
||||
MockCValidationState state;
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "version-too-low", false)).Times(1);
|
||||
EXPECT_FALSE(CheckBlock(block, state, Params(), verifier, false, false));
|
||||
EXPECT_FALSE(CheckBlock(block, state, Params(), verifier, false, false, true));
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +65,7 @@ TEST(CheckBlock, BlockSproutRejectsBadVersion) {
|
|||
auto verifier = ProofVerifier::Strict();
|
||||
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1);
|
||||
EXPECT_FALSE(CheckBlock(block, state, Params(), verifier, false, false));
|
||||
EXPECT_FALSE(CheckBlock(block, state, Params(), verifier, false, false, true));
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,7 +119,7 @@ protected:
|
|||
|
||||
// We now expect this to be a valid block.
|
||||
MockCValidationState state;
|
||||
EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), &indexPrev));
|
||||
EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), &indexPrev, true));
|
||||
}
|
||||
|
||||
// Expects a height-1 block containing a given transaction to fail
|
||||
|
@ -137,7 +137,7 @@ protected:
|
|||
// We now expect this to be an invalid block, for the given reason.
|
||||
MockCValidationState state;
|
||||
EXPECT_CALL(state, DoS(level, false, REJECT_INVALID, reason, false)).Times(1);
|
||||
EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev));
|
||||
EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev, true));
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -154,7 +154,7 @@ TEST_F(ContextualCheckBlockTest, BadCoinbaseHeight) {
|
|||
|
||||
// Treating block as genesis should pass
|
||||
MockCValidationState state;
|
||||
EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), NULL));
|
||||
EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), NULL, true));
|
||||
|
||||
// Give the transaction a Founder's Reward vout
|
||||
mtx.vout.push_back(CTxOut(
|
||||
|
@ -168,20 +168,20 @@ TEST_F(ContextualCheckBlockTest, BadCoinbaseHeight) {
|
|||
CBlockIndex indexPrev {prev};
|
||||
indexPrev.nHeight = 0;
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-height", false)).Times(1);
|
||||
EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev));
|
||||
EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev, true));
|
||||
|
||||
// Setting to an incorrect height should fail
|
||||
mtx.vin[0].scriptSig = CScript() << 2 << OP_0;
|
||||
CTransaction tx3 {mtx};
|
||||
block.vtx[0] = tx3;
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-height", false)).Times(1);
|
||||
EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev));
|
||||
EXPECT_FALSE(ContextualCheckBlock(block, state, Params(), &indexPrev, true));
|
||||
|
||||
// After correcting the scriptSig, should pass
|
||||
mtx.vin[0].scriptSig = CScript() << 1 << OP_0;
|
||||
CTransaction tx4 {mtx};
|
||||
block.vtx[0] = tx4;
|
||||
EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), &indexPrev));
|
||||
EXPECT_TRUE(ContextualCheckBlock(block, state, Params(), &indexPrev, true));
|
||||
}
|
||||
|
||||
// TEST PLAN: first, check that each ruleset accepts its own transaction type.
|
||||
|
|
10
src/init.cpp
10
src/init.cpp
|
@ -343,6 +343,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
|
||||
strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf(_("Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s)"), DEFAULT_DEBUGLOGFILE));
|
||||
strUsage += HelpMessageOpt("-exportdir=<dir>", _("Specify directory to be used when exporting data"));
|
||||
strUsage += HelpMessageOpt("-ibdskiptxverification", strprintf(_("Skip transaction verification during initial block download up to the last checkpoint height. Incompatible with flags that disable checkpoints. (default = %u)"), DEFAULT_IBD_SKIP_TX_VERIFICATION));
|
||||
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
|
||||
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
|
||||
strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
|
||||
|
@ -923,6 +924,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
#endif
|
||||
}
|
||||
|
||||
// ensure that the user has not disabled checkpoints when requesting to
|
||||
// skip transaction verification in initial block download.
|
||||
if (GetBoolArg("-ibdskiptxverification", DEFAULT_IBD_SKIP_TX_VERIFICATION)) {
|
||||
if (!GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED)) {
|
||||
return InitError(_("-ibdskiptxverification requires checkpoints to be enabled; it is incompatible with flags that disable checkpoints"));
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************* Step 3: parameter-to-internal-flags
|
||||
|
||||
fDebug = !mapMultiArgs["-debug"].empty();
|
||||
|
@ -964,6 +973,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
mempool.SetMempoolCostLimit(mempoolTotalCostLimit, mempoolEvictionMemorySeconds);
|
||||
|
||||
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
|
||||
fIBDSkipTxVerification = GetBoolArg("-ibdskiptxverification", DEFAULT_IBD_SKIP_TX_VERIFICATION);
|
||||
fCheckpointsEnabled = GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED);
|
||||
|
||||
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
|
||||
|
|
97
src/main.cpp
97
src/main.cpp
|
@ -80,6 +80,7 @@ bool fPruneMode = false;
|
|||
bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
|
||||
bool fCheckBlockIndex = false;
|
||||
bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
|
||||
bool fIBDSkipTxVerification = DEFAULT_IBD_SKIP_TX_VERIFICATION;
|
||||
bool fCoinbaseEnforcedShieldingEnabled = true;
|
||||
size_t nCoinCacheUsage = 5000 * 300;
|
||||
uint64_t nPruneTarget = 0;
|
||||
|
@ -2696,25 +2697,42 @@ static int64_t nTimeIndex = 0;
|
|||
static int64_t nTimeCallbacks = 0;
|
||||
static int64_t nTimeTotal = 0;
|
||||
|
||||
/**
|
||||
* Determine whether to do transaction checks when verifying blocks.
|
||||
* Returns `false` (allowing transaction checks to be skipped) only if all
|
||||
* of the following are true:
|
||||
* - we're currently in initial block download
|
||||
* - the `-ibdskiptxverification` flag is set
|
||||
* - the block under inspection is an ancestor of the latest checkpoint.
|
||||
*/
|
||||
static bool ShouldCheckTransactions(const CChainParams& chainparams, const CBlockIndex* pindex) {
|
||||
return !(IsInitialBlockDownload(chainparams)
|
||||
&& fIBDSkipTxVerification
|
||||
&& fCheckpointsEnabled
|
||||
&& Checkpoints::IsAncestorOfLastCheckpoint(chainparams.Checkpoints(), pindex));
|
||||
}
|
||||
|
||||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex,
|
||||
CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
bool fExpensiveChecks = true;
|
||||
if (fCheckpointsEnabled) {
|
||||
CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
|
||||
if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
|
||||
// This block is an ancestor of a checkpoint: disable script checks
|
||||
|
||||
// If this block is an ancestor of a checkpoint, disable expensive checks
|
||||
if (fCheckpointsEnabled && Checkpoints::IsAncestorOfLastCheckpoint(chainparams.Checkpoints(), pindex)) {
|
||||
fExpensiveChecks = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto verifier = ProofVerifier::Strict();
|
||||
auto disabledVerifier = ProofVerifier::Disabled();
|
||||
// proof verification is expensive, disable if possible
|
||||
auto verifier = fExpensiveChecks ? ProofVerifier::Strict() : ProofVerifier::Disabled();
|
||||
|
||||
// If in initial block download, and this block is an ancestor of a checkpoint,
|
||||
// and -ibdskiptxverification is set, disable all transaction checks.
|
||||
bool fCheckTransactions = ShouldCheckTransactions(chainparams, pindex);
|
||||
|
||||
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
|
||||
if (!CheckBlock(block, state, chainparams, fExpensiveChecks ? verifier : disabledVerifier, !fJustCheck, !fJustCheck))
|
||||
if (!CheckBlock(block, state, chainparams, verifier, !fJustCheck, !fJustCheck, fCheckTransactions))
|
||||
return false;
|
||||
|
||||
// verify that the view's current state corresponds to the previous block
|
||||
|
@ -4013,10 +4031,13 @@ bool CheckBlockHeader(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state,
|
||||
bool CheckBlock(const CBlock& block,
|
||||
CValidationState& state,
|
||||
const CChainParams& chainparams,
|
||||
ProofVerifier& verifier,
|
||||
bool fCheckPOW, bool fCheckMerkleRoot)
|
||||
bool fCheckPOW,
|
||||
bool fCheckMerkleRoot,
|
||||
bool fCheckTransactions)
|
||||
{
|
||||
// These are checks that are independent of context.
|
||||
|
||||
|
@ -4059,6 +4080,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state,
|
|||
return state.DoS(100, error("CheckBlock(): more than one coinbase"),
|
||||
REJECT_INVALID, "bad-cb-multiple");
|
||||
|
||||
// skip all transaction checks if this flag is not set
|
||||
if (!fCheckTransactions) return true;
|
||||
|
||||
// Check transactions
|
||||
BOOST_FOREACH(const CTransaction& tx, block.vtx)
|
||||
if (!CheckTransaction(tx, state, verifier))
|
||||
|
@ -4144,11 +4168,13 @@ bool ContextualCheckBlockHeader(
|
|||
|
||||
bool ContextualCheckBlock(
|
||||
const CBlock& block, CValidationState& state,
|
||||
const CChainParams& chainparams, CBlockIndex * const pindexPrev)
|
||||
const CChainParams& chainparams, CBlockIndex * const pindexPrev,
|
||||
bool fCheckTransactions)
|
||||
{
|
||||
const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
|
||||
const Consensus::Params& consensusParams = chainparams.GetConsensus();
|
||||
|
||||
if (fCheckTransactions) {
|
||||
// Check that all transactions are finalized
|
||||
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
|
||||
|
||||
|
@ -4166,6 +4192,7 @@ bool ContextualCheckBlock(
|
|||
REJECT_INVALID, "bad-txns-nonfinal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce BIP 34 rule that the coinbase starts with serialized block height.
|
||||
// In Zcash this has been enforced since launch, except that the genesis
|
||||
|
@ -4258,10 +4285,11 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
|
|||
|
||||
/**
|
||||
* Store block on disk.
|
||||
* JoinSplit proofs are never verified, because:
|
||||
* - AcceptBlock doesn't perform script checks either.
|
||||
* - The only caller of AcceptBlock verifies JoinSplit proofs elsewhere.
|
||||
* If dbp is non-NULL, the file is known to already reside on disk
|
||||
* If dbp is non-NULL, the file is known to already reside on disk.
|
||||
*
|
||||
* JoinSplit proofs are not verified here; the only caller of AcceptBlock
|
||||
* (ProcessNewBlock) later invokes ActivateBestChain, which ultimately calls
|
||||
* ConnectBlock in a manner that can verify the proofs
|
||||
*/
|
||||
static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
|
||||
{
|
||||
|
@ -4293,9 +4321,11 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
|
|||
if (fTooFarAhead) return true; // Block height is too high
|
||||
}
|
||||
|
||||
// See method docstring for why this is always disabled
|
||||
// See method docstring for why this is always disabled.
|
||||
auto verifier = ProofVerifier::Disabled();
|
||||
if ((!CheckBlock(block, state, chainparams, verifier)) || !ContextualCheckBlock(block, state, chainparams, pindex->pprev)) {
|
||||
bool fCheckTransactions = ShouldCheckTransactions(chainparams, pindex);
|
||||
if ((!CheckBlock(block, state, chainparams, verifier, true, true, fCheckTransactions)) ||
|
||||
!ContextualCheckBlock(block, state, chainparams, pindex->pprev, fCheckTransactions)) {
|
||||
if (state.IsInvalid() && !state.CorruptionPossible()) {
|
||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||
setDirtyBlockIndex.insert(pindex);
|
||||
|
@ -4346,17 +4376,9 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
|
|||
auto span = TracingSpan("info", "main", "ProcessNewBlock");
|
||||
auto spanGuard = span.Enter();
|
||||
|
||||
// Preliminary checks
|
||||
auto verifier = ProofVerifier::Disabled();
|
||||
bool checked = CheckBlock(*pblock, state, chainparams, verifier);
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
bool fRequested = MarkBlockAsReceived(pblock->GetHash());
|
||||
fRequested |= fForceProcessing;
|
||||
if (!checked) {
|
||||
return error("%s: CheckBlock FAILED", __func__);
|
||||
}
|
||||
bool fRequested = MarkBlockAsReceived(pblock->GetHash()) | fForceProcessing;
|
||||
|
||||
// Store to disk
|
||||
CBlockIndex *pindex = NULL;
|
||||
|
@ -4375,6 +4397,9 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only invoked by the miner. fCheckPOW is always false.
|
||||
*/
|
||||
bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
@ -4390,9 +4415,10 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
|
|||
// NOTE: CheckBlockHeader is called by CheckBlock
|
||||
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev))
|
||||
return false;
|
||||
if (!CheckBlock(block, state, chainparams, verifier, fCheckPOW, fCheckMerkleRoot))
|
||||
// The following may be duplicative of the `CheckBlock` call within `ConnectBlock`
|
||||
if (!CheckBlock(block, state, chainparams, verifier, fCheckPOW, fCheckMerkleRoot, true))
|
||||
return false;
|
||||
if (!ContextualCheckBlock(block, state, chainparams, pindexPrev))
|
||||
if (!ContextualCheckBlock(block, state, chainparams, pindexPrev, true))
|
||||
return false;
|
||||
if (!ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true))
|
||||
return false;
|
||||
|
@ -4784,21 +4810,28 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
|
|||
CBlockIndex* pindexFailure = NULL;
|
||||
int nGoodTransactions = 0;
|
||||
CValidationState state;
|
||||
// No need to verify JoinSplits twice
|
||||
auto verifier = ProofVerifier::Disabled();
|
||||
|
||||
// Flags used to permit skipping checks for efficiency
|
||||
auto verifier = ProofVerifier::Disabled(); // No need to verify JoinSplits twice
|
||||
bool fCheckTransactions = true;
|
||||
|
||||
for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
|
||||
if (pindex->nHeight < chainActive.Height()-nCheckDepth)
|
||||
break;
|
||||
|
||||
CBlock block;
|
||||
// check level 0: read from disk
|
||||
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
|
||||
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
|
||||
// check level 1: verify block validity
|
||||
if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams, verifier))
|
||||
fCheckTransactions = ShouldCheckTransactions(chainparams, pindex);
|
||||
if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams, verifier, true, true, fCheckTransactions))
|
||||
return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
|
||||
// check level 2: verify undo validity
|
||||
if (nCheckLevel >= 2 && pindex) {
|
||||
CBlockUndo undo;
|
||||
|
@ -4808,6 +4841,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
|
|||
return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
|
||||
if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
|
||||
// insightexplorer: do not update indices (false)
|
||||
|
@ -4823,6 +4857,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
|
|||
nGoodTransactions += block.vtx.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (ShutdownRequested())
|
||||
return true;
|
||||
}
|
||||
|
|
12
src/main.h
12
src/main.h
|
@ -113,6 +113,7 @@ static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
|
|||
/** Default for -permitbaremultisig */
|
||||
static const bool DEFAULT_PERMIT_BAREMULTISIG = true;
|
||||
static const bool DEFAULT_CHECKPOINTS_ENABLED = true;
|
||||
static const bool DEFAULT_IBD_SKIP_TX_VERIFICATION = false;
|
||||
static const bool DEFAULT_TXINDEX = false;
|
||||
static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100;
|
||||
|
||||
|
@ -164,6 +165,7 @@ extern bool fTimestampIndex;
|
|||
extern bool fIsBareMultisigStd;
|
||||
extern bool fCheckBlockIndex;
|
||||
extern bool fCheckpointsEnabled;
|
||||
extern bool fIBDSkipTxVerification;
|
||||
// TODO: remove this flag by structuring our code such that
|
||||
// it is unneeded for testing
|
||||
extern bool fCoinbaseEnforcedShieldingEnabled;
|
||||
|
@ -447,13 +449,17 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus
|
|||
/** Functions for validating blocks and updating the block tree */
|
||||
|
||||
/** Context-independent validity checks */
|
||||
|
||||
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state,
|
||||
const CChainParams& chainparams,
|
||||
bool fCheckPOW = true);
|
||||
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state,
|
||||
const CChainParams& chainparams,
|
||||
ProofVerifier& verifier,
|
||||
bool fCheckPOW = true, bool fCheckMerkleRoot = true);
|
||||
bool fCheckPOW,
|
||||
bool fCheckMerkleRoot,
|
||||
bool fCheckTransactions);
|
||||
|
||||
/** Context-dependent validity checks.
|
||||
* By "context", we mean only the previous block headers, but not the UTXO
|
||||
|
@ -461,7 +467,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state,
|
|||
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state,
|
||||
const CChainParams& chainparams, CBlockIndex *pindexPrev);
|
||||
bool ContextualCheckBlock(const CBlock& block, CValidationState& state,
|
||||
const CChainParams& chainparams, CBlockIndex *pindexPrev);
|
||||
const CChainParams& chainparams,
|
||||
CBlockIndex *pindexPrev,
|
||||
bool fCheckTransactions);
|
||||
|
||||
/** Apply the effects of this block (with given index) on the UTXO set represented by coins.
|
||||
* Validity checks that depend on the UTXO set are also done; ConnectBlock()
|
||||
|
|
|
@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE(May15)
|
|||
// After May 15'th, big blocks are OK:
|
||||
forkingBlock.nTime = tMay15; // Invalidates PoW
|
||||
auto verifier = ProofVerifier::Strict();
|
||||
BOOST_CHECK(CheckBlock(forkingBlock, state, Params(), verifier, false, false));
|
||||
BOOST_CHECK(CheckBlock(forkingBlock, state, Params(), verifier, false, false, true));
|
||||
}
|
||||
|
||||
SetMockTime(0);
|
||||
|
|
Loading…
Reference in New Issue