Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
3027043
Merge bitcoin/bitcoin#25651: refactor: make all NodeImpl/ChainImpl/Ex…
Aug 1, 2022
83ba97c
refactor: remove make-up code from backport bitcoin#26933 by pasta-claw
knst Jun 22, 2026
e16afad
Merge bitcoin/bitcoin#25648: refactor: Remove all policy globals
glozow Aug 3, 2022
c0075b8
Merge bitcoin/bitcoin#25772: test: Add missing static to IsStandardTx…
fanquake Aug 3, 2022
14a050c
Merge bitcoin/bitcoin#25905: refactor: Move ChainstateManager options…
Aug 25, 2022
f180d15
Merge bitcoin/bitcoin#25951: log: Move validation option logging to L…
Sep 1, 2022
8ea330d
Merge bitcoin/bitcoin#25222: refactor: Pass reference to LookUpStats
Sep 13, 2022
cd9aa77
Merge bitcoin/bitcoin#25971: refactor: Use std::string for thread and…
Sep 16, 2022
bc1ebc2
Merge bitcoin/bitcoin#26250: fuzz: add mempool_utils.cpp
Oct 5, 2022
4bab3fe
Merge bitcoin/bitcoin#26103: refactor: mempool: use CTxMemPool::Limits
glozow Oct 9, 2022
f8d3c09
fix(llmq): treat unregistered types as inactive in IsQuorumActive
PastaPastaPasta Aug 4, 2026
9f026a9
fix: bound DYNBITSET allocation against remaining stream size
PastaPastaPasta Aug 3, 2026
e42e666
chore: drop low-value IsQuorumActive comments and test
PastaPastaPasta Aug 4, 2026
43ec910
Merge #7525: backport: bitcoin#25222, #25648, #25651, #25772, #25905,…
PastaPastaPasta Aug 5, 2026
2dcef69
refactor: pass CDeterministicMNManager by reference to CDSNotificatio…
PastaPastaPasta Aug 5, 2026
d1b4f75
refactor: move CDSNotificationInterface into NodeContext
PastaPastaPasta Aug 5, 2026
e5c8384
fix(net): address ChainLock seen-cache follow-up
PastaPastaPasta Aug 5, 2026
dc1d21e
Merge #7544: fix: treat unregistered types as inactive in IsQuorumActive
PastaPastaPasta Aug 6, 2026
aa1447f
serialize: require SizedStream for ReadFixedBitSet instead of duck-ty…
PastaPastaPasta Aug 3, 2026
13336e8
Merge bitcoin/bitcoin#25204: rpc: remove deprecated top-level fee fie…
knst May 30, 2022
a48944e
partial Merge bitcoin-core/gui#613: Remove unnecessary wallet include…
knst Jun 2, 2022
ce720b3
Merge bitcoin/bitcoin#25689: fuzz: Remove no-op SetMempoolConstraints
knst Jul 26, 2022
8fc8f80
Merge bitcoin/bitcoin#25785: bench: Add a benchmark for descriptor ex…
knst Aug 12, 2022
f95d19b
fix: follow-up for bitcoin#21148 - orphanage should be cleaned by the…
knst Aug 6, 2026
92243fb
Merge #18628: test: Add various low-level p2p tests
knst Apr 15, 2020
452481a
Merge bitcoin/bitcoin#19393: test: Add more tests for orphan tx handling
knst Jul 5, 2022
c4c8b98
Merge #7548: fix(net): follow up on ChainLock cache feedback
PastaPastaPasta Aug 6, 2026
032e959
Merge #7546: refactor: move CDSNotificationInterface into NodeContext
PastaPastaPasta Aug 6, 2026
2f0bd0e
test: restore complete spork21 signing coverage
PastaPastaPasta Aug 6, 2026
4c33e73
Merge #7532: fix: bound DYNBITSET allocation against remaining stream…
PastaPastaPasta Aug 7, 2026
0c4973f
Merge #7552: test: restore complete spork21 signing coverage
PastaPastaPasta Aug 7, 2026
5eec6ae
Merge #7551: backport: bitcoin#18628, #19393, #25204, #25689, #25785,…
PastaPastaPasta Aug 7, 2026
fbd895c
partial Merge bitcoin/bitcoin#25717: p2p: Implement anti-DoS headers …
knst Aug 30, 2022
30ab363
Merge bitcoin/bitcoin#25963: CBlockLocator: performance-move-const-ar…
knst Aug 31, 2022
abb7ab4
Merge #7514: backport: partial bitcoin#25717, #25963 - anti-dos heade…
PastaPastaPasta Aug 7, 2026
ab65592
Merge #7456: backport: assumeutxo M2 — EvoDB multi-chainstate isolati…
PastaPastaPasta Aug 7, 2026
483b3d7
Merge bitcoin/bitcoin#25740: assumeutxo: background validation comple…
PastaPastaPasta Jul 11, 2026
9cfc65a
backport: adapt Dash EvoDB completion path for bitcoin#25740
PastaPastaPasta Jul 11, 2026
3da9105
Merge bitcoin/bitcoin#27862: validation: Stricter assumeutxo error ha…
PastaPastaPasta Jul 11, 2026
d1ffdd6
Merge bitcoin/bitcoin#28050: test: make assumeUTXO test capture the e…
PastaPastaPasta Jul 11, 2026
43efc47
Merge bitcoin/bitcoin#27746: Rework validation logic for assumeutxo
ryanofsky Jul 31, 2023
2ef1222
backport: adapt bitcoin#27746 for Dash
PastaPastaPasta Jul 11, 2026
44bd797
refactor: share the block-data-unavailable sentinel as a named constant
PastaPastaPasta Aug 7, 2026
ab3b671
validation: move the mempool to the snapshot chainstate on activation
PastaPastaPasta Aug 7, 2026
cedba66
docs: note the cross-chainstate duplicate-commitment corner
PastaPastaPasta Aug 7, 2026
4b1294c
test: assert cold snapshot activation captures no base MN-list marker
PastaPastaPasta Aug 7, 2026
413afb1
fix: report a missing snapshot base block as a startup error, not an …
PastaPastaPasta Aug 11, 2026
d16440b
refactor: centralize durable rename/remove for the snapshot lifecycle
PastaPastaPasta Aug 11, 2026
a8b6790
docs: fix stale check_block_index reference and explain deferred cand…
PastaPastaPasta Aug 11, 2026
c28ddc8
test: cover background MN-hash erase and the promote/discard recovery…
PastaPastaPasta Aug 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/dash/lint-tidy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ iwyu_tool.py \
"src/init" \
"src/kernel" \
"src/node/chainstate.cpp" \
"src/node/mempool_args.cpp" \
"src/node/minisketchwrapper.cpp" \
"src/policy/feerate.cpp" \
"src/policy/packages.cpp" \
Expand Down
68 changes: 36 additions & 32 deletions doc/design/assumeutxo.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
Assumeutxo is a feature that allows fast bootstrapping of a validating dashd
instance with a very similar security model to assumevalid.

The RPC commands `dumptxoutset` and `loadtxoutset` are used to respectively generate
and load UTXO snapshots. The utility script `./contrib/devtools/utxo_snapshot.sh` may
be of use.
The RPC commands `dumptxoutset` and `loadtxoutset` (yet to be merged) are used to
respectively generate and load UTXO snapshots. The utility script
`./contrib/devtools/utxo_snapshot.sh` may be of use.

## General background

Expand All @@ -17,14 +17,9 @@ be of use.

- A new block index `nStatus` flag is introduced, `BLOCK_ASSUMED_VALID`, to mark block
index entries that are required to be assumed-valid by a chainstate created
from a UTXO snapshot. This flag is mostly used as a way to modify certain
from a UTXO snapshot. This flag is used as a way to modify certain
CheckBlockIndex() logic to account for index entries that are pending validation by a
chainstate running asynchronously in the background. We also use this flag to control
which index entries are added to setBlockIndexCandidates during LoadBlockIndex().

- Indexing implementations via BaseIndex can no longer assume that indexation happens
sequentially, since background validation chainstates can submit BlockConnected
events out of order with the active chain.
chainstate running asynchronously in the background.

- The concept of UTXO snapshots is treated as an implementation detail that lives
behind the ChainstateManager interface. The external presentation of the changes
Expand Down Expand Up @@ -76,9 +71,15 @@ original chainstate remains in use as active.

