Skip to content

Commit

Permalink
Improve DMD Core
Browse files Browse the repository at this point in the history
Fix for Assertion `hashPrevBlock == view.GetBestBlock()' failed.
  • Loading branch information
Chris committed Jan 20, 2018
1 parent e167786 commit bb16260
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 74 deletions.
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 3)
define(_CLIENT_VERSION_MINOR, 0)
define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_BUILD, 14)
define(_CLIENT_VERSION_BUILD, 15)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2017)
define(_COPYRIGHT_YEAR, 2018)
AC_INIT([Diamond Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[http://bit.diamonds],[diamond])
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_HEADERS([src/config/diamond-config.h])
Expand Down
129 changes: 58 additions & 71 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3794,84 +3794,71 @@ bool static LoadBlockIndexDB()
LogPrintf("%s: Last shutdown was prepared: %s\n", __func__, fLastShutdownWasPrepared);

//Check for inconsistency with block file info and internal state
if (!fLastShutdownWasPrepared && !GetBoolArg("-forcestart", false) && !GetBoolArg("-reindex", false) && (vSortedByHeight.size() != vinfoBlockFile[nLastBlockFile].nHeightLast + 1) && (vinfoBlockFile[nLastBlockFile].nHeightLast != 0)) {
//The database is in a state where a block has been accepted and written to disk, but not
//all of the block has perculated through the code. The block and the index should both be
//intact (although assertions are added if they are not), and the block will be reprocessed
//to ensure all data will be accounted for.
LogPrintf("%s: Inconsistent State Detected mapBlockIndex.size()=%d blockFileBlocks=%d\n", __func__, vSortedByHeight.size(), vinfoBlockFile[nLastBlockFile].nHeightLast + 1);
LogPrintf("%s: lastIndexPos=%d blockFileSize=%d\n", __func__, vSortedByHeight[vSortedByHeight.size() - 1].second->GetBlockPos().nPos,
vinfoBlockFile[nLastBlockFile].nSize);

//try reading the block from the last index we have
bool isFixed = true;
string strError = "";
LogPrintf("%s: Attempting to re-add last block that was recorded to disk\n", __func__);

//get the last block that was properly recorded to the block info file
CBlockIndex* pindexLastMeta = vSortedByHeight[vinfoBlockFile[nLastBlockFile].nHeightLast + 1].second;

//fix Assertion `hashPrevBlock == view.GetBestBlock()' failed. By adjusting height to the last recorded by coinsview
CBlockIndex* pindexCoinsView = mapBlockIndex[pcoinsTip->GetBestBlock()];
for(unsigned int i = vinfoBlockFile[nLastBlockFile].nHeightLast + 1; i < vSortedByHeight.size(); i++)
{
pindexLastMeta = vSortedByHeight[i].second;
if(pindexLastMeta->nHeight > pindexCoinsView->nHeight)
break;
}

LogPrintf("%s: Last block properly recorded: #%d %s\n", __func__, pindexLastMeta->nHeight, pindexLastMeta->GetBlockHash().ToString().c_str());

