Browse Source

Merge pull request #6061

eb83719 Consensus: Refactor: Separate Consensus::CheckTxInputs and GetSpendHeight in CheckInputs (Jorge Timón)
0.13
Wladimir J. van der Laan 10 years ago
parent
commit
eba2f061a0
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 30
      src/main.cpp
  2. 7
      src/main.h

30
src/main.cpp

@ -1395,22 +1395,21 @@ bool CScriptCheck::operator()() {
return true; return true;
} }
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) int GetSpendHeight(const CCoinsViewCache& inputs)
{ {
if (!tx.IsCoinBase()) LOCK(cs_main);
{ CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
if (pvChecks) return pindexPrev->nHeight + 1;
pvChecks->reserve(tx.vin.size()); }
namespace Consensus {
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight)
{
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network. // for an attacker to attempt to split the network.
if (!inputs.HaveInputs(tx)) if (!inputs.HaveInputs(tx))
return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString())); return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
// While checking, GetBestBlock() refers to the parent block.
// This is also true for mempool checks.
CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
int nSpendHeight = pindexPrev->nHeight + 1;
CAmount nValueIn = 0; CAmount nValueIn = 0;
CAmount nFees = 0; CAmount nFees = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++) for (unsigned int i = 0; i < tx.vin.size(); i++)
@ -1449,6 +1448,19 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
if (!MoneyRange(nFees)) if (!MoneyRange(nFees))
return state.DoS(100, error("CheckInputs(): nFees out of range"), return state.DoS(100, error("CheckInputs(): nFees out of range"),
REJECT_INVALID, "bad-txns-fee-outofrange"); REJECT_INVALID, "bad-txns-fee-outofrange");
return true;
}
}// namespace Consensus
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks)
{
if (!tx.IsCoinBase())
{
if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs)))
return false;
if (pvChecks)
pvChecks->reserve(tx.vin.size());
// The first loop above does all the inexpensive checks. // The first loop above does all the inexpensive checks.
// Only if ALL inputs pass do we perform expensive ECDSA signature checks. // Only if ALL inputs pass do we perform expensive ECDSA signature checks.

7
src/main.h

@ -487,4 +487,11 @@ extern CCoinsViewCache *pcoinsTip;
/** Global variable that points to the active block tree (protected by cs_main) */ /** Global variable that points to the active block tree (protected by cs_main) */
extern CBlockTreeDB *pblocktree; extern CBlockTreeDB *pblocktree;
/**
* Return the spend height, which is one more than the inputs.GetBestBlock().
* While checking, GetBestBlock() refers to the parent block. (protected by cs_main)
* This is also true for mempool checks.
*/
int GetSpendHeight(const CCoinsViewCache& inputs);
#endif // BITCOIN_MAIN_H #endif // BITCOIN_MAIN_H

Loading…
Cancel
Save