feat(upgrade): v1.6.3 rescue migration, evm hardening (v0.6.0-tac.15) - #94
Merged
Merged
Conversation
Ships the hardening deferred from v1.6.2: bech32 address-length guard, atomic StateDB.Commit, precompile out-of-gas semantics (#1049) and the feemarket EndBlock clamp (#1259).
Repays the old OFT escrow to the 19 in-flight-message recipients, funds the new OFT, redirects the six compromised validators' self-unbonding stake to a TAC-controlled account, and undelegates every remaining delegation on those validators back to its own owner. The handler never returns an error. x/upgrade turns a handler error into a panic in PreBlocker, so an abort would halt the chain — and since this code is public and the accounts it touches are adversary-controlled, any exact-match guard would be a halt trigger costing one utac. Every task and item is isolated in a CacheContext, panics are recovered, balance checks are sufficiency tests, and expected totals are logged rather than asserted. Task B sweeps the compromised accounts instead of a fixed record list, so it still works if the stake was moved beforehand, and uses Unbond plus SetUnbondingDelegationEntry because Undelegate can only write the entry under the delegator. Task C, handling third-party funds, uses the stock Undelegate and skips on error. Gated on chain-id tacchain_239-1.
rekeyUBD is the only hand-written state surgery in the migration, and its
worst failure is silent: if the {dest, validator} pair never lands in the
completion-time queue slice, DequeueAllMatureUBDQueue never yields it,
CompleteUnbonding is never called, and the stake stays locked in
not_bonded_tokens_pool forever. Nothing surfaces the problem either — the
staking EndBlocker swallows a CompleteUnbonding error with `continue`.
Each test therefore drains the mature queue and asserts the payout would
actually fire, and fire only for the destination. Covered: a single entry,
TOE 6's two-entries-two-times shape, two entries sharing one completion
time, unrelated pairs in the same slice, merging into a record the
destination already holds, and re-keying to the current owner.
Validated by mutation: dropping the queue insert, leaving the UnbondingId
index dangling, overwriting instead of merging, fixing only the first
completion time, and discarding unrelated queue pairs are each caught.
Narrows rekeyUBD to a staking keeper plus an address codec so it can be
driven without a full app.
Rehearsed against a mainnet snapshot at height 25,017,373 through the real two-binary path, and repeated in a second process to check determinism.
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.
Mainnet upgrade planned for Monday 2026-09-14, 10:00 UTC. Must land before 2026-09-23 15:35 UTC, when the compromised validators' self-unbonding matures.
Ships a rescue migration (
app/upgrades/v1.6.3/, gated on chain-idtacchain_239-1): repays the 19 in-flight-message recipients from the old OFT escrow, funds the new OFT from the Foundation multisig, rescues the compromised validators' self-unbonding stake to a TAC-controlled account with completion times unchanged, and undelegates all 995 delegations on those validators back to their own owners. Pluscosmos/evm→v0.6.0-tac.15.