Skip to content

Commit

Permalink
Automate database corruption fix caused by out of sync txdb.
Browse files Browse the repository at this point in the history
  • Loading branch information
presstab committed Nov 21, 2017
1 parent 84e0dc3 commit 5654732
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 135 deletions.
7 changes: 4 additions & 3 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ static Checkpoints::MapCheckpoints mapCheckpoints =
(867733, uint256("03b26296bf693de5782c76843d2fb649cb66d4b05550c6a79c047ff7e1c3ae15"))
(879650, uint256("227e1d2b738b6cd83c46d1d64617934ec899d77cee34336a56e61b71acd10bb2"))
(895400, uint256("7796a0274a608fac12d400198174e50beda992c1d522e52e5b95b884bc1beac6"))//block that serial# range is enforced
(895991, uint256("d53013ed7ea5c325b9696c95e07667d6858f8ff7ee13fecfa90827bf3c9ae316"));//network split here
(895991, uint256("d53013ed7ea5c325b9696c95e07667d6858f8ff7ee13fecfa90827bf3c9ae316"))//network split here
(908000, uint256("202708f8c289b676fceb832a079ff6b308a28608339acbf7584de533619d014d"));
static const Checkpoints::CCheckpointData data = {
&mapCheckpoints,
1510187238, // * UNIX timestamp of last checkpoint block
1816040, // * total number of transactions between genesis and last checkpoint
1510948627, // * UNIX timestamp of last checkpoint block
1842739, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
2000 // * estimated number of transactions per day after checkpoint
};
Expand Down
14 changes: 12 additions & 2 deletions src/checkpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,25 @@ static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;

bool fEnabled = true;

bool CheckBlock(int nHeight, const uint256& hash)
bool CheckBlock(int nHeight, const uint256& hash, bool fMatchesCheckpoint)
{
if (!fEnabled)
return true;

const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;

MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
if (i == checkpoints.end()) return true;
// If looking for an exact match, then return false
if (i == checkpoints.end()) return !fMatchesCheckpoint;
return hash == i->second;
}

//! Returns true only when both the height and hash match a checkpoint
bool IsCheckpointedBlock(int nHeight, const uint256& hash)
{
const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
if (i == checkpoints.end()) return false;
return hash == i->second;
}

Expand Down
2 changes: 1 addition & 1 deletion src/checkpoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct CCheckpointData {
};

//! Returns true if block passes checkpoint checks
bool CheckBlock(int nHeight, const uint256& hash);
bool CheckBlock(int nHeight, const uint256& hash, bool fMatchesCheckpoint = false);

//! Return conservative estimate of total number of blocks, 0 if unknown
int GetTotalBlocksEstimate();
Expand Down
54 changes: 4 additions & 50 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1371,59 +1371,13 @@ bool AppInit2(boost::thread_group& threadGroup)
}

// PIVX: recalculate Accumulator Checkpoints that failed to database properly
if (!listAccCheckpointsNoDB.empty() && chainActive.Tip()->GetBlockHeader().nVersion >= Params().Zerocoin_HeaderVersion()) {
if (!listAccCheckpointsNoDB.empty()) {
uiInterface.InitMessage(_("Calculating missing accumulators..."));
LogPrintf("%s : finding missing checkpoints\n", __func__);

//search the chain to see when zerocoin started
int nZerocoinStart = 0;
CBlockIndex* pindex = chainActive.Tip();
while (pindex->pprev) {
if (pindex->GetBlockHeader().nVersion >= Params().Zerocoin_HeaderVersion())
nZerocoinStart = pindex->nHeight;
else if (nZerocoinStart)
break;

pindex = pindex->pprev;
}

// find each checkpoint that is missing
pindex = chainActive[nZerocoinStart];
while (!listAccCheckpointsNoDB.empty()) {
if (ShutdownRequested())
break;

// find checkpoints by iterating through the blockchain beginning with the first zerocoin block
if (pindex->nAccumulatorCheckpoint != pindex->pprev->nAccumulatorCheckpoint) {

double dPercent = (pindex->nHeight - nZerocoinStart) / (double)(chainActive.Height() - nZerocoinStart);
uiInterface.ShowProgress(_("Calculating missing accumulators..."), (int)(dPercent * 100));
if(find(listAccCheckpointsNoDB.begin(), listAccCheckpointsNoDB.end(), pindex->nAccumulatorCheckpoint) != listAccCheckpointsNoDB.end()) {
uint256 nCheckpointCalculated = 0;
if (!CalculateAccumulatorCheckpoint(pindex->nHeight, nCheckpointCalculated)) {
// GetCheckpoint could have terminated due to a shutdown request. Check this here.
if (ShutdownRequested())
break;
return InitError(_("Failed to calculate accumulator checkpoint"));
}

//check that the calculated checkpoint is what is in the index.
if(nCheckpointCalculated != pindex->nAccumulatorCheckpoint) {
LogPrintf("%s : height=%d calculated_checkpoint=%s actual=%s\n", __func__, pindex->nHeight, nCheckpointCalculated.GetHex(), pindex->nAccumulatorCheckpoint.GetHex());
return InitError(_("Calculated accumulator checkpoint is not what is recorded by block index"));
}

auto it = find(listAccCheckpointsNoDB.begin(), listAccCheckpointsNoDB.end(), pindex->nAccumulatorCheckpoint);
listAccCheckpointsNoDB.erase(it);
}
}

// if we have iterated to the end of the blockchain, then checkpoints should be in sync
if (pindex->nHeight + 1 <= chainActive.Height())
pindex = chainActive[pindex->nHeight + 1];
else
break;
}
string strError;
if (!ReindexAccumulators(listAccCheckpointsNoDB, strError))
return InitError(strError);
}

uiInterface.InitMessage(_("Verifying blocks..."));
Expand Down
Loading

0 comments on commit 5654732

Please sign in to comment.