Auto merge of #4770 - nuttycom:fastsync, r=nuttycom

Add -ibdskiptxverification flag to allow faster synchronization.

Subsumes #4037
This commit is contained in:
Homu 2020-10-13 13:54:05 +00:00
commit b076c8dfc5
7 changed files with 131 additions and 69 deletions

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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)"),
@ -420,13 +421,13 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-nuparams=hexBranchId:activationHeight", "Use given activation height for specified network upgrade (regtest-only)");
strUsage += HelpMessageOpt("-nurejectoldversions", strprintf("Reject peers that don't know about the current epoch (regtest-only) (default: %u)", DEFAULT_NU_REJECT_OLD_VERSIONS));
strUsage += HelpMessageOpt(
"-fundingstream=streamId:startHeight:endHeight:comma_delimited_addresses",
"-fundingstream=streamId:startHeight:endHeight:comma_delimited_addresses",
"Use given addresses for block subsidy share paid to the funding stream with id <streamId> (regtest-only)");
}
string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, "
"rand, receiveunsafe, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + " " + _("<category> can be:") + " " + debugCategories + ". " +
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + " " + _("<category> can be:") + " " + debugCategories + ". " +
_("For multiple specific categories use -debug=<category> multiple times."));
strUsage += HelpMessageOpt("-experimentalfeatures", _("Enable use of experimental features"));
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
@ -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
@ -1106,8 +1116,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError("Funding stream parameters malformed, expecting streamId:startHeight:endHeight:comma_delimited_addresses");
}
int nFundingStreamId;
if (!ParseInt32(vStreamParams[0], &nFundingStreamId) ||
nFundingStreamId < Consensus::FIRST_FUNDING_STREAM ||
if (!ParseInt32(vStreamParams[0], &nFundingStreamId) ||
nFundingStreamId < Consensus::FIRST_FUNDING_STREAM ||
nFundingStreamId >= Consensus::MAX_FUNDING_STREAMS) {
return InitError(strprintf("Invalid streamId (%s)", vStreamParams[0]));
}

View File

@ -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
fExpensiveChecks = false;
}
// 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,26 +4168,29 @@ 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();
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
if (fCheckTransactions) {
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
// Check transaction contextually against consensus rules at block height
if (!ContextualCheckTransaction(tx, state, chainparams, nHeight, true)) {
return false; // Failure reason has been set in validation state object
}
// Check transaction contextually against consensus rules at block height
if (!ContextualCheckTransaction(tx, state, chainparams, nHeight, true)) {
return false; // Failure reason has been set in validation state object
}
int nLockTimeFlags = 0;
int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
? pindexPrev->GetMedianTimePast()
: block.GetBlockTime();
if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
return state.DoS(10, error("%s: contains a non-final transaction", __func__),
REJECT_INVALID, "bad-txns-nonfinal");
int nLockTimeFlags = 0;
int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
? pindexPrev->GetMedianTimePast()
: block.GetBlockTime();
if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
return state.DoS(10, error("%s: contains a non-final transaction", __func__),
REJECT_INVALID, "bad-txns-nonfinal");
}
}
}
@ -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;
}

View File

@ -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;
@ -210,11 +212,11 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals);
/** Unregister a network node */
void UnregisterNodeSignals(CNodeSignals& nodeSignals);
/**
/**
* Process an incoming block. This only returns after the best known valid
* block is made active. Note that it does not, however, guarantee that the
* specific block passed to it has been checked for validity!
*
*
* @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation.
* @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
* @param[in] pblock The block we want to process.
@ -311,7 +313,7 @@ struct CNodeStateStats {
CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree);
/**
/**
* Count ECDSA signature operations the old-fashioned (pre-0.6) way
* @return number of sigops this transaction's outputs will produce when spent
* @see CTransaction::FetchInputs
@ -320,7 +322,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx);
/**
* Count ECDSA signature operations in pay-to-script-hash inputs.
*
*
* @param[in] mapInputs Map of previous transactions that have outputs we're spending
* @return maximum number of sigops required to validate this transaction's inputs
* @see CTransaction::FetchInputs
@ -390,9 +392,9 @@ bool IsExpiringSoonTx(const CTransaction &tx, int nNextBlockHeight);
*/
bool CheckFinalTx(const CTransaction &tx, int flags = -1);
/**
/**
* Closure representing one script verification
* Note that this stores references to the spending transaction
* Note that this stores references to the spending transaction
*/
class CScriptCheck
{
@ -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()
@ -469,9 +477,9 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state,
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins,
const CChainParams& chainparams, bool fJustCheck = false);
/**
/**
* Check a block is completely valid from start to finish (only works on top
* of our current best block, with cs_main held)
* of our current best block, with cs_main held)
*/
bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
@ -521,7 +529,7 @@ int GetSpendHeight(const CCoinsViewCache& inputs);
uint64_t CalculateCurrentUsage();
/**
/**
* Return a CMutableTransaction with contextual default values based on set of consensus rules at nHeight. The expiryDelta will
* either be based on the command-line argument '-txexpirydelta' or derived from consensusParams.
*/

View File

@ -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);