Skip to content

feat(zkatsnark): honour resource limits, add circuit breaker, fix boolpolicy audit info deserializer - #2591

Merged
adecaro merged 1 commit into
feature/zkat-snark-driverfrom
zkatsnark/driver-wiring
Oct 30, 2026
Merged

adecaro merged 1 commit into
feature/zkat-snark-driverfrom
zkatsnark/driver-wiring

Conversation

@adecaro

@adecaro adecaro commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR closes the "driver-wiring" parity gap between the zkatsnark driver and zkatdlog. It is one of a series of parallel parity PRs against feature/zkat-snark-driver.

Before this change, the zkatsnark driver:

  • ignored the configured token.validation.limits and hard-coded driver.ResourceLimits{}.WithDefaults();
  • did not wrap the wallet service with the observability decorator / circuit breaker;
  • did not register the boolpolicy audit info deserializer, so boolpolicy identities resolved an empty enrollment ID and malformed member audit info was accepted silently.

What changed

(a) Resource limits

  • NewTokenDriver now takes a driver.ResourceLimitsProvider as its last parameter, like zkatdlog. dig supplies it, so the integration SDK (integration/token/common/sdk/fzkatsnark) needs no change.
  • NewTokenService resolves the limits right before validator.NewValidator and fails with failed resolving validator resource limits if the provider errors.
  • IssueService.maxOutputs() (the upgrade split) now uses the configured limits.
  • New fuzz target FuzzActionResourceLimits (nogh/v1/validator/validator_limits_fuzz_test.go). It runs through ActionDeserializer.DeserializeActions against the default limits and a small custom set. It seeds boundary and boundary+1 cases for inputs, outputs and metadata entries, for both issue and transfer actions. The target is wired into .github/workflows/nightly-fuzz.yml as zkatsnark-action-limits.

(b) Circuit breaker / observability

  • NewTokenService decorates the wallet service with observability.NewWalletServiceDecoratorWithConfig(ws, metricsProvider, LoadCircuitBreakerConfig(tmsConfig)). The decorated service is passed to the four authorization arguments (their ordering is unchanged), the issue service, the transfer service and zkatsnark.NewTokenService. The deserializer and identity provider stay on the raw wallet service, as in zkatdlog.
  • zkatsnark.NewTokenService now takes driver.WalletService. Godoc was added for it and for Service.
  • WalletServiceFactory.NewWalletService also returns a decorated service, using &disabled.Provider{}.

(c) boolpolicy audit info

  • NewEIDRHDeserializer now registers boolpolicy.NewAuditInfoDeserializer(d), the same as zkatdlog.

Docs

  • docs/drivers/zkatsnark.md: new "Driver Wiring" section. It notes that operators running plonkfri must raise maxRequestBytes and maxActionBytes under token.validation.limits, and that the upgrade-split limit is configurable.
  • docs/drivers/validation-resource-limits.md: lists the zkatsnark NewTokenDriver and adds a ZKAT-SNARK limits table.
  • docs/services/observability.md: mentions ZKAT-SNARK.

Behaviour changes

  1. The configured token.validation.limits now apply to the zkatsnark endorser-side validator and to the upgrade split. Operators running plonkfri must raise maxActionBytes and maxRequestBytes themselves.
  2. boolpolicy identities now resolve a real enrollment ID. Malformed component audit info is now an error.
  3. The circuit breaker stays disabled unless it is configured. Metrics now appear under the TMS-scoped prefix.

Dependency note

The new import of token/services/observability required running go mod tidy in the zkatsnark module. That bumped golang.org/x/net from v0.61.0 to v0.62.0, which matches what the root module already requires. Other parallel PRs may touch the same go.mod/go.sum lines.

Tests

  • driver/deserializer_test.go is a regression test. It failed on the base branch: the EID came back as "" instead of "wallet-42", and malformed member audit info gave no error. It passes after the fix. It also covers conflicting members and legally missing (nil) member audit info.
  • driver/driver_test.go covers:
    • the driver name and the early error paths of NewTokenService;
    • configured limits reaching Validator.Limits;
    • the wallet service being an *observability.WalletServiceDecorator;
    • provider errors and wallet-service errors;
    • the factory returning a decorated service, plus its error cases.
  • TestIssueServiceMaxOutputs pins the upgrade split at the limit and at limit+1.

