Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 3,506 Lines • ▼ Show 20 Lines | if (first_invalid != nullptr) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
NotifyHeaderTip(); | NotifyHeaderTip(); | ||||
return true; | return true; | ||||
} | } | ||||
/** Store block on disk. If dbp is non-nullptr, the file is known to already | |||||
* reside on disk */ | |||||
static CDiskBlockPos SaveBlockToDisk(CValidationState &state, | |||||
const CBlock &block, int nHeight, | |||||
const CChainParams &chainparams, | |||||
const CDiskBlockPos *dbp) { | |||||
unsigned int nBlockSize = | |||||
::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); | |||||
CDiskBlockPos blockPos; | |||||
if (dbp != nullptr) blockPos = *dbp; | |||||
if (!FindBlockPos(state, blockPos, nBlockSize + 8, nHeight, | |||||
block.GetBlockTime(), dbp != nullptr)) { | |||||
error("%s: FindBlockPos failed", __func__); | |||||
return CDiskBlockPos(); | |||||
} | |||||
if (dbp == nullptr) { | |||||
if (!WriteBlockToDisk(block, blockPos, chainparams.DiskMagic())) { | |||||
AbortNode("Failed to write block"); | |||||
return CDiskBlockPos(); | |||||
} | |||||
} | |||||
return blockPos; | |||||
} | |||||
/** | /** | ||||
* Store a block on disk. | * Store a block on disk. | ||||
* | * | ||||
* @param[in] config The global config. | * @param[in] config The global config. | ||||
* @param[in-out] pblock The block we want to accept. | * @param[in-out] pblock The block we want to accept. | ||||
* @param[out] ppindex The last new block index, only set if the block | * @param[out] ppindex The last new block index, only set if the block | ||||
* was accepted. | * was accepted. | ||||
* @param[in] fRequested A boolean to indicate if this block was requested | * @param[in] fRequested A boolean to indicate if this block was requested | ||||
* from our peers. | * from our peers. | ||||
* @param[in] dbp If non-null, the disk position of the block. | * @param[in] dbp If non-null, the disk position of the block. | ||||
* @param[in-out] fNewBlock True if block was first received via this call. | * @param[in-out] fNewBlock True if block was first received via this call. | ||||
* @return True if the block is accepted as a valid block and written to disk. | * @return True if the block is accepted as a valid block and written to disk. | ||||
*/ | */ | ||||
static bool AcceptBlock(const Config &config, | static bool AcceptBlock(const Config &config, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
CValidationState &state, CBlockIndex **ppindex, | CValidationState &state, CBlockIndex **ppindex, | ||||
bool fRequested, const CDiskBlockPos *dbp, | bool fRequested, const CDiskBlockPos *dbp, | ||||
bool *fNewBlock) { | bool *fNewBlock) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const CBlock &block = *pblock; | const CBlock &block = *pblock; | ||||
if (fNewBlock) { | if (fNewBlock) { | ||||
*fNewBlock = false; | *fNewBlock = false; | ||||
} | } | ||||
CBlockIndex *pindexDummy = nullptr; | CBlockIndex *pindexDummy = nullptr; | ||||
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy; | CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy; | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | static bool AcceptBlock(const Config &config, | ||||
// Header is valid/has work and the merkle tree is good. | // Header is valid/has work and the merkle tree is good. | ||||
// Relay now, but if it does not build on our best tip, let the | // Relay now, but if it does not build on our best tip, let the | ||||
// SendMessages loop relay it. | // SendMessages loop relay it. | ||||
if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) { | if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) { | ||||
GetMainSignals().NewPoWValidBlock(pindex, pblock); | GetMainSignals().NewPoWValidBlock(pindex, pblock); | ||||
} | } | ||||
int nHeight = pindex->nHeight; | |||||
const CChainParams &chainparams = config.GetChainParams(); | const CChainParams &chainparams = config.GetChainParams(); | ||||
// Write block to history file | // Write block to history file | ||||
try { | try { | ||||
unsigned int nBlockSize = | CDiskBlockPos blockPos = | ||||
::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); | SaveBlockToDisk(state, block, pindex->nHeight, chainparams, dbp); | ||||
CDiskBlockPos blockPos; | if (blockPos.IsNull()) { | ||||
if (dbp != nullptr) { | return state.Error(strprintf( | ||||
blockPos = *dbp; | "%s: Failed to find position to write new block to disk", | ||||
} | __func__)); | ||||
if (!FindBlockPos(state, blockPos, nBlockSize + 8, nHeight, | |||||
block.GetBlockTime(), dbp != nullptr)) { | |||||
return error("AcceptBlock(): FindBlockPos failed"); | |||||
} | |||||
if (dbp == nullptr) { | |||||
if (!WriteBlockToDisk(block, blockPos, chainparams.DiskMagic())) { | |||||
AbortNode(state, "Failed to write block"); | |||||
} | |||||
} | } | ||||
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | ||||
return error("AcceptBlock(): ReceivedBlockTransactions failed"); | return error("AcceptBlock(): ReceivedBlockTransactions failed"); | ||||
} | } | ||||
} catch (const std::runtime_error &e) { | } catch (const std::runtime_error &e) { | ||||
return AbortNode(state, std::string("System error: ") + e.what()); | return AbortNode(state, std::string("System error: ") + e.what()); | ||||
} | } | ||||
if (fCheckForPruning) { | if (fCheckForPruning) { | ||||
▲ Show 20 Lines • Show All 918 Lines • ▼ Show 20 Lines | bool LoadGenesisBlock(const CChainParams &chainparams) { | ||||
if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash())) { | if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash())) { | ||||
return true; | return true; | ||||
} | } | ||||
// Only add the genesis block if not reindexing (in which case we reuse the | // Only add the genesis block if not reindexing (in which case we reuse the | ||||
// one already on disk) | // one already on disk) | ||||
try { | try { | ||||
CBlock &block = const_cast<CBlock &>(chainparams.GenesisBlock()); | CBlock &block = const_cast<CBlock &>(chainparams.GenesisBlock()); | ||||
// Start new block file | |||||
unsigned int nBlockSize = | |||||
::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); | |||||
CDiskBlockPos blockPos; | |||||
CValidationState state; | CValidationState state; | ||||
if (!FindBlockPos(state, blockPos, nBlockSize + 8, 0, | CDiskBlockPos blockPos = | ||||
block.GetBlockTime())) { | SaveBlockToDisk(state, block, 0, chainparams, nullptr); | ||||
return error("%s: FindBlockPos failed", __func__); | if (blockPos.IsNull()) { | ||||
} | |||||
if (!WriteBlockToDisk(block, blockPos, chainparams.DiskMagic())) { | |||||
return error("%s: writing genesis block to disk failed", __func__); | return error("%s: writing genesis block to disk failed", __func__); | ||||
} | } | ||||
CBlockIndex *pindex = AddToBlockIndex(block); | CBlockIndex *pindex = AddToBlockIndex(block); | ||||
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | ||||
return error("%s: genesis block not accepted", __func__); | return error("%s: genesis block not accepted", __func__); | ||||
} | } | ||||
} catch (const std::runtime_error &e) { | } catch (const std::runtime_error &e) { | ||||
return error("%s: failed to write genesis block: %s", __func__, | return error("%s: failed to write genesis block: %s", __func__, | ||||
▲ Show 20 Lines • Show All 657 Lines • Show Last 20 Lines |