Skip to content

fix(opencode): stop submitting expired verified protos - #1438

Open
bmc08gt wants to merge 3 commits into
code/cashfrom
fix/verified-proto-expiry
Open

fix(opencode): stop submitting expired verified protos#1438
bmc08gt wants to merge 3 commits into
code/cashfrom
fix/verified-proto-expiry

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Bugsnag 6aa188d3ce44e305cadc4a0a: a withdrawal failed three times with SubmitIntentError.StaleState: exchange rate is stale. The protos in the request were signed about 23 minutes before submission, and the server rejects anything older than 15.

VerifiedProtoManager.getOrEvict already checks the timestamp against a 15-minute TTL. When it finds an expired entry it evicts it from the map and then returns it anyway. RealVerifiedFiatCalculator.resolveVerifiedState treats any non-null result as usable, so the fresh-fetch branch never ran: none of the three attempts logged "Fetching fresh". The live-mint stream re-saved the same old-stamped protos every few seconds, so each retry hit the same path.

Three changes in the manager:

  • getOrEvict returns null for an expired entry, so the calculator falls through to getLiveMintData and either gets a fresh proof or fails with StaleRate before the request goes out.
  • The ceiling drops from 15 minutes to 13, matching iOS clientMaxAge and leaving headroom for the request to land inside the server's window.
  • saveRates and saveReserveStates skip protos that arrive already past the ceiling, the same check iOS makes in VerifiedProtoService on arrival.

kotlin.time.Clock is injected through an internal primary constructor; the no-arg @Inject constructor delegates to Clock.System, so Hilt and the two VerifiedProtoManager() factory call sites are unchanged. VerifiedProtoManagerTest drives the expiry boundary with a fake clock, and RealVerifiedFiatCalculatorTest gains a case showing a null cache hit triggers the fetch.

This does not explain why the stream kept sending protos stamped 23 minutes old. If the backend keeps doing that, the refetch will fail with StaleRate instead of succeeding, which is still the right outcome for the user's balance but leaves the backend question open.

@bmc08gt bmc08gt self-assigned this Sep 9, 2026
@github-actions github-actions Bot added area: network gRPC, connectivity, API, exchange rates type: fix Bug fix labels Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: network gRPC, connectivity, API, exchange rates type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant