params/extras: relaunch-safety test + regenerate canonical upgrade fixtures

Round-2 follow-up to the luxfi/genesis upgrade.json reschedule fix (17
live-at-genesis precompiles pinned to blockTimestamp 0; warp two-step
strict-PQ toggle moved after the zero-timestamp block; dead dexConfig
0x9010 dropped).

- relaunch_safety_test.go (new): drives the node's REAL fork-application
  primitive extras.IsForkTransition (parent=nil reduces to fork <=
  genesisTime, exactly what GetActivatingPrecompileConfigs evaluates when
  a relaunched node builds its first rule set) against the embedded
  canonical fixtures. Asserts the invariant: every precompile that
  activates at/under the C-Chain genesis time (mainnet 1730446786 /
  testnet 1730517266) is in the live-at-block-0 set AND pinned to exactly
  0; every other entry is strictly future; and all 17 live precompiles are
  present (no relaunch divergence). No entry sits in the (0, genesisTime]
  retroactive-reschedule window.

- mainnet_upgrade_v46.json / testnet_upgrade_v47.json: regenerated
  byte-for-byte from the corrected canonical genesis configs (46 / 44
  entries; the 25 timestamp diffs were the 1766708400 -> 0 normalization
  plus the warp reorder).

- precompile_upgrade_rollout_test.go: WarpRequiresPrimaryNetworkSigners
  updated for the two-step toggle — warp is declared in the genesis
  chainConfig, and the schedule carries disable@strictPQ-1 then
  re-enable@strictPQ; the PQ signer-policy assertion targets the re-enable
  entry, and same-key strict-increase is enforced (mirrors
  verifyPrecompileUpgrades).

- upgrade_unmarshal_test.go / testnet_upgrade_unmarshal_test.go: fixture
  doc comments rewritten to the live-at-0 / strict-PQ-toggle / BLS /
  Quasar-Edition tier layout; RegressionProof entry-count assertion 45 ->
  46 to match the embedded fixture.

