Skip to content

feat(core,ethexe,pallet-gear): strip WASM custom sections from InstrumentedCode#5367

Open
ukint-vs wants to merge 12 commits intomasterfrom
vs/strip-wasm-custom-sections
Open

feat(core,ethexe,pallet-gear): strip WASM custom sections from InstrumentedCode#5367
ukint-vs wants to merge 12 commits intomasterfrom
vs/strip-wasm-custom-sections

Conversation

@ukint-vs
Copy link
Copy Markdown
Member

Summary

Strip WASM custom sections (e.g. sails:idl, producers) from InstrumentedCode
before persisting. They are never consumed at sandbox execution time — IDL readers
pull from OriginalCode via the gear_readWasmCustomSection RPC. Keeping them in
InstrumentedCode just inflates the bytes that are reloaded into Wasmer/Wasmtime
on every execution, gas-billed to users on Vara, and synced over libp2p on ethexe.

Since commit dafb483 the instrumentation pipeline round-tripped custom sections
so the IDL survived on-chain. This PR moves the stripping to the single choke point
Code::try_new_internal, so both pallet-gear and ethexe benefit from one call.
name_section is preserved — Wasmer/Wasmtime trap backtraces stay readable.

Changes

utils/wasm-instrument & core

  • Module::strip_custom_sections() — clears custom_sections, keeps
    name_section. Rustdoc notes the intentional divergence from
    wasm_optimizer::Optimizer::strip_custom_sections, which clears both.
  • Code::try_new_internal calls it right before module.serialize(), so the
    code_len captured into CodeMetadata reflects the bytes actually stored
    (this is what pallet-gear charges gas against).

ethexe

  • ethexe_runtime_common::VERSION: 1 → 2.
  • DB key layout for InstrumentedCode extended from (u32, CodeId) to
    (runtime_id: u32, version: u32, CodeId). This closes a latent bug where
    various call sites passed RUNTIME_ID where production code expected
    VERSION — both happened to equal 1, so the mismatch was silently benign
    until this PR. All production call sites now pass (RUNTIME_ID, VERSION).
  • DB migration v3::migration_from_v2 drops stale InstrumentedCode entries
    stored under the old 2-tuple layout. ethexe-db::LATEST_VERSION: 2 → 3.
  • RPC code_getInstrumented(runtime_id, code_id) signature is preserved
    the handler internally defaults to ethexe_runtime_common::VERSION.
    External clients are not affected.

Vara / pallet-gear

  • Schedule::InstructionWeights::version: 1900 → 1910. Triggers lazy
    re-instrumentation of existing on-chain programs via the standard
    queue.rs::needs_reinstrumentation path — no storage migration required.

Gas impact (Vara)

Program upload and re-instrumentation cost drops slightly; the stored
instrumented bytes are smaller because IDL + producers + any other custom
sections are no longer included. The drop is proportional to IDL size (typically
1–20 KiB). IDL readers are unaffected — gear_readWasmCustomSection reads
OriginalCode.

Weight regeneration for pallet_gear is deferred to CI / a maintainer pass
since local benchmark runs produce hardware-biased numbers.

Migration story

Vara: lazy. Existing programs reinstrument on next execution via
reinstrument_code when Schedule::InstructionWeights::version changes. No
storage migration.

ethexe: the v3 DB migration drops stale InstrumentedCode entries stored
under the old key layout. The migration does not itself re-instrument — it
relies on the normal code observation pipeline to re-populate entries on next
touch. Operators upgrading a live node should expect a brief window where
existing programs return MissingInstrumentedCodeForProgram until their codes
are re-observed. Acceptable given ethexe's pre-mainnet status; if that ever
changes, add a lazy re-instrument fallback in instrumented_code_and_metadata.

