Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Copyright (c) 2017 The Bitcoin developers | // Copyright (c) 2017-2018 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "validation.h" | #include "validation.h" | ||||
#include "arith_uint256.h" | #include "arith_uint256.h" | ||||
#include "chainparams.h" | #include "chainparams.h" | ||||
#include "checkpoints.h" | #include "checkpoints.h" | ||||
▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | |||||
static bool FlushStateToDisk(const CChainParams &chainParams, | static bool FlushStateToDisk(const CChainParams &chainParams, | ||||
CValidationState &state, FlushStateMode mode, | CValidationState &state, FlushStateMode mode, | ||||
int nManualPruneHeight = 0); | int nManualPruneHeight = 0); | ||||
static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | ||||
int nManualPruneHeight); | int nManualPruneHeight); | ||||
static void FindFilesToPrune(std::set<int> &setFilesToPrune, | static void FindFilesToPrune(std::set<int> &setFilesToPrune, | ||||
uint64_t nPruneAfterHeight); | uint64_t nPruneAfterHeight); | ||||
static FILE *OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); | static FILE *OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); | ||||
static uint32_t GetBlockScriptFlags(const CBlockIndex *pindex, | uint32_t GetBlockScriptFlags(const CBlockIndex *pindex, | ||||
const Config &config); | const Config &config); | ||||
static bool IsFinalTx(const CTransaction &tx, int nBlockHeight, | static bool IsFinalTx(const CTransaction &tx, int nBlockHeight, | ||||
int64_t nBlockTime) { | int64_t nBlockTime) { | ||||
if (tx.nLockTime == 0) { | if (tx.nLockTime == 0) { | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 782 Lines • ▼ Show 20 Lines | // Check for conflicts with in-memory transactions | ||||
uint32_t scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; | uint32_t scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; | ||||
if (!config.GetChainParams().RequireStandard()) { | if (!config.GetChainParams().RequireStandard()) { | ||||
scriptVerifyFlags = | scriptVerifyFlags = | ||||
SCRIPT_ENABLE_SIGHASH_FORKID | | SCRIPT_ENABLE_SIGHASH_FORKID | | ||||
gArgs.GetArg("-promiscuousmempoolflags", scriptVerifyFlags); | gArgs.GetArg("-promiscuousmempoolflags", scriptVerifyFlags); | ||||
} | } | ||||
if (hasMonolith) { | |||||
scriptVerifyFlags |= SCRIPT_ENABLE_MONOLITH_OPCODES; | |||||
} | |||||
const bool hasReplayProtection = | const bool hasReplayProtection = | ||||
IsReplayProtectionEnabledForCurrentBlock(config); | IsReplayProtectionEnabledForCurrentBlock(config); | ||||
if (hasReplayProtection) { | if (hasReplayProtection) { | ||||
scriptVerifyFlags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | scriptVerifyFlags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | ||||
} | } | ||||
// 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, false, | if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false, | ||||
txdata)) { | txdata)) { | ||||
// State filled in by CheckInputs. | // State filled in by CheckInputs. | ||||
return false; | return false; | ||||
} | } | ||||
// Check again against the current block tip's script verification flags | // Check again against the current block tip's script verification flags | ||||
// to cache our script execution flags. This is, of course, useless if | // to cache our script execution flags. This is, of course, useless if | ||||
▲ Show 20 Lines • Show All 546 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < tx.vin.size(); i++) { | ||||
const Amount amount = coin.GetTxOut().nValue; | const Amount amount = coin.GetTxOut().nValue; | ||||
// Verify signature | // Verify signature | ||||
CScriptCheck check(scriptPubKey, amount, tx, i, flags, sigCacheStore, | CScriptCheck check(scriptPubKey, amount, tx, i, flags, sigCacheStore, | ||||
txdata); | txdata); | ||||
if (pvChecks) { | if (pvChecks) { | ||||
pvChecks->push_back(std::move(check)); | pvChecks->push_back(std::move(check)); | ||||
} else if (!check()) { | } else if (!check()) { | ||||
if (flags & ~SCRIPT_ENABLE_MONOLITH_OPCODES) { | |||||
// Check whether the failure was caused by an opcode used in | |||||
// the monolith fork deployment. We do not want to trigger DoS | |||||
// protection and cause a network split if so. | |||||
CScriptCheck check2(scriptPubKey, amount, tx, i, | |||||
flags |= | |||||
SCRIPT_ENABLE_MONOLITH_OPCODES, | |||||
sigCacheStore, txdata); | |||||
if (check2()) { | |||||
return state.Invalid( | |||||
false, REJECT_INVALID, | |||||
strprintf("monolith-fork-script-failure (%s)", | |||||
ScriptErrorString(check.GetScriptError()))); | |||||
} | |||||
} | |||||
if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) { | if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) { | ||||
// Check whether the failure was caused by a non-mandatory | // Check whether the failure was caused by a non-mandatory | ||||
// script verification check, such as non-standard DER encodings | // script verification check, such as non-standard DER encodings | ||||
// or non-null dummy arguments; if so, don't trigger DoS | // or non-null dummy arguments; if so, don't trigger DoS | ||||
// protection to avoid splitting the network between upgraded | // protection to avoid splitting the network between upgraded | ||||
// and non-upgraded nodes. | // and non-upgraded nodes. | ||||
CScriptCheck check2(scriptPubKey, amount, tx, i, | CScriptCheck check2(scriptPubKey, amount, tx, i, | ||||
flags & | flags & | ||||
~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, | ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, | ||||
sigCacheStore, txdata); | sigCacheStore, txdata); | ||||
if (check2()) { | if (check2()) { | ||||
return state.Invalid( | return state.Invalid( | ||||
false, REJECT_NONSTANDARD, | false, REJECT_NONSTANDARD, | ||||
strprintf("non-mandatory-script-verify-flag (%s)", | strprintf("non-mandatory-script-verify-flag (%s)", | ||||
ScriptErrorString(check.GetScriptError()))); | ScriptErrorString(check.GetScriptError()))); | ||||
} | } | ||||
} | } | ||||
// Failures of other flags indicate a transaction that is invalid in | // Failures of other flags indicate a transaction that is invalid in | ||||
// new blocks, e.g. a invalid P2SH. We DoS ban such nodes as they | // new blocks, e.g. a invalid P2SH. We DoS ban such nodes as they | ||||
// are not following the protocol. That said during an upgrade | // are not following the protocol. That said during an upgrade | ||||
// careful thought should be taken as to the correct behavior - we | // careful thought should be taken as to the correct behavior - we | ||||
// may want to continue peering with non-upgraded nodes even after | // may want to continue peering with non-upgraded nodes even after | ||||
// soft-fork super-majority signaling has occurred. | // soft-fork super-majority signaling has occurred. | ||||
return state.DoS( | return state.DoS( | ||||
100, false, REJECT_INVALID, | 100, false, REJECT_INVALID, | ||||
▲ Show 20 Lines • Show All 292 Lines • ▼ Show 20 Lines | bool Condition(const CBlockIndex *pindex, | ||||
((ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0; | ((ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0; | ||||
} | } | ||||
}; | }; | ||||
// Protected by cs_main | // Protected by cs_main | ||||
static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS]; | static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS]; | ||||
// Returns the script flags which should be checked for a given block | // Returns the script flags which should be checked for a given block | ||||
static uint32_t GetBlockScriptFlags(const CBlockIndex *pindex, | uint32_t GetBlockScriptFlags(const CBlockIndex *pindex, | ||||
const Config &config) { | const Config &config) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const Consensus::Params &consensusparams = | const Consensus::Params &consensusparams = | ||||
config.GetChainParams().GetConsensus(); | config.GetChainParams().GetConsensus(); | ||||
// 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); | ||||
Show All 28 Lines | uint32_t GetBlockScriptFlags(const CBlockIndex *pindex, | ||||
// s in their signature. We also make sure that signature that are supposed | // s in their signature. We also make sure that signature that are supposed | ||||
// to fail (for instance in multisig or other forms of smart contracts) are | // to fail (for instance in multisig or other forms of smart contracts) are | ||||
// null. | // null. | ||||
if (IsDAAEnabled(config, pindex->pprev)) { | if (IsDAAEnabled(config, pindex->pprev)) { | ||||
flags |= SCRIPT_VERIFY_LOW_S; | flags |= SCRIPT_VERIFY_LOW_S; | ||||
flags |= SCRIPT_VERIFY_NULLFAIL; | flags |= SCRIPT_VERIFY_NULLFAIL; | ||||
} | } | ||||
if (IsMonolithEnabled(config, pindex)) { | |||||
flags |= SCRIPT_ENABLE_MONOLITH_OPCODES; | |||||
} | |||||
// We make sure this node will have replay protection during the next hard | // We make sure this node will have replay protection during the next hard | ||||
// fork. | // fork. | ||||
if (IsReplayProtectionEnabled(config, pindex->pprev)) { | if (IsReplayProtectionEnabled(config, pindex->pprev)) { | ||||
flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | ||||
} | } | ||||
return flags; | return flags; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 3,474 Lines • Show Last 20 Lines |