Commit Graph

110 Commits

Author SHA1 Message Date
Martin Zumsande
69baddc910 validation: do not add the snapshot block to candidates of bg chainstate
The snapshot block needs to be added to the candidates set of the
assumed-valid chain because it will be the tip of that chainstate
right after snapshot activation.
However, adding it also to the background chainstate is not necessary
for anything. Before, the index would linger in the set without being
connectable. It will be eventually added to the set as part of the
normal block download - no extra logic is necessary here.
2026-03-09 16:40:24 +07:00
Ava Chow
8b70ed6996 Merge bitcoin/bitcoin#34521: validation: fix UB in LoadChainTip
20ae9b98ea Extend functional test for setBlockIndexCandidates UB (marcofleon)
854a6d5a9a validation: fix UB in LoadChainTip (marcofleon)
9249e6089e validation: remove LoadChainTip call from ActivateSnapshot (marcofleon)

Pull request description:

  Addresses https://github.com/bitcoin/bitcoin/issues/34503. See this issue for more details as well.

  Fixes a bug where, under certain conditions, `setBlockIndexCandidates` had blocks in it that were worse than the tip. The block index candidate set uses `nSequenceId` as a sort key, so modifying this field while blocks are in the set results in undefined behavior. This PR populates `setBlockIndexCandidates` after the `nSequenceId` modifications, avoiding the UB.

ACKs for top commit:
  achow101:
    ACK 20ae9b98ea
  sedited:
    Re-ACK 20ae9b98ea
  sipa:
    Code review ACK 20ae9b98ea

Tree-SHA512: 121c170bb70fb6365089d578db63c811e7926e129d7206e569947f7a1f6c5ddc8d5f4937b80f1ba1b7d7daa42789b143ca5b56f154b7ab968a1cd55f925f378d
2026-03-06 08:22:42 -08:00
marcofleon
854a6d5a9a validation: fix UB in LoadChainTip
The removal of the chain tip from setBlockIndexCandidates was
happening after nSequenceId was modified. Since the set uses
nSequenceId as a sort key, modifying it while the element is in the
set is undefined behavior, which can cause the erase to fail.

With assumeutxo, a second form of UB exists: two chainstates each
have their own candidate set, but share the same CBlockIndex
objects. Calling LoadChainTip on one chainstate mutates nSequenceIds
that are also in the other chainstate's set.

Fix by populating setBlockIndexCandidates after all changes to
nSequenceId.
2026-03-04 19:39:20 +00:00
Hodlinator
dbbb780af0 test: move and simplify BOOST_CHECK ostream helpers
Move the operator<< overloads used by BOOST_CHECK_* out of the
unit test machinery test/setup_common, into test/util/common.h.

And replace the individual per-type ToString() overloads with
a single concept-constrained template that covers any type
exposing a ToString() method. This is important to not add
uint256.h and transaction_identifier.h dependencies to the
shared test/util/common.h file.

Co-authored-by: furszy <matiasfurszyfer@protonmail.com>
2026-02-26 11:28:55 -03:00
stratospher
fb3e1bf9c9 test: check LoadBlockIndex correctly recomputes invalidity flags
Add a test for block index transitioning from legacy
BLOCK_FAILED_CHILD to BLOCK_FAILED_VALID behavior.

In the scenario where a valid block has a BLOCK_FAILED_CHILD
parent and a BLOCK_FAILED_VALID grandparent, ensure that all
three blocks are correctly marked as BLOCK_FAILED_VALID
after reloading the block index.
2026-02-17 21:40:46 +05:30
Lőrinc
557b41a38c validation: make IsInitialBlockDownload() lock-free
`ChainstateManager::IsInitialBlockDownload()` is queried on hot paths and previously acquired `cs_main` internally, contributing to lock contention.

Cache the IBD status in `m_cached_is_ibd`, and introduce `ChainstateManager::UpdateIBDStatus()` to latch it once block loading has finished and the current chain tip has enough work and is recent.
Call the updater after tip updates and after `ImportBlocks()` completes.

Since `IsInitialBlockDownload()` no longer updates the cache, drop `mutable` from `m_cached_is_ibd` and only update it from `UpdateIBDStatus()` under `cs_main`.

Update the new unit test to showcase the new `UpdateIBDStatus()`.

