Skip to content

test(python/svm): add unit tests for ExactSvmSchemeV1 facilitator#152

Open
0xAxiom wants to merge 1 commit intocoinbase:mainfrom
0xAxiom:test/python-svm-v1-facilitator-unit-tests
Open

test(python/svm): add unit tests for ExactSvmSchemeV1 facilitator#152
0xAxiom wants to merge 1 commit intocoinbase:mainfrom
0xAxiom:test/python-svm-v1-facilitator-unit-tests

Conversation

@0xAxiom
Copy link
Copy Markdown

@0xAxiom 0xAxiom commented May 4, 2026

Summary

Add 41 unit tests for python/x402/x402/mechanisms/svm/exact/v1/facilitator.py — the only file in mechanisms/svm/exact/v1/ without a dedicated test module after #151 landed test_exact_v1_client.py. test_facilitator.py covers ExactSvmFacilitatorScheme (V2) and only borrows ExactSvmSchemeV1 for one shared-cache cross-version case; the V1 verify/settle pipelines themselves had no direct coverage.

Coverage

  • Constructor + attributesscheme, caip_family, default-vs-injected SettlementCache.
  • get_extra / get_signers — multi-address selection, fresh-list return.
  • V1 top-level gatesscheme mismatch, network mismatch (V1 stores both at the payload top level, unlike V2).
  • feePayer extra gates — missing / None / non-string / unmanaged paths all surface the expected invalid_reason without touching the transaction bytes.
  • Transaction decode failures — invalid base64 and empty-base64 payload both surface ERR_TRANSACTION_DECODE_FAILED before instruction parsing.
  • Real V1 transaction happy path — the verify pipeline runs against bytes built by the V1 client (ExactSvmClientV1) with mocked RPC.
  • V1-specific max_amount_required gate — below threshold returns ERR_AMOUNT_INSUFFICIENT with payer surfaced; exact threshold accepts.
  • Mint mismatch / recipient ATA mismatch / fee_payer_transferring — all exercised against the real V1 transaction bytes.
  • Memo extra match/mismatch — accepts when memo matches; returns ERR_MEMO_MISMATCH with payer when it doesn't.
  • Simulation/sign failure — both surface ERR_SIMULATION_FAILED with the underlying error string in invalid_message.
  • Compute-budget price cap — exercised by patching MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS; sanity guard pins the constant at 5_000_000.
  • Settle short-circuit — verify failure surfaces network from payload.network (V1 differs from V2 here).
  • Settle happy path — returns mockSignature123 with send_transaction + confirm_transaction ordering captured.
  • Settle error paths — send/confirm/missing-feePayer all surface ERR_TRANSACTION_FAILED with the original exception string in error_message.
  • Settle feePayer propagation — pulls from requirements.extra into sign_transaction.
  • Duplicate-settlement cache — same-instance + cross-instance shared-cache.
  • Helper round-trip smoke — V1 client output decodes to the 3–6 instruction range the facilitator accepts.

Test plan

  • uv run pytest tests/unit/mechanisms/svm/test_exact_v1_facilitator.py — 41/41 passing
  • uv run pytest tests/unit/mechanisms/svm/ — 161/161 passing (no regressions in sibling suites)
  • uv run pytest tests/unit/ — 852/852 passing
  • uv run ruff format --check . — 191 files clean
  • uv run ruff check . — clean
  • Changeset fragment added at python/x402/changelog.d/python-svm-exact-v1-facilitator-tests.doc.md
  • Commit GPG-signed

Add 41 unit tests for python/x402/x402/mechanisms/svm/exact/v1/facilitator.py
- the only file in mechanisms/svm/exact/v1/ without a dedicated test module
after PR x402-foundation#151 landed test_exact_v1_client.py. test_facilitator.py covers
ExactSvmFacilitatorScheme (V2) and only borrows ExactSvmSchemeV1 for one
shared-cache cross-version case; the V1 verify/settle pipelines themselves
had no direct coverage.

Coverage:

- Constructor + scheme/caip_family attributes + default-vs-injected
  SettlementCache (via the optional settlement_cache constructor arg).
- get_extra picks one of the signer's addresses; get_signers returns a
  fresh list, not the signer's internal storage.
- V1 top-level scheme and network mismatch gates (V1 stores both at the
  payload top level; V2 only puts them on the requirements).
- feePayer extra missing/None/non-string/unmanaged paths all surface the
  expected invalid_reason without touching the transaction bytes.
- Transaction decode failures: invalid base64 and empty-base64 payload
  both surface ERR_TRANSACTION_DECODE_FAILED before instruction parsing.
- Happy-path verify against a real V1 transaction built via the V1 client
  (ExactSvmClientV1) with mocked RPC, so the verify pipeline runs against
  the bytes the client actually emits.
- V1-specific max_amount_required gate: below threshold returns
  ERR_AMOUNT_INSUFFICIENT with the payer surfaced; exact threshold accepts.
- mint mismatch (asset diverges from transaction mint), recipient ATA
  mismatch (pay_to diverges from on-chain destination), and
  fee_payer_transferring (authority is in the facilitator's managed set).
- memo extra match accepts; memo extra mismatch returns ERR_MEMO_MISMATCH
  with the payer surfaced.
- Simulation failure surfaces ERR_SIMULATION_FAILED with the underlying
  error string in invalid_message; sign-failure during verify maps to the
  same ERR_SIMULATION_FAILED branch.
- Compute-budget price-cap gate exercised by patching
  MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS to 0; sanity guard pins the
  current constant value at 5_000_000.
- Settle short-circuits on verify failure with the network reported from
  payload.network in V1 (V2 reports requirements.network).
- Settle happy path returns mockSignature123 with send_transaction +
  confirm_transaction call ordering captured.
- Settle send/confirm/missing-feePayer error paths all surface
  ERR_TRANSACTION_FAILED with the original exception string in
  error_message and transaction="".
- Settle propagates the requirements.extra feePayer into sign_transaction.
- Settle duplicate-cache check works same-instance and across two V1
  facilitators sharing the same SettlementCache.
- Helper round-trip smoke test ensures the V1 client output decodes to the
  3-6 instruction range the facilitator accepts; parametrized payload
  smoke test covers V1 'solana-devnet' and 'solana' networks.

All 41 tests pass; ruff format and ruff check clean across python/x402.
Full unit suite (852 tests) still passes.
@cb-heimdall
Copy link
Copy Markdown

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants