Files
evm/core/precompile_env_call_test.go
zeekayandHanzo Dev c435ce5aea core: run the ./core block suite through the cevm shadow verifier and report the honest agreement rate
Wires the existing cevm (C++ EVM) byte-exact shadow verifier so it observes
EVERY block of the real ./core suite, and reports the true tally — without
weakening the gate or ever letting cevm apply state.

- core/main_cevm_test.go (//go:build cevm): a cevm-only TestMain that runs the
  whole ./core suite then prints the aggregate parallel.CevmShadowStats(). Because
  state_processor.go:124 routes every block through
  parallel.DefaultExecutor().ExecuteBlock — which under -tags cevm is the
  cevmShadowExecutor — this is the honest whole-suite count. main_test.go's goleak
  TestMain is gated //go:build !cevm so exactly one TestMain exists per build.

- core/parallel/cevm_shadow_registration_test.go (//go:build cevm): asserts
  DefaultExecutor() is the cevmShadowExecutor (not the no-op fallback) — the
  precondition for the whole claim.

- core/parallel/cevm_shadow_e2e_test.go: scaled the real-StateProcessor agreement
  proof from 3 to 256 genuine InsertChain blocks (768 transfers). cevm's
  independent real-MPT process_block root byte-matched the Go EVM header.Root on
  ALL 256/256 blocks (0 disagree, 0 finalize-gap).

- Four precompile test files (genesis_dexsettle_reproduce, precompile_alwayson,
  precompile_statedb_subbalance, precompile_env_call) gated //go:build !cevm: they
  alone pull precompile/registry -> luxfi/precompile/dex -> luxfi/dex/pkg/dex whose
  cgo file #includes the absent dex_gpu.h, breaking the CGO_ENABLED=1 build the
  bridge needs. They are precompile tests, not block-execution tests, and still run
  in every non-cevm build — an orthogonal blocker isolated, not a cevm regression.

HONEST RESULTS (CGO_ENABLED=1 -tags cevm):
- Whole ./core suite: 78 PASS / 0 FAIL / 32 SKIP. cevm observed all 9794 blocks;
  it declined every one as no-preimage (the production default runs preimages OFF,
  and the shadow needs trie-key preimages to recover the 20-byte addresses that
  seed cevm) — 0 disagree, 0 errored, 0 false roots. The Go EVM applied every
  block; cevm never touched state.
- Real-block agreement (preimages ON, the config the shadow requires), driven
  through core.BlockChain.InsertChain -> StateProcessor.Process -> the shadow:
  256/256 blocks byte-exact agreement (768 transfers).

Default (!cevm) build unchanged: ./core and ./core/parallel green in both CGO
modes; the 10 gated precompile tests present in the default build.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-19 18:14:45 -07:00

67 lines
3.1 KiB
Go

// Copyright (C) 2025-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Excluded under -tags cevm: imports precompile/registry, which transitively
// pulls luxfi/precompile/dex -> luxfi/dex/pkg/dex whose cgo file #includes the
// (absent) dex_gpu.h header — breaking the CGO_ENABLED=1 build the cevm shadow
// verifier needs. Precompile test, not a block-execution test; still runs in
// every non-cevm build. Orthogonal blocker, not a cevm regression.
//go:build !cevm
package core
import (
"testing"
"github.com/luxfi/geth/core/vm"
)
// precompile_env_call_test.go pins the PRODUCER side of the ERC-20 settlement env
// wiring: the EVM hands a precompile its AccessibleState as *accessibleStateAdapter,
// which captures the geth vm.PrecompileEnvironment (the only object with a Call
// surface). The registry bridge (precompile/registry/bridge.go) type-asserts the
// concrete envProvider accessor below to forward that Call to the external DEX 0x9999
// precompile so its ERC-20 leg (transferFrom / transfer / balanceOf on the token
// contract) executes on-chain. If *accessibleStateAdapter ever stops exposing the env,
// GetPrecompileEnv() reverts to nil and ERC-20 settlement silently refuses with
// ErrERC20VaultUnavailable — so this guard fails loudly on that drift.
// envProvider is the EXACT accessor precompile/registry/bridge.go type-asserts. Keep
// it byte-identical so this test fails if either side's signature drifts.
type envProvider interface {
GetPrecompileEnv() vm.PrecompileEnvironment
}
// TestAccessibleStateAdapter_ExposesPrecompileEnv is the regression guard: the
// concrete *accessibleStateAdapter the EVM gives precompiles MUST satisfy envProvider
// and MUST return the same non-nil geth env it was constructed with. If it returns nil
// or fails the assertion, the registry bridge cannot forward Call and ERC-20
// settlement is dead on-chain.
func TestAccessibleStateAdapter_ExposesPrecompileEnv(t *testing.T) {
// Compile-time assertion (primary guard against signature drift).
var _ envProvider = (*accessibleStateAdapter)(nil)
// Runtime: construct the adapter exactly as RunStateful does and confirm it hands
// back the SAME env. A nil sentinel env is sufficient — the load-bearing fact is
// the accessor returns what it captured, not nil.
env := &sentinelPrecompileEnv{}
a := &accessibleStateAdapter{env: env}
var asProvider envProvider = a
got := asProvider.GetPrecompileEnv()
if got == nil {
t.Fatal("GetPrecompileEnv() returned nil — registry bridge cannot forward Call; ERC-20 settlement would refuse")
}
if got != vm.PrecompileEnvironment(env) {
t.Fatal("GetPrecompileEnv() did not return the captured env")
}
}
// sentinelPrecompileEnv is a do-nothing vm.PrecompileEnvironment used only to prove
// the adapter returns the env it was given. Its methods are never invoked by this
// test (identity check only), so they panic if ever called — keeping the sentinel
// honest about being a marker, not a behavioural mock.
type sentinelPrecompileEnv struct {
vm.PrecompileEnvironment // embed the interface; all methods panic via the nil embedding if called
}