Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 1,450 Lines • ▼ Show 20 Lines | if (fileOld) { | ||||
FileCommit(fileOld); | FileCommit(fileOld); | ||||
fclose(fileOld); | fclose(fileOld); | ||||
} | } | ||||
} | } | ||||
static bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, | static bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, | ||||
unsigned int nAddSize); | unsigned int nAddSize); | ||||
static bool WriteUndoDataForBlock(const CBlockUndo &blockundo, | |||||
CValidationState &state, CBlockIndex *pindex, | |||||
const CChainParams &chainparams) { | |||||
// Write undo information to disk | |||||
if (pindex->GetUndoPos().IsNull()) { | |||||
CDiskBlockPos _pos; | |||||
if (!FindUndoPos( | |||||
state, pindex->nFile, _pos, | |||||
::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) { | |||||
return error("ConnectBlock(): FindUndoPos failed"); | |||||
} | |||||
if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), | |||||
chainparams.DiskMagic())) { | |||||
return AbortNode(state, "Failed to write undo data"); | |||||
} | |||||
// update nUndoPos in block index | |||||
pindex->nUndoPos = _pos.nPos; | |||||
pindex->nStatus = pindex->nStatus.withUndo(); | |||||
setDirtyBlockIndex.insert(pindex); | |||||
} | |||||
return true; | |||||
} | |||||
static bool WriteTxIndexDataForBlock(const CBlock &block, | |||||
CValidationState &state, | |||||
CBlockIndex *pindex) { | |||||
CDiskTxPos pos(pindex->GetBlockPos(), | |||||
GetSizeOfCompactSize(block.vtx.size())); | |||||
std::vector<std::pair<uint256, CDiskTxPos>> vPos; | |||||
vPos.reserve(block.vtx.size()); | |||||
for (const CTransactionRef &tx : block.vtx) { | |||||
vPos.push_back(std::make_pair(tx->GetHash(), pos)); | |||||
pos.nTxOffset += ::GetSerializeSize(*tx, SER_DISK, CLIENT_VERSION); | |||||
} | |||||
if (fTxIndex) { | |||||
if (!pblocktree->WriteTxIndex(vPos)) { | |||||
return AbortNode(state, "Failed to write transaction index"); | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
static CCheckQueue<CScriptCheck> scriptcheckqueue(128); | static CCheckQueue<CScriptCheck> scriptcheckqueue(128); | ||||
void ThreadScriptCheck() { | void ThreadScriptCheck() { | ||||
RenameThread("bitcoin-scriptch"); | RenameThread("bitcoin-scriptch"); | ||||
scriptcheckqueue.Thread(); | scriptcheckqueue.Thread(); | ||||
} | } | ||||
// Protected by cs_main | // Protected by cs_main | ||||
▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Lines | static bool ConnectBlock(const Config &config, const CBlock &block, | ||||
int nInputs = 0; | int nInputs = 0; | ||||
// Sigops counting. We need to do it again because of P2SH. | // Sigops counting. We need to do it again because of P2SH. | ||||
uint64_t nSigOpsCount = 0; | uint64_t nSigOpsCount = 0; | ||||
const uint64_t currentBlockSize = | const uint64_t currentBlockSize = | ||||
::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); | ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); | ||||
const uint64_t nMaxSigOpsCount = GetMaxBlockSigOpsCount(currentBlockSize); | const uint64_t nMaxSigOpsCount = GetMaxBlockSigOpsCount(currentBlockSize); | ||||
CDiskTxPos pos(pindex->GetBlockPos(), | |||||
GetSizeOfCompactSize(block.vtx.size())); | |||||
std::vector<std::pair<uint256, CDiskTxPos>> vPos; | |||||
vPos.reserve(block.vtx.size()); | |||||
blockundo.vtxundo.reserve(block.vtx.size() - 1); | blockundo.vtxundo.reserve(block.vtx.size() - 1); | ||||
for (const auto &ptx : block.vtx) { | for (const auto &ptx : block.vtx) { | ||||
const CTransaction &tx = *ptx; | const CTransaction &tx = *ptx; | ||||
nInputs += tx.vin.size(); | nInputs += tx.vin.size(); | ||||
vPos.push_back(std::make_pair(tx.GetId(), pos)); | |||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); | |||||
if (tx.IsCoinBase()) { | if (tx.IsCoinBase()) { | ||||
// We've already checked for sigops count before P2SH in CheckBlock. | // We've already checked for sigops count before P2SH in CheckBlock. | ||||
nSigOpsCount += GetSigOpCountWithoutP2SH(tx, flags); | nSigOpsCount += GetSigOpCountWithoutP2SH(tx, flags); | ||||
} | } | ||||
if (fIsMagneticAnomalyEnabled || tx.IsCoinBase()) { | if (fIsMagneticAnomalyEnabled || tx.IsCoinBase()) { | ||||
// We do not need to throw when a transaction is duplicated. If they | // We do not need to throw when a transaction is duplicated. If they | ||||
// are in the same block, CheckBlock will catch it, and if they are | // are in the same block, CheckBlock will catch it, and if they are | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | LogPrint(BCLog::BENCH, | ||||
nInputs - 1, 0.001 * (nTime4 - nTime2), | nInputs - 1, 0.001 * (nTime4 - nTime2), | ||||
nInputs <= 1 ? 0 : 0.001 * (nTime4 - nTime2) / (nInputs - 1), | nInputs <= 1 ? 0 : 0.001 * (nTime4 - nTime2) / (nInputs - 1), | ||||
nTimeVerify * 0.000001); | nTimeVerify * 0.000001); | ||||
if (fJustCheck) { | if (fJustCheck) { | ||||
return true; | return true; | ||||
} | } | ||||
// Write undo information to disk | if (!WriteUndoDataForBlock(blockundo, state, pindex, | ||||
if (pindex->GetUndoPos().IsNull() || | config.GetChainParams())) { | ||||
!pindex->IsValid(BlockValidity::SCRIPTS)) { | return false; | ||||
if (pindex->GetUndoPos().IsNull()) { | |||||
CDiskBlockPos _pos; | |||||
if (!FindUndoPos( | |||||
state, pindex->nFile, _pos, | |||||
::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + | |||||
40)) { | |||||
return error("ConnectBlock(): FindUndoPos failed"); | |||||
} | |||||
if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), | |||||
config.GetChainParams().DiskMagic())) { | |||||
return AbortNode(state, "Failed to write undo data"); | |||||
} | |||||
// update nUndoPos in block index | |||||
pindex->nUndoPos = _pos.nPos; | |||||
pindex->nStatus = pindex->nStatus.withUndo(); | |||||
} | } | ||||
if (!pindex->IsValid(BlockValidity::SCRIPTS)) { | |||||
pindex->RaiseValidity(BlockValidity::SCRIPTS); | pindex->RaiseValidity(BlockValidity::SCRIPTS); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} | } | ||||
if (fTxIndex && !pblocktree->WriteTxIndex(vPos)) { | if (!WriteTxIndexDataForBlock(block, state, pindex)) { | ||||
return AbortNode(state, "Failed to write transaction index"); | return false; | ||||
} | } | ||||
// add this block to the view's block chain | // add this block to the view's block chain | ||||
view.SetBestBlock(pindex->GetBlockHash()); | view.SetBestBlock(pindex->GetBlockHash()); | ||||
int64_t nTime5 = GetTimeMicros(); | int64_t nTime5 = GetTimeMicros(); | ||||
nTimeIndex += nTime5 - nTime4; | nTimeIndex += nTime5 - nTime4; | ||||
LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs]\n", | LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs]\n", | ||||
▲ Show 20 Lines • Show All 3,578 Lines • Show Last 20 Lines |