Skip to content

feat(calldata)!: migrate method-call key "method" -> "" (v0.6 genvm ABI)#96

Draft
MuncleUscles wants to merge 2 commits into
v0.19-devfrom
feat/calldata-abi-empty-key
Draft

feat(calldata)!: migrate method-call key "method" -> "" (v0.6 genvm ABI)#96
MuncleUscles wants to merge 2 commits into
v0.19-devfrom
feat/calldata-abi-empty-key

Conversation

@MuncleUscles

@MuncleUscles MuncleUscles commented Jul 1, 2026

Copy link
Copy Markdown
Member

Migrates genlayer-py to the GenVM v0.6 calldata ABI, which renames the
method-call key from "method" to "" (empty string). Because the calldata
encoder sorts map keys ascending, "" sorts first — the method name becomes
the binary prefix of the encoded calldata. genvm-manager auto-remaps
"method" -> "" but logs an error on every call, so the SDK must migrate.

SDK-side counterpart of the wire-format change already merged in genlayer-node
(#1502) and genlayer-studio (#1697).

Wire-format change

Before: calldata.encode({"args": [...], "method": "foo"})
After: calldata.encode({"args": [...], "": "foo"})

The empty key sorts first in canonical calldata encoding, so for a call to
ask_for_coin(...) the raw calldata now begins with the method-name bytes:

old: 16 04 61 72 67 73 ... 06 6d 65 74 68 6f 64 64 61 73 6b 5f 66 6f 72 5f 63 6f 69 6e   (…"method"·ask_for_coin)
new: 16 00 64 61 73 6b 5f 66 6f 72 5f 63 6f 69 6e 04 61 72 67 73 ...                      (·""·ask_for_coin·"args"…)

What changed

  • genlayer_py/contracts/utils.pymake_calldata_object, the sole
    producer of the method key, now emits ret[""] = method. This is the only
    source change; it flows through every method-call path (write / read / sim /
    estimate + encode_tx_data_call).
  • Encoder/decoder unchanged — both are key-agnostic. The decoder
    round-trips whatever key is present, so decoded calldata now exposes the
    method name under "" with no decoder change.
  • Tests — consensus + smoke round-trip assertions read call_data[""];
    new test_method_key_is_empty_string_binary_prefix asserts the "" key is
    present, "method" is absent, and the method-name bytes precede the "args"
    key bytes in the raw calldata (proving "" sorts first). This test fails
    under the old key.
  • Fixtures — regenerated the raw / base64 / readable calldata sample data
    ({"": "ask_for_coin", ...}) in the write sample-data files and conftest.
    Deploy (constructor) fixtures are unaffected — they carry no method key.

Compatibility

No back-compat toggle: genlayer-py has no calldata versioning mechanism, and
none is introduced (matching node/studio). Calldata built by this SDK is
incompatible with pre-v0.6 GenVM.

BREAKING CHANGE: method-call calldata now keys the method name under ""
instead of "method".

Testing

uv run --python 3.13 pytest tests/unit -m "not testnet" -> 91 passed, 17
deselected
(testnet-marked tests need live RPC). Verified the new property
test fails when reverted to the old "method" key.

Depends-On: genlayerlabs/genvm-manager#1
Depends-On: https://github.com/genlayerlabs/genlayer-node/pull/1502
Depends-On: https://github.com/genlayerlabs/genlayer-dev-env/pull/95
Depends-On: https://github.com/genlayerlabs/genlayer-e2e/pull/619
Depends-On: genlayerlabs/genlayer-studio#1697
Depends-On: #96
Depends-On: genlayerlabs/genlayer-js#192
Depends-On: genlayerlabs/genlayer-testing-suite#98

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 88eae784-c9b4-4dca-8131-2d988a61edf9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/calldata-abi-empty-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The GenVM v0.6 calldata ABI renames the method-call key from "method" to
"" (empty string). Because the calldata encoder sorts map keys ascending,
"" sorts first, so the method name becomes the binary prefix of the encoded
calldata. genvm-manager auto-remaps "method" -> "" but logs an error on every
call; SDKs must migrate to stop the error and match the canonical wire format.

- make_calldata_object (genlayer_py/contracts/utils.py) is the sole producer
  of the method key; it now emits ret[""] = method. This flows through every
  method-call path (write/read/sim/estimate + encode_tx_data_call).
- The calldata encoder/decoder are key-agnostic and unchanged; the decoder
  round-trips whatever key is present, so decoding auto-adapts.
- Updated consensus/smoke round-trip assertions to read call_data[""] and
  added test_method_key_is_empty_string_binary_prefix, which asserts the ""
  key is present, "method" is absent, and the method name precedes the "args"
  key bytes in the raw calldata (proving "" sorts first). This test fails
  under the old key.
- Regenerated the raw / base64 / readable calldata fixtures to the new wire
  format ({"": "ask_for_coin", ...}) across the write sample-data files and
  conftest. Deploy (constructor) fixtures are unaffected — they carry no
  method key.

No back-compat toggle: the codebase has no calldata versioning mechanism and
none is introduced.

BREAKING CHANGE: method-call calldata now keys the method name under "" (empty
string) instead of "method", per the v0.6 GenVM calldata ABI. Calldata built by
this SDK is incompatible with pre-v0.6 GenVM, and decoded calldata exposes the
method name under the "" key.
@kp2pml30 kp2pml30 force-pushed the feat/calldata-abi-empty-key branch from 3e6e87f to 57fd841 Compare July 9, 2026 08:38
The tests/e2e/contracts fixtures used the v0.2.x SDK idiom and fail under
GenVM v0.6 with NameError (from genlayer import * no longer binds gl).
Migrate all 15 to v0.3:
- from genlayer import * -> import genlayer as gl + from genlayer.types import *
- gl.Contract -> gl.contract.Contract; gl.ContractAt -> gl.contract.get_at;
  gl.deploy_contract -> gl.contract.deploy
- gl.DynArray/TreeMap -> gl.storage.*; @allow_storage -> @gl.storage.allow
- gl.eq_principle_* -> gl.eq_principle.*; gl.exec_prompt -> gl.nondet.exec_prompt;
  gl.get_webpage -> gl.nondet.web.render
- drop callable u256(x) wrapping (aliases are Annotated[int], not callable)

multi_tenant_storage.py additionally dropped the removed emit(gas=...) kwarg
(v0.3 emit takes value/on/use_balance/fee_params; a normal internal message's
fee comes from the sender's prefunded pool, no per-emit gas limit).

The py-genlayer:test Depends placeholder is unchanged.
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