Skip to content

Opcodes v2, bulk memory opcodes activation + metering, FFI hardening - #989

Merged
andrei-marinica merged 21 commits into
feat/new-executorfrom
opcodes-v2
Nov 5, 2026
Merged

andrei-marinica merged 21 commits into
feat/new-executorfrom
opcodes-v2

Conversation

@andrei-marinica

@andrei-marinica andrei-marinica commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Notes

Meters memory.copy/memory.fill with base + per-byte gas costs, gated behind the new OpcodeV2Flag, and introduces opcode versioning (v1/v2) in the executor. Updates the wasmer2 binary to match the companion Rust executor change.

Ported from PR #943 onto current master (original branch was based on rc/after-supernova, not master; history not preserved).

Opcode version V2: bulk memory opcodes

Adds an opcode version to the executor configuration. V2 whitelists and meters memory.copy and memory.fill.

What changes

  • New executor.OpcodeVersion (V1, V2). The host picks it from the new OpcodeV2Flag and passes it to the executor.
  • Executor.SetOpcodeCosts is replaced by SetOpcodeConfig(version, costs) error, which now returns errors. A nil cost table is rejected instead of silently metering everything at zero.
  • Bulk memory metering: a flat cost (MemoryCopy, MemoryFill) plus a per-byte cost (MemoryCopyPerByte, MemoryFillPerByte). Both are added to the V3 and V4 gas schedules.
  • V2 also drops the legacy exception handling opcodes (Catch, CatchAll, Delegate, Rethrow, Throw, Try, Unwind) and the reference type opcodes (RefFunc, RefIsNull, RefNull, TypedSelect). V1 is unchanged.
  • The host applies the opcode version and gas schedule through one function that clears both the warm instance cache and the compiled code cache. It does the same when the flag flips under a running host, and when a host is created.
  • Compilation options are now converted field by field to a C mirror struct, instead of an unsafe cast.
  • Code generator reworked: opcode lists are split into V1, V2, per-byte and additional costs, and it also emits the Rust cost and whitelist code. Generated output matches the executor repo exactly.
  • Tests added for metering deltas, memory contents, activation, cache clearing, FFI layout and host reconfiguration.

Dropped opcodes

The opcodes dropped in V2 do not appear in deployed contracts on mainnet. This was investigated in another repo.

Out of scope

Activating OpcodeV2Flag is not part of this PR. It will follow the Wasmer 7 integration and the executor management refactor. The node must also define the flag and add the two per-byte costs to its gas schedules before it can run this VM.

Executor binaries

Built from mx-vm-executor-rs, branch rc/after-supernova, commit 4ac9f6e (crate version 0.5.2). The shipped header is identical to the one in that repo.

Meters memory.copy/memory.fill with base + per-byte gas costs,
gated behind the new OpcodeV2Flag, and introduces opcode
versioning (v1/v2) in the executor. Updates the wasmer2 binary
to match the companion Rust executor change (mx-vm-executor-rs#79).

Ported from PR #943 onto current master (original branch was based
on rc/after-supernova, not master; history not preserved).
@codecov

codecov Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.62264% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 28.07%. Comparing base (f525913) to head (41b593d).

Files with missing lines Patch % Lines
wasmer2/wasmer2Executor.go 52.63% 8 Missing and 1 partial ⚠️
wasmer2/bridge2.go 73.33% 4 Missing ⚠️
vmhost/hostCore/host.go 90.32% 3 Missing ⚠️
wasmer2/wasmer2ExecutorFactory.go 66.66% 2 Missing and 1 partial ⚠️
executor/wrapper/wrapperExecutor.go 0.00% 2 Missing ⚠️
executor/wrapper/wrapperExecutorFactory.go 80.00% 1 Missing ⚠️
Additional details and impacted files
@@                  Coverage Diff                  @@
##           feat/new-executor     #989      +/-   ##
=====================================================
+ Coverage              25.41%   28.07%   +2.66%     
=====================================================
  Files                     89       64      -25     
  Lines                  19055    17982    -1073     
=====================================================
+ Hits                    4842     5049     +207     
+ Misses                 13886    12603    -1283     
- Partials                 327      330       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@andrei-marinica
andrei-marinica changed the base branch from master to feat/new-executor October 14, 2026 07:02
@andrei-marinica
andrei-marinica requested a balanced review from Copilot October 14, 2026 07:41
@andrei-marinica
andrei-marinica marked this pull request as ready for review October 14, 2026 07:42

