Repository navigation
feat(minter): scan the watched deposit addresses on a timer and queue the detected deposits - #283
Merged
Merged
Conversation
Replace the outdated section 3.1.1, which described per-transaction crediting with getSignaturesForAddress and quotas replenished by the removed process_deposit endpoint, with a design that builds on the balance sweep of deposit_sol: a free registration endpoint, a scan timer reading watched deposit addresses in batches with getMultipleAccounts, a schedule adapted from the ckETH minter, a fixed fee in SOL deducted from the minted amount, and a watchlist persisted only as a bounded snapshot at pre_upgrade. Every change to the interface, the arguments and the event log is additive, since the minter is deployed on mainnet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
State that a re-armed account is reported as watching again, that the main account receives the sweepable amount minus the fee share, correct the worst-case cost arithmetic and state its success assumption, and distinguish a failed upgrade from a reinstallation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ring Move the sequence diagram of the automatic flow ahead of its explanation, remove the semicolon that broke the mermaid parser on GitHub, and define the deposit id where it is first used in the section. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he constraint State that scan ticks are guarded like the other timers so that they never overlap, and base the automatic deposit fee constraint on the single-signature fee share that a pending mint actually bears. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Drop the separate status query: calling the registration endpoint again returns the stored registration or the id of the deposit in flight, as deposit_eth does in the ckETH minter. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… signature lookup Spell out that scan ticks never overlap, that the fee derivation is a single-attempt estimate with re-arm costs absorbed by the minter, and that only manual deposits are retried by the caller. Remove getSignaturesForAddress from the RPC inventory and cost tables, since the minter no longer uses it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A re-armed entry restarts its schedule from the first gap, bounded by the remaining window, and a re-arm only ever follows a detection. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Record the watchlist snapshot on every upgrade so that an older one cannot be replayed after the watchlist emptied, and let the transaction submission section account for deposits queued by the balance scan. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The window ends with the last scan, and the next registration call starts a new window rather than reporting a registration without a next scan. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…it ids Follow the ckETH minter: a registration freezes neither the minimum deposit amount nor the automatic deposit fee, both are quoted and the values in force at detection apply, the fee being recorded with the queued deposit. deposit_sol compares the latest deposit id of the account before and after its balance read, and a registration is allowed while a deposit_sol call is in progress. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…edule Measure gaps from the previous scan as before, but end the window at a fixed 24 hours after registration, as the ckETH minter does, so that the accumulated tick and call delays have slack and clients and the re-arm share one unambiguous boundary. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ence Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…owner rationale The fee recorded at detection matters for deposits an upgrade finds not yet credited; a credited deposit has its mint amount in CreditedSweep. The minter's principal is excluded as a deposit owner because its default account is the ledger's minting account, not because of an address collision. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…xample with the automatic flow Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er a concurrent scan Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…n delay and the fee worst case Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…or to new registrations Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…vents the automatic flow adds Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
gregorydemay
force-pushed
the
DEFI-2780-08-scan-timer
branch
from
October 14, 2026 09:04
a51206a to
0f2515d
Compare
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
A concurrent manual deposit can race with the scan and trigger the duplicate in-flight deposit assertion.
1 open finding
What changed in this PR
Adds timer-driven scanning of watched Solana deposit addresses and queues eligible deposits automatically.
Changes:
- Adds batched balance scanning with scheduling and concurrency guards.
- Adds scan metrics and unit/integration coverage.
- Updates automatic-deposit design documentation.
| File | Description |
|---|---|
minter/src/storage/mod.rs |
Stores scan outcome counters. |
minter/src/state/mod.rs |
Adds scan task and deposit-call lookup. |
minter/src/rpc/mod.rs |
Enables the balance batching helper. |
minter/src/metrics.rs |
Exposes scan outcome metrics. |
minter/src/main.rs |
Registers the scan timer. |
minter/src/deposit/automatic/scan/tests.rs |
Tests scan behavior and scheduling. |
minter/src/deposit/automatic/scan/mod.rs |
Implements watched-address scanning. |
minter/src/deposit/automatic/mod.rs |
Exports scan functionality. |
minter/src/constants.rs |
Defines the scan interval. |
integration_tests/tests/tests.rs |
Tests timer-based deposit detection. |
integration_tests/src/fixtures.rs |
Adds batched-account RPC mocks. |
docs/src/development/design.md |
Updates scan behavior and cost bounds. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…queues a deposit Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…name Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…counts parameters Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ing its balance read Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e alone Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ee under the new name Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…endpoint Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
eichhorl
approved these changes
Oct 23, 2026
…t per address The balances are paired with the addresses by position, and the SOL RPC canister does not guarantee one account per requested address in the pinned version, so a short response would leave the addresses past its end unread. A response with the wrong number of accounts is now an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pins the parameters, the response size estimate and the cycles the minter chooses for 1 and 100 addresses, which the tests of the response alone leave unchecked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e to the SOL RPC canister As for every other call, the SOL RPC canister prices the call with its own default estimate, which allows 192 bytes per account without data in its upcoming release, close to what the minter estimated, so the minter no longer mirrors the canister's internal sizes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recording it when the responses arrive skipped a slot that passed while the reads were in flight. The registration the reads were made for must still be live when they arrive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… a failed read A tick that finds the previous one still waiting for its calls makes no call, and a failed read of a registration that was replaced or expired meanwhile leaves the current registration untouched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…balance read of deposit_sol Pins why deposit_sol compares the latest deposit id of the account rather than the one in flight: a deposit queued by a scan and minted before the balance read returns must not free the account for a second deposit from the stale balance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d one Since a balance scan of the automatic flow can queue the deposit an account's deposit_sol call returns, its mint may be reduced by the automatic deposit fee. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follows the minter, which no longer passes a response size estimate with getMultipleAccounts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the pins to the dfinity/sol-rpc-canister#394 commit with the released sol_rpc_client 7.0.0 and sol_rpc_types 4.0.0, and run the integration tests against the SOL RPC canister v1.4.0 release wasm. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mbjorkqvist
approved these changes
Nov 4, 2026
|
✅ No security or compliance issues detected. Reviewed everything up to 1f09987. Security OverviewDetected Code Changes
|
# Conflicts: # minter/src/rpc/mod.rs
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.



Adds the scan timer of the automatic deposit flow of #272: every minute, the due watched addresses are read in batches, a balance reaching the minimum deposit amount is queued exactly as
deposit_solwould queue it, with the fee in force, and a failed read counts as a scan so that the cost of a registration stays within its schedule. Sincedeposit_soland a scan may read the balance of the same address concurrently, adeposit_solcall during whose balance read a scan queued a deposit for the account returns that deposit and charges only the read, so that the same balance is never queued twice. Covered by unit tests of the scan and of that interleaving, and a PocketIC test of a deposit detected and queued by the timer.🤖 Generated with Claude Code