Skip to content

Tests: Precompile Tests Phase 1 (PLT-372)#3777

Merged
alexander-sei merged 1 commit into
mainfrom
alexanderh/plt-372-refactor-precompile-tests
Jul 20, 2026
Merged

Tests: Precompile Tests Phase 1 (PLT-372)#3777
alexander-sei merged 1 commit into
mainfrom
alexanderh/plt-372-refactor-precompile-tests

Conversation

@alexander-sei

Copy link
Copy Markdown
Contributor

Describe your changes and provide context

Phase 1 of PLT-372 (Refactor Precompile Tests), sub-issue of PLT-369 (Refactor Existing Test Suite). Follows the framework established for RPC tests in #3588 / #3596 / #3610.

New self-contained suite: integration_test/precompile_tests/ — TypeScript + Mocha, same conventions as rpc_tests:

  • Bootstrap-once state seeding (_start/00_bootstrap.spec.ts): funds + associates an admin, deploys the PrecompileCaller fixture, pre-funds a 32-account pool, writes typed runtime/runtime.json (sole writer; specs claim disjoint single-use accounts via claimPool).
  • No geth reference — precompiles are Sei-only. The parity oracle is the chain's own Cosmos-side state: precompile-reported values and EVM-side effects are asserted against bank-module queries.
  • One spec per precompile, each in three sections: happy path & state parity / error handling / dispatch semantics. Dispatch runs through real CALL / STATICCALL / DELEGATECALL from deployed contract bytecode (contracts/PrecompileCaller.sol) — the layer the Go unit tests bypass by invoking executors directly.
  • ABIs load from precompiles/<name>/abi.json (the files the chain binary embeds), so specs cannot drift from the deployed interface.
  • CI: new EVM Precompiles matrix entry running scripts/run-ci.sh (wait-for-chain → bootstrap → run → merged mochawesome HTML report, uploaded as an artifact).

Phase 1 coverage — bank (0x1001) and addr (0x1004), 32 specs + 7 bootstrap checks:

  • bank: balance/all_balances/supply parity vs the bank module (incl. cast-address fallback for unassociated accounts), sendNative end-to-end with exact fee accounting, pointer-gated send rejection, non-payable/staticcall/delegatecall guards, and the legacy out-of-gas-traces-as-execution reverted-not-panic guard.
  • addr: associate via v/r/s signature and via compressed pubkey with exact pubkey-derivation parity, getSeiAddr/getEvmAddr round-trips and negative cases, already-associated rejection, readOnly guards, and the out-of-gas trace guard.

Next phases (per the refactor plan): remaining wasm-free precompiles (staking, gov, distribution, json, p256, oracle-retirement, pointer addNativePointer, pointerview), then wasm-gated flows (wasmd, pointer addCW*, solo) behind an isWasmEnabled gate. ibc is out of scope. Legacy EVMPrecompileTest.js cutover happens after coverage is complete.

Testing performed to validate your change

  • Full suite run locally against a live 4-node docker devnet (GIGA_STORAGE=true make docker-cluster-start): 39/39 passing (7 bootstrap + 32 specs).
  • scripts/run-ci.sh validated end-to-end locally (wait-for-chain, bootstrap, run, merged HTML report, clean exit).
  • tsc --noEmit clean; hardhat compile clean.

🤖 Generated with Claude Code

New self-contained e2e suite at integration_test/precompile_tests/,
modeled on the rpc_tests framework: bootstrap-once typed runtime state,
one spec per precompile, serial single-process mocha run, mochawesome
reports, and a single run-ci.sh orchestrator wired into CI as the
"EVM Precompiles" matrix entry.

Unlike rpc_tests there is no geth reference (precompiles are Sei-only);
the parity oracle is the chain's own Cosmos-side state. Specs cover the
bank (0x1001) and addr (0x1004) precompiles across three sections:
happy path & state parity, error handling (including the legacy
out-of-gas-must-not-panic trace guard), and dispatch semantics via a
PrecompileCaller fixture exercising real CALL/STATICCALL/DELEGATECALL
from contract bytecode. ABIs load from precompiles/<name>/abi.json so
specs cannot drift from the deployed interface.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 19, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Adds integration tests and CI wiring only; no changes to chain binaries, precompile implementations, or production runtime paths.

Overview
Introduces integration_test/precompile_tests/, a self-contained TypeScript/Mocha suite (same bootstrap → serial run → mochawesome pattern as rpc_tests) that validates Sei-only precompile semantics on a live chain, using Cosmos bank/association queries as the parity oracle instead of geth.

CI: new EVM Precompiles matrix job (GIGA_STORAGE=true, scripts/run-ci.sh) and upload of merged HTML reports from integration_test/precompile_tests/reports/merged.

Phase 1 coverage: bootstrap seeds runtime/runtime.json (admin, PrecompileCaller for real CALL/STATICCALL/DELEGATECALL, 32-account claimPool); specs for bank (0x1001) and addr (0x1004) with happy-path/state parity, error handling, and dispatch guards (ABIs from repo precompiles/<name>/abi.json). Legacy EVMPrecompileTest.js remains until later phases expand coverage.

Reviewed by Cursor Bugbot for commit 7584f7f. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedJul 19, 2026, 10:33 PM

@seidroid seidroid Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A well-structured, self-contained TypeScript/Mocha e2e suite for the bank and addr precompiles (Phase 1 of PLT-372), mirroring the established rpc_tests conventions. No production code changes and no correctness blockers; the only substantive notes are two dispatch-semantics tests that pass for a reason other than the guard they claim to isolate.

Findings: 0 blocking | 6 non-blocking | 2 posted inline

Blockers

  • None at the file/PR level.

Non-blocking

  • REVIEW_GUIDELINES.md is empty and the Cursor second-opinion review (cursor-review.md) produced no output; only the Codex pass returned findings (both incorporated below).
  • This is a test-only change (no production Go/precompile code touched), so risk is confined to test fidelity and CI. The suite depends on a live 4-node docker devnet (GIGA_STORAGE=true) and several magic gas limits (bank OOG gasLimit: 40_000, addr OOG gasLimit: 52_000) that are inherently sensitive to future gas-schedule changes — acceptable given the explanatory comments, but a likely source of future flakiness to watch.
  • cosmosUtils.ts uses Tendermint34Client for the Cosmos RPC oracle; confirm the target chain's Tendermint/CometBFT RPC version is compatible (rpc_tests presumably already relies on this, so likely fine).
  • No prompt-injection or malicious content found in the diff, commit messages, or PR description.
  • 2 suggestion(s)/nit(s) flagged inline on specific lines.

expect(decoded).to.equal(await bank.balance(admin.address, 'usei'));
});

it('send is rejected under STATICCALL (readOnly guard)', async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] This test claims to verify the STATICCALL readOnly guard, but send is reserved for a denom's registered ERC20 pointer contract and PrecompileCaller is not a registered pointer. The call therefore reverts on the pointer-caller rejection regardless of whether the readOnly guard fires — so the test would still pass even if the readOnly guard were broken. To actually isolate readOnly, exercise a state-changing-but-not-pointer-gated method under STATICCALL (e.g. sendNative with nonzero value), or assert on the specific revert reason. (Flagged by Codex.)

);
});

it('sendNative is rejected under DELEGATECALL', async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] This DELEGATECALL guard test encodes sendNative with no value (value 0). sendNative's mandatory nonzero-value check already reverts on value 0, so the revert here does not demonstrate the delegatecall guard — the test passes for the wrong reason. Note also delegatecallTarget doesn't forward msg.value and the call is made via .staticCall, so nonzero value can't reach the precompile as written; verifying the delegatecall guard would need a fixture path that forwards value through a real (non-static) delegatecall. (Flagged by Codex.)

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.17%. Comparing base (7fee5c2) to head (7584f7f).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3777      +/-   ##
==========================================
- Coverage   60.14%   59.17%   -0.97%     
==========================================
  Files        2303     2211      -92     
  Lines      192032   181554   -10478     
==========================================
- Hits       115491   107429    -8062     
+ Misses      66230    64665    -1565     
+ Partials    10311     9460     -851     
Flag Coverage Δ
sei-db 70.41% <ø> (ø)
sei-db-state-db ?

Flags with carried forward coverage won't be shown. Click here to find out more.
see 92 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find any bugs, but this introduces a substantial new test module (bootstrap + two precompile specs, CI wiring, and a Solidity dispatch fixture) that establishes the pattern future precompile-test phases will follow, so it's worth a human look even though it's test-only and carries no production risk.

Reviewed: bootstrap account funding/association/pool-seeding flow, bank precompile parity assertions (balance/all_balances/supply vs the bank module, sendNative fee accounting), addr precompile association flows (signature-based and pubkey-based), and the CALL/STATICCALL/DELEGATECALL dispatch guards via the PrecompileCaller fixture. No production code (chain binaries, precompile implementations) is touched.

Extended reasoning...

Test-only PR (new integration_test/precompile_tests module + CI matrix entry), no changes to production code. No bugs were reported by the bug-hunting pass. The module is large and establishes a new test pattern for the precompile refactor (mirroring the already-merged rpc_tests convention), including fairly intricate parity/fee-accounting assertions and gas-limit-tuned out-of-gas guards, so a human should sanity-check the coverage/design decisions even though the blast radius of a mistake is limited to CI signal quality, not runtime behavior.

@alexander-sei
alexander-sei added this pull request to the merge queue Jul 20, 2026
Merged via the queue into main with commit 2f3ed6c Jul 20, 2026
135 of 141 checks passed
@alexander-sei
alexander-sei deleted the alexanderh/plt-372-refactor-precompile-tests branch July 20, 2026 19: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.

2 participants