Copilot AI 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.

🟡 Changes recommended

Long-lived hosts do not update the executor when Opcode V2 activates, and FFI configuration failures are silently ignored.

5 open findings
What changed in this PR

Adds versioned opcode configuration, V2 bulk-memory support with per-byte metering, and safer Go/Rust FFI structures.

Changes:

  • Gates and meters memory.copy/memory.fill under opcode V2.
  • Regenerates opcode definitions, gas schedules, C API, and executor artifacts.
  • Adds activation and gas-accounting tests.
File Description
wasmer2/​wasmer2ExecutorFactory.go Passes opcode version during executor creation.
wasmer2/​wasmer2Executor.go Configures versioned costs and explicit FFI options.
wasmer2/​opcodeCost.go Adds generated bulk-memory costs.
wasmer2/​libvmexeccapi.h Updates the C ABI.
wasmer2/​bridge2.go Adds explicit compilation-option conversion.
vmhost/​vmhooks/​generate/​eiGenWriteWASMOpcodeCostFuncHelpers.go Adjusts file closing.
vmhost/​vmhooks/​generate/​eiGenWriteWASMOpcodeCostConfigHelpers.go Adjusts file closing.
vmhost/​vmhooks/​generate/​eiGenWriteWASMOpcodeCost.go Adjusts file closing.
vmhost/​vmhooks/​generate/​eiGenWriteRustWasmerProdImports.go Updates generated Rust imports.
vmhost/​vmhooks/​generate/​eiGenWriteRustWasmerOpcodeCost.go Generates versioned metering logic.
vmhost/​vmhooks/​generate/​eiGenWriteRustWasmerMeteringHelpers.go Removes obsolete generator.
vmhost/​vmhooks/​generate/​eiGenWriteRustWasmerExperimentalImports.go Updates experimental imports.
vmhost/​vmhooks/​generate/​eiGenWriteRustVMHooksSignatures.go Generates hook signatures.
vmhost/​vmhooks/​generate/​eiGenWriteRustUtil.go Maps hook types to wasmparser types.
vmhost/​vmhooks/​generate/​eiGenWriteRustOpcodeWhitelisted.go Generates versioned whitelists.
vmhost/​vmhooks/​generate/​eiGenWriteRustOpcodeCost.go Uses centralized cost names.
vmhost/​vmhooks/​generate/​eiGenWriteRustCapiOpcodeCost.go Generates the C ABI cost mirror.
vmhost/​vmhooks/​generate/​eiGenWriteOpcodeCostFuncHelpers.go Removes manual extraction generator.
vmhost/​vmhooks/​generate/​eiGenWriteOpcodeCost.go Generates Go costs and extraction.
vmhost/​vmhooks/​generate/​eiGenOpcodeNames.go Centralizes opcode versions and costs.
vmhost/​vmhooks/​generate/​cmd/​README.md Documents generator inputs and ABI layout.
vmhost/​vmhooks/​generate/​cmd/​input/​wasmer2_per_byte_opcodes.txt Lists per-byte opcodes.
vmhost/​vmhooks/​generate/​cmd/​input/​wasmer2_allowed_opcodes_v2.txt Defines V2’s opcode set.
vmhost/​vmhooks/​generate/​cmd/​input/​wasmer2_allowed_opcodes_v1.txt Separates non-opcode costs from V1.
vmhost/​vmhooks/​generate/​cmd/​input/​wasmer2_additional_costs.txt Lists additional executor costs.
vmhost/​vmhooks/​generate/​cmd/​input/​wasm_opcodes.txt Adds per-byte schedule fields.
vmhost/​vmhooks/​generate/​cmd/​eiGenMain.go Produces and copies new Rust outputs.
vmhost/​vmhooks/​generate/​cmd/​.gitignore Ignores new path configuration files.
vmhost/​hosttest/​forbidden_opcodes_test.go Tests V1/V2 bulk-memory acceptance.
vmhost/​hosttest/​bulkMemoryGas_test.go Tests base and per-byte metering.
vmhost/​hostCore/​host.go Selects and applies opcode versions.
vmhost/​flags.go Introduces OpcodeV2Flag.
vmhost/​contexts/​runtime_test.go Configures V2 in runtime tests.
vmhost/​contexts/​async_test.go Configures V2 in async tests.
test/​contracts/​bulk-memory/​README.md Documents the gas test contract.
test/​contracts/​bulk-memory/​bulk-memory.wat Provides bulk-memory test endpoints.
test/​contracts/​bulk-memory/​build.sh Builds the WAT fixture.
scenario/​gasSchedules/​gasScheduleV4.toml Adds V4 per-byte costs.
scenario/​gasSchedules/​gasScheduleV3.toml Adds V3 per-byte costs.
scenario/​gasSchedules/​gasScheduleEmbedGenerated.go Refreshes embedded schedules.
mock/​context/​executorMock.go Updates the mocked executor API.
executor/​wrapper/​wrapperExecutor.go Forwards versioned configuration.
executor/​gasCostWASM.go Adds per-byte cost fields.
executor/​executorOpcodeVersion.go Defines V1 and V2.
executor/​executorFactory.go Adds version to factory arguments.
executor/​executor.go Updates the executor interface.
config/​gasSchedule.go Populates per-byte costs.
config/​config.toml Adds default per-byte costs.
codecov.yml Excludes generated code from coverage.
Files not reviewed (2)
  • executor/gasCostWASM.go: Generated file
  • scenario/gasSchedules/gasScheduleEmbedGenerated.go: Generated file

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread vmhost/hostCore/host.go Resolved
Comment thread wasmer2/wasmer2Executor.go Resolved
Comment thread wasmer2/bridge2.go Resolved
@andrei-marinica
andrei-marinica changed the base branch from feat/new-executor to master October 23, 2026 10:03
@andrei-marinica
andrei-marinica requested a balanced review from Copilot October 29, 2026 12:49
@andrei-marinica
andrei-marinica changed the base branch from master to feat/new-executor October 29, 2026 12:55

