Skip to content

Commit

Permalink
Merge #405: [Main] Automate database corruption fix caused by out of …
Browse files Browse the repository at this point in the history
…sync txdb.

8469261 Deprecate spork_11. (presstab)
15c355b Ask for sporks from 1st peer. Consider Verifying Blocks as IDB. (presstab)
43af66b Add message popup when db corrupt. Make ReindexAccumulators() use ref list. (presstab)
3eabaa2 Remove unused code and add null check. (presstab)
5654732 Automate database corruption fix caused by out of sync txdb. (presstab)

Tree-SHA512: 6c612d7a8e6a80c456514c402afb161932d947fa9761544ab6f53df6932969095bfd4022a2f426913bcf1456fc5369b654c58cbfd5065081ee29634843dfe7c4
  • Loading branch information
Mrs-X committed Nov 24, 2017
2 parents beae959 + 8469261 commit e415420
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 148 deletions.
9 changes: 6 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 Expand Up @@ -139,6 +140,7 @@ class CMainParams : public CChainParams
nBlockRecalculateAccumulators = 908000; //Trigger a recalculation of accumulators
nBlockFirstFraudulent = 891737; //First block that bad serials emerged
nBlockLastGoodCheckpoint = 891730; //Last valid accumulator checkpoint
nBlockEnforceInvalidUTXO = 902850; //Start enforcing the invalid UTXO's

/**
* Build the genesis block. Note that the output of the genesis coinbase cannot
Expand Down Expand Up @@ -256,6 +258,7 @@ class CTestNetParams : public CMainParams
nBlockRecalculateAccumulators = 9908000; //Trigger a recalculation of accumulators
nBlockFirstFraudulent = 9891737; //First block that bad serials emerged
nBlockLastGoodCheckpoint = 9891730; //Last valid accumulator checkpoint
nBlockEnforceInvalidUTXO = 9902850; //Start enforcing the invalid UTXO's

//! Modify the testnet genesis block so the timestamp is valid for a later start.
genesis.nTime = 1454124731;
Expand Down
2 changes: 2 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class CChainParams
int Zerocoin_Block_FirstFraudulent() const { return nBlockFirstFraudulent; }
int Zerocoin_Block_LastGoodCheckpoint() const { return nBlockLastGoodCheckpoint; }
int Zerocoin_StartTime() const { return nZerocoinStartTime; }
int Block_Enforce_Invalid() const { return nBlockEnforceInvalidUTXO; }

protected:
CChainParams() {}
Expand Down Expand Up @@ -173,6 +174,7 @@ class CChainParams
int nBlockRecalculateAccumulators;
int nBlockFirstFraudulent;
int nBlockLastGoodCheckpoint;
int nBlockEnforceInvalidUTXO;
};

/**
Expand Down
5 changes: 3 additions & 2 deletions src/checkpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ 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;
}

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
58 changes: 7 additions & 51 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1326,8 +1326,10 @@ bool AppInit2(boost::thread_group& threadGroup)
LoadSporksFromDB();

uiInterface.InitMessage(_("Loading block index..."));
if (!LoadBlockIndex()) {
string strBlockIndexError = "";
if (!LoadBlockIndex(strBlockIndexError)) {
strLoadError = _("Error loading block database");
strLoadError = strprintf("%s : %s", strLoadError, strBlockIndexError);
break;
}

Expand Down Expand Up @@ -1371,59 +1373,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 e415420

Please sign in to comment.