You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(core,cmd,eth,docs): handle chain config mismatch by cli flag
Replace unconditional rewind-on-mismatch with an explicit chain-config mismatch policy exposed via --chain-config-mismatch-policy and ethconfig.Config.ChainConfigMismatchPolicy.
Supported policies:
- exit (default): fail fast without mutating the database.
- rewind-and-update: rewind to compatErr.RewindTo and persist the resolved config.
- update-config-only: persist the resolved config without rewinding.
- ignore-mismatch: keep the in-memory config and skip database writes.
Writable opens preserve the selected recovery mode, while readonly opens reject policies that would require rewinds or writes. The CLI resolves the policy from config or flag, threads it through MakeChain, and documents the new operator-facing startup behavior.
assertCommandFailsWithChainConfigError(t, exportCmd, "Can't open blockchain in readonly mode: the local chain configuration requires rewind. Use the correct --networkid/--datadir combination, or reopen the database in writable mode so the chain can rewind, then retry.")
863
+
assertCommandFailsWithChainConfigErrors(
864
+
t,
865
+
exportCmd,
866
+
"Can't open blockchain: mismatching",
867
+
cmdutils.ChainConfigMismatchPolicyExitHint,
868
+
)
859
869
if_, err:=os.Stat(exportFile); err==nil {
860
870
t.Fatalf("expected export to fail without creating %s", exportFile)
assertCommandFailsWithChainConfigError(t, exportCmd, "Can't open blockchain in readonly mode: the local chain configuration requires rewind. Use the correct --networkid/--datadir combination, or reopen the database in writable mode so the chain can rewind, then retry.")
942
+
assertCommandFailsWithChainConfigErrors(
943
+
t,
944
+
exportCmd,
945
+
"Can't open blockchain: mismatching",
946
+
cmdutils.ChainConfigMismatchPolicyExitHint,
947
+
)
933
948
if_, err:=os.Stat(exportFile); err==nil {
934
949
t.Fatalf("expected export to fail without creating %s", exportFile)
Copy file name to clipboardExpand all lines: cmd/utils/cmd.go
+18Lines changed: 18 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -43,6 +43,8 @@ import (
43
43
44
44
const (
45
45
importBatchSize=2500
46
+
47
+
ChainConfigMismatchPolicyExitHint="Hint: Use --chain-config-mismatch-policy to recover; Or restart with a matching XDC binary and the same network/genesis settings."
46
48
)
47
49
48
50
// Fatalf formats a message to standard error and exits the program.
Copy file name to clipboardExpand all lines: cmd/utils/flags.go
+45-10Lines changed: 45 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -131,6 +131,12 @@ var (
131
131
Usage: "Allow same-hash custom overrides on built-in IDs to use custom chain config",
132
132
Category: flags.EthCategory,
133
133
}
134
+
ChainConfigMismatchPolicyFlag=&cli.StringFlag{
135
+
Name: "chain-config-mismatch-policy",
136
+
Usage: "Startup policy when chain config mismatches stored config: exit|rewind-and-update|update-config-only|ignore-mismatch (warning: update-config-only/ignore-mismatch may cause state/consensus divergence; expert use only)",
return"Can't open blockchain in readonly mode: genesis state is missing and requires recovery. Reopen the database in writable mode to recover the missing genesis state, then retry."
return"Can't open blockchain in readonly mode: head state is missing and requires repair. Reopen the database in writable mode to repair the missing head state, then retry."
return"Can't open blockchain in readonly mode: the local chain contains a denylisted hash and requires rewind. Reopen the database in writable mode so the chain can rewind past the denylisted hash, then retry."
1859
1868
caseerrors.Is(err, core.ErrReadOnlyConfigRewind):
1860
-
return"Can't open blockchain in readonly mode: the local chain configuration requires rewind. Use the correct --networkid/--datadir combination, or reopen the database in writable mode so the chain can rewind, then retry."
1869
+
return"Can't open blockchain in readonly mode: the selected chain-config mismatch policy requires rewind. Reopen in writable mode, or use --chain-config-mismatch-policy=ignore-mismatch to avoid rewind in readonly mode."
1870
+
caseerrors.Is(err, core.ErrReadOnlyConfigUpdate):
1871
+
return"Can't open blockchain in readonly mode: the selected chain-config mismatch policy requires writing chain config. Reopen in writable mode, or use --chain-config-mismatch-policy=ignore-mismatch in readonly mode."
t.Fatalf("expected sentinel panic, have %v", recovered)
336
339
}
337
-
want:="Can't open blockchain in readonly mode: the local chain configuration requires rewind. Use the correct --networkid/--datadir combination, or reopen the database in writable mode so the chain can rewind, then retry."
340
+
want:="Can't open blockchain in readonly mode: the selected chain-config mismatch policy requires rewind. Reopen in writable mode, or use --chain-config-mismatch-policy=ignore-mismatch to avoid rewind in readonly mode."
338
341
ifgot!=want {
339
342
t.Fatalf("unexpected fatal message: have %q want %q", got, want)
340
343
}
341
344
}()
342
345
343
-
MakeChain(ctx, stack, true)
346
+
MakeChain(ctx, stack, true, "")
344
347
t.Fatal("expected MakeChain to terminate via fatal hook")
want: "Can't open blockchain in readonly mode: the local chain configuration requires rewind. Use the correct --networkid/--datadir combination, or reopen the database in writable mode so the chain can rewind, then retry.",
377
+
want: "Can't open blockchain in readonly mode: the selected chain-config mismatch policy requires rewind. Reopen in writable mode, or use --chain-config-mismatch-policy=ignore-mismatch to avoid rewind in readonly mode.",
378
+
},
379
+
{
380
+
name: "config update",
381
+
err: core.ErrReadOnlyConfigUpdate,
382
+
want: "Can't open blockchain in readonly mode: the selected chain-config mismatch policy requires writing chain config. Reopen in writable mode, or use --chain-config-mismatch-policy=ignore-mismatch in readonly mode.",
383
+
},
384
+
{
385
+
name: "config exit",
386
+
err: core.ErrConfigMismatchPolicyExit,
387
+
want: "Can't open blockchain: "+ChainConfigMismatchPolicyExitHint,
0 commit comments