Copilot AI 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.

🟡 Changes recommended

The wrapper factory drops OpcodeVersion, causing V2-enabled hosts to create V1 executors and reject bulk-memory contracts, with epoch reconfiguration unable to repair the mismatch.

3 open issues
5 resolved since last review
2 files not reviewed
  • executor/gasCostWASM.go: Generated file
  • scenario/gasSchedules/gasScheduleEmbedGenerated.go: Generated file

Review effort: Balanced

Comment thread executor/executorFactory.go Resolved
Comment thread vmhost/hostCore/host.go Resolved
Comment thread wasmer2/wasmer2Executor.go Resolved

Copilot AI 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.

🟡 Changes recommended

Recreating a V2 host over a retained V1 cache skips invalidation, allowing cached contracts to bypass the V2 opcode whitelist.

2 open issues
3 resolved since last review
2 files not reviewed
  • executor/gasCostWASM.go: Generated file
  • scenario/gasSchedules/gasScheduleEmbedGenerated.go: Generated file

Review effort: Balanced

Comment thread vmhost/hostCore/host.go Resolved
Comment thread vmhost/hosttest/bulkMemoryGas_test.go Resolved

Copilot AI 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.

🟡 Changes recommended

Opcode configuration failures return without destroying the allocated native executor, causing native memory leaks on repeated failed factory calls.

1 open issue
2 resolved since last review
2 files not reviewed
  • executor/gasCostWASM.go: Generated file
  • scenario/gasSchedules/gasScheduleEmbedGenerated.go: Generated file

Review effort: Balanced

Comment thread wasmer2/wasmer2ExecutorFactory.go Resolved

Copilot AI 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.

🔵 Needs a closer look

Consensus-critical opcode, gas-metering, and native ABI changes require human validation of shipped executor binaries across supported platforms and epoch-notifier/feature-flag activation ordering, which source review alone cannot establish.

No open issues 🎉

1 resolved since last review
2 files not reviewed
  • executor/gasCostWASM.go: Generated file
  • scenario/gasSchedules/gasScheduleEmbedGenerated.go: Generated file

Review effort: Balanced

@andrei-marinica
andrei-marinica merged commit 7f3312a into feat/new-executor Nov 5, 2026
7 checks passed
@andrei-marinica
andrei-marinica deleted the opcodes-v2 branch November 5, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants