diff --git a/src/masternodes/undos.cpp b/src/masternodes/undos.cpp index ba9f452e2a..ebc6176c52 100644 --- a/src/masternodes/undos.cpp +++ b/src/masternodes/undos.cpp @@ -7,24 +7,24 @@ /// @attention make sure that it does not overlap with those in masternodes.cpp/tokens.cpp/undos.cpp/accounts.cpp !!! const unsigned char CUndosView::ByUndoKey::prefix = 'u'; -void CUndosView::ForEachUndo(std::function)> callback, UndoKey const & start) +void CUndosView::ForEachUndo(std::function)> callback, UndoKey const & start) { ForEach(callback, start); } -Res CUndosView::SetUndo(UndoKey key, CUndo const & undo) +Res CUndosView::SetUndo(UndoKey const & key, CUndo const & undo) { WriteBy(key, undo); return Res::Ok(); } -Res CUndosView::DelUndo(UndoKey key) +Res CUndosView::DelUndo(UndoKey const & key) { EraseBy(key); return Res::Ok(); } -boost::optional CUndosView::GetUndo(UndoKey key) const +boost::optional CUndosView::GetUndo(UndoKey const & key) const { CUndo val; bool ok = ReadBy(key, val); diff --git a/src/masternodes/undos.h b/src/masternodes/undos.h index 76b29908b9..2d215e8184 100644 --- a/src/masternodes/undos.h +++ b/src/masternodes/undos.h @@ -11,11 +11,11 @@ class CUndosView : public virtual CStorageView { public: - void ForEachUndo(std::function)> callback, UndoKey const & start = {}); + void ForEachUndo(std::function)> callback, UndoKey const & start = {}); - boost::optional GetUndo(UndoKey key) const; - Res SetUndo(UndoKey key, CUndo const & undo); - Res DelUndo(UndoKey key); + boost::optional GetUndo(UndoKey const & key) const; + Res SetUndo(UndoKey const & key, CUndo const & undo); + Res DelUndo(UndoKey const & key); // tags struct ByUndoKey { static const unsigned char prefix; }; diff --git a/src/validation.cpp b/src/validation.cpp index 3fd88d2d2c..cbfb6b041e 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2419,6 +2419,22 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl } mnview.SetLastHeight(pindex->nHeight); + if (fCheckpointsEnabled) { + auto &checkpoints = chainparams.Checkpoints().mapCheckpoints; + auto it = checkpoints.lower_bound(pindex->nHeight); + if (it != checkpoints.begin()) { + --it; + CCustomCSView pruned(mnview); + mnview.ForEachUndo([&](UndoKey const & key, CLazySerialize) { + if (key.height >= it->first) { // don't erase checkpoint height + return false; + } + return pruned.DelUndo(key).ok; + }); + pruned.Flush(); + } + } + int64_t nTime5 = GetTimeMicros(); nTimeIndex += nTime5 - nTime4; LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5 - nTime4), nTimeIndex * MICRO, nTimeIndex * MILLI / nBlocksTotal); @@ -3007,7 +3023,7 @@ bool CChainState::ActivateBestChainStep(CValidationState& state, const CChainPar InvalidChainFound(vpindexToConnect.front()); } state = CValidationState(); - if (pindexConnect == pindexMostWork) { + if (fCheckpointsEnabled && pindexConnect == pindexMostWork) { // NOTE: Invalidate blocks back to last checkpoint auto &checkpoints = chainparams.Checkpoints().mapCheckpoints; auto it = checkpoints.lower_bound(pindexConnect->nHeight);