Skip to content

fix(sn-manager): remove automatic EVM rollback#313

Merged
mateeullahmalik merged 2 commits into
masterfrom
fix/sn-manager-remove-evm-auto-rollback
Jul 23, 2026
Merged

fix(sn-manager): remove automatic EVM rollback#313
mateeullahmalik merged 2 commits into
masterfrom
fix/sn-manager-remove-evm-auto-rollback

Conversation

@mateeullahmalik

@mateeullahmalik mateeullahmalik commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator
 1|## Summary
 2|
 3|Remove sn-manager's automatic EVM rollback and make the EVM transition a forward-only gate:
 4|
 5|- pre-v2.6 SuperNode + EVM target + missing `evm_key_name` => block the forward install
 6|- current SuperNode >= v2.6 => allow normal update processing even when `evm_key_name` is absent
 7|- SuperNode startup remains authoritative for key readiness and now explicitly rejects active keys that are neither legacy `secp256k1` nor `eth_secp256k1`
 8|- remove the hard-coded v2.5.0 download/symlink/config rollback path
 9|- retain visibility of `rolled-back.log` files written by v2.6.1, labeled as historical
10|
11|## RCA
12|
13|`evm_key_name` is transitional state. A successful migration intentionally rewrites `supernode.key_name` to the active EVM key and clears `supernode.evm_key_name`.
14|
15|The v2.6.1 sn-manager preflight treated the missing transitional field as evidence that any current >= v2.6 node was stuck. On the next update check it automatically:
16|
17|1. installed/selected v2.5.0-testnet,
18|2. rewrote sn-manager `current_version`,
19|3. wrote restart state,
20|4. restarted against an EVM keyring.
21|
22|v2.5.x cannot decode/use that EVM key, producing the reported crash loop. The rollback decision was therefore based on an invalid invariant: **absence of a transitional input does not mean post-migration state is invalid**.
23|
24|The corrected ownership boundary is:
25|
26|- **sn-manager:** only prevents an unprepared pre-EVM binary from crossing the v2.6 boundary.
27|- **supernode startup:** validates the active key. Legacy active keys require a valid configured EVM migration key; active post-migration keys must be `eth_secp256k1`; unsupported key types fail closed before services start.
28|
29|## Behavior / invariants
30|
31|| Chain | Current SN | `evm_key_name` | Target | Result |
32||---|---:|---|---:|---|
33|| no EVM | any | any | any | allow |
34|| EVM | < v2.6 | absent | >= v2.6 | block, keep current binary |
35|| EVM | < v2.6 | present | >= v2.6 | allow; SuperNode validates key on startup |
36|| EVM | >= v2.6 | absent | any forward target | allow; SuperNode validates active key |
37|
38|Invariants:
39|
40|- sn-manager never initiates an EVM compatibility downgrade.
41|- post-migration config without `evm_key_name` is a valid steady state.
42|- unprepared pre-v2.6 nodes do not cross the EVM binary boundary.
43|- invalid active key algorithms fail before SuperNode services start.
44|
45|## Additional safety hardening
46|
47|- The active `current` symlink, not cached manager config, is authoritative for version comparisons.
48|- Every automatic path is monotonic and atomically refuses equal/older activation; explicit `sn-manager use` remains the only downgrade-capable selector.
49|- Release staging, per-version installation, SuperNode config writes, and active-symlink changes are serialized with a fixed lock order.
50|- Confirmed compatibility blocks are sticky: an inconclusive probe cannot erase a prior or concurrently published block.
51|- Release channel selection for `init`, first-start, `get`, and `check` comes from the actual configured chain; explicit init conflicts are rejected.
52|- Migration validates local secp256k1/eth_secp256k1 key material and commits post-migration config before destructive legacy-key deletion, with config restoration on deletion failure.
53|
54|## State-machine impact
55|
56|None.
57|
58|- **State keys changed:** none (chain or module state)
59|- **CheckTx / DeliverTx:** unchanged
60|- **BeginBlock / EndBlock:** unchanged
61|- **Determinism / replay:** unchanged; this is off-chain process/config behavior
62|- **Partial failure:** the forward block leaves the current binary/config in place; startup key validation fails before service initialization
63|- **Migration / upgrade handler:** none required
64|
65|Filesystem mutations removed:
66|
67|- no automatic v2.5.0 download
68|- no automatic current symlink downgrade
69|- no automatic sn-manager `current_version` downgrade
70|- no rollback-created `.needs_restart`
71|- no new `rolled-back.log`
72|
73|## Rollout constraint / remediation
74|
75|**Important:** a currently deployed old manager cannot reliably self-deliver this fix. Its old preflight can roll the SuperNode back before the manager-update branch executes; after rollback, the old forward gate can block the combined update.
76|
77|Affected nodes therefore need a one-time **out-of-band sn-manager replacement** (package/install script/config-management/manual binary swap), then:
78|
79|1. ensure the EVM-capable SuperNode release is installed/selected,
80|2. verify `supernode.key_name` points to an `eth_secp256k1` key,
81|3. keep `evm_key_name` absent after completed migration,
82|4. restart and verify `EVM module detected`, gateway/service startup, and epoch report submission,
83|5. do not restore v2.5.x against the EVM keyring.
84|
85|For nodes not yet migrated, configure a valid EVM key in `evm_key_name` before crossing v2.6.
86|
87|## Risk
88|
89|- A current >= v2.6 node missing `evm_key_name` is no longer downgraded by sn-manager. If its active key is legacy or unsupported, SuperNode startup fails closed with an actionable error instead.
90|- Existing historical rollback markers remain on disk; status now labels them historical to avoid presenting them as a current action.
91|- The one-time rollout deadlock above requires explicit operator handling.
92|
93|## Rollback strategy
94|
95|- Before release: revert this commit.
96|- After any EVM migration: **do not deploy the old manager or v2.5 SuperNode as an operational rollback**; that reintroduces the crash-loop condition. Roll back operationally by pinning the current EVM-capable binaries and disabling auto-update while investigating.
97|- No chain rollback or state restoration is involved.
98|
99|## Observability

