Skip to content

Regenerate evm_call_wasm_example_counter.sol BCS code from the counter format snapshot #6326

@ma2bd

Description

@ma2bd

Motivation

linera-service/tests/fixtures/evm_call_wasm_example_counter.sol is a Solidity fixture that exercises EVM → Wasm calls into the counter-no-graphql example. Its bcs_serialize_CounterOperation function is a frozen snapshot of what serde-generate's Solidity backend would have emitted when the fixture was first authored (PR #3717): the generated output was copy-pasted into the file once and has been hand-maintained since.

That worked while CounterOperation was a stable single-variant enum with sequential uint8 discriminants. With #6314, CounterOperation now carries #[derive(StableEnum)], so its variant tag is a 4-byte ULEB128 encoding of Keccak256("Increment")[..4] rather than uint8(0). The fixture's BCS serializer was hand-edited in that PR to hardcode the tag (hex\"BFD58759\"), but this is fragile: any future rename or variant addition silently breaks the EVM→Wasm test (it manifests as a RuntimeError: unreachable Wasm trap, not a localized fixture error).

Proposal

Adopt the same pattern the bridge uses for BridgeTypes.sol / FungibleBridge.sol, scoped to this fixture:

  1. Generate the types. Add a build script (in a small dedicated crate or in linera-service's own `build.rs`) that:

    • Reads `examples/counter-no-graphql/tests/snapshots/format__format.snap`,
    • Strips the insta header (`splitn(3, "---").nth(2)`),
    • Parses the YAML into a `serde_reflection::Registry`,
    • Feeds it to `serde_generate::solidity::Installer` with module name `CounterOperationTypes`,
    • Writes the result to `linera-service/tests/fixtures/CounterOperationTypes.sol`.

    With the workspace `[patch.crates-io]` pin to the zefchain serde-reflection fork (commit `8882df9`), the emitted code will use the correct 4-byte ULEB128 Keccak tags automatically — no hand-coded constants.

  2. Split the fixture. Refactor `evm_call_wasm_example_counter.sol` so the generated content lives in `CounterOperationTypes.sol` (imported via `import "./CounterOperationTypes.sol";`). The hand-written content stays:

    • `serde_json_serialize_CounterRequest` and the JSON deserializer (still hand-maintained — service queries don't go through BCS),
    • The `nest_increment` / `nest_get_value` entry points,
    • The fixed-width `bcs_serialize_uint64` / `bcs_deserialize_uint64` helpers if they aren't duplicated by the generated module.
  3. Drift check. Add a CI step that runs the generator into a temp dir and `diff`s against the in-tree `CounterOperationTypes.sol`, mirroring the existing `LineraTypes.sol` check in `.github/workflows/rust.yml`. Alternatively, the build script itself can fail when the in-tree file is out of date.

Out of scope / open questions

  • Whether to keep `serde_json_*` codegen separate or also generate it (today it's hand-rolled because no generator targets JSON-over-Solidity for query encoding).
  • Whether to extend the same pattern to other potential EVM↔Wasm fixtures preemptively. Probably wait for a second instance to land before generalizing.

Links

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions