Skip to content

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

Open
0xAxiom wants to merge 1 commit into
coinbase: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 into
coinbase: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

@0xAxiom
Copy link
Copy Markdown
Author

0xAxiom commented May 20, 2026

Friendly ping — this PR has been open for 16 days awaiting review. Happy to address any feedback or rebase if needed. Thanks for your time!

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