|
|
@ -1604,7 +1604,7 @@ bool CScriptCheck::operator()() { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) |
|
|
|
bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) |
|
|
|
{ |
|
|
|
if (!tx.IsCoinBase()) |
|
|
|
{ |
|
|
@ -1620,10 +1620,6 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons |
|
|
|
if (!inputs.HavePourRequirements(tx)) |
|
|
|
return state.Invalid(error("CheckInputs(): %s pour requirements not met", 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 nFees = 0; |
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) |
|
|
@ -1632,12 +1628,8 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons |
|
|
|
const CCoins *coins = inputs.AccessCoins(prevout.hash); |
|
|
|
assert(coins); |
|
|
|
|
|
|
|
// If prev is coinbase, check that it's matured
|
|
|
|
if (coins->IsCoinBase()) { |
|
|
|
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) |
|
|
|
return state.Invalid( |
|
|
|
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), |
|
|
|
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Check for negative or overflow input values
|
|
|
@ -1715,6 +1707,35 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) |
|
|
|
{ |
|
|
|
if (!tx.IsCoinBase()) |
|
|
|
{ |
|
|
|
// 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; |
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) |
|
|
|
{ |
|
|
|
const COutPoint &prevout = tx.vin[i].prevout; |
|
|
|
const CCoins *coins = inputs.AccessCoins(prevout.hash); |
|
|
|
assert(coins); |
|
|
|
|
|
|
|
// If prev is coinbase, check that it's matured
|
|
|
|
if (coins->IsCoinBase()) { |
|
|
|
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) |
|
|
|
return state.Invalid( |
|
|
|
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), |
|
|
|
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return NonContextualCheckInputs( |
|
|
|
tx, state, inputs, fScriptChecks, flags, cacheStore, pvChecks |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
|
|
bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart) |
|
|
|