Skip to content

Release gate: v0.19-dev → v0.19 (waits for cross-repo E2E) - #91

Open
MuncleUscles wants to merge 15 commits into
v0.19from
v0.19-dev
Open

Release gate: v0.19-dev → v0.19 (waits for cross-repo E2E)#91
MuncleUscles wants to merge 15 commits into
v0.19from
v0.19-dev

Conversation

@MuncleUscles

Copy link
Copy Markdown
Member

Standing release-gate PR: v0.19-devv0.19

This is a long-lived gate PR, not a normal feature PR. Do not merge ad-hoc.

Purpose

  • v0.19-dev is the active integration branch for the v0.6 fee work. Individual PRs merge into v0.19-dev and only need to pass normal repo CI — they are not blocked on the full cross-repo release train being green.
  • This PR is the single point where v0.19-dev is promoted to v0.19. It waits for cross-repo E2E (the release train) to go green before it is merged.
  • Other projects in the release train test against v0.19-dev.

How to use

  • Keep this PR open as the running view of "what would ship to v0.19".
  • Merge only when the full release-train E2E is green.

(Mirrors genlayerlabs/genlayer-consensus#1070.)

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

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: Team

Run ID: be993a5c-1f3e-42ee-8e87-404e9409a0cf

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 v0.19-dev

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.

MuncleUscles and others added 13 commits June 10, 2026 13:07
… parity with genlayer-js (#90)

* feat(fees)!: estimation correctness, wait-for-decided semantics, v0.6 parity with genlayer-js

Mirrors genlayer-js feat/v06-fee-estimation-rework (same designer rulings):
- effective receipt gas price = max(quoteGasPrice(), eth_gasPrice); zero price on
  an enabled policy raises instead of producing a zero cap; effective execution
  budget floor = max(on-chain view, price x 306,192 gas local recompute)
- simulation-derived budgets no longer clobbered by the 100M default (floor vs
  observed x headroom); default constant documented as provisional w/ TODO(data)
- wait_until='decided'|'finalized' replaces status (legacy param mapped with
  one-time DeprecationWarning); new is_successful(tx) helper
- enum completeness: status 14 LEADER_REVEALING (fixes a KeyError crash mid-poll),
  VoteType 3 TIMEOUT / 4 NONDET_DISAGREE, v0.6 ResultType remap
- DEPLOY_CALL_KEY = bytes32(1) deploy sentinel; fee revert selector naming in
  send errors (InsufficientFees/MaxPriceExceeded/ExecutionBudgetExceeded/
  BudgetTooLow/RollupBudgetBelowFloor/FeeValueMustBeNonZero)

py-specific parity fixes:
- asimov chain config gains FeeManager/RoundsStorage/Appeals addresses (parity
  with js testnetAsimov)
- Studio floor-fallback formula unified with js (message-reveal leg included)
- appeal_transaction/top_up_and_submit_appeal auto-resolve the minimum bond when
  value is omitted (previously defaulted to 0 = guaranteed on-chain revert);
  top_up_fees now requires value

* ci: run tests on pushes to dev branches

tests.yml had no push trigger at all — merges to v0.19-dev got zero
post-merge CI.
…y key = bytes32(0) (#93)

The wildcard sentinel previously shared bytes32(0) with GenVM's natural
empty-method-name key (deploy, emit_transfer), making deploy-specific
Mode-2 allocations impossible. Per cross-team decision, the wildcard
moves to the untagged keccak256 of empty bytes
(0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470),
which is provably outside the derived-key space. DEPLOY_CALL_KEY drops
the bytes32(1) sentinel (GenVM ask withdrawn) and now equals
CALL_KEY_UNNAMED = bytes32(0), matching what GenVM actually emits.

Must land together with the consensus CALL_KEY_WILDCARD constant and the
node Mode-2 tree decode change in v0.6.
Admin merged after required repo CI passed; optional E2E app check is queued/non-blocking for dev-branch PRs.
* feat(vesting): add vesting staking actions

* feat(vesting): validator-leg actions (join/deposit/exit/claim, operator transfer, identity, wallet reads)

Mirrors the genlayer-js validator actions for the CON-607 Vesting.sol
surface: vesting_validator_join/deposit/exit/claim, operator-transfer
initiate/complete/cancel, set_identity (extra_cid str/hex handling as
in js), and get_validator_wallets/validator_wallet_count/
validator_deposited/is_validator_wallet reads.
…BI) (#96)

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

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.

* test(e2e): migrate contract fixtures to genvm v0.3 SDK API

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.

---------

Co-authored-by: kp2pml30 <kp2pml30@gmail.com>
* test: add v0.19 bug hunt regressions

* fix: resolve v0.19 bug hunt regressions
CON-715 removed ValidatorWalletBlueprint.setOperator in favour of
initiateOperatorTransfer + completeOperatorTransfer. Against a consensus
deployment carrying that change, set_operator fails with
ABIFunctionNotFound: the function 'setOperator' was not found in this
contract's abi.

Adds the two calls plus cancel_operator_transfer and the get_pending_operator
view, and keeps set_operator for deployments that still expose it.

This SDK had no proof-of-possession support at all, so the encoding is new
here: genlayer_py.staking.operator_registration mirrors genlayer-js's
createOperatorRegistration — keccak over abi.encode(domain, chainId, registrar,
owner, pubKey[0], pubKey[1]), signed EIP-191 by the operator key. Both SDKs
sign proofs the same contract verifies, so the test pins the exact vector
genlayer-js asserts (domain hash, message hash and signature bytes) rather than
only checking internal consistency.

The registrar differs by flow and is the easy thing to get wrong: the factory
verifies a validator join, the wallet verifies a rotation. get_operator_transfer_context
builds the wallet-bound context and reads owner() from the wallet rather than
assuming the caller is the owner, and initiate_operator_transfer verifies the
proof locally so a factory-bound one fails with a clear message instead of an
opaque revert. A test pins that a join proof does not verify for a rotation.

Not addressed here: validator_join still encodes the retired validatorJoin() /
validatorJoin(address) overloads, which CON-666 replaced with
validatorJoin(uint256[2],bytes). That is the same migration and now has the
helper it needs, but it changes a public signature, so it wants its own change.

Verified: pytest tests/unit — 141 passing.
…105)

* chore(genvm): update runner hashes and align v0.3 ABI names ⬆️

Bump the v0.3 runner pins to the new ids, rename the raw fee-params
aliases leader/validator_timeunits_allocation to
leader/validator_time_units_allocation, and keep the wait_until rename
of accepted to decided.

* fix(genvm): give VecDB its explicit distance metric 🐛

The pinned embeddings runner's `VecDB` takes the distance metric as a fourth
type parameter. Three arguments now fail at contract import, which leaves the
deploy without state rather than reporting a type error.

`log_indexer_testnet.py` is deliberately left alone: it targets Asimov, which
runs the older SDK.
* fix: read the consensus surfaces the resolution-kernel train exposes

The train withdraws reads this SDK is built on, and none of them fail in a
way a caller would notice:

  - getTransactionData(txId, timestamp) is gone. It answered with a status
    PROJECTED at a caller-supplied clock; the chain now keeps the stored
    record and the projection apart, behind getStoredTransactionData(txId)
    and getTransactionLifecycle. This is what the py lane traceback rooted
    at, and it is a hard failure -- web3 cannot find the function.
  - activeValidators() and activeValidatorsCount() are gone. Committee
    capacity is 1,543 seats and an address[] that long overruns the
    return-size limit, so the joined registry is only readable in slices.
  - validatorView() dropped its left/right/parent tree links, so the tuple
    went from twelve fields to nine.
  - ReadyToFinalize was removed from TransactionStatus at ordinal 11 and
    the three above it shifted down. Left alone, a ValidatorsTimeout
    transaction decoded as READY_TO_FINALIZE -- no error, the wrong answer.
  - previousStatus was dropped from the Transaction struct that
    getTransactionAllData returns, so status sits at index 2 and the rest
    moved up one slot.

The transaction read now detects rather than assumes: chains are upgraded
independently, so it picks whichever of the two reads the chain's own ABI
offers. Both return the same 23-field struct -- only field [0] was renamed
currentTimestamp to observedAt -- so the positional decode is untouched.

active_validators() pages the joined registry: validatorsJoinedCount()
bounds the walk and getValidatorsJoined(start, size) returns each page. The
count is read first so a registry that grows underneath the walk cannot
spin the loop, and a short page means it shrank instead. Page size is 64,
matching genlayer-node's walk over the same registry.

TransactionStatus keeps its READY_TO_FINALIZE member, because the node
still reports that state. What changed is that no chain value decodes to
it, so the name-to-number map no longer carries an ordinal for it: 11
belongs to VALIDATORS_TIMEOUT now, and there is no free number that would
not collide.

* fix: align Python SDK with train contracts

* fix: keep studio appeals on the pre-train call shape

The train adaptation routed every appeal action through the resolution-kernel
lifecycle reads. Studio chains (localnet and studionet, which share chain id
61999) run the studio-embedded consensus, which predates the train: its
ConsensusData exposes neither getTransactionLifecycle nor
estimateLatestAppealCharge, and its ConsensusMain, refetched from the simulator
RPC, still declares submitAppeal(bytes32). The decision-guarded encoding
therefore aborted with "value has 2 items when 1 were expected" before the call
was ever sent.

The sibling genlayer-js defect failed the studio suites of e2e run 33112369501.
This mirrors its fix, genlayer-js 04a0bde: guard each affected action on the
studio chain check that transactions.actions.get_transaction already uses, and
reinstate the pre-train behaviour recovered from the v0.19-dev base.

- appeal_transaction encodes submitAppeal(bytes32) against the chain's own
  ConsensusMain ABI.
- top_up_and_submit_appeal encodes
  topUpAndSubmitAppeal(bytes32, FeesDistribution) without a decision id.
- get_appeal_quote, get_appeal_charge and get_min_appeal_bond report the missing
  quote surface with the error the base already raised on studio.
- Both appeal writes keep the base value semantics: the pre-train resolver read
  the bond through FeeManager/RoundsStorage, which studio chains never
  configure, so an omitted value raises the base message verbatim. A call that
  binds to no decision cannot honour a decision guard, so expected_decision_id
  is refused there.

can_appeal and the rounds-storage reads already returned their base error on
studio: their missing-contract guards run before any train read, so they are
left alone. This SDK has no finalizeTransaction, resolveTransactions or
finalizeDecisions surface to adapt.

The train path is unchanged for non-studio chains. The appeal tests that pin it
now build a train chain client, since the shared helper defaulted to the studio
chain id.

* feat(transactions)!: layer consumer and protocol lifecycles

Expose materialized transaction progress as a small state-discriminated lifecycle, make receipt waits target stored decisions or finalization, and keep projection/action/source/decision identity in the explicit advanced read.\n\nRemove the old public status compatibility surface and normalize advanced protocol names, decimal decision IDs, and evaluation timestamps across local and contract-backed networks.\n\nValidation: 189 offline unit tests with 13 old-deployment tests excluded; 12 Asimov smoke tests; focused lifecycle tests; E2E collection; docs; Black; build and installed-wheel smoke.

* fix(appeals): support Studio decision-bound lifecycle

* ci: skip pre-train smoke on v0.19 PRs

* fix(studio): decouple native appeal and lifecycle reads

* fix(fees): fund default consensus rotations

---------

Co-authored-by: Edgars <edgars@genlayerlabs.com>
* fix(fees): mirror consensus deposit quote

* fix(studio): bind appeal actions to decisions

Use Studio's authoritative appeal quote for omitted payment and decision inputs, encode the v0.6 decision-bound selectors, and expose matching can-appeal behavior without attempting EVM contract reads.

* fix(fees): encode internal message price caps

* fix(studio): surface mined envelope reverts

* fix(fees): encode schedule-free topups

* fix(appeals): admit unfunded rounds safely

Route the public appeal action through topUpAndSubmitAppeal, whose consensus-derived schedule extension accepts both pre-funded and unfunded rounds. Preserve direct submitAppeal encoding only as a low-level conformance surface.\n\nCover the exact selector, decision binding, compatibility tuple, quoted value, and caller-provided value on deployed Consensus and Studio.
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.

3 participants