Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 1,426 Lines • ▼ Show 20 Lines | static void InvalidBlockFound(CBlockIndex *pindex, | ||||
if (!state.CorruptionPossible()) { | if (!state.CorruptionPossible()) { | ||||
pindex->nStatus = pindex->nStatus.withFailed(); | pindex->nStatus = pindex->nStatus.withFailed(); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
setBlockIndexCandidates.erase(pindex); | setBlockIndexCandidates.erase(pindex); | ||||
InvalidChainFound(pindex); | InvalidChainFound(pindex); | ||||
} | } | ||||
} | } | ||||
void UpdateCoins(CCoinsViewCache &view, const CTransaction &tx, CTxUndo &txundo, | void SpendCoins(CCoinsViewCache &view, const CTransaction &tx, CTxUndo &txundo, | ||||
int nHeight) { | int nHeight) { | ||||
// Mark inputs spent. | // Mark inputs spent. | ||||
if (!tx.IsCoinBase()) { | if (tx.IsCoinBase()) { | ||||
return; | |||||
} | |||||
txundo.vprevout.reserve(tx.vin.size()); | txundo.vprevout.reserve(tx.vin.size()); | ||||
for (const CTxIn &txin : tx.vin) { | for (const CTxIn &txin : tx.vin) { | ||||
txundo.vprevout.emplace_back(); | txundo.vprevout.emplace_back(); | ||||
bool is_spent = | bool is_spent = view.SpendCoin(txin.prevout, &txundo.vprevout.back()); | ||||
view.SpendCoin(txin.prevout, &txundo.vprevout.back()); | |||||
assert(is_spent); | assert(is_spent); | ||||
} | } | ||||
} | } | ||||
// Add outputs. | void UpdateCoins(CCoinsViewCache &view, const CTransaction &tx, CTxUndo &txundo, | ||||
int nHeight) { | |||||
SpendCoins(view, tx, txundo, nHeight); | |||||
AddCoins(view, tx, nHeight); | AddCoins(view, tx, nHeight); | ||||
} | } | ||||
void UpdateCoins(CCoinsViewCache &view, const CTransaction &tx, int nHeight) { | void UpdateCoins(CCoinsViewCache &view, const CTransaction &tx, int nHeight) { | ||||
CTxUndo txundo; | // Mark inputs spent. | ||||
UpdateCoins(view, tx, txundo, nHeight); | if (!tx.IsCoinBase()) { | ||||
for (const CTxIn &txin : tx.vin) { | |||||
bool is_spent = view.SpendCoin(txin.prevout); | |||||
assert(is_spent); | |||||
} | |||||
} | |||||
// Add outputs. | |||||
AddCoins(view, tx, nHeight); | |||||
} | } | ||||
bool CScriptCheck::operator()() { | bool CScriptCheck::operator()() { | ||||
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; | const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; | ||||
return VerifyScript(scriptSig, scriptPubKey, nFlags, | return VerifyScript(scriptSig, scriptPubKey, nFlags, | ||||
CachingTransactionSignatureChecker(ptxTo, nIn, amount, | CachingTransactionSignatureChecker(ptxTo, nIn, amount, | ||||
cacheStore, txdata), | cacheStore, txdata), | ||||
&error); | &error); | ||||
▲ Show 20 Lines • Show All 748 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < block.vtx.size(); i++) { | ||||
control.Add(vChecks); | control.Add(vChecks); | ||||
} | } | ||||
CTxUndo undoDummy; | CTxUndo undoDummy; | ||||
if (i > 0) { | if (i > 0) { | ||||
blockundo.vtxundo.push_back(CTxUndo()); | blockundo.vtxundo.push_back(CTxUndo()); | ||||
} | } | ||||
UpdateCoins(view, tx, i == 0 ? undoDummy : blockundo.vtxundo.back(), | SpendCoins(view, tx, i == 0 ? undoDummy : blockundo.vtxundo.back(), | ||||
pindex->nHeight); | pindex->nHeight); | ||||
AddCoins(view, tx, pindex->nHeight); | |||||
vPos.push_back(std::make_pair(tx.GetId(), pos)); | vPos.push_back(std::make_pair(tx.GetId(), pos)); | ||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); | pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); | ||||
} | } | ||||
int64_t nTime3 = GetTimeMicros(); | int64_t nTime3 = GetTimeMicros(); | ||||
nTimeConnect += nTime3 - nTime2; | nTimeConnect += nTime3 - nTime2; | ||||
LogPrint(BCLog::BENCH, | LogPrint(BCLog::BENCH, | ||||
▲ Show 20 Lines • Show All 2,373 Lines • ▼ Show 20 Lines | static bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &view, | ||||
// TODO: merge with ConnectBlock | // TODO: merge with ConnectBlock | ||||
CBlock block; | CBlock block; | ||||
if (!ReadBlockFromDisk(block, pindex, config)) { | if (!ReadBlockFromDisk(block, pindex, config)) { | ||||
return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", | return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", | ||||
pindex->nHeight, pindex->GetBlockHash().ToString()); | pindex->nHeight, pindex->GetBlockHash().ToString()); | ||||
} | } | ||||
for (const CTransactionRef &tx : block.vtx) { | for (const CTransactionRef &tx : block.vtx) { | ||||
if (!tx->IsCoinBase()) { | // Pass check = true as every addition may be an overwrite. | ||||
for (const CTxIn &txin : tx->vin) { | AddCoins(view, *tx, pindex->nHeight, true); | ||||
view.SpendCoin(txin.prevout); | |||||
} | } | ||||
for (const CTransactionRef &tx : block.vtx) { | |||||
if (tx->IsCoinBase()) { | |||||
continue; | |||||
} | } | ||||
// Pass check = true as every addition may be an overwrite. | for (const CTxIn &txin : tx->vin) { | ||||
AddCoins(view, *tx, pindex->nHeight, true); | view.SpendCoin(txin.prevout); | ||||
} | |||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool ReplayBlocks(const Config &config, CCoinsView *view) { | bool ReplayBlocks(const Config &config, CCoinsView *view) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
▲ Show 20 Lines • Show All 860 Lines • Show Last 20 Lines |