Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 851 Lines • ▼ Show 20 Lines | // Check for conflicts with in-memory transactions | ||||
std::string errString; | std::string errString; | ||||
if (!pool.CalculateMemPoolAncestors( | if (!pool.CalculateMemPoolAncestors( | ||||
entry, setAncestors, nLimitAncestors, nLimitAncestorSize, | entry, setAncestors, nLimitAncestors, nLimitAncestorSize, | ||||
nLimitDescendants, nLimitDescendantSize, errString)) { | nLimitDescendants, nLimitDescendantSize, errString)) { | ||||
return state.DoS(0, false, REJECT_NONSTANDARD, | return state.DoS(0, false, REJECT_NONSTANDARD, | ||||
"too-long-mempool-chain", false, errString); | "too-long-mempool-chain", false, errString); | ||||
} | } | ||||
unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; | uint32_t scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; | ||||
if (!Params().RequireStandard()) { | if (!Params().RequireStandard()) { | ||||
scriptVerifyFlags = | scriptVerifyFlags = | ||||
GetArg("-promiscuousmempoolflags", scriptVerifyFlags); | GetArg("-promiscuousmempoolflags", scriptVerifyFlags); | ||||
} | } | ||||
if (IsUAHFenabledForCurrentBlock(config)) { | const bool hasUAHF = IsUAHFenabledForCurrentBlock(config); | ||||
if (hasUAHF) { | |||||
scriptVerifyFlags |= SCRIPT_ENABLE_SIGHASH_FORKID; | scriptVerifyFlags |= SCRIPT_ENABLE_SIGHASH_FORKID; | ||||
} | } | ||||
// Check against previous transactions. This is done last to help | // Check against previous transactions. This is done last to help | ||||
// prevent CPU exhaustion denial-of-service attacks. | // prevent CPU exhaustion denial-of-service attacks. | ||||
PrecomputedTransactionData txdata(tx); | PrecomputedTransactionData txdata(tx); | ||||
if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, | if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, | ||||
txdata)) { | txdata)) { | ||||
// State filled in by CheckInputs. | // State filled in by CheckInputs. | ||||
return false; | return false; | ||||
} | } | ||||
// Check again against just the consensus-critical mandatory script | // Check again against just the consensus-critical mandatory script | ||||
// verification flags, in case of bugs in the standard flags that cause | // verification flags, in case of bugs in the standard flags that cause | ||||
// transactions to pass as valid when they're actually invalid. For | // transactions to pass as valid when they're actually invalid. For | ||||
// instance the STRICTENC flag was incorrectly allowing certain | // instance the STRICTENC flag was incorrectly allowing certain | ||||
// CHECKSIG NOT scripts to pass, even though they were invalid. | // CHECKSIG NOT scripts to pass, even though they were invalid. | ||||
// | // | ||||
// There is a similar check in CreateNewBlock() to prevent creating | // There is a similar check in CreateNewBlock() to prevent creating | ||||
// invalid blocks, however allowing such transactions into the mempool | // invalid blocks, however allowing such transactions into the mempool | ||||
// can be exploited as a DoS attack. | // can be exploited as a DoS attack. | ||||
// | // | ||||
// SCRIPT_ENABLE_SIGHASH_FORKID is also added as to ensure we do not | // SCRIPT_ENABLE_SIGHASH_FORKID is also added as to ensure we do not | ||||
// filter out transactions using the antireplay feature. | // filter out transactions using the antireplay feature. | ||||
if (!CheckInputs(tx, state, view, true, | { | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS | | // Depending on the UAHF activation, we require SIGHASH_FORKID or | ||||
SCRIPT_ENABLE_SIGHASH_FORKID, | // not. | ||||
true, txdata)) { | // TODO: Cleanup after the Hard Fork. | ||||
return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed " | uint32_t mandatoryFlags = MANDATORY_SCRIPT_VERIFY_FLAGS; | ||||
if (hasUAHF) { | |||||
mandatoryFlags |= SCRIPT_ENABLE_SIGHASH_FORKID; | |||||
} | |||||
if (!CheckInputs(tx, state, view, true, mandatoryFlags, true, | |||||
txdata)) { | |||||
return error( | |||||
"%s: BUG! PLEASE REPORT THIS! ConnectInputs failed " | |||||
"against MANDATORY but not STANDARD flags %s, %s", | "against MANDATORY but not STANDARD flags %s, %s", | ||||
__func__, txid.ToString(), FormatStateMessage(state)); | __func__, txid.ToString(), FormatStateMessage(state)); | ||||
} | } | ||||
} | |||||
// This transaction should only count for fee estimation if | // This transaction should only count for fee estimation if | ||||
// the node is not behind and it is not dependent on any other | // the node is not behind and it is not dependent on any other | ||||
// transactions in the mempool. | // transactions in the mempool. | ||||
bool validForFeeEstimation = | bool validForFeeEstimation = | ||||
IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); | IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); | ||||
// Store transaction in memory. | // Store transaction in memory. | ||||
▲ Show 20 Lines • Show All 953 Lines • ▼ Show 20 Lines | if (fEnforceBIP30) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// BIP16 didn't become active until Apr 1 2012 | // BIP16 didn't become active until Apr 1 2012 | ||||
int64_t nBIP16SwitchTime = 1333238400; | int64_t nBIP16SwitchTime = 1333238400; | ||||
bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime); | bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime); | ||||
unsigned int flags = | uint32_t flags = | ||||
fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; | fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; | ||||
// Start enforcing the DERSIG (BIP66) rule | // Start enforcing the DERSIG (BIP66) rule | ||||
if (pindex->nHeight >= chainparams.GetConsensus().BIP66Height) { | if (pindex->nHeight >= chainparams.GetConsensus().BIP66Height) { | ||||
flags |= SCRIPT_VERIFY_DERSIG; | flags |= SCRIPT_VERIFY_DERSIG; | ||||
} | } | ||||
// Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule | // Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule | ||||
if (pindex->nHeight >= chainparams.GetConsensus().BIP65Height) { | if (pindex->nHeight >= chainparams.GetConsensus().BIP65Height) { | ||||
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; | flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; | ||||
} | } | ||||
// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) | // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) | ||||
// using versionbits logic. | // using versionbits logic. | ||||
int nLockTimeFlags = 0; | int nLockTimeFlags = 0; | ||||
if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), | if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), | ||||
Consensus::DEPLOYMENT_CSV, | Consensus::DEPLOYMENT_CSV, | ||||
versionbitscache) == THRESHOLD_ACTIVE) { | versionbitscache) == THRESHOLD_ACTIVE) { | ||||
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; | flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; | ||||
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; | nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; | ||||
} | } | ||||
// If the UAHF is enabled, we start accepting replay protected txns | // If the UAHF is enabled, we start accepting replay protected txns | ||||
if (IsUAHFenabled(config, pindex->pprev)) { | const bool hasUAHF = IsUAHFenabled(config, pindex->pprev); | ||||
if (hasUAHF) { | |||||
flags |= SCRIPT_VERIFY_STRICTENC; | |||||
flags |= SCRIPT_ENABLE_SIGHASH_FORKID; | flags |= SCRIPT_ENABLE_SIGHASH_FORKID; | ||||
} | } | ||||
int64_t nTime2 = GetTimeMicros(); | int64_t nTime2 = GetTimeMicros(); | ||||
nTimeForks += nTime2 - nTime1; | nTimeForks += nTime2 - nTime1; | ||||
LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", | LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", | ||||
0.001 * (nTime2 - nTime1), nTimeForks * 0.000001); | 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001); | ||||
▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | static bool ConnectBlock(const Config &config, const CBlock &block, | ||||
GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); | GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); | ||||
hashPrevBestCoinBase = block.vtx[0]->GetId(); | hashPrevBestCoinBase = block.vtx[0]->GetId(); | ||||
int64_t nTime6 = GetTimeMicros(); | int64_t nTime6 = GetTimeMicros(); | ||||
nTimeCallbacks += nTime6 - nTime5; | nTimeCallbacks += nTime6 - nTime5; | ||||
LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", | LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", | ||||
0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001); | 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001); | ||||
// If this block activates UAHF, we clear the mempool. This ensure that | |||||
// we'll only get replay protected transaction in the mempool going forward. | |||||
if (!hasUAHF && IsUAHFenabled(config, pindex)) { | |||||
mempool.clear(); | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Update the on-disk chain state. | * Update the on-disk chain state. | ||||
* The caches and indexes are flushed depending on the mode we're called with | * The caches and indexes are flushed depending on the mode we're called with | ||||
* if they're too large, if it's been a while since the last write, | * if they're too large, if it's been a while since the last write, | ||||
* or always and in all cases if we're in prune mode and are deleting files. | * or always and in all cases if we're in prune mode and are deleting files. | ||||
▲ Show 20 Lines • Show All 2,902 Lines • Show Last 20 Lines |