Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 3,282 Lines • ▼ Show 20 Lines | bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | ||||
} else if (pindexNew->pprev && | } else if (pindexNew->pprev && | ||||
pindexNew->pprev->IsValid(BlockValidity::TREE)) { | pindexNew->pprev->IsValid(BlockValidity::TREE)) { | ||||
mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew)); | mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew)); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, | static bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, | ||||
unsigned int nAddSize, unsigned int nHeight, | unsigned int nHeight, uint64_t nTime, | ||||
uint64_t nTime, bool fKnown = false) { | bool fKnown = false) { | ||||
LOCK(cs_LastBlockFile); | LOCK(cs_LastBlockFile); | ||||
unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; | unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; | ||||
if (vinfoBlockFile.size() <= nFile) { | if (vinfoBlockFile.size() <= nFile) { | ||||
vinfoBlockFile.resize(nFile + 1); | vinfoBlockFile.resize(nFile + 1); | ||||
} | } | ||||
if (!fKnown) { | if (!fKnown) { | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if (!fKnown) { | ||||
"Pre-allocating up to position 0x%x in blk%05u.dat\n", | "Pre-allocating up to position 0x%x in blk%05u.dat\n", | ||||
nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile); | nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile); | ||||
AllocateFileRange(file, pos.nPos, | AllocateFileRange(file, pos.nPos, | ||||
nNewChunks * BLOCKFILE_CHUNK_SIZE - | nNewChunks * BLOCKFILE_CHUNK_SIZE - | ||||
pos.nPos); | pos.nPos); | ||||
fclose(file); | fclose(file); | ||||
} | } | ||||
} else { | } else { | ||||
return state.Error("out of disk space"); | return error("out of disk space"); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
setDirtyFileInfo.insert(nFile); | setDirtyFileInfo.insert(nFile); | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 447 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(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(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[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. | ||||
▲ Show 20 Lines • Show All 121 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(block, pindex->nHeight, chainparams, dbp); | ||||
CDiskBlockPos blockPos; | if (blockPos.IsNull()) { | ||||
if (dbp != nullptr) { | state.Error(strprintf( | ||||
blockPos = *dbp; | "%s: Failed to find position to write new block to disk", | ||||
} | __func__)); | ||||
return false; | |||||
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 905 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 | CDiskBlockPos blockPos = | ||||
unsigned int nBlockSize = | SaveBlockToDisk(block, 0, chainparams, nullptr); | ||||
::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); | if (blockPos.IsNull()) { | ||||
CDiskBlockPos blockPos; | |||||
CValidationState state; | |||||
if (!FindBlockPos(state, blockPos, nBlockSize + 8, 0, | |||||
block.GetBlockTime())) { | |||||
return error("%s: FindBlockPos failed", __func__); | |||||
} | |||||
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); | ||||
CValidationState state; | |||||
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__, | ||||
e.what()); | e.what()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 652 Lines • Show Last 20 Lines |