Commands run (all pass):

cd x/token/core/zkatsnark
go test ./nogh/v1/driver/ -run 'TestNewDriver|TestNewTokenService|TestWalletServiceFactory|TestEIDRHDeserializer' -count=1 -v
go test ./nogh/v1/ -run 'TestIssueServiceMaxOutputs|TestSplitUpgradeTotal' -count=1
go test ./nogh/v1/validator/ -run '^FuzzActionResourceLimits$' -count=1 -v
go test ./nogh/v1/validator -run='^$' -fuzz='^FuzzActionResourceLimits$' -fuzztime=20s   # ~122k execs, no failures
go test -timeout 60m -count=1 ./nogh/v1/ ./nogh/v1/driver/ ./nogh/v1/validator/
go test -race -count=1 ./nogh/v1/driver/
go build ./... && go vet ./nogh/v1/driver/ ./nogh/v1/ ./nogh/v1/validator/
golangci-lint run --timeout=8m ./nogh/v1/ ./nogh/v1/driver/... ./nogh/v1/validator/...   # 0 issues
gofmt -l nogh/v1   # clean

cd integration
go vet ./token/common/sdk/fzkatsnark/ ./token/fungible/ ./token/fungible/views/
go test ./token/common/sdk/fzkatsnark/ -count=1   # dig resolves the new parameter

An independent reviewer re-ran the build, vet, targeted tests, a fuzz run, the race test, lint, gofmt and go mod tidy -diff, and confirmed that the regression test fails on the base branch.

Out of scope / follow-ups / limitations

  • Not run here: the full make unit-tests-zkatsnark shards under -race, and the NWO integration tests (covered by a separate parity PR).
  • zkatsnark has no MaxProofBytes check by design, so proof size is not a fuzz dimension.
  • These items are handled by other parity PRs in the series:
    • the unchecked type assertion in ws.go;
    • errors.Errorf("...[%s]", err) in driver.go/validator.go;
    • LoadAuditRetryConfig in NewAuditorService;
    • the authorization multiplexer ordering.
  • Merge coordination: this PR passes decoratedWS to the four authorization multiplexer arguments. If the multiplexer-ordering PR merges first, keep decoratedWS in its new ordering when resolving the conflict, and vice versa.

🤖 Generated with Claude Code

… audit deserializer

Align the zkatsnark driver wiring with zkatdlog:

- NewTokenDriver takes the dig-provided driver.ResourceLimitsProvider and
  NewTokenService passes the resolved limits to the validator, so
  token.validation.limits is honoured by the endorser-side validator and
  by IssueService.maxOutputs (upgrade split) instead of hard-coded
  defaults.
- The wallet service is decorated with the observability circuit breaker
  (NewWalletServiceDecoratorWithConfig) in Driver.NewTokenService and in
  WalletServiceFactory.NewWalletService; the decorated service backs
  authorization, issue/transfer services and the token service.
  zkatsnark.NewTokenService now takes driver.WalletService.
- NewEIDRHDeserializer registers boolpolicy.NewAuditInfoDeserializer(d)
  instead of the zero value, which silently dropped the enrollment ID of
  policy identities and skipped component audit-info checks.

Add driver wiring unit tests, a policy enrollment-ID test, a maxOutputs
test, and FuzzActionResourceLimits (wired into nightly fuzzing). Update
the zkatsnark, resource-limits and observability docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
@adecaro
adecaro force-pushed the zkatsnark/driver-wiring branch from 27ed044 to fc088b1 Compare October 30, 2026 09:49
@adecaro
adecaro merged commit c4f6e0e into feature/zkat-snark-driver Oct 30, 2026
235 checks passed
@adecaro
adecaro deleted the zkatsnark/driver-wiring branch October 30, 2026 10:29
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.

1 participant