CBlock lastMetaBlock;
if (!ReadBlockFromDisk(lastMetaBlock, pindexLastMeta)) {
isFixed = false;
strError = strprintf("failed to read block %d from disk", pindexLastMeta->nHeight);
}
//Fix for Diamind
if (!fLastShutdownWasPrepared && !GetBoolArg("-forcestart", false) && !GetBoolArg("-reindex", false)) {
unsigned int nHeightLastBlockFile = vinfoBlockFile[nLastBlockFile].nHeightLast + 1;
if (vSortedByHeight.size() > nHeightLastBlockFile && pcoinsTip->GetBestBlock() != vSortedByHeight[nHeightLastBlockFile].second->GetBlockHash()) {
//The database is in a state where a block has been accepted and written to disk, but the
//transaction database (pcoinsTip) was not flushed to disk, and is therefore not in sync with
//the block index database.
string strError = "";
if (!mapBlockIndex.count(pcoinsTip->GetBestBlock())) {
strError = "The wallet has been not been closed gracefully, causing the transaction database to be out of sync with the block database";
return false;
}
LogPrintf("%s : pcoinstip synced to block height %d, block index height %d\n", __func__,
mapBlockIndex[pcoinsTip->GetBestBlock()]->nHeight, vSortedByHeight.size());

//get the index associated with the point in the chain that pcoinsTip is synced to
CBlockIndex *pindexLastMeta = vSortedByHeight[vinfoBlockFile[nLastBlockFile].nHeightLast + 1].second;
CBlockIndex *pindex = vSortedByHeight[0].second;
unsigned int nSortedPos = 0;
for (unsigned int i = 0; i < vSortedByHeight.size(); i++) {
nSortedPos = i;
if (vSortedByHeight[i].first == mapBlockIndex[pcoinsTip->GetBestBlock()]->nHeight + 1) {
pindex = vSortedByHeight[i].second;
break;
}
}

//set the chain to the block before lastMeta so that the meta block will be seen as new
chainActive.SetTip(pindexLastMeta->pprev);
// Start at the last block that was successfully added to the txdb (pcoinsTip) and manually add all transactions that occurred for each block up until
// the best known block from the block index db.
CCoinsViewCache view(pcoinsTip);
while (nSortedPos < vSortedByHeight.size()) {
CBlock block;
if (!ReadBlockFromDisk(block, pindex)) {
strError = "The wallet has been not been closed gracefully and has caused corruption of blocks stored to disk. Data directory is in an unusable state";
return false;
}

//Process the lastMetaBlock again, using the known location on disk
CDiskBlockPos blockPos = pindexLastMeta->GetBlockPos();
CValidationState state;
ProcessNewBlock(state, NULL, &lastMetaBlock, &blockPos);
vector<CTxUndo> vtxundo;
vtxundo.reserve(block.vtx.size() - 1);
uint256 hashBlock = block.GetHash();
for (unsigned int i = 0; i < block.vtx.size(); i++) {
CValidationState state;
CTxUndo undoDummy;
if (i > 0)
vtxundo.push_back(CTxUndo());
UpdateCoins(block.vtx[i], state, view, i == 0 ? undoDummy : vtxundo.back(), pindex->nHeight);
view.SetBestBlock(hashBlock);
}

//ensure that everything is as it should be
if (pcoinsTip->GetBestBlock() != vSortedByHeight[vSortedByHeight.size() - 1].second->GetBlockHash()) {
isFixed = false;
strError = "pcoinsTip best block is not correct";
}
if(pindex->nHeight >= pindexLastMeta->nHeight)
break;

//properly account for all of the blocks that were not in the meta data. If this is not done the file
//positioning will be wrong and blocks will be overwritten and later cause serialization errors
CBlockIndex *pindexLast = vSortedByHeight[vSortedByHeight.size() - 1].second;
CBlock lastBlock;
if (!ReadBlockFromDisk(lastBlock, pindexLast)) {
isFixed = false;
strError = strprintf("failed to read block %d from disk", pindexLast->nHeight);
}
vinfoBlockFile[nLastBlockFile].nHeightLast = pindexLast->nHeight;
vinfoBlockFile[nLastBlockFile].nSize = pindexLast->GetBlockPos().nPos + ::GetSerializeSize(lastBlock, SER_DISK, CLIENT_VERSION);;
setDirtyFileInfo.insert(nLastBlockFile);
FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
pindex = vSortedByHeight[++nSortedPos].second;
}

//Print out file info again
pblocktree->ReadLastBlockFile(nLastBlockFile);
vinfoBlockFile.resize(nLastBlockFile + 1);
LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
}
LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
// Save the updates to disk
if (!view.Flush() || !pcoinsTip->Flush())
LogPrintf("%s : failed to flush view\n", __func__);

if (!isFixed) {
strError = "Failed reading from database. " + strError + ". The block database is in an inconsistent state and may cause issues in the future."
"To force start use -forcestart";
uiInterface.ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
abort();
LogPrintf("%s: Last block properly recorded: #%d %s\n", __func__, pindexLastMeta->nHeight,
pindexLastMeta->GetBlockHash().ToString().c_str());
LogPrintf("%s : pcoinstip=%d %s\n", __func__, mapBlockIndex[pcoinsTip->GetBestBlock()]->nHeight,
pcoinsTip->GetBestBlock().GetHex());
}
LogPrintf("Passed corruption fix\n");
}
}

// Check whether we need to continue reindexing
bool fReindexing = false;
Expand Down
2 changes: 1 addition & 1 deletion src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle* networkStyle, QWidget* parent) : QMai

GUIUtil::restoreWindowGeometry("nWindow", QSize(880, 550), this);

QString windowTitle = tr("DMD Diamond Core - Wallet 3.0.0.14") + " - ";
QString windowTitle = tr("DMD Diamond Core - Wallet 3.0.0.15") + " - ";
#ifdef ENABLE_WALLET
/* if compiled with wallet support, -disablewallet can still disable the wallet */
enableWallet = !GetBoolArg("-disablewallet", false);
Expand Down

0 comments on commit bb16260

Please sign in to comment.