|
|
@ -2759,7 +2759,7 @@ static bool ReceivedBlockTransactions(const CBlock &block, CValidationState& sta |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false) |
|
|
|
static bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_LastBlockFile); |
|
|
|
LOCK(cs_LastBlockFile); |
|
|
|
|
|
|
|
|
|
|
@ -2808,7 +2808,7 @@ static bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned i |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
return state.Error("out of disk space"); |
|
|
|
return error("out of disk space"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -3196,6 +3196,25 @@ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, CValidatio |
|
|
|
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.MessageStart())) { |
|
|
|
|
|
|
|
AbortNode("Failed to write block"); |
|
|
|
|
|
|
|
return CDiskBlockPos(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return blockPos; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */ |
|
|
|
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */ |
|
|
|
static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const CDiskBlockPos* dbp, bool* fNewBlock) |
|
|
|
static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const CDiskBlockPos* dbp, bool* fNewBlock) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -3257,19 +3276,13 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation |
|
|
|
if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) |
|
|
|
if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) |
|
|
|
GetMainSignals().NewPoWValidBlock(pindex, pblock); |
|
|
|
GetMainSignals().NewPoWValidBlock(pindex, pblock); |
|
|
|
|
|
|
|
|
|
|
|
int nHeight = pindex->nHeight; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Write block to history file
|
|
|
|
// Write block to history file
|
|
|
|
try { |
|
|
|
try { |
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
|
|
|
CDiskBlockPos blockPos = SaveBlockToDisk(block, pindex->nHeight, chainparams, dbp); |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
if (blockPos.IsNull()) { |
|
|
|
if (dbp != nullptr) |
|
|
|
state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__)); |
|
|
|
blockPos = *dbp; |
|
|
|
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.MessageStart())) |
|
|
|
|
|
|
|
AbortNode(state, "Failed to write block"); |
|
|
|
|
|
|
|
if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus())) |
|
|
|
if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus())) |
|
|
|
return error("AcceptBlock(): ReceivedBlockTransactions failed"); |
|
|
|
return error("AcceptBlock(): ReceivedBlockTransactions failed"); |
|
|
|
} catch (const std::runtime_error& e) { |
|
|
|
} catch (const std::runtime_error& e) { |
|
|
@ -4037,15 +4050,11 @@ bool LoadGenesisBlock(const CChainParams& chainparams) |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock()); |
|
|
|
CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock()); |
|
|
|
// Start new block file
|
|
|
|
CDiskBlockPos blockPos = SaveBlockToDisk(block, 0, chainparams, nullptr); |
|
|
|
unsigned int nBlockSize = ::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.MessageStart())) |
|
|
|
|
|
|
|
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, chainparams.GetConsensus())) |
|
|
|
if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus())) |
|
|
|
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) { |
|
|
|