Skip to content

compat: ZK-tier input commitment, two-step pool exit, and refund claims for current compute contracts - #12

Merged
SaulBuilds merged 3 commits into
mainfrom
fix/r2-compute-compat
Sep 26, 2026
Merged

SaulBuilds merged 3 commits into
mainfrom
fix/r2-compute-compat

Conversation

@SaulBuilds

Copy link
Copy Markdown
Contributor

Compat update of citrate_sdk.compute for the current compute contracts on citrate-chain main.

What changes

  • ZK-tier input commitment. post_job(..., input_commitment=...): a job verified under the ZK tier (tier "ZK", or "Commitment" with max_price strictly above 10 SALT) posts the inference circuit's 32-byte BN254 input commitment as inputHash. The client checks that the commitment is a non-zero scalar below the field modulus, and that the model hash is below it too, before sending. A job without a valid commitment raises ZKCommitmentError and no transaction is sent. Commitment and TEE jobs at or under the threshold are unchanged. effective_tier() is exported. postJob targets computeMarketplace when configured, and falls back to computePool otherwise.
  • Two-step pool exit. request_leave() is followed by leave_pool() once LEAVE_COOLDOWN (150 blocks) has passed. leave_status() reports the pending exit. If no exit is pending, leave_pool() sends requestLeave; inside the cooldown it raises LeaveNotReadyError. join_pool() takes the required stake.
  • Refund claims. claim_refund and refund_owed (InferenceRouter), claim_native_refund and native_refund_owed (ComputeMarketplace), and claim_requester_refund and requester_refund_pending (ComputePoolTraining). Each claim reads the owed amount first and raises NothingToClaimError rather than sending a call that reverts.
  • The ZK-tier "hello world" test now passes a canonical commitment.

Evidence

Item Tests Tripwire Mutation Status
BN254 inputHash for ZK / auto-ZK tests/test_r2_compute_compat.py (ZK, >10 SALT, boundary at exactly 10 SALT, non-canonical/zero/short/non-hex commitments, model hash at r, messages), tests/test_compute.py, anvil tests/test_r2_compute_anvil.py modulus + threshold constants pinned behavioural revert: 26 red → green; mutmut on compute.py: survivors in changed functions are equivalent (int.from_bytes default byteorder, "UTF-8", cast(None, …), None vs False) or message-only, and the user-facing messages are now pinned FIXED
requestLeave + cooldown compat tests (no request → requestLeave; inside cooldown → error; after → leavePool), anvil e2e LEAVE_COOLDOWN_BLOCKS pinned same run FIXED
refund claim APIs compat tests (selectors, targets, nothing-owed guard), anvil e2e selectors checked against the contract ABI same run FIXED

The anvil tests are env-gated (CITRATE_R2_ANVIL_ADDRS, optional CITRATE_R2_ANVIL_RPC). They ran 6/6 against a local deploy of the chain-main contracts.

Local CI (same commands as ci.yml)

baseline (main 3bed9ac) this branch
uv lock --check ok ok
uv run --frozen ruff check . clean clean
uv run --frozen mypy . clean (82 files) clean (84 files)
uv run --frozen pytest -q 756 passed, 1 failed, 43 skipped 813 passed, 1 failed, 43 skipped
pip-audit (locked set) unchanged unchanged

The one failure is test_economics_simulation.py::TestPerformance::test_10year_medium_under_60s. It fails on main too: it is a wall-clock test, and the local machine is shared and under load.

🤖 Generated with Claude Code

https://claude.ai/code/session_012cD3fDq5vhh2YWZPU2SV6H

BerryManifold and others added 3 commits September 25, 2026 16:59
- post_job: jobs verified under the ZK tier (tier "ZK", or "Commitment"
  above 10 SALT) post the circuit's 32-byte BN254 input commitment as
  inputHash via the new input_commitment argument; the client checks it is
  a non-zero scalar below the field modulus (and the model hash is too)
  before sending. Other tiers are unchanged.
- ComputePool exit is two steps: request_leave(), then leave_pool() once
  LEAVE_COOLDOWN (150 blocks) has elapsed; leave_status() reports it.
  join_pool() takes the required stake.
- Refund claims: claim_refund / refund_owed (InferenceRouter),
  claim_native_refund / native_refund_owed (ComputeMarketplace),
  claim_requester_refund / requester_refund_pending (ComputePoolTraining).
- postJob targets computeMarketplace when configured (falls back to
  computePool).
- Env-gated end-to-end test against the contracts on a local anvil.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012cD3fDq5vhh2YWZPU2SV6H
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012cD3fDq5vhh2YWZPU2SV6H
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012cD3fDq5vhh2YWZPU2SV6H
@SaulBuilds
SaulBuilds merged commit 55f159e into main Sep 26, 2026
10 checks passed
@SaulBuilds
SaulBuilds deleted the fix/r2-compute-compat branch September 26, 2026 04:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants