|
|
@ -269,18 +269,33 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) { |
|
|
|
bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<CBlockIndex*>& blockinfo) { |
|
|
|
CDBBatch batch(*this); |
|
|
|
if (fZdebug) |
|
|
|
fprintf(stderr, "%s: Writing block files\n", __FUNCTION__); |
|
|
|
for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { |
|
|
|
batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second); |
|
|
|
for (const auto& it : fileInfo) { |
|
|
|
batch.Write(make_pair(DB_BLOCK_FILES, it.first), *it.second); |
|
|
|
} |
|
|
|
batch.Write(DB_LAST_BLOCK, nLastFile); |
|
|
|
if (fZdebug) |
|
|
|
fprintf(stderr, "%s: Writing block index\n", __FUNCTION__); |
|
|
|
for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { |
|
|
|
batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it)); |
|
|
|
for (const auto& it : blockinfo) { |
|
|
|
std::pair<char, uint256> key = make_pair(DB_BLOCK_INDEX, it->GetBlockHash()); |
|
|
|
try { |
|
|
|
CDiskBlockIndex dbindex {it, [this, &key]() { |
|
|
|
// It can happen that the index entry is written, then the Equihash solution is cleared from memory,
|
|
|
|
// then the index entry is rewritten. In that case we must read the solution from the old entry.
|
|
|
|
CDiskBlockIndex dbindex_old; |
|
|
|
if (!Read(key, dbindex_old)) { |
|
|
|
LogPrintf("%s: Failed to read index entry", __func__); |
|
|
|
throw runtime_error("Failed to read index entry"); |
|
|
|
} |
|
|
|
return dbindex_old.GetSolution(); |
|
|
|
}}; |
|
|
|
batch.Write(key, dbindex); |
|
|
|
} catch (const runtime_error&) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
return WriteBatch(batch, true); |
|
|
|
} |
|
|
@ -293,6 +308,11 @@ bool CBlockTreeDB::EraseBatchSync(const std::vector<const CBlockIndex*>& blockin |
|
|
|
return WriteBatch(batch, true); |
|
|
|
} |
|
|
|
|
|
|
|
bool CBlockTreeDB::ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex) const { |
|
|
|
return Read(make_pair(DB_BLOCK_INDEX, blockhash), dbindex); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) const { |
|
|
|
return Read(make_pair(DB_TXINDEX, txid), pos); |
|
|
|
} |
|
|
@ -692,7 +712,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts() |
|
|
|
pindexNew->nTime = diskindex.nTime; |
|
|
|
pindexNew->nBits = diskindex.nBits; |
|
|
|
pindexNew->nNonce = diskindex.nNonce; |
|
|
|
pindexNew->nSolution = diskindex.nSolution; |
|
|
|
// the Equihash solution will be loaded lazily from the dbindex entry
|
|
|
|
// pindexNew->nSolution = diskindex.nSolution;
|
|
|
|
pindexNew->nStatus = diskindex.nStatus; |
|
|
|
pindexNew->nCachedBranchId = diskindex.nCachedBranchId; |
|
|
|
pindexNew->nTx = diskindex.nTx; |
|
|
@ -716,10 +737,24 @@ bool CBlockTreeDB::LoadBlockIndexGuts() |
|
|
|
|
|
|
|
//fprintf(stderr,"loadguts ht.%d\n",pindexNew->GetHeight());
|
|
|
|
// Consistency checks
|
|
|
|
auto header = pindexNew->GetBlockHeader(); |
|
|
|
/*
|
|
|
|
CBlockHeader header; |
|
|
|
{ |
|
|
|
LOCK(cs_main); |
|
|
|
try { |
|
|
|
header = pindexNew->GetBlockHeader(); |
|
|
|
} catch (const runtime_error&) { |
|
|
|
return error("LoadBlockIndex(): failed to read index entry: diskindex hash = %s", |
|
|
|
diskindex.GetBlockHash().ToString()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (header.GetHash() != diskindex.GetBlockHash()) |
|
|
|
return error("LoadBlockIndex(): inconsistent header vs diskindex hash: header hash = %s, diskindex hash = %s", |
|
|
|
header.GetHash().ToString(), diskindex.GetBlockHash().ToString()); |
|
|
|
if (header.GetHash() != pindexNew->GetBlockHash()) |
|
|
|
return error("LoadBlockIndex(): block header inconsistency detected: on-disk = %s, in-memory = %s", |
|
|
|
diskindex.ToString(), pindexNew->ToString()); |
|
|
|
|
|
|
|
if ( 0 ) // POW will be checked before any block is connected
|
|
|
|
{ |
|
|
|
uint8_t pubkey33[33]; |
|
|
@ -727,6 +762,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() |
|
|
|
if (!CheckProofOfWork(header,pubkey33,pindexNew->GetHeight(),Params().GetConsensus())) |
|
|
|
return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString()); |
|
|
|
} |
|
|
|
*/ |
|
|
|
pcursor->Next(); |
|
|
|
} else { |
|
|
|
return error("LoadBlockIndex() : failed to read value"); |
|
|
|