Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 153 Lines • ▼ Show 20 Lines | for (const uint256 &hash : locator.vHave) { | ||||
if (pindex->GetAncestor(chain.Height()) == chain.Tip()) { | if (pindex->GetAncestor(chain.Height()) == chain.Tip()) { | ||||
return chain.Tip(); | return chain.Tip(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return chain.Genesis(); | return chain.Genesis(); | ||||
} | } | ||||
CCoinsViewDB *pcoinsdbview = nullptr; | std::unique_ptr<CCoinsViewDB> pcoinsdbview; | ||||
CCoinsViewCache *pcoinsTip = nullptr; | std::unique_ptr<CCoinsViewCache> pcoinsTip; | ||||
CBlockTreeDB *pblocktree = nullptr; | std::unique_ptr<CBlockTreeDB> pblocktree; | ||||
enum FlushStateMode { | enum FlushStateMode { | ||||
FLUSH_STATE_NONE, | FLUSH_STATE_NONE, | ||||
FLUSH_STATE_IF_NEEDED, | FLUSH_STATE_IF_NEEDED, | ||||
FLUSH_STATE_PERIODIC, | FLUSH_STATE_PERIODIC, | ||||
FLUSH_STATE_ALWAYS | FLUSH_STATE_ALWAYS | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints *lp, | ||||
std::pair<int, int64_t> lockPair; | std::pair<int, int64_t> lockPair; | ||||
if (useExistingLockPoints) { | if (useExistingLockPoints) { | ||||
assert(lp); | assert(lp); | ||||
lockPair.first = lp->height; | lockPair.first = lp->height; | ||||
lockPair.second = lp->time; | lockPair.second = lp->time; | ||||
} else { | } else { | ||||
// pcoinsTip contains the UTXO set for chainActive.Tip() | // pcoinsTip contains the UTXO set for chainActive.Tip() | ||||
CCoinsViewMemPool viewMemPool(pcoinsTip, mempool); | CCoinsViewMemPool viewMemPool(pcoinsTip.get(), mempool); | ||||
std::vector<int> prevheights; | std::vector<int> prevheights; | ||||
prevheights.resize(tx.vin.size()); | prevheights.resize(tx.vin.size()); | ||||
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { | for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { | ||||
const CTxIn &txin = tx.vin[txinIndex]; | const CTxIn &txin = tx.vin[txinIndex]; | ||||
Coin coin; | Coin coin; | ||||
if (!viewMemPool.GetCoin(txin.prevout, coin)) { | if (!viewMemPool.GetCoin(txin.prevout, coin)) { | ||||
return error("%s: Missing input", __func__); | return error("%s: Missing input", __func__); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | static bool AcceptToMemoryPoolWorker( | ||||
} | } | ||||
{ | { | ||||
CCoinsView dummy; | CCoinsView dummy; | ||||
CCoinsViewCache view(&dummy); | CCoinsViewCache view(&dummy); | ||||
Amount nValueIn = Amount::zero(); | Amount nValueIn = Amount::zero(); | ||||
LockPoints lp; | LockPoints lp; | ||||
CCoinsViewMemPool viewMemPool(pcoinsTip, pool); | CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool); | ||||
view.SetBackend(viewMemPool); | view.SetBackend(viewMemPool); | ||||
// Do all inputs exist? | // Do all inputs exist? | ||||
for (const CTxIn txin : tx.vin) { | for (const CTxIn txin : tx.vin) { | ||||
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) { | if (!pcoinsTip->HaveCoinInCache(txin.prevout)) { | ||||
coins_to_uncache.push_back(txin.prevout); | coins_to_uncache.push_back(txin.prevout); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,697 Lines • ▼ Show 20 Lines | static bool DisconnectTip(const Config &config, CValidationState &state, | ||||
CBlock &block = *pblock; | CBlock &block = *pblock; | ||||
if (!ReadBlockFromDisk(block, pindexDelete, config)) { | if (!ReadBlockFromDisk(block, pindexDelete, config)) { | ||||
return AbortNode(state, "Failed to read block"); | return AbortNode(state, "Failed to read block"); | ||||
} | } | ||||
// Apply the block atomically to the chain state. | // Apply the block atomically to the chain state. | ||||
int64_t nStart = GetTimeMicros(); | int64_t nStart = GetTimeMicros(); | ||||
{ | { | ||||
CCoinsViewCache view(pcoinsTip); | CCoinsViewCache view(pcoinsTip.get()); | ||||
assert(view.GetBestBlock() == pindexDelete->GetBlockHash()); | assert(view.GetBestBlock() == pindexDelete->GetBlockHash()); | ||||
if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK) { | if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK) { | ||||
return error("DisconnectTip(): DisconnectBlock %s failed", | return error("DisconnectTip(): DisconnectBlock %s failed", | ||||
pindexDelete->GetBlockHash().ToString()); | pindexDelete->GetBlockHash().ToString()); | ||||
} | } | ||||
bool flushed = view.Flush(); | bool flushed = view.Flush(); | ||||
assert(flushed); | assert(flushed); | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | static bool ConnectTip(const Config &config, CValidationState &state, | ||||
// Apply the block atomically to the chain state. | // Apply the block atomically to the chain state. | ||||
int64_t nTime2 = GetTimeMicros(); | int64_t nTime2 = GetTimeMicros(); | ||||
nTimeReadFromDisk += nTime2 - nTime1; | nTimeReadFromDisk += nTime2 - nTime1; | ||||
int64_t nTime3; | int64_t nTime3; | ||||
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", | LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", | ||||
(nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); | (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); | ||||
{ | { | ||||
CCoinsViewCache view(pcoinsTip); | CCoinsViewCache view(pcoinsTip.get()); | ||||
bool rv = ConnectBlock(config, blockConnecting, state, pindexNew, view); | bool rv = ConnectBlock(config, blockConnecting, state, pindexNew, view); | ||||
GetMainSignals().BlockChecked(blockConnecting, state); | GetMainSignals().BlockChecked(blockConnecting, state); | ||||
if (!rv) { | if (!rv) { | ||||
if (state.IsInvalid()) { | if (state.IsInvalid()) { | ||||
InvalidBlockFound(pindexNew, state); | InvalidBlockFound(pindexNew, state); | ||||
} | } | ||||
return error("ConnectTip(): ConnectBlock %s failed (%s)", | return error("ConnectTip(): ConnectBlock %s failed (%s)", | ||||
▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | static bool ActivateBestChainStep(const Config &config, CValidationState &state, | ||||
} | } | ||||
if (fBlocksDisconnected) { | if (fBlocksDisconnected) { | ||||
// If any blocks were disconnected, disconnectpool may be non empty. Add | // If any blocks were disconnected, disconnectpool may be non empty. Add | ||||
// any disconnected transactions back to the mempool. | // any disconnected transactions back to the mempool. | ||||
disconnectpool.updateMempoolForReorg(config, true); | disconnectpool.updateMempoolForReorg(config, true); | ||||
} | } | ||||
mempool.check(pcoinsTip); | mempool.check(pcoinsTip.get()); | ||||
// Callbacks/notifications for a new best chain. | // Callbacks/notifications for a new best chain. | ||||
if (fInvalidFound) { | if (fInvalidFound) { | ||||
CheckForkWarningConditionsOnNewFork(vpindexToConnect.back()); | CheckForkWarningConditionsOnNewFork(vpindexToConnect.back()); | ||||
} else { | } else { | ||||
CheckForkWarningConditions(); | CheckForkWarningConditions(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,075 Lines • ▼ Show 20 Lines | bool TestBlockValidity(const Config &config, CValidationState &state, | ||||
assert(pindexPrev && pindexPrev == chainActive.Tip()); | assert(pindexPrev && pindexPrev == chainActive.Tip()); | ||||
if (fCheckpointsEnabled && | if (fCheckpointsEnabled && | ||||
!CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, | !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, | ||||
block.GetHash())) { | block.GetHash())) { | ||||
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, | return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, | ||||
state.GetRejectReason().c_str()); | state.GetRejectReason().c_str()); | ||||
} | } | ||||
CCoinsViewCache viewNew(pcoinsTip); | CCoinsViewCache viewNew(pcoinsTip.get()); | ||||
CBlockIndex indexDummy(block); | CBlockIndex indexDummy(block); | ||||
indexDummy.pprev = pindexPrev; | indexDummy.pprev = pindexPrev; | ||||
indexDummy.nHeight = pindexPrev->nHeight + 1; | indexDummy.nHeight = pindexPrev->nHeight + 1; | ||||
// NOTE: CheckBlockHeader is called by CheckBlock | // NOTE: CheckBlockHeader is called by CheckBlock | ||||
if (!ContextualCheckBlockHeader(config, block, state, pindexPrev, | if (!ContextualCheckBlockHeader(config, block, state, pindexPrev, | ||||
GetAdjustedTime())) { | GetAdjustedTime())) { | ||||
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, | return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, | ||||
▲ Show 20 Lines • Show All 1,518 Lines • Show Last 20 Lines |