Tests

  • utils/wasm-instrument: strip_custom_sections_clears_custom_but_keeps_name,
    strip_custom_sections_on_empty_module_is_noop.
  • gear-core: instrumented_code_strips_custom_sections_but_original_keeps_them
    end-to-end through Code::try_new, asserts OriginalCode retains sails:idl
    and InstrumentedCode has no custom sections.
  • ethexe-processor: instrumented_code_strips_custom_sections — same contract
    across the full Processor::process_code pipeline.
  • ethexe-db: test_instrumented_code extended with cross-runtime and
    cross-version isolation assertions (bumping either constant must invalidate
    prior entries).
  • pallet-gear: stripping_reduces_instrumented_code_len — uploads a program
    with a 4 KiB sails:idl section, asserts OriginalCode preserves it and
    InstrumentedCode strips all custom sections.

Verification

cargo nextest run -p gear-wasm-instrument
cargo nextest run -p gear-core -E 'test(code::)'
cargo nextest run -p pallet-gear --tests
cargo nextest run -p "ethexe-*" --no-fail-fast

Not in scope

  • Eager re-instrumentation during the ethexe v3 migration (would require threading
    a processor through the migration framework).
  • Moving RUNTIME_ID / VERSION constants into ethexe-common to eliminate
    the hard-coded (1, 2, ...) literal in mock.rs (blocked by the current
    dep graph; tracked with a TODO).
  • Re-running pallet_gear runtime weight benchmarks (CI / maintainer task on
    canonical hardware).

🤖 Generated with Claude Code

…mentedCode

Since commit dafb483 the instrumentation pipeline kept custom sections
(sails:idl, producers, etc.) inside the persisted instrumented artifact.
They are never consumed at sandbox execution time — IDL readers use
OriginalCode via the gear_readWasmCustomSection RPC. Keep them out of
InstrumentedCode so the sandbox load path is smaller and per-byte gas
charges on Vara drop accordingly.

Changes:

* utils/wasm-instrument: add Module::strip_custom_sections (preserves
  name_section so Wasmer/Wasmtime trap backtraces stay readable).
* core/src/code: call the strip in Code::try_new_internal before
  module.serialize(), so both pallet-gear and ethexe benefit.
* ethexe_runtime_common::VERSION 1 → 2 and extend the ethexe
  InstrumentedCode DB key from (u32, CodeId) to
  (runtime_id: u32, version: u32, CodeId). Fixes a latent bug where
  various call sites passed RUNTIME_ID instead of VERSION; now both
  participate in the key. RPC code_getInstrumented gains a `version`
  parameter (breaking RPC change).
* pallet_gear Schedule InstructionWeights::version 1900 → 1910 to
  trigger lazy re-instrumentation of existing on-chain programs.

Gas impact on Vara: program upload and re-instrumentation cost drops
slightly; the stored instrumented bytes are smaller. IDL readers are
unaffected (they read OriginalCode). Existing programs lazily migrate
to the stripped shape on their next execution via reinstrument_code.

Tests:

* wasm-instrument unit tests: strip clears custom, keeps name; no-op on
  empty module.
* gear-core end-to-end: OriginalCode keeps sails:idl, InstrumentedCode
  has no custom sections.
* ethexe processor integration: same contract across the full
  process_code pipeline.
* pallet-gear regression: stripping_reduces_instrumented_code_len
  uploads a program with a 4 KiB sails:idl section and asserts the
  strip + net size-drop contract end-to-end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@semanticdiff-com
Copy link
Copy Markdown

semanticdiff-com Bot commented Apr 21, 2026

Review changes with  SemanticDiff

Changed Files
File Status
  ethexe/service/src/tests/mod.rs  59% smaller
  ethexe/db/src/migrations/init.rs  53% smaller
  ethexe/rpc/src/apis/code.rs  41% smaller
  ethexe/db/src/database.rs  11% smaller
  ethexe/runtime/common/src/lib.rs  7% smaller
  core/src/code/mod.rs  1% smaller
  CLAUDE.md Unsupported file format
  ethexe/common/src/db.rs  0% smaller
  ethexe/common/src/mock.rs  0% smaller
  ethexe/compute/src/compute.rs  0% smaller
  ethexe/db/src/iterator.rs  0% smaller
  ethexe/db/src/migrations/mod.rs Unsupported file format
  ethexe/db/src/migrations/v1.rs  0% smaller
  ethexe/db/src/migrations/v2.rs  0% smaller
  ethexe/db/src/migrations/v4.rs  0% smaller
  ethexe/db/src/migrations/v5.rs  0% smaller
  ethexe/processor/src/tests.rs  0% smaller
  ethexe/runtime/common/Cargo.toml Unsupported file format
  gsdk/vara_runtime.scale Unsupported file format
  pallets/gear/src/schedule.rs  0% smaller
  pallets/gear/src/tests.rs  0% smaller
  utils/wasm-instrument/src/module.rs  0% smaller

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request optimizes the storage and execution of instrumented WASM code by stripping unnecessary custom sections before persistence. It introduces a versioned database key layout for InstrumentedCode to improve isolation and maintainability, accompanied by a necessary database migration for ethexe. These changes collectively reduce storage overhead and gas costs while ensuring that essential metadata remains available for RPC readers and debugging.

