-
Notifications
You must be signed in to change notification settings - Fork 715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core][Qt] Rewind block index to last checkpoint functionality #2820
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -182,12 +182,13 @@ static MapCheckpoints mapCheckpoints = { | |
{3014000, uint256S("78ad99b7225f73c42238bd7ca841ff700542b92bba75a0ef2ed351caa560f87f")}, //!< PIVX v5.3.0 enforced | ||
{3024000, uint256S("be4bc75afcfb9136924810f7483b2695089a366cc4ee27fd6dc3ecd5396e1f0f")}, //!< Superblock | ||
{3715200, uint256S("a676b9a598c393c82b949c37dd35013aeda55f5d18ab062349db6a8235972aaa")}, //!< Superblock for 5.5.0 mainnet rewards changeover | ||
{3780000, uint256S("2667fa1d552999aca930ced7fd3902ae5721e5c256a607049e3c47a3137a18ee")}, //!< Fri, 10 Mar 2023 rewindblockindex testing | ||
}; | ||
|
||
static const CCheckpointData data = { | ||
&mapCheckpoints, | ||
1591401645, // * UNIX timestamp of last checkpoint block | ||
5607713, // * total number of transactions between genesis and last checkpoint | ||
1678401150, // * UNIX timestamp of last checkpoint block | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hence re-update those with last v5.5 checkpoint There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, I will rebase and we just make sure to update more checkpoints more frequently |
||
8716106, // * total number of transactions between genesis and last checkpoint | ||
// (the tx=... number in the UpdateTip debug.log lines) | ||
3000 // * estimated number of transactions per day after checkpoint | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3741,6 +3741,102 @@ bool CVerifyDB::VerifyDB(CCoinsView* coinsview, int nCheckLevel, int nCheckDepth | |
return true; | ||
} | ||
|
||
bool RewindBlockIndexToLastCheckpoint(const CChainParams& chainparams, bool& clearWitnessCaches, bool fJustCheck) | ||
{ | ||
LOCK(cs_main); | ||
|
||
// Get current Height and current Checkpoints | ||
int nHeight = chainActive.Height(); | ||
const CBlockIndex* prevCheckPoint = GetLastCheckpoint(); | ||
const int checkPointHeight = prevCheckPoint ? prevCheckPoint->nHeight : 0; | ||
|
||
// First load options | ||
if(!fJustCheck) | ||
return true; | ||
Comment on lines
+3753
to
+3755
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we automatically detect if a rewind is needed?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there are checkpoints between the tip and the last (known) checkpoint, we are not on the right chain. and this is right, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not see a possibility in automatically detecting a rewind. In such we have two cases: IE: Checkpoint block is 2150000, we are at block 2150010, if there was any in-between, that user would already have synced those |
||
|
||
clearWitnessCaches = true; | ||
CValidationState state; | ||
const int blocksToRollBack = nHeight - checkPointHeight; | ||
// Iterate to start removing blocks | ||
while (nHeight > checkPointHeight) { | ||
if (!DisconnectTip(state, chainparams, nullptr)) { | ||
return error("%s: unable to disconnect block at height %i", __func__, nHeight); | ||
} | ||
// Occasionally flush state to disk. | ||
if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) | ||
return false; | ||
|
||
nHeight = chainActive.Height(); | ||
} | ||
|
||
// Collect blocks to be removed (blocks in mapBlockIndex must be at least BLOCK_VALID_TREE). | ||
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data | ||
// to disk before writing the chainstate, resulting in a failure to continue if interrupted. | ||
std::vector<const CBlockIndex*> vBlocks; | ||
for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { | ||
CBlockIndex* pindexIter = it->second; | ||
if (!chainActive.Contains(pindexIter)) { | ||
// Add to the list of blocks to remove | ||
vBlocks.emplace_back(pindexIter); | ||
if (pindexIter == pindexBestInvalid) { | ||
// Reset invalid block marker if it was pointing to this block | ||
pindexBestInvalid = nullptr; | ||
} | ||
// Reduce validity | ||
pindexIter->nStatus = std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) | (pindexIter->nStatus & ~BLOCK_VALID_MASK); | ||
// Remove have-data flags. | ||
pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO); | ||
// Remove storage location. | ||
pindexIter->nFile = 0; | ||
pindexIter->nDataPos = 0; | ||
pindexIter->nUndoPos = 0; | ||
// Remove various other things | ||
pindexIter->nTx = 0; | ||
pindexIter->nChainTx = 0; | ||
pindexIter->nSequenceId = 0; | ||
// Update indices | ||
setBlockIndexCandidates.erase(pindexIter); | ||
auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev); | ||
while (ret.first != ret.second) { | ||
if (ret.first->second == pindexIter) { | ||
ret.first = mapBlocksUnlinked.erase(ret.first); | ||
} else { | ||
++ret.first; | ||
} | ||
} | ||
} else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) { | ||
setBlockIndexCandidates.insert(pindexIter); | ||
} | ||
} | ||
|
||
// Set pindexBestHeader to the current chain tip | ||
// (since we are about to delete the block it is pointing to) | ||
pindexBestHeader = chainActive.Tip(); | ||
|
||
// Erase block indices on-disk | ||
if (!pblocktree->EraseBatchSync(vBlocks)) { | ||
return AbortNode(state, "Failed to erase from block index database"); | ||
} | ||
|
||
// Erase block indices in-memory | ||
for (auto pindex : vBlocks) { | ||
auto ret = mapBlockIndex.find(*pindex->phashBlock); | ||
if (ret != mapBlockIndex.end()) { | ||
mapBlockIndex.erase(ret); | ||
delete pindex; | ||
} | ||
} | ||
|
||
CheckBlockIndex(); | ||
|
||
if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
|
||
/** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */ | ||
static bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This checkpoint is useless
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree! I should have prefaced thats for testing since the last checkpoint was a big further back and would have been a faster sync