feat: add read-state upgrade handler - #311
Merged
Merged
Conversation
x/vm sets the coin info in its own PreBlock, but x/upgrade's PreBlocker runs first, so any upgrade handler touching EVM state hits a nil global and halts the chain. Upstream provides this fallback; nothing was populating it.
GetAccount reads the balance, which resolves the EVM coin denom. A code check has no business loading balances, and it panics when run from an upgrade.
Adds the x/ucallback store and reserves every system-contract address still unclaimed in the A/B/C ranges — 41 of 47 on donut, including 0xC2, which x/ucallback needs before it can ingest anything.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Upgrade handler for the
x/ucallbackread-state module that landed in #310.What it does
ucallbackstore. New module, soStoreUpgrades.Addedis required —RunMigrationsregisters the consensus version but cannot create a store the multistore was never told about, and the node fails to load at the upgrade height without it.SYSTEM_CONTRACTSis 47 entries, not 7 —constants.go'sinit()fills the 0xA0-0xAF / 0xB0-0xBF / 0xC0-0xCF ranges with a full proxy+admin+impl triple each. The genesis loop only runs at InitGenesis, so slots added after a chain launched were never reserved on it. Checked against live donut: 41 of the 47 are bare, includingUNIVERSAL_CALLBACK(0x…C2), which x/ucallback needs before it can ingest anything. The other 6 are skipped by the already-deployed guard.Two fixes it depends on
Both are chain halts found by running the upgrade locally, not by tests.
5f1607ab— EVM coin-info fallback. x/vm sets the coin-info global in its ownPreBlock, butx/upgrade's PreBlocker runs first. Any handler touching EVM state resolves the coin denom through a still-nil global and the node dies mid-upgrade. Upstream provides a fallback for exactly this window; nothing here was populating it. Split by build tag — under-tags=testthat setter writes the coin info rather than a fallback and collides withvm.InitGenesis.4af77abc— code-hash check.isContractDeployedwent throughGetAccount, which loads the balance and hits the same global. Now reads the code-hash store directly. Same semantics, same F-2026-17025 sentinel guard.FixReservedBytecodesurvived on donut only because it writes code without ever reading an account.Verification
Local cosmovisor simulation,
release/v1.1.39-donut→ this branch, passed first attempt:To reproduce donut's state the OLD binary was built with auto-reservation disabled — the release branch already reserves all 47 at genesis, so a stock fresh chain cannot reproduce the gap.
Plan name must be exactly
read-state.