Skip to content

blockstorage: handle undo for assumeutxo base block already on disk#35307

Open
shuv-amp wants to merge 1 commit into
bitcoin:masterfrom
shuv-amp:blockstorage-assumeutxo-base-range
Open

blockstorage: handle undo for assumeutxo base block already on disk#35307
shuv-amp wants to merge 1 commit into
bitcoin:masterfrom
shuv-amp:blockstorage-assumeutxo-base-range

Conversation

@shuv-amp
Copy link
Copy Markdown

@shuv-amp shuv-amp commented May 17, 2026

A node can receive the assumeutxo snapshot base block before loading the
snapshot. In that case the block data is written before
BlockManager::m_snapshot_height is set, so it is tracked by the normal
blockfile cursor.

After loadtxoutset() sets m_snapshot_height, the same height maps to the
ASSUMED blockfile range. If background validation later connects the base
block that was already on disk, WriteBlockUndo() could require an ASSUMED
cursor even though no post-snapshot block data had created one yet.

Handle this by writing undo data to the block's existing file when the
height-derived cursor is not present. Keep the existing cursor finalization
logic when a cursor exists.

FlushChainstateBlockFile() now receives the tip block index, so it can flush
the file where the tip is actually stored when needed.

The functional test stores the snapshot base block before loading the snapshot,
then feeds the missing historical blocks and waits for background validation to
complete.

Tested:

test/functional/feature_assumeutxo.py --configfile=$PWD/build/test/config.ini --timeout-factor=4

@DrahtBot
Copy link
Copy Markdown
Contributor

DrahtBot commented May 17, 2026

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35307.

Reviews

See the guideline for information on the review process.
A summary of reviews will appear here.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #30342 (kernel, logging: Pass Logger instances to kernel objects by ryanofsky)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

An assumeutxo snapshot base block can be stored before loadtxoutset()
sets BlockManager::m_snapshot_height. After the snapshot is loaded,
BlockfileTypeForHeight() classifies that height as ASSUMED, but the
ASSUMED blockfile cursor may not exist yet.

When background validation connects the already-stored base block, write
undo data to the block's existing file without requiring the
height-derived cursor to exist. Keep the existing cursor finalization
logic when the cursor is present.

FlushChainstateBlockFile now receives the tip block index, so it can
flush the file where the tip is actually stored if no height-derived
cursor exists. A snapshot chainstate at the base height can still return
without flushing because it has not written post-snapshot block data.

Add functional coverage for storing the snapshot base block before
loading the snapshot, then completing background validation.
@shuv-amp shuv-amp force-pushed the blockstorage-assumeutxo-base-range branch from a33b9d4 to 1a22546 Compare May 17, 2026 17:18
@shuv-amp shuv-amp changed the title blockstorage: keep assumeutxo base block in normal blockfile range blockstorage: handle undo for assumeutxo base block already on disk May 17, 2026
@shuv-amp shuv-amp marked this pull request as ready for review May 17, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants