Support testnet rollback.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2018-07-31 22:29:14 +01:00
parent 871e1726c6
commit 66856b2b3c
3 changed files with 48 additions and 21 deletions

View File

@ -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;
@ -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;
}
@ -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();

View File

@ -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);
@ -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;

View File

@ -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
{