The background chainstate connects the assumeutxo snapshot base block. If that
block is stored before loadtxoutset() sets BlockManager::m_snapshot_height,
it is written using the normal blockfile cursor.
After snapshot activation, the base height was classified as ASSUMED. If
background validation later connected the already-stored base block,
WriteBlockUndo() could require an ASSUMED cursor that had not been
initialized.
Classify only blocks above the snapshot base height as ASSUMED. Keep the
snapshot chainstate flush path from flushing the normal cursor while it is still
at the base height.
When loading a snapshot chainstate from disk, keep an already-stored base block
in m_blocks_unlinked until its parents are processed, and avoid adding the
historical target to setBlockIndexCandidates before then. VerifyDB also
stops before disconnecting the snapshot base, where the snapshot database lacks
the ancestor UTXO data.
The functional test stores the snapshot base block before loading the snapshot, restarts after snapshot activation, then feeds the missing historical blocks and checks that background validation completes.
Tested:
test/functional/feature_assumeutxo.py --configfile=$PWD/build/test/config.ini --timeout-factor=4
test/functional/wallet_assumeutxo.py --configfile=$PWD/build/test/config.ini --timeout-factor=4