Refill an emptied VSS store from local state at unlock - #172
Merged
Merged
Conversation
dcorral
force-pushed
the
fix/vss-empty-store-resync
branch
from
September 11, 2026 17:11
cc61f0d to
038686d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refill an emptied VSS store from local state at unlock
Issue
When the VSS server loses its data (stack stopped, postgres data dir wiped, server restarted) and the node is restarted against the now-empty store, nothing re-uploads the node's existing state. The node keeps working normally because reads are local-first, but the rebuilt VSS store is silently incomplete:
/vssbackupinforeportsbackup_exists: falseandbackup_required: false, and the store only receives the handful of keys that happen to be rewritten after the restart. A later disk loss would restore without the RGB wallet and without every channel whose monitor was not rewritten since the wipe.Two independent gaps cause this:
Reproduction
--vss-url, init and unlock it, then lock it._rgbcompanion).Before this PR: the channel manager key is absent from the VSS store and
/vssbackupinforeportsbackup_exists: false. The e2e testvss_wiped_store_is_refilled_on_unlockreproduces this and fails onkey missing after refill: _/_/managerwhen the refill is disabled.Fix
SyncedKvStore::push_missing_to_vsslists the remote keys once and writes every local row the remote lacks. It never overwrites a key the remote already holds, and it skips rows that are local-only by design: the pending replication queue, the consignment re-import marker, network graph and scorer. It runs at unlock whenever local state exists, so a wiped or partial store is refilled before the background processor starts.VssKvStore::list_all_keys(paginated key listing without values),SeaOrmKvStore::list_all, and the existing remove path split intoremove_rawso tests can wipe rgb-lib's backup keys, which do not follow the node's key format.Both failures at unlock (resync or initial RGB upload) abort the unlock with an explicit error rather than silently running with an incomplete backup.
Tests
synced_kv_store_push_fills_missing_remote_keys(unit, needs the VSS server): wipes the remote, plants a foreign value, and asserts that missing keys are pushed, the existing value is not overwritten, local-only rows stay local, and a second push is a no-op.vss_wiped_store_is_refilled_on_unlock(e2e): init, unlock, lock, wipe both stores, unlock again, then asserts every key present before the wipe is back and/vssbackupinforeportsbackup_exists: true.