Skip to content

feat(evm): add native precompile runtime base#336

Merged
phenix3443 merged 1 commit into
precompile-integrationfrom
precompile/native-runtime-base
Jul 14, 2026
Merged

feat(evm): add native precompile runtime base#336
phenix3443 merged 1 commit into
precompile-integrationfrom
precompile/native-runtime-base

Conversation

@phenix3443

Copy link
Copy Markdown
Contributor

What

Subtask 1 of the precompile → cosmos/evm native-mode migration: add x/evm/precompiles/base, a thin shared runtime skeleton over cosmos/evm's precompiles/common. This lets moca precompiles stop hand-rolling GetCacheContext / Snapshot / RevertToSnapshot / commit templates (currently duplicated across all 11) and share one snapshot / gas-metering / balance-sync implementation.

API (base.Precompile)

Embeds cosmos/evm's common.Precompile + the precompile ABI:

  • RunPrecompile(evm, contract, readonly, exec) — rejects native value up front (moca precompiles are not payable), then delegates to RunNativeAction (the official snapshot / gas / balance-handler model, which converts action errors into EVM reverts).
  • Dispatch(contract, readonly, isTx) — pass-through to SetupABI: method dispatch by ID, read-only write protection, argument unpacking.
  • WithBalanceHandler(bankKeeper) — opt-in BalanceHandlerFactory for state-changing precompiles that move native balances.

Intended per-precompile usage:

func (c *Contract) Run(evm, contract, readonly) ([]byte, error) {
	return c.RunPrecompile(evm, contract, readonly, c.Execute)
}
func (c *Contract) Execute(ctx, evm, contract, readonly) ([]byte, error) {
	method, args, err := c.Dispatch(contract, readonly, c.IsTransaction)
	...switch method.Name...
}

Design notes

  • Execute signature: the plan doc wrote Execute(ctx, stateDB, contract, readonly), but moca handlers emit logs via evm (evm.StateDB.AddLog), matching cosmos/evm's own precompiles which pass the EVM, not the StateDB. So ExecuteFn takes evm (StateDB is reachable via evm.StateDB).
  • Gas: empty KvGasConfig (like cosmos/evm's own precompiles); moca keeps charging a flat per-method cost via each precompile's RequiredGas, so the base must not double-charge store gas.
  • RejectValue is kept as the mandatory pre-check (migration decision 1).

Tests

Helper-level unit tests (no EVM needed): constructor wiring (address / empty gas / balance-handler opt-in) and Dispatch behavior (routes tx/query methods, unpacks args, rejects tx methods in read-only calls). The full runtime path (RunPrecompileRunNativeAction) is exercised end-to-end by the bank migration (subtask 2), which runs through EvmKeeper.CallEVMWithData.

  • No existing precompile is migrated here (additive only).
  • go test ./x/evm/precompiles/base -count=1 → ok.
  • Base branch is precompile-integration.

Add x/evm/precompiles/base, a thin wrapper over cosmos/evm's
precompiles/common native runtime, so moca precompiles can stop
hand-rolling GetCacheContext/Snapshot/RevertToSnapshot/commit templates
and share one snapshot, gas-metering and balance-sync implementation.

base.Precompile embeds cosmos/evm's common.Precompile and the ABI, and:
- RunPrecompile rejects native value up front (moca precompiles are not
  payable) then delegates to RunNativeAction (official snapshot/gas/balance
  model, error->revert)
- Dispatch is a pass-through to SetupABI (method dispatch + read-only write
  protection + arg unpacking)
- WithBalanceHandler opt-in wires cosmos/evm's bank-event -> StateDB sync

Helper unit tests cover constructor wiring and dispatch/read-only behavior.
No existing precompile is migrated in this change.
@github-actions github-actions Bot added the tests label Jul 14, 2026
@phenix3443 phenix3443 merged commit fd0e998 into precompile-integration Jul 14, 2026
10 of 11 checks passed
@phenix3443 phenix3443 deleted the precompile/native-runtime-base branch July 14, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant