Skip to content

Audit-token cache fast-fail fallback for recently-audited outputs - #2204

Draft
Effi-S wants to merge 1 commit into
mainfrom
fix-2176
Draft

Audit-token cache fast-fail fallback for recently-audited outputs#2204
Effi-S wants to merge 1 commit into
mainfrom
fix-2176

Conversation

@Effi-S

@Effi-S Effi-S commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #2176

Problem

Auditor-side transaction validation (AuditorCheck
common.RetrieveAuditTokens, token/core/common/auditor.go) can spuriously
fail when a transaction references — as inputs — outputs of a very
recently-audited transaction. The SQL-backed token store returns a hard
"token not found for key [...]" the moment a requested output row is
missing, and those rows are only written asynchronously by the finality
listener (token/services/ttx/finality/listener.go) once the network reports
the referenced transaction as final. A closely-following transaction can
therefore reach audit validation before those rows are persisted.

See parent issue #2105 for the full analysis of the race.

Scope of this issue

This tracks only the cache fast-fail solution (Suggestion 2 in #2105,
refined in the review on #2140), not the retry/backoff mitigation that
landed in #2140.

The idea: tokens.Service already maintains an in-memory RequestsCache,
populated at audit-approval time (AuditApproveView.Call,
token/services/ttx/auditor.go, via CacheRequest) and removed in
AppendValid (token/services/tokens/tokens.go). Its lifetime lines up
exactly with the race window, and the cached value is byte-identical to what
the DB read returns (owner_raw, token_type, quantity). Consulting this
cache on a DB miss lets audit validation resolve the in-flight token
immediately — fast — instead of relying on a multi-second backoff window
that is unbounded under load and only shrinks (never removes) the failure
probability.

Proposed shape:

  • DB read first; consult the tokens.Service cache only on a miss.
  • Replicate the auditor = true filter (Flags.Auditor) so a cached entry
    is only used where the DB read would have qualified.
  • token/core/common cannot import token/services/tokens directly, so this
    needs a consumer-side interface plus an adapter wired in the SDK, and
    tokens.Service (or a narrow view of it) plumbed into AuditorService
    construction for both the fabtoken and zkatdlog drivers — a dependency that
    does not exist in either construction chain today.

Known limits

The cache is in-process and best-effort (Ristretto's Set result is
discarded), so a process restart or a second auditor replica falls straight
through it. This is why the cache is a complement to the backoff, not a
replacement: the backoff remains the outer net for whatever the cache does
not cover.

Impact

Removes the multi-second latency the backoff adds to the common case (a
just-audited output referenced on the same node), turning a slow retry into
an immediate cache hit, while further reducing the spurious-failure rate for
quickly-chained transactions.

@Effi-S Effi-S added this to the Q3/26 milestone Aug 12, 2026
@Effi-S Effi-S self-assigned this Aug 12, 2026
@Effi-S Effi-S closed this Aug 12, 2026
@Effi-S Effi-S reopened this Aug 13, 2026
@Effi-S Effi-S closed this Aug 16, 2026
@Effi-S Effi-S reopened this Aug 17, 2026
Signed-off-by: Effi-S <effi.szt@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audit-token cache fast-fail fallback for recently-audited outputs

1 participant