|
|
@ -1018,9 +1018,9 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock |
|
|
|
int nHeight = -1; |
|
|
|
int nHeight = -1; |
|
|
|
{ |
|
|
|
{ |
|
|
|
CCoinsViewCache &view = *pcoinsTip; |
|
|
|
CCoinsViewCache &view = *pcoinsTip; |
|
|
|
CCoins coins; |
|
|
|
const CCoins* coins = view.AccessCoins(hash); |
|
|
|
if (view.GetCoins(hash, coins)) |
|
|
|
if (coins) |
|
|
|
nHeight = coins.nHeight; |
|
|
|
nHeight = coins->nHeight; |
|
|
|
} |
|
|
|
} |
|
|
|
if (nHeight > 0) |
|
|
|
if (nHeight > 0) |
|
|
|
pindexSlow = chainActive[nHeight]; |
|
|
|
pindexSlow = chainActive[nHeight]; |
|
|
@ -1372,19 +1372,20 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi |
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) |
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const COutPoint &prevout = tx.vin[i].prevout; |
|
|
|
const COutPoint &prevout = tx.vin[i].prevout; |
|
|
|
const CCoins &coins = inputs.GetCoins(prevout.hash); |
|
|
|
const CCoins *coins = inputs.AccessCoins(prevout.hash); |
|
|
|
|
|
|
|
assert(coins); |
|
|
|
|
|
|
|
|
|
|
|
// If prev is coinbase, check that it's matured
|
|
|
|
// If prev is coinbase, check that it's matured
|
|
|
|
if (coins.IsCoinBase()) { |
|
|
|
if (coins->IsCoinBase()) { |
|
|
|
if (nSpendHeight - coins.nHeight < COINBASE_MATURITY) |
|
|
|
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) |
|
|
|
return state.Invalid( |
|
|
|
return state.Invalid( |
|
|
|
error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins.nHeight), |
|
|
|
error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), |
|
|
|
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); |
|
|
|
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check for negative or overflow input values
|
|
|
|
// Check for negative or overflow input values
|
|
|
|
nValueIn += coins.vout[prevout.n].nValue; |
|
|
|
nValueIn += coins->vout[prevout.n].nValue; |
|
|
|
if (!MoneyRange(coins.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) |
|
|
|
if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn)) |
|
|
|
return state.DoS(100, error("CheckInputs() : txin values out of range"), |
|
|
|
return state.DoS(100, error("CheckInputs() : txin values out of range"), |
|
|
|
REJECT_INVALID, "bad-txns-inputvalues-outofrange"); |
|
|
|
REJECT_INVALID, "bad-txns-inputvalues-outofrange"); |
|
|
|
|
|
|
|
|
|
|
@ -1414,10 +1415,11 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi |
|
|
|
if (fScriptChecks) { |
|
|
|
if (fScriptChecks) { |
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) { |
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) { |
|
|
|
const COutPoint &prevout = tx.vin[i].prevout; |
|
|
|
const COutPoint &prevout = tx.vin[i].prevout; |
|
|
|
const CCoins &coins = inputs.GetCoins(prevout.hash); |
|
|
|
const CCoins* coins = inputs.AccessCoins(prevout.hash); |
|
|
|
|
|
|
|
assert(coins); |
|
|
|
|
|
|
|
|
|
|
|
// Verify signature
|
|
|
|
// Verify signature
|
|
|
|
CScriptCheck check(coins, tx, i, flags, 0); |
|
|
|
CScriptCheck check(*coins, tx, i, flags, 0); |
|
|
|
if (pvChecks) { |
|
|
|
if (pvChecks) { |
|
|
|
pvChecks->push_back(CScriptCheck()); |
|
|
|
pvChecks->push_back(CScriptCheck()); |
|
|
|
check.swap(pvChecks->back()); |
|
|
|
check.swap(pvChecks->back()); |
|
|
@ -1429,7 +1431,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi |
|
|
|
// arguments; if so, don't trigger DoS protection to
|
|
|
|
// arguments; if so, don't trigger DoS protection to
|
|
|
|
// avoid splitting the network between upgraded and
|
|
|
|
// avoid splitting the network between upgraded and
|
|
|
|
// non-upgraded nodes.
|
|
|
|
// non-upgraded nodes.
|
|
|
|
CScriptCheck check(coins, tx, i, |
|
|
|
CScriptCheck check(*coins, tx, i, |
|
|
|
flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, 0); |
|
|
|
flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, 0); |
|
|
|
if (check()) |
|
|
|
if (check()) |
|
|
|
return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag"); |
|
|
|
return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag"); |
|
|
@ -1615,8 +1617,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C |
|
|
|
(pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); |
|
|
|
(pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); |
|
|
|
if (fEnforceBIP30) { |
|
|
|
if (fEnforceBIP30) { |
|
|
|
BOOST_FOREACH(const CTransaction& tx, block.vtx) { |
|
|
|
BOOST_FOREACH(const CTransaction& tx, block.vtx) { |
|
|
|
const uint256& hash = tx.GetHash(); |
|
|
|
const CCoins* coins = view.AccessCoins(tx.GetHash()); |
|
|
|
if (view.HaveCoins(hash) && !view.GetCoins(hash).IsPruned()) |
|
|
|
if (coins && !coins->IsPruned()) |
|
|
|
return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"), |
|
|
|
return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"), |
|
|
|
REJECT_INVALID, "bad-txns-BIP30"); |
|
|
|
REJECT_INVALID, "bad-txns-BIP30"); |
|
|
|
} |
|
|
|
} |
|
|
|