100|
101|- Existing update-blocked.log and sn-manager status visibility remain for unprepared pre-v2.6 nodes.
102|- Historical v2.6.1 rollback markers are displayed as Historical Rollback Marker (v2.6.1).
103|- SuperNode logs a startup error for legacy keys without evm_key_name and for unsupported active key types.
104|
105|## Verification
106|
107|### Automated
108|
109|- go test ./... in sn-manager
110|- go vet ./... in sn-manager
111|- go test -race ./internal/updater ./internal/utils ./internal/version in sn-manager
112|- make test-unit
113|- go vet ./... in repository root
114|- go test -v ./tests/integration/...
115|- go mod tidy produced no root or sn-manager module diff
116|- sn-manager and SuperNode release builds succeeded
117|- concurrent installation, sticky-block, stale-config, release-channel, key-validation, and config-write regression tests
118|- independent production-gate review: passed with no security or logic findings
119|
120|### Devnet
121|
122|Fresh EVM devnet with 10 validators and 10 SuperNodes using this branch:
123|
124|- all 10 SuperNodes registered and started with canonical post-migration-shaped config (key_name is EVM; evm_key_name absent)
125|- restarted SN0 from that same config; it resumed and submitted/retained epoch-report progress
126|- changed SN9 to a legacy active key with no evm_key_name; startup refused before services with the expected migration remediation error
127|- live sn-manager preflight against the running EVM chain:
128| - current v2.6.1-testnet, no evm_key_name, target v2.6.2-testnet => allow
129| - current v2.5.2-testnet, no evm_key_name, target v2.6.2-testnet => block
130|- all 10 validators returned one identical app hash at height 421
131|- all processes were stopped cleanly after evidence collection
132|
133|## Test notes
134|
135|The repository has no make lint target. Formatting, go vet, module-tidy checks, full tests, race checks for the modified manager packages, builds, and independent review were run instead.
136|

Treat evm_key_name as a transitional migration input rather than a permanent readiness marker. Already-EVM-capable supernodes now remain on the forward update path after migration removes that field; pre-v2.6 nodes without it remain blocked.\n\nRemove the v2.5.0 rollback/download/config mutation path, preserve historical marker visibility, and make supernode startup explicitly reject unsupported active key types.\n\nVerified with sn-manager unit/vet/race tests, full supernode tests, integration tests, independent review, and a 10-validator/10-supernode EVM devnet restart rehearsal.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes sn-manager’s automatic EVM rollback behavior and makes the EVM transition a forward-only update gate, while shifting key-type correctness enforcement to SuperNode startup/migration validation.

Changes:

  • Remove the auto-rollback-to-v2.5.0 path and associated rollback marker creation; retain historical visibility of rolled-back.log.
  • Update EVM preflight logic to only block forward installs for pre-v2.6 nodes missing evm_key_name, and to allow normal updates for already EVM-capable nodes.
  • Tighten SuperNode key validation to explicitly reject unsupported active key types (not legacy secp256k1 and not eth_secp256k1), with new unit coverage.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
supernode/cmd/evmigration.go Rejects unsupported active key algorithms during migration/startup validation.
supernode/cmd/evmigration_test.go Adds a test ensuring unsupported active key types are rejected.
sn-manager/internal/utils/chain_id.go Updates comments to reflect removal of rollback readers and the forward-only preflight purpose.
sn-manager/internal/updater/updater.go Removes the rollback execution branch from the auto-update loop and updates preflight documentation.
sn-manager/internal/updater/rollback.go Deletes the hard-coded rollback implementation and its download/symlink/config mutation path.
sn-manager/internal/updater/rollback_test.go Removes rollback unit tests corresponding to deleted rollback behavior.
sn-manager/internal/updater/preflight.go Removes rollback decision and updates predicate to allow already EVM-capable nodes with missing transitional config.
sn-manager/internal/updater/preflight_test.go Updates decision table to reflect forward-only gating behavior.
sn-manager/internal/updater/preflight_state.go Extracts/retains block-marker and historical rollback-marker path helpers + block marker state handling.
sn-manager/internal/updater/preflight_state_test.go Adds tests for the extracted block marker state handling.
sn-manager/cmd/status.go Updates status output to label rolled-back.log as a historical marker (v2.6.1).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sn-manager/internal/updater/preflight.go
Prevent automatic downgrades and stale-config activation across the EVM migration boundary. Serialize config and binary mutations, preserve confirmed compatibility blocks, select release channels from the configured chain, and validate migration key material before destructive cleanup.

Add regression, race, CI, and operator recovery coverage.
@mateeullahmalik
mateeullahmalik merged commit d8a2787 into master Jul 23, 2026
13 checks passed
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.

4 participants