Auto merge of #3443 - daira:testnet-rollback, r=str4d

Support testnet rollback.

Part of #1302. Closes #2905.
This commit is contained in:
Homu 2018-08-08 05:28:08 -07:00
commit 40f320e0ee
3 changed files with 48 additions and 21 deletions

View File

@ -1434,6 +1434,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;
@ -1493,7 +1495,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;
}
@ -1643,7 +1645,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;
clearWitnessCaches = false;
if (rewindLength > 0) {
LogPrintf("*** First insufficiently validated block at height %d, rewind length %d\n", nHeight, rewindLength);
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
{