Description
Ingestor::process in crates/ingest/src/lib.rs records an unattributed deposit with address_id: None ("quarantine") whenever the muxed id or memo id it extracts doesn't match any row returned by Store::address_by_muxed_id. This can legitimately happen when a customer sends funds to a muxed address moments before the corresponding POST /v1/wallets/:id/addresses call that would have registered it (a race between off-chain address generation and on-chain funding). Today, once quarantined, a deposit has no path back to being attributed — there is no store method or route to retroactively link a quarantined transactions row to an addresses row once it's created.
Requirements and Context
- Add
pub async fn attribute_quarantined_deposit(&self, transaction_id: Uuid, address_id: Uuid) -> Result<(), StoreError> to crates/store/src/lib.rs, updating transactions.address_id only when it is currently NULL (never overwrite an already-attributed deposit).
- Add
pub async fn list_quarantined_transactions(&self, wallet_id: Uuid) -> Result<Vec<Transaction>, StoreError> to make quarantined deposits discoverable (currently there is no way to query for them specifically — list_transactions returns everything mixed together).
- Wiring an actual API route for this is a natural next step but is explicitly out of scope for this ticket — keep it store-layer only, and note the follow-up API-route need in the PR description.
Suggested Execution
Branch: feat/ingest/quarantine-recovery
Implement Changes
- Add both methods to
crates/store/src/lib.rs.
Test and Commit
attribute_quarantined_deposit_links_an_unattributed_transaction.
attribute_quarantined_deposit_never_overwrites_an_already_attributed_transaction.
list_quarantined_transactions_returns_only_null_address_id_rows.
- Run
cargo test -p octo-store locally before committing.
Example Commit Message
feat(store): add quarantine-recovery primitives for late-attributed deposits
Once a deposit was quarantined (no matching address at ingest time), nothing
in the store layer could ever link it back to an address created afterward.
Adds attribute_quarantined_deposit (idempotent, never overwrites) and
list_quarantined_transactions so a future recovery flow has something to
build on.
Guidelines
- This ticket is store-layer only; do not add an API route in this PR even though it's the obvious next step — keep the scope reviewable.
- Reference this issue with
Closes #<issue-number> in the PR description.
Description
Ingestor::processincrates/ingest/src/lib.rsrecords an unattributed deposit withaddress_id: None("quarantine") whenever the muxed id or memo id it extracts doesn't match any row returned byStore::address_by_muxed_id. This can legitimately happen when a customer sends funds to a muxed address moments before the correspondingPOST /v1/wallets/:id/addressescall that would have registered it (a race between off-chain address generation and on-chain funding). Today, once quarantined, a deposit has no path back to being attributed — there is no store method or route to retroactively link a quarantinedtransactionsrow to anaddressesrow once it's created.Requirements and Context
pub async fn attribute_quarantined_deposit(&self, transaction_id: Uuid, address_id: Uuid) -> Result<(), StoreError>tocrates/store/src/lib.rs, updatingtransactions.address_idonly when it is currentlyNULL(never overwrite an already-attributed deposit).pub async fn list_quarantined_transactions(&self, wallet_id: Uuid) -> Result<Vec<Transaction>, StoreError>to make quarantined deposits discoverable (currently there is no way to query for them specifically —list_transactionsreturns everything mixed together).Suggested Execution
Branch:
feat/ingest/quarantine-recoveryImplement Changes
crates/store/src/lib.rs.Test and Commit
attribute_quarantined_deposit_links_an_unattributed_transaction.attribute_quarantined_deposit_never_overwrites_an_already_attributed_transaction.list_quarantined_transactions_returns_only_null_address_id_rows.cargo test -p octo-storelocally before committing.Example Commit Message
Guidelines
Closes #<issue-number>in the PR description.