Once the snapshot chainstate is loaded and validated, it is promoted to active
chainstate and a sync to tip begins. A new chainstate directory is created in the
datadir for the snapshot chainstate called `chainstate_snapshot`. When this directory
is present in the datadir, the snapshot chainstate will be detected and loaded as
active on node startup (via `DetectSnapshotChainstate()`).
datadir for the snapshot chainstate called `chainstate_snapshot`.

When this directory is present in the datadir, the snapshot chainstate will be detected
and loaded as active on node startup (via `DetectSnapshotChainstate()`).

A special file is created within that directory, `base_blockhash`, which contains the
serialized `uint256` of the base block of the snapshot. This is used to reinitialize
the snapshot chainstate on subsequent inits. Otherwise, the directory is a normal
leveldb database.

| | |
| ---------- | ----------- |
Expand All @@ -88,7 +89,7 @@ active on node startup (via `DetectSnapshotChainstate()`).
The snapshot begins to sync to tip from its base block, technically in parallel with
the original chainstate, but it is given priority during block download and is
allocated most of the cache (see `MaybeRebalanceCaches()` and usages) as our chief
consideration is getting to network tip.
goal is getting to network tip.

**Failure consideration:** if shutdown happens at any point during this phase, both
chainstates will be detected during the next init and the process will resume.
Expand All @@ -107,33 +108,36 @@ sequentially.
### Background chainstate hits snapshot base block

Once the tip of the background chainstate hits the base block of the snapshot
chainstate, we stop use of the background chainstate by setting `m_stop_use` (not yet
committed - see bitcoin#15606), in `CompleteSnapshotValidation()`, which is checked in
`ActivateBestChain()`). We hash the background chainstate's UTXO set contents and
ensure it matches the compiled value in `CMainParams::m_assumeutxo_data`.

The background chainstate data lingers on disk until shutdown, when in
`ChainstateManager::Reset()`, the background chainstate is cleaned up with
`ValidatedSnapshotShutdownCleanup()`, which renames the `chainstate_[hash]` datadir as
`chainstate`.
chainstate, we stop use of the background chainstate by setting `m_disabled`, in
`MaybeCompleteSnapshotValidation()`, which is checked in `ActivateBestChain()`. We hash the
background chainstate's UTXO set contents and ensure it matches the compiled value in
`CMainParams::m_assumeutxo_data`. In Dash, completion additionally compares the
deterministic masternode-list hash the background chainstate derived at the base block
against the hash recorded at snapshot activation, and the EvoDB best-block markers
against both chainstates' coins tips; any divergence fails completion with
`EVO_STATE_MISMATCH` and quarantines the snapshot exactly like a UTXO hash mismatch.

| | |
| ---------- | ----------- |
| number of chainstates | 2 (ibd has `m_stop_use=true`) |
| number of chainstates | 2 (ibd has `m_disabled=true`) |
| active chainstate | snapshot |

**Failure consideration:** if dashd unexpectedly halts after `m_stop_use` is set on
the background chainstate but before `CompleteSnapshotValidation()` can finish, the
need to complete snapshot validation will be detected on subsequent init by
`ChainstateManager::CheckForUncleanShutdown()`.
The background chainstate data lingers on disk until the program is restarted.

### Dashd restarts sometime after snapshot validation has completed

When dashd initializes again, what began as the snapshot chainstate is now
indistinguishable from a chainstate that has been built from the traditional IBD
process, and will be initialized as such.
After a shutdown and subsequent restart, `LoadChainstate()` cleans up the background
chainstate with `ValidatedSnapshotCleanup()`, which renames the `chainstate_snapshot`
datadir as `chainstate` and removes the now unnecessary background chainstate data.

| | |
| ---------- | ----------- |
| number of chainstates | 1 |
| active chainstate | ibd |
| active chainstate | ibd (was snapshot, but is now fully validated) |

What began as the snapshot chainstate is now indistinguishable from a chainstate that
has been built from the traditional IBD process, and will be initialized as such.

A file will be left in `chainstate/base_blockhash`, which indicates that the
chainstate, even though now fully validated, was originally started from a snapshot
with the corresponding base blockhash.
4 changes: 2 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ BITCOIN_CORE_H = \
masternode/payments.h \
masternode/sync.h \
masternode/utils.h \
mempool_args.h \
memusage.h \
merkleblock.h \
messagesigner.h \
Expand All @@ -346,6 +345,7 @@ BITCOIN_CORE_H = \
node/context.h \
node/eviction.h \
node/interface_ui.h \
node/mempool_args.h \
node/mempool_persist_args.h \
node/miner.h \
node/minisketchwrapper.h \
Expand Down Expand Up @@ -600,7 +600,6 @@ libbitcoin_node_a_SOURCES = \
masternode/payments.cpp \
masternode/sync.cpp \
masternode/utils.cpp \
mempool_args.cpp \
net.cpp \
net_processing.cpp \
netfulfilledman.cpp \
Expand All @@ -614,6 +613,7 @@ libbitcoin_node_a_SOURCES = \
node/eviction.cpp \
node/interface_ui.cpp \
node/interfaces.cpp \
node/mempool_args.cpp \
node/mempool_persist_args.cpp \
node/miner.cpp \
node/minisketchwrapper.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ bench_bench_dash_SOURCES = \
bench/crypto_hash.cpp \
bench/data.cpp \
bench/data.h \
bench/descriptors.cpp \
bench/duplicate_inputs.cpp \
bench/ecdsa.cpp \
bench/ellswift.cpp \
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.test_fuzz.include
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ TEST_FUZZ_H = \
test/fuzz/FuzzedDataProvider.h \
test/fuzz/util.h \
test/util/mining.h \
test/fuzz/mempool_utils.h \
test/fuzz/util/mempool.h \
test/fuzz/util/net.h

libtest_fuzz_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS)
Expand All @@ -21,5 +21,6 @@ libtest_fuzz_a_SOURCES = \
test/fuzz/fuzz.cpp \
test/util/mining.cpp \
test/fuzz/util.cpp \
test/fuzz/util/mempool.cpp \
test/fuzz/util/net.cpp \
$(TEST_FUZZ_H)
30 changes: 30 additions & 0 deletions src/bench/descriptors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <key.h>
#include <script/descriptor.h>
#include <script/standard.h>

#include <string>
#include <utility>

static void ExpandDescriptor(benchmark::Bench& bench)
{
const auto desc_str = "sh(multi(15,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06))";
const std::pair<int64_t, int64_t> range = {0, 1000};
FlatSigningProvider provider;
std::string error;
auto desc = Parse(desc_str, provider, error);

bench.run([&] {
for (int i = range.first; i <= range.second; ++i) {
std::vector<CScript> scripts;
bool success = desc->Expand(i, provider, scripts, provider);
assert(success);
}
});
}

BENCHMARK(ExpandDescriptor, benchmark::PriorityLevel::HIGH);
3 changes: 1 addition & 2 deletions src/bench/load_external.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ static void LoadExternalBlockFile(benchmark::Bench& bench)
fclose(file);
}

Chainstate& chainstate{testing_setup->m_node.chainman->ActiveChainstate()};
std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
FlatFilePos pos;
bench.run([&] {
// "rb" is "binary, O_RDONLY", positioned to the start of the file.
// The file will be closed by LoadExternalBlockFile().
FILE* file{fsbridge::fopen(blkfile, "rb")};
chainstate.LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent);
testing_setup->m_node.chainman->LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent);
});
fs::remove(blkfile);
}
Expand Down
47 changes: 24 additions & 23 deletions src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,32 +29,33 @@ void CChain::SetTip(CBlockIndex& block)
}
}

CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
int nStep = 1;
std::vector<uint256> vHave;
vHave.reserve(32);

if (!pindex)
pindex = Tip();
while (pindex) {
vHave.push_back(pindex->GetBlockHash());
// Stop when we have added the genesis block.
if (pindex->nHeight == 0)
break;
std::vector<uint256> LocatorEntries(const CBlockIndex* index)
{
int step = 1;
std::vector<uint256> have;
if (index == nullptr) return have;

have.reserve(32);
while (index) {
have.emplace_back(index->GetBlockHash());
if (index->nHeight == 0) break;
// Exponentially larger steps back, plus the genesis block.
int nHeight = std::max(pindex->nHeight - nStep, 0);
if (Contains(pindex)) {
// Use O(1) CChain index if possible.
pindex = (*this)[nHeight];
} else {
// Otherwise, use O(log n) skiplist.
pindex = pindex->GetAncestor(nHeight);
}
if (vHave.size() > 10)
nStep *= 2;
int height = std::max(index->nHeight - step, 0);
// Use skiplist.
index = index->GetAncestor(height);
if (have.size() > 10) step *= 2;
}
return have;
}

return CBlockLocator(vHave);
CBlockLocator GetLocator(const CBlockIndex* index)
{
return CBlockLocator{LocatorEntries(index)};
}

CBlockLocator CChain::GetLocator() const
{
return ::GetLocator(Tip());
}

const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
Expand Down
30 changes: 22 additions & 8 deletions src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ enum BlockStatus : uint32_t {
BLOCK_VALID_TRANSACTIONS = 3,

//! Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends, BIP30.
//! Implies all parents are also at least CHAIN.
//! Implies all parents are either at least VALID_CHAIN, or are ASSUMED_VALID
BLOCK_VALID_CHAIN = 4,

//! Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
//! Scripts & signatures ok. Implies all parents are either at least VALID_SCRIPTS, or are ASSUMED_VALID.
BLOCK_VALID_SCRIPTS = 5,

//! All validity bits.
Expand All @@ -119,10 +119,18 @@ enum BlockStatus : uint32_t {
BLOCK_CONFLICT_CHAINLOCK = 128, //!< conflicts with chainlock system

/**
* If set, this indicates that the block index entry is assumed-valid.
* Certain diagnostics will be skipped in e.g. CheckBlockIndex().
* It almost certainly means that the block's full validation is pending
* on a background chainstate. See `doc/design/assumeutxo.md`.
* If ASSUMED_VALID is set, it means that this block has not been validated
* and has validity status less than VALID_SCRIPTS. Also that it may have
* descendant blocks with VALID_SCRIPTS set, because they can be validated
* based on an assumeutxo snapshot.
*
* When an assumeutxo snapshot is loaded, the ASSUMED_VALID flag is added to
* unvalidated blocks at the snapshot height and below. Then, as the background
* validation progresses, and these blocks are validated, the ASSUMED_VALID
* flags are removed. See `doc/design/assumeutxo.md` for details.
*
* This flag is only used to implement checks in CheckBlockIndex() and
* should not be used elsewhere.
*/
BLOCK_ASSUMED_VALID = 256,
};
Expand Down Expand Up @@ -478,8 +486,8 @@ class CChain
/** Set/initialize a chain with a given tip. */
void SetTip(CBlockIndex& block);

/** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
CBlockLocator GetLocator(const CBlockIndex* pindex = nullptr) const;
/** Return a CBlockLocator that refers to the tip in of this chain. */
CBlockLocator GetLocator() const;

/** Find the last common block between this chain and a block index entry. */
const CBlockIndex* FindFork(const CBlockIndex* pindex) const;
Expand All @@ -488,4 +496,10 @@ class CChain
CBlockIndex* FindEarliestAtLeast(int64_t nTime, int height) const;
};

/** Get a locator for a block index entry. */
CBlockLocator GetLocator(const CBlockIndex* index);

/** Construct a list of hash entries to put in a locator. */
std::vector<uint256> LocatorEntries(const CBlockIndex* index);

#endif // BITCOIN_CHAIN_H
14 changes: 1 addition & 13 deletions src/chainlock/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ ChainlockHandler::ChainlockHandler(chainlock::Chainlocks& chainlocks, Chainstate
scheduler{std::make_unique<CScheduler>()},
scheduler_thread{
std::make_unique<std::thread>(std::thread(util::TraceThread, "cl-schdlr", [&] { scheduler->serviceQueue(); }))},
seenChainLocks{SEEN_CHAINLOCKS_RETAINED_SIZE, SEEN_CHAINLOCKS_PRUNE_AFTER_SIZE}
seenChainLocks{SEEN_CHAINLOCKS_CUTOFF_SIZE, SEEN_CHAINLOCKS_MAX_SIZE}
{
}

Expand Down Expand Up @@ -89,18 +89,6 @@ size_t ChainlockHandler::SeenChainLockCacheSizeForTesting() const
return seenChainLocks.size();
}

size_t ChainlockHandler::SeenChainLockCacheRetainedSizeForTesting() const
{
LOCK(cs);
return seenChainLocks.max_size();
}

size_t ChainlockHandler::SeenChainLockCachePruneAfterSizeForTesting() const
{
LOCK(cs);
return seenChainLocks.prune_after_size();
}

void ChainlockHandler::UpdateTxFirstSeenMap(const Uint256HashSet& tx, const int64_t& time)
{
AssertLockNotHeld(cs);
Expand Down
16 changes: 2 additions & 14 deletions src/chainlock/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,8 @@ class ChainlockHandler final : public CValidationInterface
std::atomic<bool> tryLockChainTipScheduled{false};
std::atomic<bool> isEnabled{false};

//! Number of recently seen CLSIG hashes retained once `seenChainLocks` is pruned.
static constexpr size_t SEEN_CHAINLOCKS_RETAINED_SIZE{1024};
//! Size `seenChainLocks` may grow to before the next insertion prunes it back down to
//! SEEN_CHAINLOCKS_RETAINED_SIZE. Pruning partitions every entry, and CLSIG hashes are
//! recorded before the signature is verified, so pruning on each insertion past the retained
//! size lets a peer turn a stream of unique CLSIG hashes into a stream of full-map partition
//! passes under `cs`. Pruning only after twice the retained size amortises that cost over the
//! entries dropped in a single batch, at the price of a larger transient cache. The 2x ratio
//! matches the default in unordered_lru_cache.
static constexpr size_t SEEN_CHAINLOCKS_PRUNE_AFTER_SIZE{2 * SEEN_CHAINLOCKS_RETAINED_SIZE};
static constexpr size_t SEEN_CHAINLOCKS_CUTOFF_SIZE{1024};
static constexpr size_t SEEN_CHAINLOCKS_MAX_SIZE{2 * SEEN_CHAINLOCKS_CUTOFF_SIZE};

const CBlockIndex* lastNotifyChainLockBlockIndex GUARDED_BY(cs){nullptr};
Uint256HashMap<std::chrono::seconds> txFirstSeenTime GUARDED_BY(cs);
Expand All @@ -86,10 +78,6 @@ class ChainlockHandler final : public CValidationInterface
bool AlreadyHave(const CInv& inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
void UpdateTxFirstSeenMap(const Uint256HashSet& tx, const int64_t& time) EXCLUSIVE_LOCKS_REQUIRED(!cs);
size_t SeenChainLockCacheSizeForTesting() const EXCLUSIVE_LOCKS_REQUIRED(!cs);
//! Number of entries retained after the seen cache is pruned.
size_t SeenChainLockCacheRetainedSizeForTesting() const EXCLUSIVE_LOCKS_REQUIRED(!cs);
//! Size the seen cache may grow to before it is pruned back to the retained size.
size_t SeenChainLockCachePruneAfterSizeForTesting() const EXCLUSIVE_LOCKS_REQUIRED(!cs);

[[nodiscard]] MessageProcessingResult ProcessNewChainLock(NodeId from, const chainlock::ChainLockSig& clsig,
const llmq::CQuorumManager& qman,
Expand Down
Loading
Loading