Co-authored-by: Patrick Strateman <patrick.strateman@gmail.com>
Co-authored-by: Martin Zumsande <mzumsande@gmail.com>
2026-01-12 16:57:20 +01:00
Lőrinc
8d531c6210 validation: invert m_cached_finished_ibd to m_cached_is_ibd
Rename and invert the internal IBD latch so the cached value directly matches `IsInitialBlockDownload()` (true while in IBD, then latched to false).

This is a behavior-preserving refactor to avoid double negatives.
2026-01-12 16:54:11 +01:00
Lőrinc
8be54e3b19 test: cover IBD exit conditions
Add a unit test that exercises the `IsInitialBlockDownload()` decision matrix by varying the cached latch, `BlockManager::LoadingBlocks()`, and tip work/recency inputs.

This documents the current latching behavior and provides a baseline for later refactors.
2026-01-12 16:48:09 +01:00
MarcoFalke
fa5f297748 scripted-diff: [doc] Unify stale copyright headers
-BEGIN VERIFY SCRIPT-

 sed --in-place --regexp-extended \
   's;( 20[0-2][0-9])(-20[0-2][0-9])? The Bitcoin Core developers;\1-present The Bitcoin Core developers;g' \
   $( git grep -l 'The Bitcoin Core developers' -- ':(exclude)COPYING' ':(exclude)src/ipc/libmultiprocess' ':(exclude)src/minisketch' )

-END VERIFY SCRIPT-
2025-12-16 22:21:15 +01:00
Ryan Ofsky
ae85c495f1 refactor: Delete ChainstateManager::GetAll() method
Just use m_chainstates array instead.
2025-12-12 06:49:59 -04:00
Ryan Ofsky
e514fe6116 refactor: Delete ChainstateManager::SnapshotBlockhash() method
SnapshotBlockhash() is only called two places outside of tests, and is used
redundantly in some tests, checking the same field as other checks. Simplify by
dropping the method and using the m_from_snapshot_blockhash field directly.
2025-12-12 06:49:59 -04:00
Ryan Ofsky
ee35250683 refactor: Delete ChainstateManager::IsSnapshotValidated() method
IsSnapshotValidated() is only called one place outside of tests, and is use
redundantly in some tests, asserting that a snapshot is not validated when a
snapshot chainstate does not even exist. Simplify by dropping the method and
checking Chainstate m_assumeutxo field directly.
2025-12-12 06:49:59 -04:00
Ryan Ofsky
d9e82299fc refactor: Delete ChainstateManager::IsSnapshotActive() method
IsSnapshotActive() method is only called one place outside of tests and
asserts, and is confusing because it returns true even after the snapshot is
fully validated.

The documentation which said this "implies that a background validation
chainstate is also in use" is also incorrect, because after the snapshot is
validated, the background chainstate gets disabled and IsUsable() would return
false.
2025-12-12 06:49:59 -04:00
Ryan Ofsky
840bd2ef23 refactor: Pass chainstate parameters to MaybeCompleteSnapshotValidation
Remove hardcoded references to m_ibd_chainstate and m_snapshot_chainstate so
MaybeCompleteSnapshotValidation function can be simpler and focus on validating
the snapshot without dealing with internal ChainstateManager states.

This is a step towards being able to validate the snapshot outside of
ActivateBestChain loop so cs_main is not locked for minutes when the snapshot
block is connected.
2025-12-12 06:49:59 -04:00
Ryan Ofsky
1598a15aed refactor: Deduplicate Chainstate activation code
Move duplicate code from ChainstateManager::ActivateSnapshot and
ChainstateManager::ActivateExistingSnapshot methods to a new
ChainstateManager::AddChainstate method.

The "AddChainstate" method name doesn't mention snapshots even though it is
only used to add snapshot chainstates now, because it becomes more generalized
in a later commit in this PR ("refactor: Add ChainstateManager::m_chainstates
member")
2025-12-12 06:49:59 -04:00
Ryan Ofsky
de00e87548 test: Fix broken chainstatemanager_snapshot_init check
The following test code never checked anything because the if statement was
always false:

    if (cs != &chainman_restarted.ActiveChainstate()) {
        BOOST_CHECK_EQUAL(cs->m_chain.Height(), 109);
    }

Also, the height of the background chainstate it was intending to check is 110,
not 109. Fix both problems by rewriting the check.
2025-12-12 06:49:59 -04:00
TheCharlatan
7fbb1bc44b kernel: Move block tree db open to block manager
This commit is done in preparation for the next commit. Here, the block
tree options are moved to the blockmanager options and the block tree is
instantiated through a helper method of the BlockManager, which is
removed again in the next commit.

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
2025-01-20 21:19:39 +01:00
Ryan Ofsky
5ca28ef28b refactor: Split up NodeContext shutdown_signal and shutdown_request
Instead of having a single NodeContext::shutdown member that is used both to
request shutdowns and check if they have been requested, use separate members
for each. Benefits of this change:

1. Should make code a little clearer and easier to search because it is easier
   to see which parts of code are triggering shutdowns and which parts are just
   checking to see if they were triggered.

2. Makes it possible for init.cpp to specify additional code to run when a
   shutdown is requested, like signalling the m_tip_block_cv condition variable.

Motivation for this change was to remove hacky NodeContext argument and
m_tip_block_cv access from the StopRPC function, so StopRPC can just be
concerned with RPC functionality, not other node functionality.
2024-10-01 09:10:54 +02:00
Lőrinc
19947863e1 Use BOOST_CHECK_EQUAL for optional, arith_uint256, uint256, uint160
Example error before:
> unknown location:0: fatal error: in "validation_chainstatemanager_tests/chainstatemanager_args": std::bad_optional_access: bad_optional_access
test/validation_chainstatemanager_tests.cpp:781: last checkpoint

after:
> test/validation_chainstatemanager_tests.cpp:801: error: in "validation_chainstatemanager_tests/chainstatemanager_args": check set_opts({"-assumevalid=0"}).assumed_valid_block == uint256::ZERO has failed [std::nullopt != 0000000000000000000000000000000000000000000000000000000000000000]

Also added extra minimum_chainwork test to make it symmetric with assumevalid

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
2024-09-11 15:41:15 +02:00
MarcoFalke
fa9d7d5d20 test: Work around boost compilation error 2024-09-06 15:57:33 +02:00
merge-script
d184fc3ba4 Merge bitcoin/bitcoin#30571: test: [refactor] Use m_rng directly
948238a683 test: Remove FastRandomContext global (Ryan Ofsky)
fa0fe08eca scripted-diff: [test] Use g_rng/m_rng directly (MarcoFalke)
fa54cab473 test: refactor: Accept any RandomNumberGenerator in RandMoney (MarcoFalke)
68f77dd21e test: refactor: Pass rng parameters to test functions (Ryan Ofsky)
fa19af555d test: refactor: Move g_insecure_rand_ctx.Reseed out of the helper that calls MakeRandDeterministicDANGEROUS (MarcoFalke)
3dc527f460 test: refactor: Give unit test functions access to test state (Ryan Ofsky)
fab023e177 test: refactor: Make unsigned promotion explicit (MarcoFalke)
fa2cb654ec test: Add m_rng alias for the global random context (MarcoFalke)
fae7e3791c test: Correct the random seed log on a prevector test failure (MarcoFalke)

Pull request description:

  This is mostly a style-cleanup for the tests' random generation:

  1) `g_insecure_rand_ctx` in the tests is problematic, because the name is a leftover when the generator was indeed insecure. However, now the generator is *deterministic*, because the seed is either passed in or printed (c.f. RANDOM_CTX_SEED). Stating that deterministic randomness is insecure in the tests seems redundant at best. Fix it by just using `m_rng` for the name.

  2) The global random context has many one-line aliases, such as `InsecureRand32`. This is problematic, because the same line of code may use the context directly and through a wrapper at the same time. For example in net_tests (see below). This inconsistency is harmless, but confusing. Fix it by just removing the one-line aliases.

  ```
  src/test/net_tests.cpp:        auto msg_data_1 = g_insecure_rand_ctx.randbytes<uint8_t>(InsecureRandRange(100000));
  ````

  3) The wrapper for randmoney has the same problem that the same unit test uses the context directly and through a wrapper at the same time. Also, it has a single type of Rng hardcoded. Fix it by accepting any type.

ACKs for top commit:
  hodlinator:
    ACK 948238a683
  ryanofsky:
    Code review ACK 948238a683. Only changes since last review were changing a comments a little bit.
  marcofleon:
    Code review ACK 948238a683. Only changes since my last review are the improvements in `prevector_tests`.

Tree-SHA512: 69c6b46a42cb743138ee8c87ff26a588dbe083e3efb3dca49b8a133ba5d3b09e8bf01c590ec7e121a7d77cb1fd7dcacd927a9ca139ac65e1f7c6d1ec46f93b57
2024-08-28 16:56:32 +01:00
Ava Chow
2c7a4231db Merge bitcoin/bitcoin#30569: node: reduce unsafe uint256S usage
18d65d2772 test: use uint256::FromUserHex for RANDOM_CTX_SEED (stickies-v)
6819e5a329 node: use uint256::FromUserHex for -assumevalid parsing (stickies-v)
2e58fdb544 util: remove unused IsHexNumber (stickies-v)
8a44d7d3c1 node: use uint256::FromUserHex for -minimumchainwork parsing (stickies-v)
70e2c87737 refactor: add uint256::FromUserHex helper (stickies-v)
85b7cbfcbe test: unittest chainstatemanager_args (stickies-v)

Pull request description:

  Since fad2991ba0, `uint256S` has been [deprecated](fad2991ba0 (diff-800776e2dda39116e889839f69409571a5d397de048a141da7e4003bc099e3e2R138)) because it is less robust than the `base_blob::FromHex()` introduced in [the same PR](https://github.com/bitcoin/bitcoin/pull/30482). Specifically, it tries to recover from length-mismatches, recover from untrimmed whitespace, 0x-prefix and garbage at the end, instead of simply requiring exactly 64 hex-only characters. _(see also #30532)_

  This PR carves out the few `uint256S` callsites that may potentially prove a bit more controversial to change because they deal with user input and backwards incompatible behaviour change.

  The main behaviour change introduced in this PR is:
  - `-minimumchainwork` will raise an error when input is longer than 64 hex digits
  - `-assumevalid` will raise an error when input contains invalid hex characters, or when it is longer than 64 hex digits
  - test: the optional RANDOM_CTX_SEED env var will now cause tests to abort when it contains invalid hex characters, or when it is longer than 64 hex digits

  After this PR, the remaining work to remove `uint256S` completely is almost entirely mechanical and/or test related. I will open that PR once #30560 is merged because it builds on that.

ACKs for top commit:
  hodlinator:
    re-ACK 18d65d2772
  l0rinc:
    ACK 18d65d2772
  achow101:
    ACK 18d65d2772
  ryanofsky:
    Code review ACK 18d65d2772. Very nice change that cleans up the API, adds checking for invalid values, makes parsing of values more consistent, and adds test coverage.

Tree-SHA512: ec118ea3d56e1dfbc4c79acdbfc797f65c4d2107b0ca9577c848b4ab9b7cb8d05db9f3c7fe8441a09291aca41bf671572431f4eddc59be8fb53abbea76bbbf86
2024-08-27 16:47:54 -04:00
MarcoFalke
fa0fe08eca scripted-diff: [test] Use g_rng/m_rng directly
-BEGIN VERIFY SCRIPT-

 # Use m_rng in unit test files
 ren() { sed -i "s:\<$1\>:$2:g" $( git grep -l "$1" src/test/*.cpp src/wallet/test/*.cpp src/test/util/setup_common.cpp ) ; }
 ren InsecureRand32                m_rng.rand32
 ren InsecureRand256               m_rng.rand256
 ren InsecureRandBits              m_rng.randbits
 ren InsecureRandRange             m_rng.randrange
 ren InsecureRandBool              m_rng.randbool
 ren g_insecure_rand_ctx           m_rng
 ren g_insecure_rand_ctx_temp_path g_rng_temp_path

-END VERIFY SCRIPT-
2024-08-26 11:19:52 +02:00
stickies-v
6819e5a329 node: use uint256::FromUserHex for -assumevalid parsing
Removes dependency on unsafe and deprecated uint256S.

This makes parsing more strict, by returning an error
when the input contains non-hex characters, or when it
contains more than 64 hex digits.

Also make feature_assumevalid.py more robust by using CBlock.hash
which is guaranteed to be 64 characters long, as opposed to the
variable-length hex(CBlock.sha256)
2024-08-23 13:53:40 +01:00
stickies-v
8a44d7d3c1 node: use uint256::FromUserHex for -minimumchainwork parsing
Removes dependency on unsafe and deprecated uint256S.

This makes parsing more strict, by returning an error
when the input contains more than 64 hex digits.
2024-08-23 13:53:40 +01:00
stickies-v
85b7cbfcbe test: unittest chainstatemanager_args 2024-08-21 19:29:25 +01:00
Fabian Jahr
bf0efb4fc7 scripted-diff: Modernize naming of nChainTx and nTxCount
-BEGIN VERIFY SCRIPT-
sed -i 's/nChainTx/m_chain_tx_count/g' $(git grep -l 'nChainTx' ./src)
sed -i 's/nTxCount/tx_count/g' $(git grep -l 'nTxCount' ./src)
-END VERIFY SCRIPT-
2024-08-04 14:24:43 +02:00
MarcoFalke
fa690c8e53 test: [refactor] Pass TestOpts 2024-07-08 16:11:15 +02:00
stickies-v
260f8da71a refactor: remove warnings globals 2024-06-13 11:20:49 +01:00
Fabian Jahr
de95953d87 rpc: Optimize serialization disk space of dumptxoutset
Co-authored-by: Aurèle Oulès <aurele@oules.com>
Co-authored-by: TheCharlatan <seb.kung@gmail.com>
2024-05-21 13:38:07 +02:00
Ryan Ofsky
9d9a7458a2 assumeutxo: Remove BLOCK_ASSUMED_VALID flag
Flag adds complexity and is not currently used for anything.
2024-03-18 11:28:40 -05:00
Ryan Ofsky
ef29c8b662 assumeutxo: Get rid of faked nTx and nChainTx values
The `PopulateAndValidateSnapshot` function introduced in
f6e2da5fb7 from #19806 has been setting fake
`nTx` and `nChainTx` values that can show up in RPC results (see #29328) and
make `CBlockIndex` state hard to reason about, because it is difficult to know
whether the values are real or fake.

Revert to previous behavior of setting `nTx` and `nChainTx` to 0 when the
values are unknown, instead of faking them.

This commit fixes at least two assert failures in the (pindex->nChainTx ==
pindex->nTx + prev_chain_tx) check that would happen previously. Tests for
these failures are added separately in the next two commits.

Compatibility note: This change could result in -checkblockindex failures if a
snapshot was loaded by a previous version of Bitcoin Core and not fully
validated, because fake nTx values will have been saved to the block index. It
would be pretty easy to avoid these failures by adding some compatibility code
to `LoadBlockIndex` and changing `nTx` values from 1 to 0 when they are fake
(when `(pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS`), but a
little simpler not to worry about being compatible in this case.
2024-03-18 11:28:40 -05:00
TheCharlatan
84f5c135b8 refactor: De-globalize g_signals 2024-02-15 14:37:01 +01:00
TheCharlatan
3fba3d5dee [refactor] Make signals optional in mempool and chainman
This is done in preparation for the next two commits, where the
CMainSignals are de-globalized.

This avoids adding new constructor arguments to the ChainstateManager
and CTxMemPool classes over the next two commits.

This could also allow future tests that are only interested in the
internal behaviour of the classes to forgo instantiating the signals.
2024-02-15 13:28:45 +01:00
MarcoFalke
fad0fafd5a refactor: Fix timedata includes 2024-02-01 13:52:05 +01:00
dergoegge
ff9039f6ea Remove GetAdjustedTime 2024-01-05 17:16:38 +00:00
Ryan Ofsky
feeb7b816a refactor: Remove calls to StartShutdown from KernelNotifications
Use SignalInterrupt object instead. There is a slight change in behavior here
because the previous StartShutdown code used to abort on failure and the
new code logs errors instead.
2023-12-04 15:39:15 -04:00
Ryan Ofsky
73133c36aa refactor: Add NodeContext::shutdown member
Add NodeContext::shutdown variable and start using it to replace the
kernel::Context::interrupt variable. The latter can't easily be removed right
away but will be removed later in this PR.

Moving the interrupt object from the kernel context to the node context
increases flexibility of the kernel API so it is possible to use multiple
interrupt objects, or avoid creating one if one is not needed. It will also
allow getting rid of the kernel::g_context global later in this PR, replacing
it with a private SignalInterrupt instance in init.cpp

There is no change in behavior in this commit outside of unit tests. In unit
tests there should be no visible change either, but internally now each test
has its own interrupt variable so the variable will be automatically reset
between tests.
2023-12-04 15:39:15 -04:00
dergoegge
9e58c5bcd9 Use Txid in COutpoint 2023-11-21 13:15:44 +00:00
ismaelsadeeq
81dfeddea7 refactor: update MAX_DISCONNECTED_TX_POOL from kb to bytes 2023-10-13 14:25:37 +01:00
James O'Beirne
9511fb3616 validation: assumeutxo: swap m_mempool on snapshot activation
Otherwise we will not receive transactions during background sync until
restart.
2023-09-30 06:40:17 -04:00
James O'Beirne
49ef778158 test: adjust chainstate tests to use recognized snapshot base
In future commits, loading the block index while making use of a
snapshot is contingent on the snapshot being recognized by chainparams.

Ensure all existing unittests that use snapshots use a recognized
snapshot (at height 110).

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
2023-09-30 06:40:17 -04:00
James O'Beirne
434495a8c1 chainparams: add blockhash to AssumeutxoData
This allows us to reference assumeutxo configuration by blockhash as
well as height; this is helpful in future changes when we want to
reference assumeutxo configurations before the block index is loaded.
2023-09-30 06:38:47 -04:00
glozow
4313c77400 make DisconnectedBlockTransactions responsible for its own memory management
Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
2023-09-13 13:03:38 +01:00
glozow
cf5f1faa03 MOVEONLY: DisconnectedBlockTransactions to its own file
This struct is only used in validation + tests and has very little to do
with txmempool.
2023-09-13 13:01:59 +01:00
Ryan Ofsky
94a98fbd1d assumeutxo cleanup: Move IsInitialBlockDownload & NotifyHeaderTip to ChainstateManager
This change makes IsInitialBlockDownload and NotifyHeaderTip functions no
longer tied to individual Chainstate objects. It makes them work with the
ChainstateManager object instead so code is simpler and it is no longer
possible to call them incorrectly with an inactive Chainstate.

This change also makes m_cached_finished_ibd caching easier to reason about,
because now there is only one cached value instead of two (for background and
snapshot chainstates) so the cached IBD state now no longer gets reset when a
snapshot is loaded.

There should be no change in behavior because these functions were always
called on the active ChainState objects.

These changes were discussed previously
https://github.com/bitcoin/bitcoin/pull/27746#discussion_r1246868905 and
https://github.com/bitcoin/bitcoin/pull/27746#discussion_r1237552792 as
possible followups for that PR.
2023-08-18 12:52:30 -04:00
Suhas Daftuar
768690b7ce Fix initialization of setBlockIndexCandidates when working with multiple chainstates
When using assumeutxo and multiple chainstates are active, the background
chainstate should consider all HAVE_DATA blocks that are ancestors of the
snapshotted block and that have more work than the tip as potential candidates.
2023-07-24 16:23:38 -04:00
Suhas Daftuar
d43a1f1a2f Tighten requirements for adding elements to setBlockIndexCandidates
When using assumeutxo, we only need the background chainstate to consider
blocks that are on the chain leading to the snapshotted block.

Note that this introduces the new invariant that we can only have an assumeutxo
snapshot where the snapshotted blockhash is in our block index. Unknown block
hashes that are somehow passed in will cause assertion failures when processing
new blocks.

Includes test fixes and improvements by Andrew Chow and Fabian Jahr.
2023-07-24 16:23:38 -04:00
Suhas Daftuar
471da5f6e7 Move block-arrival information / preciousblock counters to ChainstateManager
Block arrival information (and the preciousblock RPC, a related concept) are
both chainstate-agnostic, so these are moved to ChainstateManager. This should
just be a refactor, without any observable behavior changes.
2023-07-14 17:09:06 -04:00
furszy
3e8bf2e10c test: make assumeUTXO test capture the expected fatal error
The test is exercising the error, so it can capture it before
the test framework displays it on the console as an unforeseen
fatal error.
2023-07-08 11:45:34 -03:00