Changeset View
Changeset View
Standalone View
Standalone View
src/validation.h
Show First 20 Lines • Show All 460 Lines • ▼ Show 20 Lines | bool AcceptToMemoryPool(const Config &config, CTxMemPool &pool, | ||||
bool *pfMissingInputs, bool bypass_limits, | bool *pfMissingInputs, bool bypass_limits, | ||||
const Amount nAbsurdFee, bool test_accept = false) | const Amount nAbsurdFee, bool test_accept = false) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
/** Convert CValidationState to a human-readable message for logging */ | /** Convert CValidationState to a human-readable message for logging */ | ||||
std::string FormatStateMessage(const CValidationState &state); | std::string FormatStateMessage(const CValidationState &state); | ||||
/** | /** | ||||
* Simple class for regulating resource usage during CheckInputs (and | |||||
* CScriptCheck), atomic so as to be compatible with parallel validation. | |||||
*/ | |||||
class CheckInputsLimiter { | |||||
std::atomic<int64_t> remaining; | |||||
public: | |||||
CheckInputsLimiter(int64_t limit) : remaining(limit) {} | |||||
bool consume_and_check(int consumed) { | |||||
auto newvalue = (remaining -= consumed); | |||||
return newvalue >= 0; | |||||
} | |||||
bool check() { return remaining >= 0; } | |||||
}; | |||||
/** | |||||
* Check whether all inputs of this transaction are valid (no double spends, | * Check whether all inputs of this transaction are valid (no double spends, | ||||
* scripts & sigs, amounts). This does not modify the UTXO set. | * scripts & sigs, amounts). This does not modify the UTXO set. | ||||
* | * | ||||
* If pvChecks is not nullptr, script checks are pushed onto it instead of being | * If pvChecks is not nullptr, script checks are pushed onto it instead of being | ||||
* performed inline. Any script checks which are not necessary (eg due to script | * performed inline. Any script checks which are not necessary (eg due to script | ||||
* execution cache hits) are, obviously, not pushed onto pvChecks/run. | * execution cache hits) are, obviously, not pushed onto pvChecks/run. | ||||
* | * | ||||
* Upon success nSigChecksOut will be filled in with either: | * Upon success nSigChecksOut will be filled in with either: | ||||
* - correct total for all inputs, or, | * - correct total for all inputs, or, | ||||
* - 0, in the case when checks were pushed onto pvChecks (i.e., a cache miss | * - 0, in the case when checks were pushed onto pvChecks (i.e., a cache miss | ||||
* with pvChecks non-null), in which case the total can be found by executing | * with pvChecks non-null), in which case the total can be found by executing | ||||
* pvChecks and adding the results. | * pvChecks and adding the results. | ||||
* | * | ||||
* Setting sigCacheStore/scriptCacheStore to false will remove elements from the | * Setting sigCacheStore/scriptCacheStore to false will remove elements from the | ||||
* corresponding cache which are matched. This is useful for checking blocks | * corresponding cache which are matched. This is useful for checking blocks | ||||
* where we will likely never need the cache entry again. | * where we will likely never need the cache entry again. | ||||
* | |||||
* pLimitSigChecks can be passed to limit the sigchecks count either in parallel | |||||
* or serial validation. With pvChecks null (serial validation), breaking the | |||||
* pLimitSigChecks limit will abort evaluation early and return false. With | |||||
* pvChecks not-null (parallel validation): the cached nSigChecks may itself | |||||
* break the limit in which case false is returned, OR, each entry in the | |||||
* returned pvChecks must be executed exactly once in order to probe the limit | |||||
* accurately. | |||||
*/ | */ | ||||
bool CheckInputs(const CTransaction &tx, CValidationState &state, | bool CheckInputs(const CTransaction &tx, CValidationState &state, | ||||
const CCoinsViewCache &view, bool fScriptChecks, | const CCoinsViewCache &view, bool fScriptChecks, | ||||
const uint32_t flags, bool sigCacheStore, | const uint32_t flags, bool sigCacheStore, | ||||
bool scriptCacheStore, | bool scriptCacheStore, | ||||
const PrecomputedTransactionData &txdata, int &nSigChecksOut, | const PrecomputedTransactionData &txdata, int &nSigChecksOut, | ||||
std::vector<CScriptCheck> *pvChecks = nullptr) | std::vector<CScriptCheck> *pvChecks = nullptr, | ||||
CheckInputsLimiter *pLimitSigChecks = nullptr) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
/** Get the BIP9 state for a given deployment at the current tip. */ | /** Get the BIP9 state for a given deployment at the current tip. */ | ||||
ThresholdState VersionBitsTipState(const Consensus::Params ¶ms, | ThresholdState VersionBitsTipState(const Consensus::Params ¶ms, | ||||
Consensus::DeploymentPos pos); | Consensus::DeploymentPos pos); | ||||
/** | /** | ||||
* Get the numerical statistics for the BIP9 state for a given deployment at the | * Get the numerical statistics for the BIP9 state for a given deployment at the | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx, | bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx, | ||||
int flags, LockPoints *lp = nullptr, | int flags, LockPoints *lp = nullptr, | ||||
bool useExistingLockPoints = false) | bool useExistingLockPoints = false) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
/** | /** | ||||
* Closure representing one script verification. | * Closure representing one script verification. | ||||
* Note that this stores references to the spending transaction. | * Note that this stores references to the spending transaction. | ||||
* | |||||
* Note that if pLimitSigChecks is passed, then failure does not imply that | |||||
* scripts have failed. | |||||
*/ | */ | ||||
class CScriptCheck { | class CScriptCheck { | ||||
private: | private: | ||||
CScript scriptPubKey; | CScript scriptPubKey; | ||||
Amount amount; | Amount amount; | ||||
const CTransaction *ptxTo; | const CTransaction *ptxTo; | ||||
unsigned int nIn; | unsigned int nIn; | ||||
uint32_t nFlags; | uint32_t nFlags; | ||||
bool cacheStore; | bool cacheStore; | ||||
ScriptError error; | ScriptError error; | ||||
ScriptExecutionMetrics metrics; | ScriptExecutionMetrics metrics; | ||||
PrecomputedTransactionData txdata; | PrecomputedTransactionData txdata; | ||||
CheckInputsLimiter *pLimitSigChecks; | |||||
public: | public: | ||||
CScriptCheck() | CScriptCheck() | ||||
: amount(), ptxTo(nullptr), nIn(0), nFlags(0), cacheStore(false), | : amount(), ptxTo(nullptr), nIn(0), nFlags(0), cacheStore(false), | ||||
error(ScriptError::UNKNOWN), txdata() {} | error(ScriptError::UNKNOWN), txdata(), pLimitSigChecks(nullptr) {} | ||||
CScriptCheck(const CScript &scriptPubKeyIn, const Amount amountIn, | CScriptCheck(const CScript &scriptPubKeyIn, const Amount amountIn, | ||||
const CTransaction &txToIn, unsigned int nInIn, | const CTransaction &txToIn, unsigned int nInIn, | ||||
uint32_t nFlagsIn, bool cacheIn, | uint32_t nFlagsIn, bool cacheIn, | ||||
const PrecomputedTransactionData &txdataIn) | const PrecomputedTransactionData &txdataIn, | ||||
CheckInputsLimiter *pLimitSigChecksIn = nullptr) | |||||
: scriptPubKey(scriptPubKeyIn), amount(amountIn), ptxTo(&txToIn), | : scriptPubKey(scriptPubKeyIn), amount(amountIn), ptxTo(&txToIn), | ||||
nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), | nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), | ||||
error(ScriptError::UNKNOWN), txdata(txdataIn) {} | error(ScriptError::UNKNOWN), txdata(txdataIn), | ||||
pLimitSigChecks(pLimitSigChecksIn) {} | |||||
bool operator()(); | bool operator()(); | ||||
void swap(CScriptCheck &check) { | void swap(CScriptCheck &check) { | ||||
scriptPubKey.swap(check.scriptPubKey); | scriptPubKey.swap(check.scriptPubKey); | ||||
std::swap(ptxTo, check.ptxTo); | std::swap(ptxTo, check.ptxTo); | ||||
std::swap(amount, check.amount); | std::swap(amount, check.amount); | ||||
std::swap(nIn, check.nIn); | std::swap(nIn, check.nIn); | ||||
std::swap(nFlags, check.nFlags); | std::swap(nFlags, check.nFlags); | ||||
std::swap(cacheStore, check.cacheStore); | std::swap(cacheStore, check.cacheStore); | ||||
std::swap(error, check.error); | std::swap(error, check.error); | ||||
std::swap(txdata, check.txdata); | std::swap(txdata, check.txdata); | ||||
std::swap(pLimitSigChecks, check.pLimitSigChecks); | |||||
} | } | ||||
ScriptError GetScriptError() const { return error; } | ScriptError GetScriptError() const { return error; } | ||||
ScriptExecutionMetrics GetScriptExecutionMetrics() const { return metrics; } | ScriptExecutionMetrics GetScriptExecutionMetrics() const { return metrics; } | ||||
}; | }; | ||||
/** Functions for disk access for blocks */ | /** Functions for disk access for blocks */ | ||||
▲ Show 20 Lines • Show All 159 Lines • Show Last 20 Lines |