From a4d62721a52050a0a94b5fad751b244dadd1d9e3 Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Tue, 2 Aug 2022 10:07:26 +0100 Subject: [PATCH] Delete old confirms to prevent ballooning memory usage --- src/validation.cpp | 31 ++++++++++++++++++------------- src/validation.h | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 80da5b61ff..625155a149 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2476,7 +2476,7 @@ bool StopOrInterruptConnect(const CBlockIndex *pIndex, CValidationState& state) * Validity checks that depend on the UTXO set are also done; ConnectBlock () * can fail if those validity checks fail (among other reasons). */ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, - CCoinsViewCache& view, CCustomCSView& mnview, const CChainParams& chainparams, std::vector & rewardedAnchors, bool fJustCheck) + CCoinsViewCache& view, CCustomCSView& mnview, const CChainParams& chainparams, bool & rewardedAnchors, bool fJustCheck) { AssertLockHeld(cs_main); assert(pindex); @@ -2846,7 +2846,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl error("%s: %s", __func__, res.msg), REJECT_INVALID, res.dbgMsg); } - rewardedAnchors.push_back(*res.val); + rewardedAnchors = true; if (!fJustCheck) { LogPrint(BCLog::ANCHORING, "%s: connected finalization tx: %s block: %d\n", __func__, tx.GetHash().GetHex(), pindex->nHeight); } @@ -2860,7 +2860,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl error("%s: %s", __func__, res.msg), REJECT_INVALID, res.dbgMsg); } - rewardedAnchors.push_back(*res.val); + rewardedAnchors = true; if (!fJustCheck) { LogPrint(BCLog::ANCHORING, "%s: connected finalization tx: %s block: %d\n", __func__, tx.GetHash().GetHex(), pindex->nHeight); } @@ -5181,8 +5181,8 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO); { CCoinsViewCache view(&CoinsTip()); - CCustomCSView mnview(*pcustomcsview.get()); - std::vector rewardedAnchors; + CCustomCSView mnview(*pcustomcsview); + bool rewardedAnchors{}; bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, mnview, chainparams, rewardedAnchors); GetMainSignals().BlockChecked(blockConnecting, state); if (!rv) { @@ -5217,11 +5217,16 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp pvaultHistoryDB->Flush(); } - // anchor rewards re-voting etc... - if (!rewardedAnchors.empty()) { - // we do not clear ALL votes (even they are stale) for the case of rapid tip changing. At least, they'll be deleted after their rewards - for (auto const & btcTxHash : rewardedAnchors) { - panchorAwaitingConfirms->EraseAnchor(btcTxHash); + // Delete all other confirms from memory + if (rewardedAnchors) { + std::vector oldConfirms; + panchorAwaitingConfirms->ForEachConfirm([&oldConfirms](const CAnchorConfirmMessage &confirm) { + oldConfirms.push_back(confirm.btcTxHash); + return true; + }); + + for (const auto &confirm: oldConfirms) { + panchorAwaitingConfirms->EraseAnchor(confirm); } } } @@ -6721,8 +6726,8 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, AssertLockHeld(cs_main); assert(pindexPrev && pindexPrev == ::ChainActive().Tip()); CCoinsViewCache viewNew(&::ChainstateActive().CoinsTip()); - std::vector dummyRewardedAnchors; - CCustomCSView mnview(*pcustomcsview.get()); + bool dummyRewardedAnchors{}; + CCustomCSView mnview(*pcustomcsview); uint256 block_hash(block.GetHash()); CBlockIndex indexDummy(block); indexDummy.pprev = pindexPrev; @@ -7199,7 +7204,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, CBlock block; if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); - std::vector dummyRewardedAnchors; + bool dummyRewardedAnchors{}; if (!::ChainstateActive().ConnectBlock(block, state, pindex, coins, mnview, chainparams, dummyRewardedAnchors)) return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); if (ShutdownRequested()) return true; diff --git a/src/validation.h b/src/validation.h index 8d4c609d60..6a975b6ae4 100644 --- a/src/validation.h +++ b/src/validation.h @@ -727,7 +727,7 @@ class CChainState { // Block (dis)connection on a given view: DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view, CCustomCSView& cache, std::vector & disconnectedAnchorConfirms); bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, - CCoinsViewCache& view, CCustomCSView& cache, const CChainParams& chainparams, std::vector & rewardedAnchors, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); + CCoinsViewCache& view, CCustomCSView& cache, const CChainParams& chainparams, bool & rewardedAnchors, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Apply the effects of a block disconnection on the UTXO set. bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);