Skip to content

test: cover the hub_ops cache cleanup scope - #101

Open
nklyy wants to merge 1 commit into
RGB-Tools:masterfrom
UTEXO-Protocol:test/hub-ops-cache-cleanup
Open

test: cover the hub_ops cache cleanup scope#101
nklyy wants to merge 1 commit into
RGB-Tools:masterfrom
UTEXO-Protocol:test/hub-ops-cache-cleanup

Conversation

@nklyy

@nklyy nklyy commented Aug 14, 2026

Copy link
Copy Markdown

Adds a reproducer for #100. No fix here - the test documents the expected invariant so the fix (whichever shape it takes) has something to turn green.

What the test does (sync_with_hub_cleanup_keeps_other_operations_files, src/wallet/test/multisig/mod.rs)

A 2-of-3 multisig with a hub:

  1. Operation 1 (create_utxos) is approved by cosigners 1 and 2. Cosigner 3 neither votes nor syncs, so it stays behind - the state a service wallet is in while another cosigner drives the flow.
  2. Cosigner 1 initiates operation 2, which is left Pending.
  3. Cosigner 3 downloads the files of both operations. get_or_download_files is the only way to read a pending operation's PSBT, so any flow that inspects one ends up holding these paths.
  4. Cosigner 3 catches up on operation 1 via sync_with_hub.

Then two assertions:

  • the completed operation's own cached files are gone - correct behaviour, kept as a regression guard;
  • the pending operation's cached files still exist - this is the one that fails today.

Why it matters beyond the cache

hub_ops/ is flat and wallet-wide (multisig.rs, get_cached_file_path), so the cleanup at the end of sync_with_hub deletes files belonging to operations it knows nothing about. In a long-running service several flows share one wallet directory: one has already resolved a file path from get_or_download_files while a neighbouring sync_with_hub removes the file underneath it, and reading the PSBT or consignment fails mid-signing. Without the race it still forces a re-download of every other pending operation's files, so a hub outage blocks operations whose files were already local.

The test reproduces the same loss deterministically, without concurrency.

Possible fixes (from #100, both keep the current semantics)

  • remove only the completed operation's files - OperationResponse.files already carries their file_ids;
  • or key the cache by a per-operation_idx subdirectory and drop that directory.

Verification

Compile-checked and lint-clean (cargo check --tests --features electrum, clippy, fmt). The run itself needs the tests/compose.yaml stack (bitcoind regtest, electrs, esplora, rgb-proxy, postgres, the multisig hub), so the failing assertion is expected to show up in CI rather than in this description.

sync_with_hub empties the whole hub_ops/ directory when an operation
reaches a terminal state, but that directory is a wallet-wide flat cache
keyed by file_id and shared by every operation. A wallet that already
downloaded a pending operation's files loses them, which in a service
sharing one wallet directory across flows shows up as a file vanishing
from under a concurrent reader mid-signing.

The test has a lagging cosigner cache a pending operation's files and
then catch up on an older approved one, asserting that the completed
operation's files are dropped while the pending one's survive.
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.

1 participant