Skip to content

Commit

Permalink
Support testnet rollback.
Browse files Browse the repository at this point in the history
Signed-off-by: Daira Hopwood <[email protected]>
  • Loading branch information
daira committed Aug 2, 2018
1 parent 871e172 commit 66856b2
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 21 deletions.
6 changes: 4 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024));

bool clearWitnessCaches = false;

bool fLoaded = false;
while (!fLoaded) {
bool fReset = fReindex;
Expand Down Expand Up @@ -1502,7 +1504,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)

if (!fReindex) {
uiInterface.InitMessage(_("Rewinding blocks if needed..."));
if (!RewindBlockIndex(chainparams)) {
if (!RewindBlockIndex(chainparams, clearWitnessCaches)) {
strLoadError = _("Unable to rewind the database to a pre-upgrade state. You will need to redownload the blockchain");
break;
}
Expand Down Expand Up @@ -1652,7 +1654,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterValidationInterface(pwalletMain);

CBlockIndex *pindexRescan = chainActive.Tip();
if (GetBoolArg("-rescan", false))
if (clearWitnessCaches || GetBoolArg("-rescan", false))
{
pwalletMain->ClearNoteWitnessCache();
pindexRescan = chainActive.Genesis();
Expand Down
58 changes: 40 additions & 18 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4217,7 +4217,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
return true;
}

bool RewindBlockIndex(const CChainParams& params)
bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches)
{
LOCK(cs_main);

Expand Down Expand Up @@ -4249,23 +4249,45 @@ bool RewindBlockIndex(const CChainParams& params)

// nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
auto rewindLength = chainActive.Height() - nHeight;
if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH) {
auto pindexOldTip = chainActive.Tip();
auto pindexRewind = chainActive[nHeight - 1];
auto msg = strprintf(_(
"A block chain rewind has been detected that would roll back %d blocks! "
"This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
_("Rewind details") + ":\n" +
"- " + strprintf(_("Current tip: %s, height %d"),
pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" +
"- " + strprintf(_("Rewinding to: %s, height %d"),
pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" +
_("Please help, human!");
LogPrintf("*** %s\n", msg);
uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
StartShutdown();
return false;
LogPrintf("*** First insufficiently validated block at height %d, rewind length %d\n", nHeight, rewindLength);
clearWitnessCaches = false;

if (rewindLength > 0) {
const uint256 *phashFirstInsufValidated = chainActive[nHeight]->phashBlock;
auto networkID = params.NetworkIDString();

// This is true when we intend to do a long rewind.
bool intendedRewind =
(networkID == "test" && nHeight == 252500 && *phashFirstInsufValidated ==
uint256S("0018bd16a9c6f15795a754c498d2b2083ab78f14dae44a66a8d0e90ba8464d9c"));

clearWitnessCaches = (rewindLength > MAX_REORG_LENGTH && intendedRewind);

if (clearWitnessCaches) {
auto msg = strprintf(_(
"An intended block chain rewind has been detected: network %s, hash %s, height %d"
), networkID, phashFirstInsufValidated->GetHex(), nHeight);
LogPrintf("*** %s\n", msg);
}

if (rewindLength > MAX_REORG_LENGTH && !intendedRewind) {
auto pindexOldTip = chainActive.Tip();
auto pindexRewind = chainActive[nHeight - 1];
auto msg = strprintf(_(
"A block chain rewind has been detected that would roll back %d blocks! "
"This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
_("Rewind details") + ":\n" +
"- " + strprintf(_("Current tip: %s, height %d"),
pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" +
"- " + strprintf(_("Rewinding to: %s, height %d"),
pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" +
_("Please help, human!");
LogPrintf("*** %s\n", msg);
uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
StartShutdown();
return false;
}
}

CValidationState state;
Expand Down
5 changes: 4 additions & 1 deletion src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,11 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
* When there are blocks in the active chain with missing data (e.g. if the
* activation height and branch ID of a particular upgrade have been altered),
* rewind the chainstate and remove them from the block index.
*
* clearWitnessCaches is an output parameter that will be set to true iff
* witness caches should be cleared in order to handle an intended long rewind.
*/
bool RewindBlockIndex(const CChainParams& params);
bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches);

class CBlockFileInfo
{
Expand Down

0 comments on commit 66856b2

Please sign in to comment.