Highlights

  • WASM Custom Section Stripping: Implemented Module::strip_custom_sections() to remove non-essential WASM custom sections (e.g., sails:idl, producers) from InstrumentedCode while preserving the name section for debugging.
  • Database Schema Update: Updated the InstrumentedCode database key layout from (u32, CodeId) to (runtime_id: u32, version: u32, CodeId) to support versioning and prevent potential collisions.
  • Database Migration: Added a v3 migration for ethexe to drop stale InstrumentedCode entries stored under the old key layout, ensuring compatibility with the new schema.
  • Gas and Performance: Reduced the size of stored InstrumentedCode by stripping custom sections, which lowers program upload and re-instrumentation costs on Vara.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a mechanism to strip WASM custom sections (excluding the name section) from instrumented code while ensuring they are preserved in the original code for RPC consumers. It also updates the InstrumentedCode database key layout in ethexe to include an instrumentation version, bumping the runtime version to 2 and providing a migration (v3) to clear stale entries. A compilation error was identified in the new migration file due to a missing import and inconsistent logging macro usage.

Comment thread ethexe/db/src/migrations/v3.rs Outdated
}
}

log::info!(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The log crate is not imported in this file, which will lead to a compilation error. Additionally, the rest of the ethexe-db crate (e.g., database.rs) uses the tracing crate for logging. For consistency and to fix the compilation error, please use tracing::info!.

Suggested change
log::info!(
tracing::info!(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is a false positive:

  1. No compilation error. log is declared as a direct workspace dep of ethexe-db at ethexe/db/Cargo.toml:23 (log.workspace = true). log::info! resolves via the crate path and does not require a use log import. Local cargo check -p ethexe-db passes.

  2. Logging convention. The migrations module consistently uses log::*!:

    • ethexe/db/src/migrations/v2.rs:46, 71, 115
    • ethexe/db/src/migrations/init.rs:37, 40, 59, 63, 78, 98

    Switching v3 to tracing::info! would diverge from its siblings in the same module. The tracing convention lives in ethexe/db/src/database.rs — not a crate-wide rule.

Keeping log::info! to stay consistent with the other migration files.

@ukint-vs ukint-vs self-assigned this Apr 21, 2026
@ukint-vs ukint-vs added the A0-pleasereview PR is ready to be reviewed by the team label Apr 21, 2026
@ukint-vs
Copy link
Copy Markdown
Member Author

@claude opus review

@claude
Copy link
Copy Markdown

claude Bot commented Apr 21, 2026

Claude finished @ukint-vs's task in 4m 20s —— View job


PR Review — strip WASM custom sections from InstrumentedCode

Overall: LGTM. The change is well-scoped, correctly sequenced, and the new test coverage is solid. Two minor maintenance notes below, nothing blocking.

Summary

This PR reduces the size of InstrumentedCode by stripping custom sections (notably sails:idl, producers) before serialization, while preserving the name section so runtime trap backtraces stay readable. Readers that need the IDL (e.g. gear_readWasmCustomSection) already pull from OriginalCode, so no functional regression. On the ethexe side, the DB key for instrumented code grows from (runtime_id, code_id) to (runtime_id, version, code_id) and a v3 migration drops now-stale entries. On Vara, InstructionWeights::version is bumped 1900 → 1910 to force lazy re-instrumentation.

What I verified

Stripping placement (core/src/code/mod.rs:189) — correct. strip_custom_sections() is called after utils::get_data_section_size / get_instantiated_global_section_size / get_instantiated_table_section_size / get_instantiated_element_section_size inspect the in-memory Module, and before module.serialize(). So code_len in CodeMetadata reflects the actual stored bytes — gas billing and InstrumentedCode length stay consistent.

name section preservedModule::strip_custom_sections at utils/wasm-instrument/src/module.rs clears custom_sections but leaves name_section intact. The doc comment explicitly contrasts this with wasm_optimizer::Optimizer::strip_custom_sections which clears both. Good to call out — preserving names keeps Wasmer/Wasmtime backtraces useful in production logs.

DB key layoutKey::InstrumentedCode(u32, u32, CodeId) = 8 serializes as prefix(32) + runtime_id(4) + version(4) + code_id(32) = 72 bytes. The debug upper bound at ethexe/db/src/database.rs is updated. Cross-runtime and cross-version isolation is tested in test_instrumented_code.

v3 migration (ethexe/db/src/migrations/v3.rs) — the old-body-length filter (PREFIX_LEN + OLD_BODY_LEN == 32 + 4 + 32 == 68) precisely matches the pre-v3 key shape, so we won't incidentally nuke unrelated entries sharing the discriminant. No ensure_migration_types test is warranted here since v3 only drops raw-keyed entries — nothing is decoded/re-encoded.

RPC surface (ethexe/rpc/src/apis/code.rs:32-38)code_getInstrumented(runtime_id, code_id) signature is preserved; the handler internally supplies ethexe_runtime_common::VERSION. Clean backward-compat choice, and the comment documents it.

Call sites(RUNTIME_ID, VERSION) is consistently propagated in ethexe/compute/src/codes.rs, ethexe/processor/src/handling/run/mod.rs, ethexe/db/src/iterator.rs, and ethexe/db/src/migrations/init.rs.

Findings

severity: low — hardcoded (1, 2) in mock code

File: ethexe/common/src/mock.rs line 726

db.set_instrumented_code(1, 2, code_id, instrumented);

The PR description already flags this as "not in scope" and the comment explains the dep-cycle constraint (ethexe-runtime-common depends on ethexe-common, not the other way around). Still, hardcoded literals that must stay in sync with another crate's constants are fragile — a future VERSION bump could silently miss this line and tests would go green with the wrong version. Two low-cost options:

  1. Define const RUNTIME_ID_MOCK: u32 = 1; const VERSION_MOCK: u32 = 2; locally in mock.rs and add a test in ethexe-runtime-common that asserts RUNTIME_ID == ethexe_common::mock::RUNTIME_ID_MOCK and VERSION == ethexe_common::mock::VERSION_MOCK (reverse direction is allowed since runtime-common already depends on common).
  2. Or move the mock helpers into a leaf crate that can depend on both.

Non-blocking, but worth a follow-up issue.

severity: low — migration version-pin assertions require updates on every bump

Files: ethexe/db/src/migrations/v1.rs:34, ethexe/db/src/migrations/v2.rs:37

Each prior migration has a const _ = const { assert!(crate::VERSION == super::vN::VERSION, ...) } block that must be retargeted to the newest version on each bump. It worked fine here, but this scales poorly — by v10 that's 9 edits per bump, easy to miss. A single centralized assertion in migrations/mod.rs tied to the MIGRATIONS.len() == LATEST_VERSION - OLDEST_SUPPORTED_VERSION invariant would cover it. Not required for this PR.

Informational

  • Gemini's log vs tracing comment — false positive. log is a direct workspace dep of ethexe-db and the migrations module consistently uses log::*! across v1/v2 as well. The PR author's rebuttal is correct.
  • Operator migration UX — operators upgrading to v3 will briefly see MissingInstrumentedCodeForProgram until codes are re-observed and re-instrumented. Acceptable pre-mainnet; worth a release note.
  • Vara side — the InstructionWeights::version bump to 1910 correctly triggers lazy re-instrumentation so existing deployed programs get stripped on next invocation. Good.

Tests

Coverage is thorough:

  • strip_custom_sections_clears_custom_but_keeps_name + _on_empty_module_is_noop in utils/wasm-instrument
  • instrumented_code_strips_custom_sections_but_original_keeps_them end-to-end in core/src/code
  • test_instrumented_code extended for cross-runtime and cross-version isolation in ethexe/db
  • stripping_reduces_instrumented_code_len at the pallet-gear level with a 4 KiB sails:idl payload

Ship it after the mock-constants follow-up is at least filed as an issue.


Reviewed by Claude Opus 4.7 via @claude opus review.

…ants

Extract `MOCK_RUNTIME_ID` and `MOCK_VERSION` from the `(1, 2, code_id, …)`
literal in `ethexe-common`'s mock. `ethexe-common` can't import
`ethexe_runtime_common::{RUNTIME_ID, VERSION}` directly — runtime-common
depends on common, so the reverse would be a dep cycle — but the drift is
guarded the other way: `ethexe-runtime-common` now has a dev-dep on
`ethexe-common` with the `mock` feature and a `#[cfg(test)]` assertion
that `RUNTIME_ID == MOCK_RUNTIME_ID` and `VERSION == MOCK_VERSION`. A
future bump of either real constant that forgets to update the mock
fails that test loudly instead of silently diverging.

Follow-up to #5367 review feedback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ukint-vs
Copy link
Copy Markdown
Member Author

Addressed the hardcoded (1, 2) mock literal in ddfc0bc27:

  • ethexe-common::mock now exports MOCK_RUNTIME_ID and MOCK_VERSION constants and uses them at the call site instead of the literal.
  • ethexe-runtime-common picks up ethexe-common with the mock feature as a dev-dep and adds a #[cfg(test)] assertion that RUNTIME_ID == MOCK_RUNTIME_ID && VERSION == MOCK_VERSION.

The dep-cycle constraint (runtime-common → common, not the reverse) is unchanged, so the mock can't import the real constants directly. But now a future bump of VERSION or RUNTIME_ID that forgets to update the mock fails that test loudly instead of silently drifting.

Follow-up per @claude's review.

ukint-vs and others added 4 commits April 21, 2026 16:09
- `make fmt` reflowed multi-line literals in 7 files touched by this PR
  (no semantic changes).
- `v3::migration_from_v2` imported `KVDatabase` alongside `RawDatabase`
  but never referenced the trait by name — method calls on `db.kv:
  Box<dyn KVDatabase>` resolve through the vtable without the trait in
  scope. Drop the unused import.

Fixes `check / fmt` and `check / clippy` CI failures on #5367.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`wasmparser::Payload::CustomSection` fires for every standard custom
section including the `name` section, but we intentionally preserve
`name_section` (see `Module::strip_custom_sections`'s rustdoc — it
keeps trap backtraces readable). The test's broader "no custom
sections at all" assertion therefore contradicted the design and
failed on CI despite passing the targeted `sails:idl` check.

Narrow the broader assertion to "no custom sections other than
`name`" and include the offending section name(s) in the panic message
for easier diagnostics next time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…m-sections

# Conflicts:
#	ethexe/db/src/migrations/v2.rs
#	ethexe/db/src/migrations/v3.rs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@grishasobol grishasobol left a comment

Choose a reason for hiding this comment

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

update the branch, you have side changes

ukint-vs and others added 3 commits April 22, 2026 20:21
Use the existing ModuleBuilder::push_custom_section helper in the three
tests instead of re-rolling the get_or_insert_with(Vec::new).push(...)
dance. Add a size-reduction assertion in stripping_reduces_instrumented_code_len
so the test's stated contract is actually guarded. Pin the Key enum's
InstrumentedCode discriminant via a unit test so a future Key reorder
fails loudly rather than silently mis-scanning in migrations/v4.rs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…m-sections

# Conflicts:
#	ethexe/db/src/migrations/mod.rs
#	ethexe/db/src/migrations/v2.rs
#	ethexe/db/src/migrations/v4.rs
Comment thread ethexe/common/src/db.rs Outdated
fn instrumented_code(
&self,
runtime_id: u32,
version: u32,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What the reason of adding second version? As soon as version can be changed only when runtime is changed, then we can use only one here, runtime version or instrumentation version

Comment thread ethexe/runtime/common/src/lib.rs Outdated
Comment on lines 67 to 68
pub const VERSION: u32 = 2;
pub const RUNTIME_ID: u32 = 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what the difference between version and runtime id ?

Comment thread ethexe/db/src/migrations/v5.rs Outdated
/// re-instrument existing codes — that relies on the normal code processing
/// pipeline observing the code again. Operators upgrading a live node should
/// expect a brief window where existing programs return
/// `MissingInstrumentedCodeForProgram` until their codes are re-observed.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we do not have any re-instrumentation mechanism right now

Per @grishasobol's review: `runtime_id` and `version` always change
together, so carrying both in the `InstrumentedCode` DB key and in the
`CodesStorage*` traits was redundant. Drop `RUNTIME_ID` (it had no use
outside DB-key call sites) and key by `VERSION` only — `VERSION` is
also what `Code::try_new` consumes as `instruction_weights_version`,
so it carries semantic weight that `RUNTIME_ID` did not.

DB key shape: `(runtime_id, version, code_id)` → `(version, code_id)`.
Trait signatures lose the duplicated `u32`. Mock keeps `MOCK_VERSION`
only; the runtime-common assertion test follows.

The v5 migration body is unchanged in spirit but the doc no longer
claims re-instrumentation happens (per @grishasobol — there is no such
mechanism today). Old and new key shapes now have the same byte
length, so the length-filter is dropped in favor of wiping every entry
under the `InstrumentedCode` discriminant unconditionally; all of them
are stale relative to the bumped `VERSION`.

RPC `code_getInstrumented(runtime_id, code_id)` keeps its public
signature; the `runtime_id` parameter is now ignored internally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ukint-vs
Copy link
Copy Markdown
Member Author

Addressed @grishasobol's review in cbee4d651.

Both "what's the difference between version and runtime_id" / "use only one here" comments: collapsed. The InstrumentedCode key is now (version, code_id) — single u32 discriminant. Dropped the RUNTIME_ID constant entirely (it had no callers outside DB-key sites) and kept VERSION, which is also what Code::try_new consumes as instruction_weights_version — so it carries real semantic weight. Trait signatures and the mock follow.

The public RPC code_getInstrumented(runtime_id, code_id) keeps its signature for backward compat; the runtime_id parameter is ignored internally and explicitly documented.

"we do not have any re-instrumentation mechanism right now": fixed the v5 doc to stop claiming the compute pipeline re-instruments on next observation. It doesn't — RouterEvent::CodeUploaded only fires for fresh uploads. Doc now states honestly that programs whose entries get wiped will surface MissingInstrumentedCodeForProgram until the same OriginalCode is uploaded to chain again, which is acceptable pre-mainnet. Migration logic changed accordingly: old and new key shapes now have the same byte length (4 + 32), so the length-filter no longer helps — every entry under the discriminant is stale post-bump and gets wiped unconditionally.

Tests green: ethexe-* 134/134, gear-core/gear-wasm-instrument 151/151, pallet-gear::stripping_reduces_instrumented_code_len passes.

🤖 Generated with Claude Code

Self-review pass on the previous commit:

- `VERSION` doc and v5 migration doc collapsed to the essentials.
- Drop diff-narration comments ("post-bump key shape has the same byte
  length as the pre-bump one...") — readers see only the final code.
- Drop the SAFETY comment on `unsafe { db.kv.take(...) }` in v5: the
  unsafety on `KVDatabase::take` is purely a data-loss risk, exactly
  the intent here. `let _ = ...` makes that explicit without prose.
- Tighten `Key::to_bytes`' debug_assert upper-bound to match the
  `with_capacity` hint (one `u32`, not two).
- Drop redundant comments on `instrumented_code_key_discriminant_is_stable`
  and inside `test_instrumented_code` that restated the assertion.
- Collapse the now-single-constant header in `ethexe-common::mock`.

No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A0-pleasereview PR is ready to be reviewed by the team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants