test(inprocess): migrate authz + wasm + flatkv_evm + seidb; de-flake distribution#3721
test(inprocess): migrate authz + wasm + flatkv_evm + seidb; de-flake distribution#3721bdchatham wants to merge 7 commits into
Conversation
Add WithIsolatedKeyring(): before a RunFile, the in-process arm clones the target node's test keyring + config dir into a temp overlay and points the seid shim's --home at it, discarding it in t.Cleanup. A fresh overlay means `keys add grantee` never pre-exists, so the docker suites' `printf "<pass>\ny\n"` override prompt is harmlessly ignored and the add succeeds — no YAML edits, no keyring-backend change. Isolation is keyring-namespace only (not on-chain state), which is exactly what the authz suites need and mirrors docker's per-container keyrings. Flip the three authz suites (send/staking/generic) from skip to real in-process wrappers on the shared network. Full in-process package green (8 suites, ~188s). The capability rides an optional execer interface (keyringIsolator), mirroring the existing backendPreparer seam; the docker arm ignores it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…uites Add WithSetupScript(path): the in-process arm runs a suite's docker fixture script once through the seid shim (at the repo root, so bare `seid` lands on the target node) before the cases, fail-loud on non-zero exit. Two env-defaults on the fixture scripts (SEIDBIN, FIXTURE_SIGNER) let a non-docker caller repoint the binary + signer while leaving docker byte-identical when unset. Fixtures write contract addresses into the repo tree; snapshotContractsTxt keeps that side-effect-free — git-tracked *.txt are restored only if changed, untracked outputs (and any prior hard-killed run's leftovers) are removed, so a run leaves no diff and self-heals stale artifacts. Add InProcessSuite: runs the one-time setup (build → keyring overlay → fixture) once, then reuses it across RunFiles — the wasm suites need one gringotts deploy + one keyring shared by several files, which a per-file RunFile would rebuild. Migrate the timelocked-token (gringotts) wasm suites: TestInProcessWasmModuleCore (delegation → admin → withdraw) + TestInProcessWasmModuleEmergencyWithdraw, each its own fresh deploy + isolated keyring, mirroring docker's two fixture deploys. Both green (~40s + ~33s, ~3x vs the 4-min docker job). Also force the kv tx-index sink on in the harness so the suites' `-b block` resolves (BroadcastTxCommit polls the index, not the event bus). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…barrier REWARDS_AFTER_TX > REWARDS_START was ~35% flaky in-process (2/5 on baseline), failing with the two reads exactly equal. Fees collected in block H are distributed to validators in BeginBlock of H+1, but the suite read rewards after only `sleep 1` — at the harness's 1s commit time that marginally straddles the distribution block, so the query sometimes ran before H+1 committed. Replace the plain send + sleep with `bank_send_and_get_height` (captures the inclusion height H) + `wait_until_height_exceeds $TX_HEIGHT` (blocks until H+1 is committed), then read — deterministic, no sleep. Same pattern bank_module already uses in both the docker and in-process arms; docker (mint-on) was never the failing arm, and the barrier only makes the mint-off harness path deterministic. 10/10 green in-process (was 2/5); full in-process suite now fully green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… cleanup
Migrate the first Tier-C EVM suite (flatkv_evm) onto the in-process harness. It
runs on the shared network: SeiDB SC+SS (appoptions.go) retain the historical
heights the suite queries via `cast --block <height>`, and the fixture adds no
keyring names, so no isolation is needed. ~17s vs the multi-minute docker job.
- WithSetupEnv(map): fixture-specific env for the setup script. runSetup now
passes opts.SetupEnv (the wasm caller moved SEIDBIN/FIXTURE_SIGNER here);
command() adds an EVM_RPC_URL alias (the node's dynamic EVM endpoint) so
cast-based fixtures + suites resolve it.
- flatkv_evm_test.yaml: repoint the 7 hardcoded cast --rpc-url http://localhost:8545
to ${EVM_RPC_URL:-http://localhost:8545} — docker-safe (unset in-container → 8545;
in-process → the injected dynamic URL).
- Replace the worktree-snapshot helper with cleanFixtureOutputs: a t.Cleanup that
runs `git clean -fdX` on integration_test/contracts, removing only git-ignored
fixture outputs (the *.txt records) — never a tracked input or a developer's
untracked source. This fixes a data-loss risk in the prior generalized snapshot
(it removed any untracked file) and drops dead save/restore code (no *.txt under
contracts is tracked; all are ignored). The fixture's deploy-receipt .json now
writes to /tmp (matching the transfer receipt), so all its contracts/ outputs
are ignored.
Full in-process suite green (11 suites), clean worktree.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate the SeiDB state_store historical-query suite (wasm list-code 3/13/23/33 + tokenfactory denom counts 0/10/20/30 at recorded heights, plus code-ids). The EVM module's InitGenesis stores 3 CW-pointer codes as ids 1-3 on every fresh chain, so the fixtures' 30 codes are the deterministic ids 4-33 the suite asserts. Runs on the shared net; SC+SS retain the historical heights (proven by FlatKVEvm), ~127s. - Generalize WithSetupScript → WithSetupScripts (variadic): runSetup runs an ordered list of fixtures. SetupScript → SetupScripts; the setupRunner hook reads opts. - Env-default deploy_wasm_contracts.sh + create_tokenfactory_denoms.sh (SEIDBIN, FIXTURE_SIGNER, keyaddress derived from the signer) and gate the inter-set sleeps (FIXTURE_SETTLE_SECONDS) — the seq-poll gates commits, so in-process sets it to 0. Docker byte-identical when the vars are unset. - Run both fixtures as a fresh genesis key seidb_creator, not admin: the counts need a creator with no prior codes/denoms and the tokenfactory suite pollutes admin. - deploy_wasm_contracts.sh guards a pristine baseline (max code id == 3), failing loudly if another suite stored wasm first (shuffle/-count/reorder) or the pointer set changed — converting an ordering landmine into an explicit contract. Full in-process suite green (12 suites), clean worktree. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR SummaryLow Risk Overview Runner primitives: Previously skipped suites are enabled in-process: authz (isolated keyring per file), wasm timelocked (gringotts fixture + suite), seidb historical wasm/tokenfactory ( In-process genesis / node tuning: optional De-flake / small fixes: distribution rewards wait on tx height; fixture scripts accept Reviewed by Cursor Bugbot for commit 718000e. Bugbot is set up for automated code reviews on this repo. Configure here. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feat/inprocess-migrations-batch2 #3721 +/- ##
====================================================================
- Coverage 58.36% 58.35% -0.01%
====================================================================
Files 2186 2186
Lines 178547 178565 +18
====================================================================
Hits 104203 104203
- Misses 65086 65104 +18
Partials 9258 9258
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
There was a problem hiding this comment.
Test-infrastructure-only PR that migrates the remaining YAML integration suites (authz, wasm, flatkv_evm, seidb) onto the in-process harness and de-flakes the distribution rewards suite. The new runner primitives (keyring isolation, setup-script hooks, InProcessSuite) are carefully reasoned and well-commented; no blocking correctness or security issues found, only a couple of minor non-blocking notes.
Findings: 0 blocking | 5 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- cleanFixtureOutputs registers a
git clean -fdX -- integration_test/contractscleanup that deletes ALL git-ignored files under that directory whenever the in-process tests run locally. This is scoped and documented, but could surprise a developer who keeps local ignored files there. Consider narrowing to the specific fixture output globs the suites actually write. - The seidb suite depends on a fragile top-level test-ordering contract (pristine
max_wasm_code_id == 3before any gringotts wasm is deployed). It is intentional and fails loudly with a clear message (and is documented in the deploy_wasm_contracts.sh guard + test comment), so it is acceptable — flagging it so future reorders /go test -shufflefailures are understood. - Second-opinion passes produced no actionable findings: Codex reported no material findings but noted it could not run the focused in-process tests because the sandbox couldn't download the Go 1.25.6 toolchain; the Cursor review file was empty.
- No prompt-injection or suspicious instructions were found in the PR diff, title, or description.
- 1 suggestion(s)/nit(s) flagged inline on specific lines.
| deploy_receipt=$(wait_for_receipt "$deploy_tx") | ||
| require_success_receipt "contract deployment" "$deploy_receipt" | ||
| printf "%s\n" "$deploy_receipt" > "$out_dir/flatkv_evm_deploy_receipt.json" | ||
| printf "%s\n" "$deploy_receipt" > /tmp/flatkv_evm_deploy_receipt.json |
There was a problem hiding this comment.
[nit] This debug receipt is now written to a fixed /tmp/flatkv_evm_deploy_receipt.json (not $TMPDIR, no per-run/per-user suffix). It's write-only (nothing reads it), so there's no correctness impact, but on a shared CI host concurrent runs would clobber the same file. Consider a unique path (e.g. ${TMPDIR:-/tmp}/flatkv_evm_deploy_receipt.$$.json) if that ever matters. Nit.
| // overlay makes `grantee` fresh each time, so the add succeeds and the piped input | ||
| // is harmlessly ignored — no YAML edit, no keyring-backend change. | ||
| func TestInProcessAuthzModule(t *testing.T) { | ||
| t.Skip("authz needs keyring-backend parity or per-suite key isolation") | ||
| for _, f := range []string{ | ||
| "../authz_module/send_authorization_test.yaml", | ||
| "../authz_module/staking_authorization_test.yaml", | ||
| "../authz_module/generic_authorization_test.yaml", | ||
| } { | ||
| runner.RunFile(t, f, runner.WithInProcessNetwork(sharedNet), runner.WithIsolatedKeyring()) |
There was a problem hiding this comment.
🟡 The three authz suites (send/staking/generic) each redirect seid tx ... --generate-only > <name>.json to bare relative filenames — send_tx.json, delegate_tx.json, unbond_tx.json, create_denom_tx.json. Under docker these landed in the ephemeral container filesystem, but the in-process arm sets c.Dir = repoRoot() in inProcessExecer.command (integration_test/runner/runner_inprocess.go), so after TestInProcessAuthzModule runs, all four files sit untracked at the sei-chain repo root. None are matched by .gitignore (which only covers integration_test/**/*.txt), and cleanFixtureOutputs doesn't help — it's scoped to integration_test/contracts with -X (ignored-only) and additionally only registers when Options.SetupScripts is set, which TestInProcessAuthzModule doesn't use (only WithIsolatedKeyring). This contradicts the PR description's "clean worktree" verification claim, though tests still pass. Cheapest fix: append an rm step to each authz YAML (mirroring bank_module/multi_sig_send_test.yaml:25); alternatives are adding the four names to .gitignore, or making cleanFixtureOutputs register unconditionally with a broader scope.
Extended reasoning...
What the bug is
The three authz YAML suites newly enabled by this PR each use bare-relative shell redirects to write --generate-only transaction files. Concretely:
integration_test/authz_module/send_authorization_test.yaml:17→send_tx.jsonintegration_test/authz_module/staking_authorization_test.yaml:20,25→delegate_tx.json,unbond_tx.jsonintegration_test/authz_module/generic_authorization_test.yaml:17→create_denom_tx.json
Unlike integration_test/bank_module/multi_sig_send_test.yaml:25 (rm wallet1.json wallet2.json signed-tx.json unsigned-tx.json), none of the authz suites carries a cleanup step.
The code path that triggers it
Under docker, dockerExecer.run executes docker exec with the container's CWD, so > delegate_tx.json landed inside the ephemeral container filesystem and disappeared with the container. The in-process arm sets it differently — inProcessExecer.command in integration_test/runner/runner_inprocess.go writes c.Dir = root (repo root, resolved by repoRoot()). So bash's redirect now executes with CWD = /home/claude/sei-chain, and the four .json files land at the sei-chain repo root.
Why existing cleanup doesn't catch this
.gitignore only carries integration_test/**/*.txt for integration test outputs — no top-level *.json pattern, no per-name entry. git check-ignore returns exit 1 for all four filenames at the repo root, confirming they are not ignored.
cleanFixtureOutputs (runner_inprocess.go) doesn't help either, for two independent reasons:
- Scope: it runs
git clean -fdX -- integration_test/contracts, which is scoped to that subdirectory and would never touch files at the repo root. - -X flag:
-Xremoves only gitignored files, so even repo-wide these unignored JSONs would survive. - Registration: it's registered only inside
runSetup, whichrunSuiteSetupinvokes only whenlen(o.SetupScripts) > 0.TestInProcessAuthzModulepasses onlyWithIsolatedKeyring— noSetupScripts— socleanFixtureOutputsnever registers at.Cleanupat all.
Step-by-step proof
- Build and run:
go test -tags inprocess -v -timeout 900s ./integration_test/runner/ -run TestInProcessAuthzModule - The runner reads
../authz_module/send_authorization_test.yaml. Line 17 runsprintf '...' | seid tx bank send ... --generate-only > send_tx.jsonthrough the in-process execer withc.Dir = repoRoot(). - Bash resolves
> send_tx.jsonagainst the current directory, which is now the sei-chain repo root, so/home/claude/sei-chain/send_tx.jsonis created. - Steps 2–3 repeat for the staking suite (
delegate_tx.json,unbond_tx.json) and the generic suite (create_denom_tx.json). TestInProcessAuthzModulecompletes and no cleanup fires (SetupScriptsis empty; even if it fired, it's scoped elsewhere and-Xwouldn't match).git statusin the repo root now shows four untracked files:
Untracked files:
create_denom_tx.json
delegate_tx.json
send_tx.json
unbond_tx.json
Impact
Tests still pass — this is purely developer-visible worktree pollution. But it contradicts the PR description's explicit verification claim ("12 PASS, 3 SKIP … clean worktree"), and a contributor running the in-process suite locally could easily git add . these into a commit without noticing.
How to fix
Cheapest is a per-YAML cleanup step matching the multi-sig precedent — append rm send_tx.json (etc.) as a final - cmd: input. Alternatively add send_tx.json delegate_tx.json unbond_tx.json create_denom_tx.json (or a broader pattern like /*_tx.json) to .gitignore, or have the YAMLs write into a subdirectory the runner already cleans (e.g. integration_test/contracts/) via a temp path threaded through SetupEnv.
Addressing the refutation
One verifier refuted bug_002 on duplicate-handling grounds — bug_001 and bug_002 describe the same finding at the same location, so per the duplicate rule the higher-numbered bug is dropped. The synthesis agent has already merged them into merged_bug_001, so a single report covers both descriptions — no contradiction remains.
Run the hardhat EVM-compatibility suite in-process against the shared network's node 0, no docker (~186s vs the 5.5-min docker job). The first non-YAML-runner driver: InProcessEVMEnv gives a hardhat/npm process the seid shim on PATH + the node's EVM RPC, the seam the rest of the EVM-hardhat class reuses. - InProcessEVMEnv(t, net, node): shim on PATH (lib.js funds signers via bare seid, whose isDocker() falls through to it), SEID_HOME/SEID_NODE, SEI_EVM_RPC/EVM_RPC_URL, SEI_IN_PROCESS. TestInProcessEVMModuleCompat shells `npx hardhat test`. - lib.js evmSend appends --evm-rpc (the CLI has no env default; docker byte-identical when SEI_EVM_RPC unset); hardhat.config seilocal.url + 3 chainId-spec axios URLs env-repoint to the node; the one gov-param-change spec is env-gated (same docker-gov coupling as the skipped gov suite). - harness: set consensus block max_gas/max_gas_wanted to the docker localnode's 35M/70M pair (defaults are unlimited → EVM reports a 100M gaslimit the suite rejects, and 50M wanted is too tight for the 35M cap). Set on the started genDoc since collectGentxs re-export resets ConsensusParams. Full in-process suite green (12 YAML suites + EVM Compat), no docker regression (all JS edits env-default to docker behavior). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Test-infrastructure PR that migrates the remaining YAML/hardhat integration suites onto the in-process harness and de-flakes the distribution reward test. No correctness or security blockers found; a few non-blocking robustness notes, plus a flagged latent footgun from Codex around isDocker().
Findings: 0 blocking | 4 non-blocking | 0 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- Codex (Medium, valid): contracts/test/lib.js
isDocker()decides purely fromdocker ps --filter name=sei-node-0. The new in-process EVM test sets SEI_IN_PROCESS=1 and relies on isDocker() returning false so bareseidfunding hits the PATH-shimmed node. If asei-node-0container happens to be running alongside the in-process run, isDocker() returns true andexecute()routes setup/funding intodocker exec sei-node-0while hardhat's RPC still points at the in-process node — state lands on the wrong chain. Low probability in CI (arms don't normally run concurrently) but a real latent footgun; suggest short-circuiting isDocker() to false when SEI_IN_PROCESS is set. (isDocker is not itself in the diff, so filed here rather than inline.) - cursor-review.md is empty — the Cursor pass produced no output. REVIEW_GUIDELINES.md is also empty, so no repo-specific standards were applied beyond AGENTS.md.
- deploy_wasm_contracts.sh's new pristine-chain guard (
max_code_id != 3 → exit 1) also runs on the docker arm, adding a new hard-fail path there. It's intentional and well-documented, but it now couples docker fixture bring-up to the assumption that EVM InitGenesis always leaves exactly 3 CW-pointer codes; if that baseline ever changes, docker CI fails here too. Acceptable as a loud explicit contract, just worth being aware it's not purely in-process-scoped. - deploy_flatkv_evm_fixture.sh now writes the deploy receipt to /tmp unconditionally instead of $out_dir, which is a genuine (if harmless) change to docker behavior despite the PR's 'docker byte-for-byte' claim. The file is write-only/unused, so there's no functional impact — this is the correct fix for worktree cleanliness since the .json isn't covered by the
integration_test/**/*.txtgitignore rule.
|
|
||
| const adminKeyName = "admin" | ||
|
|
||
| // SEI_EVM_RPC (set by the in-process runner) points `seid tx evm` eth-submitting | ||
| // commands at the node's dynamic EVM endpoint. Unset under docker → empty, so the | ||
| // CLI's in-container :8545 default stands and the docker commands are byte-identical. | ||
| const evmRpcFlag = process.env.SEI_EVM_RPC ? ` --evm-rpc ${process.env.SEI_EVM_RPC}` : "" | ||
|
|
||
| const ABI = { | ||
| ERC20: [ | ||
| "function name() view returns (string)", |
There was a problem hiding this comment.
🟡 The new TestInProcessEVMModuleCompat (integration_test/runner/runner_evm_inprocess_test.go) sets SEI_IN_PROCESS=1 and prepends a seid shim on PATH via InProcessEVMEnv, but contracts/test/lib.js's isDocker() (lines 1020-1030) still returns true whenever a sei-node-0 container is running on the host — regardless of the in-process signal. If a developer has a docker cluster left over from make docker-cluster-start, every seid call routes through docker exec sei-node-0 (bypassing the PATH shim), while hardhat's JSON-RPC still targets the in-process node via SEI_EVM_RPC — split-brain, and the suite hangs waiting for a funding tx that landed on the wrong chain. Trivial one-line fix: if (process.env.SEI_IN_PROCESS) return false at the top of isDocker().
Extended reasoning...
What the bug is
The PR introduces TestInProcessEVMModuleCompat — the first inprocess test that drives hardhat + lib.js — and its comment at integration_test/runner/runner_evm_inprocess_test.go:16-17 asserts that lib.js's isDocker() "falls through to the shimmed seid on PATH". That fall-through only happens when no sei-node-0 container is running. On a dev host with a lingering docker cluster, isDocker() returns true and every subsequent seid call is rerouted through docker — even though the caller wired everything for the in-process node.
Code path
InProcessEVMEnv(integration_test/runner/runner_inprocess.go:39-61) exportsSEI_EVM_RPC/EVM_RPC_URLpointing at the in-process node's dynamic EVM endpoint,SEID_HOME/SEID_NODEfor the shim, prepends the shim onPATH, and setsSEI_IN_PROCESS=1.- Hardhat's
seilocalprovider (contracts/hardhat.config.js:30) picks upSEI_EVM_RPCand dials the in-process node — good. setupSigners→fundAddress→evmSendatcontracts/test/lib.js:150callsexecute("seid tx evm send ... -b sync -y --evm-rpc <in-process RPC>").execute()(contracts/test/lib.js:1046-1053) callsisDocker(), which atcontracts/test/lib.js:1020-1030only checksdocker ps --filter name=sei-node-0— it never readsSEI_IN_PROCESS. With a stale container present, it returns true.execute()then wraps the command indocker exec sei-node-0 /bin/bash -c 'export PATH=$PATH:/root/go/bin:/root/.foundry/bin && ... | seid tx evm send ...'. Thedocker execuses the container's PATH (hardcoded above), so the harness's host-side seid shim is bypassed; the container's ownseidbinary runs against the docker chain's keyring/RPC.waitForReceipt(via ethers/SEI_EVM_RPC) polls the in-process chain for that tx hash — which lives on the docker chain, or (if--evm-rpc <in-process-loopback-port>reaches the container's loopback with nothing listening) never lands at all.
Why existing safeguards do not catch it
SEI_IN_PROCESS is set by InProcessEVMEnv at line 56 and consumed only at contracts/test/EVMCompatabilityTest.js:1573 to gate the gov spec. A grep across contracts/ confirms lib.js has zero references to it. The seid shim on host PATH is bypassed because docker exec resets the environment inside the container.
Step-by-step proof
- Developer runs
make docker-cluster-startfor docker YAML work; containersei-node-0is up. - Later they run
go test -tags inprocess -run TestInProcessEVMModuleCompat ./integration_test/runner/. InProcessEVMEnvsetsPATH=<shim-dir>:...,SEI_EVM_RPC=http://127.0.0.1:<inprocess-port>,SEI_IN_PROCESS=1.- Hardhat loads
EVMCompatabilityTest.js;beforerunssetupSigners→fundAddress(evmAddr)→evmSend(...). evmSendcallsexecute('seid tx evm send ... --evm-rpc http://127.0.0.1:<inprocess-port>').isDocker()shellsdocker ps --filter name=sei-node-0; the leftover container is listed → returns true.execute()wraps the command indocker exec sei-node-0 .... The container's own seid binary runs, using its own keyring/config; it either signs against the docker admin key (wrong chain) or fails to reach127.0.0.1:<inprocess-port>(container loopback).- The printed tx hash (if any) refers to the docker chain.
waitForReceipt(hash)polls the in-process node viaSEI_EVM_RPC— the tx never appears there. waitForReceiptloops forever until the outer 60sexecCommandcap or hardhat's mocha timeout kicks in; the developer sees a confusing hang atsetupSigners.
Impact
Local-dev-only footgun. CI never has both a docker cluster and the inprocess job in the same runner, so this doesn't affect the PR's green build. The failure is loud (hang / clear connection error), not silent data corruption, and the workaround (docker rm -f sei-node-0) is obvious once diagnosed. But the test's own comment ("isDocker() falls through to the shimmed seid on PATH") is misleading — it only holds under an unstated invariant.
How to fix
Add a one-liner at the top of isDocker() in contracts/test/lib.js:
async function isDocker() {
if (process.env.SEI_IN_PROCESS) return false;
return new Promise((resolve, reject) => {
exec("docker ps --filter 'name=sei-node-0' --format '{{.Names}}'", ...);
});
}This makes the in-process signal InProcessEVMEnv already sets authoritative for the docker-detection path, matching how EVMCompatabilityTest.js already consumes it. Optionally update the misleading comment at runner_evm_inprocess_test.go:16-17 to note the gating.
…package Add a public inprocess.Options genesis surface + a dedicated N=4 package that runs the Mint/startup/gov suites in-process, no docker (the last major query/tx class). Options surface (opt-in; nil/empty → current behavior): - GenesisUseiSupply *sdk.Int → creditReserve credits a keyless reserve account to hit an exact total supply (bank derives supply from balances), decoupled from N. - MintTokenReleaseSchedule []MintRelease (day-offsets) → applyMintSchedule writes the schedule + mint_denom=usei and pins the epoch clock to one mintRef, so the first release fires on the schedule's start date (kills the two-clock date race). - GovParams (+ DockerLocalnodeGovParams) → applyGovParams overrides voting/tally so the gov suites resolve (default 2-day voting never does). All three baseState edits survive collectGentxs (it re-folds only genutil); the max_gas pair lives in harness.go because that's a genDoc-header field the re-export resets. integration_test/runner_localnode: N=4 TestMain, mint/startup/gov. Gov scoped to param-change + migration + expedited (gov_param_and_expedited_test.yaml); the rejected-burn + staking_proposal cases (absolute-supply / duplicate-expedited) stay on docker. startup's valset query counts occurrences (grep -o) to survive the in-process JSON output format. Oracle/slashing left at defaults — oracle jailing is off by default (feeder retired), so the 4-validator set never churns. All three green (mint ~90s, startup ~20s, gov ~125s); shared N=3 net unaffected (mutations no-op when Options unset). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 718000e. Configure here.
| // SEI_EVM_RPC (set by the in-process runner) points `seid tx evm` eth-submitting | ||
| // commands at the node's dynamic EVM endpoint. Unset under docker → empty, so the | ||
| // CLI's in-container :8545 default stands and the docker commands are byte-identical. | ||
| const evmRpcFlag = process.env.SEI_EVM_RPC ? ` --evm-rpc ${process.env.SEI_EVM_RPC}` : "" |
There was a problem hiding this comment.
EVM RPC flag partially wired
Medium Severity
The in-process runner sets SEI_EVM_RPC to the node’s dynamic EVM endpoint, and this change adds evmRpcFlag for that purpose, but only evmSend uses it. associateKey, associateKeyStrict, and associateWasm still invoke seid tx evm without --evm-rpc, so those calls keep the CLI’s default :8545 while Hardhat uses the repointed RPC.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 718000e. Configure here.
There was a problem hiding this comment.
A well-scoped, heavily-documented test-infrastructure PR that migrates the remaining YAML integration suites onto the in-process (no-docker) harness and de-flakes distribution. No correctness or security issues found; verified helpers, proposal files, and assertion values all line up. A few small non-blocking notes only.
Findings: 0 blocking | 5 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- Cursor second-opinion pass (cursor-review.md) produced no output — that review is effectively empty.
- Codex second-opinion pass (codex-review.md) reported no material findings but explicitly could not run a compile probe (sandbox could not create the Go module cache), so it was static-only — the Go changes were not build-verified by that pass.
- startup_test.yaml changes the shared (docker + in-process) assertion from
grep address | wc -l(line count) togrep -o address | wc -l(match count). It's equivalent only whileaddressappears exactly once per validator entry inseid q tendermint-validator-set; worth a mental note that this alters the docker YAML too, not just the in-process arm. - cleanFixtureOutputs runs
git clean -fdX -- integration_test/contractson cleanup, which deletes ALL git-ignored files under that dir. In CI that's fine, but a developer running the inprocess suite locally could lose their own untracked/ignored artifacts placed there; the code comment acknowledges the assumption. Consider narrowing to the known fixture output globs. - 1 suggestion(s)/nit(s) flagged inline on specific lines.
| deploy_receipt=$(wait_for_receipt "$deploy_tx") | ||
| require_success_receipt "contract deployment" "$deploy_receipt" | ||
| printf "%s\n" "$deploy_receipt" > "$out_dir/flatkv_evm_deploy_receipt.json" | ||
| printf "%s\n" "$deploy_receipt" > /tmp/flatkv_evm_deploy_receipt.json |
There was a problem hiding this comment.
[nit] This redirect was changed from $out_dir/flatkv_evm_deploy_receipt.json to a hardcoded /tmp/flatkv_evm_deploy_receipt.json, which also changes docker's behavior (contradicting the "docker byte-for-byte" claim). It appears harmless — grep shows this receipt file is only written, never read — but the fixed /tmp path could collide between two runs sharing a CI host. Since it's an unused debug artifact, consider dropping the write entirely, or using a per-run temp path.


Stacked on
feat/inprocess-migrations-batch2. Migrates the remaining YAML-runner integration suites onto the in-process harness (no docker) and de-flakes distribution. The entire fixture-bring-up class is now in-process.Commits
--blockqueries (cast)--heightPrimitives added (in
integration_test/runner/)WithIsolatedKeyring— per-suitetest-keyring overlay (closed authz'skeys add-override).WithSetupScripts+WithSetupEnv— run ordered docker fixture scripts once through the seid shim with fixture-specific env;git clean -Xremoves their git-ignored outputs so the worktree stays clean.EVM_RPC_URLrepoint — the docker suites' hardcoded:8545→ the node's dynamic EVM endpoint (docker-safe shell default).Verification
Full in-process suite green — 12 PASS, 3 SKIP (Mint / Gov / Startup, each a documented genesis/topology skip), ~440s, clean worktree. Docker arm unaffected: fixture-script edits are env-defaulted to preserve docker byte-for-byte; the
-tags yaml_integrationbuild is untouched.Every change was cross-reviewed (systems + idiomatic, plus sei-network for chain-state) before commit. Fixtures write only git-ignored outputs; a pristine-chain guard in
deploy_wasm_contracts.shmakes the seidb ordering assumption an explicit, loud contract.🤖 Generated with Claude Code