Changeset View
Changeset View
Standalone View
Standalone View
src/validation.h
Show First 20 Lines • Show All 450 Lines • ▼ Show 20 Lines | |||||
/** 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 | * Simple class for regulating resource usage during CheckInputs (and | ||||
* CScriptCheck), atomic so as to be compatible with parallel validation. | * CScriptCheck), atomic so as to be compatible with parallel validation. | ||||
*/ | */ | ||||
class CheckInputsLimiter { | class CheckInputsLimiter { | ||||
protected: | |||||
std::atomic<int64_t> remaining; | std::atomic<int64_t> remaining; | ||||
public: | public: | ||||
CheckInputsLimiter(int64_t limit) : remaining(limit) {} | CheckInputsLimiter(int64_t limit) : remaining(limit) {} | ||||
bool consume_and_check(int consumed) { | bool consume_and_check(int consumed) { | ||||
auto newvalue = (remaining -= consumed); | auto newvalue = (remaining -= consumed); | ||||
return newvalue >= 0; | return newvalue >= 0; | ||||
} | } | ||||
bool check() { return remaining >= 0; } | bool check() { return remaining >= 0; } | ||||
}; | }; | ||||
class TxSigCheckLimiter : public CheckInputsLimiter { | |||||
public: | |||||
TxSigCheckLimiter() : CheckInputsLimiter(MAX_TX_SIGCHECKS) {} | |||||
// Let's make this bad boy copiable. | |||||
TxSigCheckLimiter(const TxSigCheckLimiter &rhs) | |||||
: CheckInputsLimiter(rhs.remaining.load()) {} | |||||
TxSigCheckLimiter &operator=(const TxSigCheckLimiter &rhs) { | |||||
remaining = rhs.remaining.load(); | |||||
return *this; | |||||
} | |||||
}; | |||||
/** | /** | ||||
* 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. | ||||
* | * | ||||
Show All 15 Lines | |||||
* returned pvChecks must be executed exactly once in order to probe the limit | * returned pvChecks must be executed exactly once in order to probe the limit | ||||
* accurately. | * 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, | TxSigCheckLimiter &txLimitSigChecks, | ||||
CheckInputsLimiter *pLimitSigChecks = nullptr) | CheckInputsLimiter *pBlockLimitSigChecks, | ||||
std::vector<CScriptCheck> *pvChecks) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
/** | |||||
* Handy shortcut to full fledged CheckInputs call. | |||||
*/ | |||||
static inline bool | |||||
CheckInputs(const CTransaction &tx, CValidationState &state, | |||||
const CCoinsViewCache &view, bool fScriptChecks, | |||||
const uint32_t flags, bool sigCacheStore, bool scriptCacheStore, | |||||
const PrecomputedTransactionData &txdata, int &nSigChecksOut) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
TxSigCheckLimiter nSigChecksTxLimiter; | |||||
return CheckInputs(tx, state, view, fScriptChecks, flags, sigCacheStore, | |||||
scriptCacheStore, txdata, nSigChecksOut, | |||||
nSigChecksTxLimiter, nullptr, nullptr); | |||||
} | |||||
/** 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 BIP9 state for a given deployment at a given block. */ | /** Get the BIP9 state for a given deployment at a given block. */ | ||||
ThresholdState VersionBitsBlockState(const Consensus::Params ¶ms, | ThresholdState VersionBitsBlockState(const Consensus::Params ¶ms, | ||||
Consensus::DeploymentPos pos, | Consensus::DeploymentPos pos, | ||||
const CBlockIndex *pindex); | const CBlockIndex *pindex); | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | private: | ||||
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; | TxSigCheckLimiter *pTxLimitSigChecks; | ||||
CheckInputsLimiter *pBlockLimitSigChecks; | |||||
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(), pLimitSigChecks(nullptr) {} | error(ScriptError::UNKNOWN), txdata(), pTxLimitSigChecks(nullptr), | ||||
pBlockLimitSigChecks(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) | TxSigCheckLimiter *pTxLimitSigChecksIn = nullptr, | ||||
CheckInputsLimiter *pBlockLimitSigChecksIn = 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) {} | pTxLimitSigChecks(pTxLimitSigChecksIn), | ||||
pBlockLimitSigChecks(pBlockLimitSigChecksIn) {} | |||||
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(metrics, check.metrics); | std::swap(metrics, check.metrics); | ||||
std::swap(txdata, check.txdata); | std::swap(txdata, check.txdata); | ||||
std::swap(pLimitSigChecks, check.pLimitSigChecks); | std::swap(pTxLimitSigChecks, check.pTxLimitSigChecks); | ||||
std::swap(pBlockLimitSigChecks, check.pBlockLimitSigChecks); | |||||
} | } | ||||
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 |