Verified: go vet clean; CGO_ENABLED=0 go test ./params/extras/...
./params/extras_e2e_test/... — RelaunchSafe (mainnet+testnet),
IsForwardCompatibleWithLiveActivations, WarpRequiresPrimaryNetworkSigners,
PrecompileTimestampsAreMonotonic, RegressionProof all PASS.
This commit is contained in:
2026-06-21 22:22:38 -07:00
parent 003067d76b
commit be0beda21b
6 changed files with 505 additions and 109 deletions
@@ -125,11 +125,24 @@ func TestMainnetUpgradeJSON_PrecompileTimestampsAreMonotonic(t *testing.T) {
}
// TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners enforces the
// Warp policy from red-review finding #8: the live mainnet warp config
// pins requirePrimaryNetworkSigners=true, and the canonical upgrade.json
// MUST keep it that way so every cross-chain warp message is signed by
// primary-network validators (not just a subnet quorum).
// Warp policy from red-review finding #8: the canonical upgrade.json must
// schedule warp so that, once the strict-PQ fork lands, every cross-chain
// warp message is signed by primary-network validators (not just a subnet
// quorum).
//
// Warp lives in the genesis chainConfig (cchain.json config.warpConfig at
// the genesis timestamp, with requirePrimaryNetworkSigners=false during the
// classical era). The upgrade schedule then carries a two-step toggle at the
// strict-PQ fork: disable@strictPQ-1, then re-enable@strictPQ with the
// PQ-hardened policy. Both toggles are strictly AFTER genesis time, so this
// is a genuine future upgrade — NOT a reschedule of the genesis warp (that
// would be the relaunch fork hazard; see relaunch_safety_test.go). The
// policy assertion therefore targets the RE-ENABLE entry (the one that
// carries quorumNumerator + requirePrimaryNetworkSigners); the disable entry
// carries only {blockTimestamp, disable:true}.
func TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners(t *testing.T) {
const strictPQ uint64 = 1766708400
raw := readCanonicalMainnetUpgradeJSONRaw(t)
var doc struct {
@@ -137,26 +150,62 @@ func TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners(t *testing.T) {
}
require.NoError(t, json.Unmarshal(raw, &doc))
var found bool
for _, entry := range doc.PrecompileUpgrades {
var (
foundDisable bool
foundReEnable bool
prevWarpTs *uint64
)
for i, entry := range doc.PrecompileUpgrades {
warpRaw, ok := entry["warpConfig"]
if !ok {
continue
}
found = true
var warp struct {
BlockTimestamp uint64 `json:"blockTimestamp"`
Disable bool `json:"disable"`
QuorumNumerator uint64 `json:"quorumNumerator"`
RequirePrimaryNetworkSigners bool `json:"requirePrimaryNetworkSigners"`
}
require.NoError(t, json.Unmarshal(warpRaw, &warp))
require.Equal(t, uint64(0), warp.BlockTimestamp, "warpConfig blockTimestamp must be 0")
// Every warp upgrade entry must be strictly after genesis time —
// rescheduling the genesis warp into the (0, genesisTime] window is
// the relaunch fork hazard.
require.Greaterf(t, warp.BlockTimestamp, uint64(0),
"warpConfig upgrade entry at index %d has blockTimestamp 0 — warp is declared in the genesis chainConfig; an upgrade entry pinned to 0 would collide with the genesis warp and fail verifyPrecompileUpgrades",
i,
)
// Same-key strict increase (mirrors verifyPrecompileUpgrades).
if prevWarpTs != nil {
require.Greaterf(t, warp.BlockTimestamp, *prevWarpTs,
"warpConfig entries must strictly increase in blockTimestamp (got %d after %d)",
warp.BlockTimestamp, *prevWarpTs,
)
}
ts := warp.BlockTimestamp
prevWarpTs = &ts
if warp.Disable {
foundDisable = true
require.Equalf(t, strictPQ-1, warp.BlockTimestamp,
"warpConfig disable must fire one second before the strict-PQ fork (%d), got %d",
strictPQ-1, warp.BlockTimestamp,
)
continue
}
// Re-enable entry: carries the PQ-hardened policy.
foundReEnable = true
require.Equalf(t, strictPQ, warp.BlockTimestamp,
"warpConfig re-enable must fire at the strict-PQ fork (%d), got %d", strictPQ, warp.BlockTimestamp,
)
require.Equal(t, uint64(67), warp.QuorumNumerator, "warpConfig quorumNumerator must be 67")
require.Truef(t, warp.RequirePrimaryNetworkSigners,
"warpConfig.requirePrimaryNetworkSigners must be true on lux-mainnet — every cross-chain warp message MUST be signed by primary-network validators (red-review finding #8)",
)
}
require.True(t, found, "warpConfig must be present in canonical upgrade.json")
require.True(t, foundDisable, "warpConfig disable entry must be present in canonical upgrade.json")
require.True(t, foundReEnable, "warpConfig re-enable entry (with PQ signer policy) must be present in canonical upgrade.json")
}
// TestMainnetUpgradeJSON_HasStrictPQActivation enforces that the
+237 -53
View File
@@ -8,59 +8,243 @@
"strictPQTimestamp": 1766708400
},
"precompileUpgrades": [
{"warpConfig": {"blockTimestamp": 0, "quorumNumerator": 67, "requirePrimaryNetworkSigners": true}},
{"aiMiningConfig": {"blockTimestamp": 0}},
{"blake3Config": {"blockTimestamp": 0}},
{"cggmp21Verify": {"blockTimestamp": 0}},
{"deadZeroConfig": {"blockTimestamp": 0}},
{"deadConfig": {"blockTimestamp": 0}},
{"deadFullConfig": {"blockTimestamp": 0}},
{"routerConfig": {
"blockTimestamp": 0,
"v3QuoterAddress": "0x0000000000000000000000000000000000000000",
"v3FactoryAddress": "0x0000000000000000000000000000000000000000",
"v2RouterAddress": "0x0000000000000000000000000000000000000000",
"v2FactoryAddress": "0x0000000000000000000000000000000000000000"
}},
{"fheConfig": {"blockTimestamp": 0}},
{"frostVerify": {"blockTimestamp": 0}},
{"graphConfig": {"blockTimestamp": 0}},
{"hpkeConfig": {"blockTimestamp": 0}},
{"mldsaVerify": {"blockTimestamp": 0}},
{"mlkemConfig": {"blockTimestamp": 0}},
{"pqcryptoConfig": {"blockTimestamp": 0}},
{"ringConfig": {"blockTimestamp": 0}},
{"slhdsaVerify": {"blockTimestamp": 0}},
{"zkConfig": {"blockTimestamp": 0}},
{"pulsarVerify": {"blockTimestamp": 1782864000}},
{"magnetarVerify": {"blockTimestamp": 1782864000}},
{"p3qVerify": {"blockTimestamp": 1782864000}},
{"coronaThreshold": {"blockTimestamp": 1782864000}},
{"hqcEncapsulate": {"blockTimestamp": 1782864000}},
{"bls12381G1AddConfig": {"blockTimestamp": 1782864000}},
{"bls12381G1MulConfig": {"blockTimestamp": 1782864000}},
{"bls12381G1MSMConfig": {"blockTimestamp": 1782864000}},
{"bls12381G2AddConfig": {"blockTimestamp": 1782864000}},
{"bls12381G2MulConfig": {"blockTimestamp": 1782864000}},
{"bls12381G2MSMConfig": {"blockTimestamp": 1782864000}},
{"bls12381PairingConfig": {"blockTimestamp": 1782864000}},
{"curve25519Config": {"blockTimestamp": 1782864000}},
{"x25519Config": {"blockTimestamp": 1782864000}},
{"sr25519Verify": {"blockTimestamp": 1782864000}},
{"babyjubjubConfig": {"blockTimestamp": 1782864000}},
{"pedersenConfig": {"blockTimestamp": 1782864000}},
{"poseidonConfig": {"blockTimestamp": 1782864000}},
{"pastaConfig": {"blockTimestamp": 1782864000}},
{"xwingConfig": {"blockTimestamp": 1782864000}},
{"computeMarketConfig": {"blockTimestamp": 1782864000}},
{"bridgeRegistrarConfig": {"blockTimestamp": 1782864000}},
{"stableSwapConfig": {"blockTimestamp": 1782864000}},
{"vrfConfig": {"blockTimestamp": 1782864000}},
{"attestationConfig": {"blockTimestamp": 1782864000}},
{"anchorConfig": {"blockTimestamp": 1782864000}},
{"fixedPointMathConfig": {"blockTimestamp": 1782864000}}
{
"aiMiningConfig": {
"blockTimestamp": 0
}
},
{
"blake3Config": {
"blockTimestamp": 0
}
},
{
"cggmp21Verify": {
"blockTimestamp": 0
}
},
{
"deadZeroConfig": {
"blockTimestamp": 0
}
},
{
"deadConfig": {
"blockTimestamp": 0
}
},
{
"deadFullConfig": {
"blockTimestamp": 0
}
},
{
"routerConfig": {
"blockTimestamp": 0,
"v3QuoterAddress": "0x0000000000000000000000000000000000000000",
"v3FactoryAddress": "0x0000000000000000000000000000000000000000",
"v2RouterAddress": "0x0000000000000000000000000000000000000000",
"v2FactoryAddress": "0x0000000000000000000000000000000000000000"
}
},
{
"fheConfig": {
"blockTimestamp": 0
}
},
{
"frostVerify": {
"blockTimestamp": 0
}
},
{
"graphConfig": {
"blockTimestamp": 0
}
},
{
"hpkeConfig": {
"blockTimestamp": 0
}
},
{
"mldsaVerify": {
"blockTimestamp": 0
}
},
{
"mlkemConfig": {
"blockTimestamp": 0
}
},
{
"pqcryptoConfig": {
"blockTimestamp": 0
}
},
{
"ringConfig": {
"blockTimestamp": 0
}
},
{
"slhdsaVerify": {
"blockTimestamp": 0
}
},
{
"zkConfig": {
"blockTimestamp": 0
}
},
{
"warpConfig": {
"blockTimestamp": 1766708399,
"disable": true
}
},
{
"warpConfig": {
"blockTimestamp": 1766708400,
"quorumNumerator": 67,
"requirePrimaryNetworkSigners": true
}
},
{
"bls12381G1AddConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G1MulConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G1MSMConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G2AddConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G2MulConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G2MSMConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381PairingConfig": {
"blockTimestamp": 1766708400
}
},
{
"pulsarVerify": {
"blockTimestamp": 1782864000
}
},
{
"magnetarVerify": {
"blockTimestamp": 1782864000
}
},
{
"p3qVerify": {
"blockTimestamp": 1782864000
}
},
{
"coronaThreshold": {
"blockTimestamp": 1782864000
}
},
{
"hqcEncapsulate": {
"blockTimestamp": 1782864000
}
},
{
"curve25519Config": {
"blockTimestamp": 1782864000
}
},
{
"x25519Config": {
"blockTimestamp": 1782864000
}
},
{
"sr25519Verify": {
"blockTimestamp": 1782864000
}
},
{
"babyjubjubConfig": {
"blockTimestamp": 1782864000
}
},
{
"pedersenConfig": {
"blockTimestamp": 1782864000
}
},
{
"poseidonConfig": {
"blockTimestamp": 1782864000
}
},
{
"pastaConfig": {
"blockTimestamp": 1782864000
}
},
{
"xwingConfig": {
"blockTimestamp": 1782864000
}
},
{
"computeMarketConfig": {
"blockTimestamp": 1782864000
}
},
{
"bridgeRegistrarConfig": {
"blockTimestamp": 1782864000
}
},
{
"stableSwapConfig": {
"blockTimestamp": 1782864000
}
},
{
"vrfConfig": {
"blockTimestamp": 1782864000
}
},
{
"attestationConfig": {
"blockTimestamp": 1782864000
}
},
{
"anchorConfig": {
"blockTimestamp": 1782864000
}
},
{
"fixedPointMathConfig": {
"blockTimestamp": 1782864000
}
}
],
"stateUpgrades": []
}
@@ -0,0 +1,158 @@
// Copyright (C) 2019-2026, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Relaunch-safety gate for the canonical primary-network C-Chain
// upgrade.json files.
//
// Threat addressed (Red HIGH, pre-existing): a mainnet/testnet relaunch
// from the canonical genesis must NOT re-trigger an activation that was
// already applied at block 0 on the running chain. A precompile that is
// live at genesis is a GENESIS property; only strictly-future activations
// belong in upgrade.json's precompileUpgrades schedule. Putting an
// already-live precompile at a post-genesis timestamp reschedules an
// already-applied activation, which on relaunch either (a) makes the
// relaunched node treat the precompile as INACTIVE from block 0 —
// diverging from the canonical chain where it is active at block 0
// (a consensus fork) — or (b) trips checkPrecompileCompatible
// ("missing"/"cannot retroactively enable") and refuses boot.
//
// This test drives the node's REAL fork-application primitive
// (extras.IsForkTransition, the same predicate GetActivatingPrecompileConfigs
// uses) against the embedded canonical fixtures and asserts the invariant:
//
// For the genesis -> first-block transition (parent = nil), the set of
// precompiles that activate AT genesis (blockTimestamp <= genesisTime)
// is EXACTLY the set of precompiles already live at block 0 on the
// running chain, and every other scheduled activation is strictly in
// the future (blockTimestamp > genesisTime). No entry sits in the
// (0, genesisTime] window, which is the only window that could
// retroactively re-fire an already-applied activation on relaunch.
package extras_e2e_test
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
"github.com/luxfi/evm/params/extras"
)
// cChainGenesisTime is the C-Chain (chainId 96369 mainnet / 96368 testnet)
// genesis BLOCK timestamp baked into the frozen canonical genesis. It is
// NOT the P-chain network startTime of a relaunch; the EVM genesis block
// keeps this timestamp across relaunches, so it is the boundary that
// IsForkTransition(fork, nil, genesisTime) uses to decide which precompiles
// are active at block 0.
//
// Source of truth:
//
// luxfi/genesis configs/mainnet/cchain.json -> "timestamp": "0x672485c2"
// luxfi/genesis configs/testnet/cchain.json -> "timestamp": "0x67259912"
const (
mainnetCChainGenesisTime uint64 = 0x672485c2 // 1730446786 = 2024-11-01 07:39:46 UTC
testnetCChainGenesisTime uint64 = 0x67259912 // 1730517266 = 2024-11-02 03:14:26 UTC
)
// liveAtBlockZero is the exact set of precompile config keys that the
// running mainnet AND testnet C-Chains have active at block 0. Source of
// truth: the UPGRADE_JSON heredoc in luxfi/universe
// k8s/lux-{mainnet,testnet}/luxd-startup.yaml (both carry these 17 at
// blockTimestamp:0). warpConfig is NOT in this set: it is declared in the
// genesis chainConfig itself (cchain.json config.warpConfig), not in
// upgrade.json's precompileUpgrades, so it is handled by the genesis path
// rather than the upgrade schedule.
var liveAtBlockZero = map[string]bool{
"aiMiningConfig": true,
"blake3Config": true,
"cggmp21Verify": true,
"deadZeroConfig": true,
"deadConfig": true,
"deadFullConfig": true,
"routerConfig": true,
"fheConfig": true,
"frostVerify": true,
"graphConfig": true,
"hpkeConfig": true,
"mldsaVerify": true,
"mlkemConfig": true,
"pqcryptoConfig": true,
"ringConfig": true,
"slhdsaVerify": true,
"zkConfig": true,
}
func TestMainnetUpgradeJSON_RelaunchSafe(t *testing.T) {
assertRelaunchSafe(t, readCanonicalMainnetUpgradeJSONRaw(t), mainnetCChainGenesisTime)
}
func TestTestnetUpgradeJSON_RelaunchSafe(t *testing.T) {
assertRelaunchSafe(t, readCanonicalTestnetUpgradeJSONRaw(t), testnetCChainGenesisTime)
}
// assertRelaunchSafe parses the canonical upgrade.json and proves the
// relaunch-safety invariant using the node's own IsForkTransition predicate.
func assertRelaunchSafe(t *testing.T, raw []byte, genesisTime uint64) {
t.Helper()
var cfg extras.UpgradeConfig
require.NoError(t, json.Unmarshal(raw, &cfg),
"canonical upgrade.json failed to parse — see TestMainnetUpgradeJSON_UnmarshalsAgainstRegistry")
activeAtGenesis := map[string]bool{}
for i, upg := range cfg.PrecompileUpgrades {
key := upg.Key()
ts := upg.Timestamp()
require.NotNilf(t, ts, "precompileUpgrades[%d] key=%q has nil blockTimestamp", i, key)
// The node decides "active at the genesis block" via
// IsForkTransition(fork, parent=nil, current=genesisTime). With a
// nil parent this reduces to (fork <= genesisTime). This is exactly
// what GetActivatingPrecompileConfigs(addr, nil, genesisTime, ...)
// evaluates when a relaunched node builds its first rule set.
activatesAtGenesis := extras.IsForkTransition(ts, nil, genesisTime)
if activatesAtGenesis {
// An entry that activates at/under genesis MUST be one of the
// already-live precompiles, AND it MUST be pinned to exactly 0.
// Any value in (0, genesisTime] is a reschedule of an
// already-applied activation into the retroactive window — the
// precise fork/boot-refusal hazard Red flagged.
require.Truef(t, liveAtBlockZero[key],
"RELAUNCH FORK RISK: precompileUpgrades[%d] key=%q activates at genesis "+
"(blockTimestamp=%d <= genesisTime=%d) but is NOT in the set of precompiles "+
"live at block 0 on the running chain. Either remove it (if it is genuinely "+
"future, give it blockTimestamp > %d) or, if it really is live at genesis, add "+
"it to liveAtBlockZero and pin it to 0.",
i, key, *ts, genesisTime, genesisTime)
require.Equalf(t, uint64(0), *ts,
"RELAUNCH FORK RISK: live-at-genesis precompile %q is scheduled at blockTimestamp=%d "+
"instead of 0. A non-zero timestamp <= genesisTime reschedules an already-applied "+
"activation; on relaunch the node would treat it as inactive before %d and diverge "+
"from the canonical chain (or checkPrecompileCompatible refuses boot). Pin it to 0.",
key, *ts, *ts)
activeAtGenesis[key] = true
} else {
// Strictly-future activation: must be > genesisTime. (Guaranteed
// by !activatesAtGenesis, but assert explicitly so the failure
// message is unambiguous for an operator reading the log.)
require.Greaterf(t, *ts, genesisTime,
"precompileUpgrades[%d] key=%q is treated as future but blockTimestamp=%d <= genesisTime=%d",
i, key, *ts, genesisTime)
}
}
// Completeness: every precompile known to be live at block 0 on the
// running chain MUST appear (pinned to 0) in the relaunch config.
// A missing one would make the relaunched chain LOSE a block-0
// precompile relative to the canonical chain — also a divergence.
for key := range liveAtBlockZero {
require.Truef(t, activeAtGenesis[key],
"RELAUNCH DIVERGENCE: precompile %q is live at block 0 on the running chain but is "+
"absent from (or not pinned to 0 in) the canonical relaunch upgrade.json. A relaunch "+
"would drop it from genesis state.", key)
}
}
@@ -27,11 +27,18 @@ import (
// canonicalTestnetUpgradeV47 is the byte-for-byte vendored copy of
// luxfi/genesis configs/testnet/upgrade.json at the v47 precompile-set
// freeze (warpConfig + 19 forward-dated 1766708400 net-new + 27 more
// safe-subset cryptography precompiles also at 1766708400). The
// testnet schedule front-loads all activations to the strict-PQ
// timestamp because there is no live testnet validator state to keep
// backwards-compatible against — it's the experimentation lane.
// freeze. Layout (44 entries, monotonic by blockTimestamp):
// - 17 already-live precompiles pinned to blockTimestamp:0 — these are
// active at block 0 on the running testnet (see the UPGRADE_JSON in
// luxfi/universe k8s/lux-testnet/luxd-startup.yaml). They MUST stay at
// 0 so a relaunch from genesis treats them as already-applied and
// checkPrecompileCompatible does not refuse boot.
// - 27 net-new safe-subset cryptography precompiles forward-dated to the
// strict-PQ timestamp 1766708400 (strictly after testnet genesis time
// 1730517266), so the strict-PQ gate is in force when they activate.
// Unlike mainnet there is no separate Quasar-Edition tier — testnet
// front-loads its net-new activations to the strict-PQ fork because it's
// the experimentation lane.
//
// Sync contract: if luxfi/genesis configs/testnet/upgrade.json changes,
// regenerate this file:
+17 -33
View File
@@ -8,45 +8,29 @@
"strictPQTimestamp": 1766708400
},
"precompileUpgrades": [
{"warpConfig": {"blockTimestamp": 0, "quorumNumerator": 67, "requirePrimaryNetworkSigners": true}},
{"aiMiningConfig": {"blockTimestamp": 1766708400}},
{"blake3Config": {"blockTimestamp": 1766708400}},
{"cggmp21Verify": {"blockTimestamp": 1766708400}},
{"deadZeroConfig": {"blockTimestamp": 1766708400}},
{"deadConfig": {"blockTimestamp": 1766708400}},
{"deadFullConfig": {"blockTimestamp": 1766708400}},
{"aiMiningConfig": {"blockTimestamp": 0}},
{"blake3Config": {"blockTimestamp": 0}},
{"cggmp21Verify": {"blockTimestamp": 0}},
{"deadZeroConfig": {"blockTimestamp": 0}},
{"deadConfig": {"blockTimestamp": 0}},
{"deadFullConfig": {"blockTimestamp": 0}},
{"routerConfig": {
"blockTimestamp": 1766708400,
"blockTimestamp": 0,
"v3QuoterAddress": "0x0000000000000000000000000000000000000000",
"v3FactoryAddress": "0x0000000000000000000000000000000000000000",
"v2RouterAddress": "0x0000000000000000000000000000000000000000",
"v2FactoryAddress": "0x0000000000000000000000000000000000000000"
}},
{"fheConfig": {"blockTimestamp": 1766708400}},
{"frostVerify": {"blockTimestamp": 1766708400}},
{"graphConfig": {"blockTimestamp": 1766708400}},
{"hpkeConfig": {"blockTimestamp": 1766708400}},
{"mldsaVerify": {"blockTimestamp": 1766708400}},
{"mlkemConfig": {"blockTimestamp": 1766708400}},
{"pqcryptoConfig": {"blockTimestamp": 1766708400}},
{"ringConfig": {"blockTimestamp": 1766708400}},
{"slhdsaVerify": {"blockTimestamp": 1766708400}},
{"zkConfig": {"blockTimestamp": 1766708400}},
{"feeManagerConfig": {
"blockTimestamp": 900000000,
"adminAddresses": ["0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"],
"enabledAddresses": [],
"initialFeeConfig": {
"gasLimit": 20000000,
"minBaseFee": 25000000000,
"targetGas": 15000000,
"baseFeeChangeDenominator": 36,
"minBlockGasCost": 0,
"maxBlockGasCost": 10000000,
"targetBlockRate": 2,
"blockGasCostStep": 500000
}
}},
{"fheConfig": {"blockTimestamp": 0}},
{"frostVerify": {"blockTimestamp": 0}},
{"graphConfig": {"blockTimestamp": 0}},
{"hpkeConfig": {"blockTimestamp": 0}},
{"mldsaVerify": {"blockTimestamp": 0}},
{"mlkemConfig": {"blockTimestamp": 0}},
{"pqcryptoConfig": {"blockTimestamp": 0}},
{"ringConfig": {"blockTimestamp": 0}},
{"slhdsaVerify": {"blockTimestamp": 0}},
{"zkConfig": {"blockTimestamp": 0}},
{"pulsarVerify": {"blockTimestamp": 1766708400}},
{"magnetarVerify": {"blockTimestamp": 1766708400}},
{"p3qVerify": {"blockTimestamp": 1766708400}},
@@ -48,12 +48,22 @@ import (
// canonicalMainnetUpgradeV46 is the byte-for-byte vendored copy of
// luxfi/genesis configs/mainnet/upgrade.json at the v46 precompile-set
// freeze (warpConfig + 17 live-at-block-0 + 27 forward-dated to the
// Quasar Edition activation timestamp). The dead dexConfig 0x9010 key
// was removed when node v1.30.27 dropped that precompile (its config
// key is no longer registered → it would brick the C-Chain on boot).
// Vendoring it removes runtime CWD-walking and makes this
// regression-proof hermetic in CI runners that clone only luxfi/evm.
// freeze. Layout (46 entries, monotonic by blockTimestamp):
// - 17 already-live precompiles pinned to blockTimestamp:0 — these are
// active at block 0 on the running mainnet (see the UPGRADE_JSON in
// luxfi/universe k8s/lux-mainnet/luxd-startup.yaml). They MUST stay at
// 0 so a relaunch from genesis treats them as already-applied and
// checkPrecompileCompatible does not refuse boot.
// - warpConfig disable@1766708399 then re-enable@1766708400 (PQ warp
// params at the strict-PQ fork; both strictly after genesis time).
// - 7 bls12381 family @1766708400.
// - 20 forward-dated @1782864000 (Quasar Edition activation; strictly
// after the strict-PQ gate so every classical primitive is gated).
// The dead dexConfig 0x9010 key was removed when node v1.30.27 dropped
// that precompile (its config key is no longer registered → it would
// brick the C-Chain on boot). Vendoring it removes runtime CWD-walking
// and makes this regression-proof hermetic in CI runners that clone only
// luxfi/evm.
//
// Sync contract: if luxfi/genesis configs/mainnet/upgrade.json changes,
// regenerate this file:
@@ -215,12 +225,16 @@ func TestRegressionProof_SimulatedFortyNineEntryCanonicalFails(t *testing.T) {
require.NoError(t, json.Unmarshal(raw, &ok),
"post-patch canonical (45 entries) must parse cleanly — see TestMainnetUpgradeJSON_UnmarshalsAgainstRegistry",
)
require.Lenf(t, ok.PrecompileUpgrades, 45,
"canonical entry count drifted: this regression-proof test was authored against 45 entries (warpConfig + the live + forward-dated set, after the dead dexConfig 0x9010 key was removed). If the canonical count legitimately changed, update this assertion alongside.",
require.Lenf(t, ok.PrecompileUpgrades, 46,
"canonical entry count drifted: this regression-proof test was authored against 46 entries "+
"(17 live-at-block-0 pinned to blockTimestamp:0 + warpConfig disable@1766708399 + "+
"warpConfig re-enable@1766708400 + 7 bls12381 family@1766708400 + 20 forward-dated@1782864000, "+
"after the dead dexConfig 0x9010 key was removed). If the canonical count legitimately "+
"changed, update this assertion alongside.",
)
// Build a "pre-patch" 49-entry probe by injecting three
// guaranteed-unregistered sentinel keys at a forward-date.
// guaranteed-unregistered sentinel keys at a forward-date (46 + 3 = 49).
var asObj map[string]any
require.NoError(t, json.Unmarshal(raw, &asObj))
upgrades, _ := asObj["precompileUpgrades"].([]any)