Commit Graph

53 Commits

Author SHA1 Message Date
TheCharlatan
6da6f503a6 refactor: Let CCoinsViewCache::BatchWrite return void
CCoinsViewCache::BatchWrite always returns true if called from a backed
cache, so just return void instead. Also return void from ::Sync and
::Flush.

This allows for dropping a FatalError condition and simplifying some
dead error handling code a bit.

Since we now no longer exercise the "error path" when returning from
`CCoinsView::BatchWrite`, make the method clear the cache instead. This
should only be exercised by tests and not change production behaviour.
This might slightly improve the coins_view fuzz test's ability to
generate better coverage.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
2025-12-14 22:25:31 +01:00
Ava Chow
c2975f26d6 Merge bitcoin/bitcoin#33602: [IBD] coins: reduce lookups in dbcache layer propagation
0ac969cddf validation: don't reallocate cache for short-lived CCoinsViewCache (Lőrinc)
c8f5e446dc coins: reduce lookups in dbcache layer propagation (Lőrinc)

Pull request description:

  This change is part of [[IBD] - Tracking PR for speeding up Initial Block Download](https://github.com/bitcoin/bitcoin/pull/32043)

  ### Summary

  Previously, when the parent coins cache had no entry and the child did, `BatchWrite` performed a find followed by `try_emplace`, which resulted in multiple `SipHash` computations and bucket traversals on the common insert path.
  On a different path, these caches were recreated needlessly for every block connection.

  ### Fix for double fetch

  This change uses a single leading `try_emplace` and branches on the returned `inserted` flag. In the `FRESH && SPENT` case (not used in production, only exercised by tests), we erase the just-inserted placeholder (which is constant time with no rehash anyway). Semantics are unchanged for all valid parent/child state combinations.

  This change is a minimal version of [bitcoin/bitcoin@`723c49b` (#32128)](723c49b63b) and draws simplification ideas [bitcoin/bitcoin@`ae76ec7` (#30673)](ae76ec7bcf) and https://github.com/bitcoin/bitcoin/pull/30326.

  ### Fix for temporary cache recreation

  Related to parent cache propagation, the second commit makes it possible to avoid destructuring-recreating-destructuring of these short-live parent caches created for each new block.
  A few temporary `CCoinsViewCache`'s are destructed right after the `Flush()`, therefore it is not necessary to call `ReallocateCache` to recreate them right before they're killed anyway.

  This change was based on a subset of https://github.com/bitcoin/bitcoin/pull/28945, the original authors and relevant commenters were added as coauthors to this version.

  -----

  Reindex-chainstate indicates ~1% speedup.
  <details>
  <summary>Details</summary>

  ```python
  COMMITS="647cdb4f7e8041affed887e2325ee03a91078bb1 0b0c3293ffd75afb27dadc0b28426b40132a8c6b"; \
  STOP=909090; DBCACHE=4500; \
  CC=gcc; CXX=g++; \
  BASE_DIR="/mnt/my_storage"; DATA_DIR="$BASE_DIR/BitcoinData"; LOG_DIR="$BASE_DIR/logs"; \
  (echo ""; for c in $COMMITS; do git fetch -q origin $c && git log -1 --pretty='%h %s' $c || exit 1; done; echo "") && \
  hyperfine \
    --sort command \
    --runs 2 \
    --export-json "$BASE_DIR/rdx-$(sed -E 's/(\w{8})\w+ ?/\1-/g;s/-$//'<<<"$COMMITS")-$STOP-$DBCACHE-$CC.json" \
    --parameter-list COMMIT ${COMMITS// /,} \
    --prepare "killall bitcoind 2>/dev/null; rm -f $DATA_DIR/debug.log; git checkout {COMMIT}; git clean -fxd; git reset --hard && \
      cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DENABLE_IPC=OFF && ninja -C build bitcoind && \
      ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=1000 -printtoconsole=0; sleep 20" \
    --cleanup "cp $DATA_DIR/debug.log $LOG_DIR/debug-{COMMIT}-$(date +%s).log" \
    "COMPILER=$CC ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=$DBCACHE -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0"

  647cdb4f7e Merge bitcoin/bitcoin#33311: net: Quiet down logging when router doesn't support natpmp/pcp
  0b0c3293ff validation: don't reallocate cache for short-lived CCoinsViewCache

  Benchmark 1: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 647cdb4f7e)
    Time (mean ± σ):     16233.508 s ±  9.501 s    [User: 19064.578 s, System: 951.672 s]
    Range (min … max):   16226.790 s … 16240.226 s    2 runs

  Benchmark 2: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 0b0c3293ffd75afb27dadc0b28426b40132a8c6b)
    Time (mean ± σ):     16039.626 s ± 17.284 s    [User: 18870.130 s, System: 950.722 s]
    Range (min … max):   16027.405 s … 16051.848 s    2 runs

  Relative speed comparison
          1.01 ±  0.00  COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 647cdb4f7e)
          1.00          COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 0b0c3293ffd75afb27dadc0b28426b40132a8c6b)
  ```

  </details>

ACKs for top commit:
  optout21:
    utACK 0ac969cddf
  achow101:
    ACK 0ac969cddf
  andrewtoth:
    utACK 0ac969cddf
  sedited:
    ACK 0ac969cddf

Tree-SHA512: 9fcc3f1a8314368576a4fba96ca72665527eaa3a97964ab5b39491757f3527147d134f79a5c3456f76c1330c7ef862989d23f764236c5e2563be89a81c1cee47
2025-12-10 15:02:25 -08:00
Lőrinc
24bcad3d4d refactor: remove dead code in CountWitnessSigOps
Found while reviewing #32840

The `nullptr` witness path was dead in normal code paths: removing it deletes unreachable logic.

Code coverage proof:
https://maflcko.github.io/b-c-cov/total.coverage/src/script/interpreter.cpp.gcov.html#L2135
2025-11-04 22:51:25 +01:00
Lőrinc
0ac969cddf validation: don't reallocate cache for short-lived CCoinsViewCache
A few temporary `CCoinsViewCache`'s are destructed right after the `Flush()`, therefore it is not necessary to call `ReallocateCache` to recreate them right before they're killed anyway.

* `Flush()` - retains existing functionality;
* `Flush(/*will_reuse_cache=*/false)` - skips destruction and reallocation of the parent cache since it will soon go out of scope anyway;

For the `will_reuse_cache` parameter we want to see exactly which ones will reallocate memory and which won't - since both can be valid usages.

This change was based on a subset of https://github.com/bitcoin/bitcoin/pull/28945.

Co-authored-by: Martin Ankerl <martin.ankerl@gmail.com>
2025-11-02 21:40:16 +01:00
Lőrinc
24d861da78 coins: only adjust cachedCoinsUsage on EmplaceCoinInternalDANGER insert
`EmplaceCoinInternalDANGER()` incremented `cachedCoinsUsage` even when `try_emplace` did not insert (duplicate key), inflating the counter.
This is mostly reachable in tests today since `AssumeUTXO` does not overwrite.

Increment only on successful insert, and capture `coin.DynamicMemoryUsage()` before the move so accounting uses the correct value.

Fuzz: add an `EmplaceCoinInternalDANGER` path to exercise insert-only accounting.
Unit test: emplace two different coins at the same outpoint (with different `DynamicMemoryUsage()`), verify `SelfTest()` passes and `AccessCoin(outpoint)` returns the first coin.

Co-authored-by: Andrew Toth <andrewstoth@gmail.com>
Co-authored-by: w0xlt <woltx@protonmail.com>
2025-10-12 12:37:45 -04:00
Lőrinc
d7c9d6c291 coins: fix cachedCoinsUsage accounting to prevent underflow
Move the `cachedCoinsUsage` subtract in `AddCoin()` to after the `possible_overwrite` check.
Previously a throw before assignment decremented the counter without changing the entry, which corrupted accounting and later underflowed.

In `Flush()`, reset `cachedCoinsUsage` to `0` only when `BatchWrite()` succeeds and `cacheCoins` is actually cleared. In production `BatchWrite()` returns `true`, so this mostly affects tests. On failure, leave the counter unchanged to keep it in sync with the cache.

The existing `Flush()` workaround in fuzzing was also removed now that the source of the problem was fixed, so the fuzzer no longer needs `coins_view_cache.Flush()` to realign `cachedCoinsUsage` after an exception.
Replace the prior `expected_code_path` tracking with direct assertions. The role of the variable was to verify that code execution follows only expected paths, either successful addition, or if it's an exception, the message is verified and checked that overwrite was disallowed.

With these changes the counter stays consistent across success and exception paths, so we can finally remove the `UBSan` suppressions for `CCoinsViewCache` that were masking the issue.

Included a unit test as well, attempting to add a different coin to the same outpoint without allowing overwrites and make sure it throws.
We use `SelfTest()` to validates accounting, and check that the cache remains usable.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Co-authored-by: w0xlt <woltx@protonmail.com>
2025-10-11 22:05:22 -04:00
Lőrinc
39cf8bb3d0 refactor: remove redundant usage tracking from CoinsViewCacheCursor
When a coin is spent via `SpendCoin()`, `cachedCoinsUsage` is already decremented and the coin's `scriptPubKey` is cleared, so `DynamicMemoryUsage()` is `0`.

`CoinsViewCacheCursor::NextAndMaybeErase()` was subtracting usage again when erasing spent entries.
Replace it with an assert that documents spent coins have zero dynamic memory usage by the time the cursor encounters them.

Remove the now-unnecessary `usage` reference from the cursor's constructor and member variables.
2025-10-11 21:48:04 -04:00
Anthony Towns
bddcadee82 script/verify_flags: make script_verify_flags type safe
`using script_verify_flags = uint32_t` allows implicit conversion to
and from int, so replace it with a class to have the compiler ensure we
use the correct type. Provide from_int and as_int to allow for explicit
conversions when desired.

Introduces the type `script_verify_flag_name` for the individual flag
name enumeration.
2025-08-14 10:17:32 +10:00
Antoine Poinsot
cfc42ae5b7 fuzz: add a target for the coins database
It reuses the logic from the `coins_view` target, except it uses an
in-memory CCoinsViewDB as the backend.

Note `CCoinsViewDB` will assert the best block hash is never null, so we
slightly modify the coins_view fuzz logic to take care of this.
2025-05-29 12:14:13 +01:00
Antoine Poinsot
46e14630f7 fuzz: move the coins_view target's body into a standalone function
We'll reuse it for a target where the coins view is a DB.
2025-05-23 15:32:16 +01:00
Antoine Poinsot
56d878c465 fuzz: avoid underflow in coins_view target 2025-05-23 15:32:06 +01:00
Lőrinc
cd0498eabc coins, refactor: Split up AddFlags to remove invalid states
CCoinsCacheEntry provided general access to its internal flags state, even though in reality it could only be clean, fresh, dirty or fresh|dirty.

After it got dirtied we couldn't set the state back to clean by AddFlags(0) - tests were explicitly checking against that.

This commit cleans up the public interface to make this distinction cleaner and invalid behavior impossible instead of just checked by tests.
This includes the removal of redundant `inline` qualifiers (we're inside a struct).
Also renamed `self` to `pair` to simplify the upcoming commits.

Also modernized `EmplaceCoinInternalDANGER` since it was already modified.

Co-authored-by: Andrew Toth <andrewstoth@gmail.com>
2024-12-02 13:48:04 +01:00
Lőrinc
4feaa28728 refactor: Rely on returned value of GetCoin instead of parameter
Also removed the unused coin parameter of GetCoin.

Co-authored-by: Andrew Toth <andrewstoth@gmail.com>
2024-09-18 20:03:47 +02:00
Lőrinc
46dfbf169b refactor: Return optional of Coin in GetCoin
Leaving the parameter as well for now.

Co-authored-by: TheCharlatan <seb.kung@gmail.com>
2024-09-18 20:03:47 +02:00
Andrew Toth
7825b8b9ae coins: pass linked list of flagged entries to BatchWrite
BatchWrite now iterates through the linked
list of flagged entries instead of the entire
coinsCache map.

Co-Authored-By: l0rinc <pap.lorinc@gmail.com>
2024-08-05 19:43:56 -04:00
Andrew Toth
8bd3959fea refactor: require self and sentinel parameters for AddFlags
No behavior change. Prepares for adding the CoinsCachePairs to
a linked list when flagged.
2024-08-02 00:29:42 -04:00
Andrew Toth
f08faeade2 refactor: move flags to private uint8_t and rename to m_flags
No behavior change. This prepares to add CCoinsCacheEntrys
to a doubly linked list when a flag is added.
2024-08-01 23:36:00 -04:00
Andrew Toth
8737c0cefa refactor: encapsulate flags setting with AddFlags and ClearFlags
No behavior change. This prepares moving the cache entry
flags field to private access.
2024-08-01 23:36:00 -04:00
TheCharlatan
f46b220256 fuzz: Use BasicTestingSetup for coins_view target 2024-07-19 13:37:35 +02:00
Anthony Towns
6e9e4e6130 Use ParamsWrapper for witness serialization 2023-11-14 08:45:30 +10:00
MarcoFalke
fabb5046a7 fuzz: Avoid timeout and bloat in fuzz targets
Also, fix iwyu
2023-11-08 09:51:54 +01:00
Antoine Poinsot
e417c988f6 fuzz: coins_view: remove an incorrect assertion
Again, this was not hit because the default implementation of
`CCoinsView` return `false` for `GetCoin`.
2023-08-11 18:11:07 +02:00
Antoine Poinsot
c5f6b1db56 fuzz: coins_view: correct an incorrect assertion
It is incorrect to assert that `cache.HaveCoin()` will always be `true`
if `backend.HaveCoin()` is. The coin could well have been marked as
spent in the cache but not yet flushed, in which case `cache.HaveCoin()`
would return `false`.

Note this was never hit because `exists_using_have_coin_in_backend` is
currently never `true` (it's the default implementation of `CCoinsView`.
However this might change if we were to add a target where the backend
is a `CCoinsViewDB`.
2023-08-04 13:51:30 +02:00
MarcoFalke
fa6dfaaf45 scripted-diff: Use new FUZZ_TARGET macro everywhere
-BEGIN VERIFY SCRIPT-

  ren() { sed --regexp-extended -i "s|$1|$2|g" $(git grep -l --extended-regexp "$1"); }

  # Replace FUZZ_TARGET_INIT
  ren 'FUZZ_TARGET_INIT\((.+), (.+)\)' 'FUZZ_TARGET(\1, .init = \2)'

  # Delete unused FUZZ_TARGET_INIT
  sed -i -e '37,39d' src/test/fuzz/fuzz.h

-END VERIFY SCRIPT-
2023-07-13 20:37:14 +02:00
TheCharlatan
d168458d1f scripted-diff: Remove unused chainparamsbase includes
This is a follow-up to previous commits moving the chain constants out
of chainparamsbase.

The script removes the chainparamsbase header in all files where it is
included, but not used. This is done by filtering against all defined
symbols of the header as well as its respective .cpp file.

The kernel chainparams now no longer relies on chainparamsbase.

-BEGIN VERIFY SCRIPT-
sed -i '/#include <chainparamsbase.h>/d' $( git grep -l 'chainparamsbase.h' | xargs grep -L 'CBaseChainParams\|CreateBaseChainParams\|SetupChainParamsBaseOptions\|BaseParams\|SelectBaseParams\|chainparamsbase.cpp' )
-END VERIFY SCRIPT-
2023-05-09 15:49:19 +02:00
Martin Leitner-Ankerl
9f947fc3d4 Use PoolAllocator for CCoinsMap
In my benchmarks, using this pool allocator for CCoinsMap gives about
20% faster `-reindex-chainstate` with -dbcache=5000 with practically the
same memory usage. The change in max RSS changed was 0.3%.

The `validation_flush_tests` tests need to be updated because
memory allocation is now done in large pools instead of one node at a
time, so the limits need to be updated accordingly.
2023-03-23 19:38:38 +01:00
Pieter Wuille
59e6828bb5 Add deterministic mode to CCoinsViewCache 2023-02-02 09:00:15 -05:00
Pieter Wuille
bb00357add Make test/fuzz/coins_view exercise CCoinsViewCache::Sync() 2023-01-30 13:11:53 -05:00
Hennadii Stepanov
306ccd4927 scripted-diff: Bump copyright headers
-BEGIN VERIFY SCRIPT-
./contrib/devtools/copyright_header.py update ./
-END VERIFY SCRIPT-

Commits of previous years:
- 2021: f47dda2c58
- 2020: fa0074e2d8
- 2019: aaaaad6ac9
2022-12-24 23:49:50 +00:00
Carl Dong
0848db9c35 fuzz: Remove useless GetUTXOStats fuzz case
In the GetUTXOStats fuzz case, GetUTXOStats is always called with a
CCoinsViewCache. Which is guaranteed to throw a std::logic_error when
its ::Cursor() method is called on the first line of GetUTXOStats.

In the fuzz case, we basically catch this logic error and declare
victory if we caught it.

There is no point to fuzzing this deterministic logic.

Confirmed with IWYU that the node/coinstats.h #include is no longer
necessary.
2022-05-20 16:33:24 -04:00
MarcoFalke
fad81548fa test: Avoid testing negative block heights 2022-02-02 15:32:06 +01:00
Ryan Ofsky
ce95fb36af Remove cs_main lock annotation from ChainstateManager.m_blockman
BlockManager is a large data structure, and cs_main is not required to
take its address or access every part of it. Individual BlockManager
fields and methods which do require cs_main like m_block_index and
LookupBlockIndex are already annotated separately, and these other
annotations describe locking requirements more accurately and do a
better job enforcing thread safety.

Since cs_main is not needed to access the address of the m_block object,
this commit drops cs_main LOCK calls which were added pointlessly to
satisfy this annotation in the past.

Co-authored-by: Carl Dong <contact@carldong.me>
2022-01-11 05:11:00 -05:00
Russell Yanofsky
90fc8b089d Add src/node/* code to node:: namespace 2022-01-06 22:14:16 -05:00
MarcoFalke
fa3e0da06b policy: Treat taproot as always active 2021-11-16 08:20:33 +01:00
Andrew Poelstra
214d9055ac fuzz: replace every fuzzer-controlled loop with a LIMITED_WHILE loop
Blindly chose a cap of 10000 iterations for every loop, except for
the two in script_ops.cpp and scriptnum_ops.cpp which appeared to
(sometimes) be deserializing individual bytes; capped those to one
million to ensure that sometimes we try working with massive scripts.

There was also one fuzzer-controlled loop in timedata.cpp which was
already capped, so I left that alone.

git grep 'while (fuzz' should now run clean except for timedata.cpp
2021-11-12 19:51:55 +00:00
fanquake
d09071da5b [MOVEONLY] consensus: move amount.h into consensus
Move amount.h to consensus/amount.h.
Renames, adds missing and removes uneeded includes.
2021-09-30 07:41:57 +08:00
MarcoFalke
9faa4b68db Merge bitcoin/bitcoin#22232: refactor: Pass interpreter flags as uint32_t instead of signed int
fa621ededd refactor: Pass script verify flags as uint32_t (MarcoFalke)

Pull request description:

  The flags are cast to unsigned in the interpreter anyway, so avoid the confusion (and fuzz crashes) by just passing them as unsigned from the beginning.

  Also, the flags are often inverted bit-wise with the `~` operator, which also works on signed integers, but might cause confusion as the sign bit is flipped.

  Fixes #22233

ACKs for top commit:
  theStack:
    Concept and code review ACK fa621ededd
  kristapsk:
    ACK fa621ededd
  jonatack:
    ACK fa621ededd

Tree-SHA512: ea0720f32f823fa7f075309978672aa39773c6019d12b6c1c9d611fc1983a76115b7fe2a28d50814673bb6415c311ccc05b99d6e871575fb6900faf75ed17769
2021-07-20 15:36:23 +02:00
James O'Beirne
615c1adfb0 refactor: wrap CCoinsViewCursor in unique_ptr
Specifically with CCoinsViewDB, if a raw cursor is allocated and
not freed, a cryptic leveldb assertion failure occurs on
CCoinsViewDB destruction.

See: https://github.com/google/leveldb/issues/142#issuecomment-414418135
2021-06-17 09:47:08 -04:00
MarcoFalke
fa621ededd refactor: Pass script verify flags as uint32_t
They are cast to unsigned anyway when calling VerifyScript,
bitcoinconsensus_verify_script*, or CountWitnessSigOps.
2021-06-14 08:02:45 +02:00
Carl Dong
ee0ab1e959 fuzz: Initialize a TestingSetup for test_one_input
For fuzz tests that need it.
2021-06-10 15:04:39 -04:00
practicalswift
37371268d1 Mark CheckTxInputs [[nodiscard]] (out-param txfee only set if call is successful). Avoid UUM in fuzzing harness coins_view. 2021-05-25 21:09:05 +00:00
MarcoFalke
fae4ee545a fuzz: Add missing CheckTransaction before CheckTxInputs 2021-05-17 10:04:57 +02:00
Fabian Jahr
9c8a265fd2 refactor: Pass hash_type to CoinsStats in stats object 2021-04-19 20:28:48 +02:00
MarcoFalke
eeee8f5be1 fuzz: Removed unused try-catch in coins_view 2021-03-30 10:16:22 +02:00
Carl Dong
106bcd4f39 node/coinstats: Pass in BlockManager to GetUTXOStats 2021-03-08 15:54:31 -05:00
MarcoFalke
fa576b4532 Move MakeNoLogFileContext to common libtest_util, and use it in bench
Can be reviewed with --color-moved=dimmed-zebra
2021-03-03 09:17:37 +01:00
MarcoFalke
fae216a73d scripted-diff: Rename MakeFuzzingContext to MakeNoLogFileContext
-BEGIN VERIFY SCRIPT-
 # Rename
 sed -i -e 's/MakeFuzzingContext/MakeNoLogFileContext/g' $(git grep -l MakeFuzzingContext)
 # Bump the copyright of touched files in this scripted diff to avoid touching them again later
 ./contrib/devtools/copyright_header.py update ./src/test/fuzz/
-END VERIFY SCRIPT-
2021-02-22 10:27:22 +01:00
Carl Dong
abb6fa7285 fuzz: Initialize a full TestingSetup where appropriate
A full TestingSetup is required for both coins_view and
load_external_block_file as they interact with the active chainstate.
2021-01-21 09:29:42 -05:00
MarcoFalke
fa75d40ef8 fuzz: Introduce CallOneOf helper to replace switch-case
Can be reviewed with --ignore-all-space
2021-01-11 10:37:16 +01:00
MarcoFalke
44444ba759 fuzz: Link all targets once 2020-12-10 07:15:42 +01:00