Skip to content

coin pointer + pr35295#175

Draft
l0rinc wants to merge 20 commits into
masterfrom
l0rinc/coin-pointer-pr35295-clean
Draft

coin pointer + pr35295#175
l0rinc wants to merge 20 commits into
masterfrom
l0rinc/coin-pointer-pr35295-clean

Conversation

@l0rinc
Copy link
Copy Markdown
Owner

@l0rinc l0rinc commented May 18, 2026

No description provided.

andrewtoth and others added 20 commits May 18, 2026 12:08
Introduce CoinsViewOverlay::StartFetching, which maps all input prevouts of a
block to a new m_inputs vector of InputToFetch elements. Returns a ResetGuard
which is lifetime bound to the block, while the InputToFetch elements are
lifetime bound to the block as well.

Introduce StopFetching to clear the m_inputs vector.
CCoinsViewCache::Reset is made virtual and is overridden in CoinsViewOverlay.
StopFetching is called on Reset, so the InputToFetch objects will not
exceed the lifetime of the block.

Introduce ProcessInput to fetch the utxo of an individual input in m_inputs.
Each caller fetches the input at m_input_head and increments it, so each call
will fetch the next input in the queue.

Fetch coins from the m_inputs vector in FetchCoinFromBase by scanning all inputs
until we discover the input with the correct outpoint.

This is designed deliberately so multiple threads can call ProcessInput independently.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
Inputs spending outputs of an earlier transaction in the same block won't
be in the cache or the db. They also won't be requested by FetchCoinFromBase,
so we can filter them out to not waste time trying to fetch them.

Build an unordered set of seen txids while flattening m_inputs and skip
any prevout whose hash is already in the set.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Provides a worst-case upper bound on the number of inputs that can fit in
a block, so callers (e.g. parallel input prefetching) can pre-allocate
stable storage and rule out reallocation of per-input state.

Cherry-picked from PR bitcoin#9938 (Lock-Free CheckQueue), with MAX_TXINS_PER_BLOCK
renamed to MAX_INPUTS_PER_BLOCK to match the call site.

Co-authored-by: Jeremy Rubin <jeremy.l.rubin@gmail.com>
Prepares for ProcessInput to be called from multiple threads.

This flag acts as a memory fence around InputToFetch::coin. There is no lock
guarding reads and writes of the coin field.
Instead we use the flag's release/acquire semantics to ensure that when the
main thread reads the coin it will have happened after a worker thread has
finished writing it.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Prepares for ProcessInput to be called from multiple threads.

ProcessInput reads from base. For ProcessInput to be safe to call in parallel
on separate threads, it must not be mutated.
Flush, Sync, and SetBackend can modify base, so we override these and
StopFetching before calling the base class.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Add a configuration option for the number of worker threads used for
parallel UTXO input fetching during block connection.

Default is 4 threads, max is 16, 0 disables parallel fetching.
Prepares for ProcessInput to be called from multiple threads.

Introduce a ThreadPool shared pointer to CoinsViewOverlay. A pool managed
externally can be passed in the constructor.

A global thread pool is used in fuzz harnesses since iterations can happen
faster than the OS can create and tear down thread pools.
This can cause a memory leak when fuzzing.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Leverages the thread pool to fetch inputs on multiple threads, while the overlay
serves inputs on the main thread.

This is a performance improvement over blocking the main thread to fetch inputs.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Co-authored-by: l0rinc <pap.lorinc@gmail.com>
Co-authored-by: sedited <seb.kung@gmail.com>
WriteCoinsViewEntry's local map allocates coins via the test resource and
relies on FreeAllCoins() running after BatchWrite returns. When BatchWrite
throws (e.g. EX_FRESH_MISAPPLIED in ccoins_write), that cleanup is skipped
and the temp map is destroyed with non-null coin pointers, which trips the
~CCoinsCacheEntry assertion that coin == nullptr. Catch and rethrow so the
coins are always released.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants