|
16 | 16 | #include <consensus/validation.h> |
17 | 17 | #include <deploymentstatus.h> |
18 | 18 | #include <messagesigner.h> |
| 19 | +#include <node/blockstorage.h> |
19 | 20 | #include <script/standard.h> |
20 | 21 | #include <stats/client.h> |
21 | 22 | #include <uint256.h> |
@@ -779,6 +780,23 @@ CDeterministicMNList CDeterministicMNManager::GetListForBlockInternal(gsl::not_n |
779 | 780 | for (const auto& diffIndex : listDiffIndexes) { |
780 | 781 | const auto& diff = mnListDiffsCache.at(diffIndex->GetBlockHash()); |
781 | 782 | snapshot.ApplyDiff(diffIndex, diff); |
| 783 | + |
| 784 | + static constexpr int MINI_SNAPSHOT_INTERVAL = 32; |
| 785 | + if (!node::fReindex && snapshot.GetHeight() % MINI_SNAPSHOT_INTERVAL == 0) { |
| 786 | + // Add this temporary mini-snapshot to the cache. |
| 787 | + // Persistent masternode list snapshots are stored in evo-db every 576 blocks. |
| 788 | + // To answer GetListForBlock() between these snapshots, the node must rebuild |
| 789 | + // state by applying up to 575 diffs from the nearest persistent snapshot. |
| 790 | + // If GetListForBlock() is called repeatedly in that range, the work multiplies |
| 791 | + // (up to 575 diffs * number of calls). |
| 792 | + // Mini-snapshots reduce this overhead by caching intermediate states |
| 793 | + // every MINI_SNAPSHOT_INTERVAL blocks. Unlike persistent snapshots, these live |
| 794 | + // only in memory and are cleaned up after a short time by the scheduled cleanup(). |
| 795 | + // There is also separate in-memory caching for the current tip and active quorums, |
| 796 | + // but this mini-snapshot cache specifically speeds up repeated requests |
| 797 | + // for nearby historical blocks. |
| 798 | + mnListsCache.emplace(snapshot.GetBlockHash(), snapshot); |
| 799 | + } |
782 | 800 | } |
783 | 801 |
|
784 | 802 | if (tipIndex) { |
|
0 commit comments