tests: pin EVM upgrade fixtures to canonical genesis

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-08-21 11:25:20 -07:00
co-authored by Hanzo Dev
parent 0c6e661fec
commit 125234b74a
7 changed files with 524 additions and 233 deletions
@@ -137,16 +137,10 @@ func TestMainnetUpgradeJSON_PrecompileTimestampsAreMonotonic(t *testing.T) {
// 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}.
// Warp lives in the genesis chainConfig with the classical-era policy. The
// upgrade schedule contains one replacement at the strict-PQ fork with the
// hardened signer policy. Keeping a single entry avoids two competing ways
// to describe the same activation.
func TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners(t *testing.T) {
const strictPQ uint64 = 1766708400
@@ -158,15 +152,15 @@ func TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners(t *testing.T) {
require.NoError(t, json.Unmarshal(raw, &doc))
var (
foundDisable bool
foundReEnable bool
prevWarpTs *uint64
foundWarp bool
warpCount int
)
for i, entry := range doc.PrecompileUpgrades {
warpRaw, ok := entry["warpConfig"]
if !ok {
continue
}
warpCount++
var warp struct {
BlockTimestamp uint64 `json:"blockTimestamp"`
Disable bool `json:"disable"`
@@ -182,37 +176,18 @@ func TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners(t *testing.T) {
"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
foundWarp = true
require.False(t, warp.Disable, "the canonical warp activation must not be disabled")
require.Equalf(t, strictPQ, warp.BlockTimestamp,
"warpConfig re-enable must fire at the strict-PQ fork (%d), got %d", strictPQ, warp.BlockTimestamp,
"warpConfig must activate 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, 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")
require.True(t, foundWarp, "warpConfig entry with the PQ signer policy must be present")
require.Equal(t, 1, warpCount, "canonical upgrade.json must contain exactly one warpConfig entry")
}
// readPrecompileUpgradeTimestamps decodes the precompileUpgrades array
+390
View File
@@ -0,0 +1,390 @@
{
"networkUpgradeOverrides": {
"evmTimestamp": 0,
"durangoTimestamp": 0,
"quasarTimestamp": 0,
"fortunaTimestamp": 0,
"graniteTimestamp": 0
},
"precompileUpgrades": [
{
"aiMiningConfig": {
"blockTimestamp": 1766708400
}
},
{
"blake3Config": {
"blockTimestamp": 1766708400
}
},
{
"cggmp21Verify": {
"blockTimestamp": 1766708400
}
},
{
"deadZeroConfig": {
"blockTimestamp": 1766708400
}
},
{
"deadConfig": {
"blockTimestamp": 1766708400
}
},
{
"deadFullConfig": {
"blockTimestamp": 1766708400
}
},
{
"routerConfig": {
"blockTimestamp": 1766708400,
"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
}
},
{
"ringConfig": {
"blockTimestamp": 1766708400
}
},
{
"slhdsaVerify": {
"blockTimestamp": 1766708400
}
},
{
"zkConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G1AddConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G1MulConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G1MSMConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G2AddConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G2MulConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381G2MSMConfig": {
"blockTimestamp": 1766708400
}
},
{
"bls12381PairingConfig": {
"blockTimestamp": 1766708400
}
},
{
"warpConfig": {
"blockTimestamp": 1766708400,
"quorumNumerator": 67,
"requirePrimaryNetworkSigners": true
}
},
{
"dexPositionManagerConfig": {
"blockTimestamp": 1766708400
}
},
{
"dexStateViewConfig": {
"blockTimestamp": 1766708400
}
},
{
"dexQuoterConfig": {
"blockTimestamp": 1766708400
}
},
{
"dexSettleConfig": {
"blockTimestamp": 1766708400
}
},
{
"pulsarVerify": {
"blockTimestamp": 1766708400
}
},
{
"magnetarVerify": {
"blockTimestamp": 1766708400
}
},
{
"p3qVerify": {
"blockTimestamp": 1766708400
}
},
{
"coronaThreshold": {
"blockTimestamp": 1766708400
}
},
{
"hqcEncapsulate": {
"blockTimestamp": 1766708400
}
},
{
"curve25519Config": {
"blockTimestamp": 1766708400
}
},
{
"x25519Config": {
"blockTimestamp": 1766708400
}
},
{
"sr25519Verify": {
"blockTimestamp": 1766708400
}
},
{
"babyjubjubConfig": {
"blockTimestamp": 1766708400
}
},
{
"pedersenConfig": {
"blockTimestamp": 1766708400
}
},
{
"poseidonConfig": {
"blockTimestamp": 1766708400
}
},
{
"pastaConfig": {
"blockTimestamp": 1766708400
}
},
{
"xwingConfig": {
"blockTimestamp": 1766708400
}
},
{
"computeMarketConfig": {
"blockTimestamp": 1766708400
}
},
{
"bridgeRegistrarConfig": {
"blockTimestamp": 1766708400
}
},
{
"stableSwapConfig": {
"blockTimestamp": 1766708400
}
},
{
"vrfConfig": {
"blockTimestamp": 1766708400
}
},
{
"attestationConfig": {
"blockTimestamp": 1766708400
}
},
{
"anchorConfig": {
"blockTimestamp": 1766708400
}
},
{
"fixedPointMathConfig": {
"blockTimestamp": 1766708400
}
},
{
"rewardManagerConfig": {
"blockTimestamp": 1766708400,
"adminAddresses": [
"0x9011E888251AB053B7bD1cdB598Db4f9DEd94714"
],
"initialRewardConfig": {
"rewardAddress": "0x8E29b816c6C35b13cE1ff68D33E245C2bda8ac3D"
}
}
}
],
"stateUpgrades": [
{
"blockTimestamp": 1766708400,
"accounts": {
"0x80bBc7C4C7a59C899D1B37BC14539A22D5830a84": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0xD173926A10A0C4eCd3A51B1422270b65Df0551c1": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0xeac0a50112b5ee20cc18e42ba4d37777012afd0d": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0xaa6a41cacb18bed5b98059a5fa30f9dbabe0cc64": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0xdf1de693c31e2a5eb869c329529623556b20abf3": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce212"
}
},
"0x8031e9b0d02a792cfefaa2bdca6e1289d385426f": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce212"
}
},
"0x79608e442d046ea6d3125931a33ce971ad99c6f9": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce212"
}
},
"0xa85eb8e163f4d70bfc43a4f3fcc9a8dfc42b1ae4": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce212"
}
},
"0x724f4ef0400386fc8c1011788af733bd367ac00f": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce212"
}
},
"0x3569c06a80c148d7b4b67f8a06125f6d59774243": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce212"
}
},
"0x60E0a8167FC13dE89348978860466C9ceC24B9ba": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x1E48D32a4F5e9f08DB9aE4959163300FaF8A6C8e": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x848Cff46eb323f323b6Bbe1Df274E40793d7f2c2": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x5E5290f350352768bD2bfC59c2DA15DD04A7cB88": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x26B40f650156C7EbF9e087Dd0dca181Fe87625B7": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x6EdcF3645DeF09DB45050638c41157D8B9FEa1cf": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x28BfC5DD4B7E15659e41190983e5fE3df1132bB9": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x3078847F879A33994cDa2Ec1540ca52b5E0eE2e5": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x8B982132d639527E8a0eAAD385f97719af8f5e04": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x3141b94b89691009b950c96e97Bff48e0C543E3C": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x0e4bd0dd67c15DECFbBBDBbE07Fc9d51D737693D": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0xf5a313885832d4fc71d1ef80115197c4479b58c8": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
},
"0x1af00a2590a834d14f4a8a26d1b03ebba8cf7961": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000051284dc2133e8d3a8e213dca6a6fa768cfdfcce2"
}
}
}
}
]
}
+10 -12
View File
@@ -54,15 +54,13 @@ const (
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{
// Mainnet deliberately keeps every upgrade entry after its genesis timestamp
// so replaying the imported history reproduces the original block-0 root.
var mainnetLiveAtBlockZero = map[string]bool{}
// Testnet was launched with these precompiles active at block 0. Its relaunch
// schedule must continue to pin exactly this set to timestamp zero.
var testnetLiveAtBlockZero = map[string]bool{
"aiMiningConfig": true,
"blake3Config": true,
"cggmp21Verify": true,
@@ -82,16 +80,16 @@ var liveAtBlockZero = map[string]bool{
}
func TestMainnetUpgradeJSON_RelaunchSafe(t *testing.T) {
assertRelaunchSafe(t, readCanonicalMainnetUpgradeJSONRaw(t), mainnetCChainGenesisTime)
assertRelaunchSafe(t, readCanonicalMainnetUpgradeJSONRaw(t), mainnetCChainGenesisTime, mainnetLiveAtBlockZero)
}
func TestTestnetUpgradeJSON_RelaunchSafe(t *testing.T) {
assertRelaunchSafe(t, readCanonicalTestnetUpgradeJSONRaw(t), testnetCChainGenesisTime)
assertRelaunchSafe(t, readCanonicalTestnetUpgradeJSONRaw(t), testnetCChainGenesisTime, testnetLiveAtBlockZero)
}
// 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) {
func assertRelaunchSafe(t *testing.T, raw []byte, genesisTime uint64, liveAtBlockZero map[string]bool) {
t.Helper()
var cfg extras.UpgradeConfig
@@ -4,8 +4,7 @@
"durangoTimestamp": 0,
"quasarTimestamp": 0,
"fortunaTimestamp": 0,
"graniteTimestamp": 0,
"strictPQTimestamp": 1766708400
"graniteTimestamp": 0
},
"precompileUpgrades": [
{
@@ -43,8 +42,8 @@
"blockTimestamp": 0,
"v3QuoterAddress": "0x0000000000000000000000000000000000000000",
"v3FactoryAddress": "0x0000000000000000000000000000000000000000",
"v2RouterAddress": "0x0000000000000000000000000000000000009999",
"v2FactoryAddress": "0x0000000000000000000000000000000000009999"
"v2RouterAddress": "0x0000000000000000000000000000000000000000",
"v2FactoryAddress": "0x0000000000000000000000000000000000000000"
}
},
{
@@ -77,11 +76,6 @@
"blockTimestamp": 0
}
},
{
"pqcryptoConfig": {
"blockTimestamp": 0
}
},
{
"ringConfig": {
"blockTimestamp": 0
@@ -98,16 +92,28 @@
}
},
{
"warpConfig": {
"blockTimestamp": 1766708399,
"disable": true
"pulsarVerify": {
"blockTimestamp": 1766708400
}
},
{
"warpConfig": {
"blockTimestamp": 1766708400,
"quorumNumerator": 67,
"requirePrimaryNetworkSigners": true
"magnetarVerify": {
"blockTimestamp": 1766708400
}
},
{
"p3qVerify": {
"blockTimestamp": 1766708400
}
},
{
"coronaThreshold": {
"blockTimestamp": 1766708400
}
},
{
"hqcEncapsulate": {
"blockTimestamp": 1766708400
}
},
{
@@ -145,106 +151,92 @@
"blockTimestamp": 1766708400
}
},
{
"pulsarVerify": {
"blockTimestamp": 1782864000
}
},
{
"magnetarVerify": {
"blockTimestamp": 1782864000
}
},
{
"p3qVerify": {
"blockTimestamp": 1782864000
}
},
{
"coronaThreshold": {
"blockTimestamp": 1782864000
}
},
{
"hqcEncapsulate": {
"blockTimestamp": 1782864000
}
},
{
"curve25519Config": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"x25519Config": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"sr25519Verify": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"babyjubjubConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"pedersenConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"poseidonConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"pastaConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"xwingConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"computeMarketConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"bridgeRegistrarConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"stableSwapConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"vrfConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"attestationConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"anchorConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"fixedPointMathConfig": {
"blockTimestamp": 1782864000
"blockTimestamp": 1766708400
}
},
{
"rewardManagerConfig": {
"blockTimestamp": 1766708400,
"adminAddresses": [
"0x9011E888251AB053B7bD1cdB598Db4f9DEd94714"
],
"initialRewardConfig": {
"rewardAddress": "0xEAbCC110fAcBfebabC66Ad6f9E7B67288e720B59"
}
}
}
],
"stateUpgrades": []
}
}
@@ -1,7 +1,7 @@
// Copyright (C) 2019-2026, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Testnet-side regression gate. Mirrors mainnet_upgrade_v46.json's
// Testnet-side regression gate. Mirrors mainnet_upgrade.json's
// upgrade_unmarshal_test.go (task #99) for the Lux primary testnet
// C-Chain upgrade schedule. The mainnet test wouldn't catch a testnet
// drift because the canonical fixture vendored there is only mainnet;
@@ -25,28 +25,17 @@ import (
_ "github.com/luxfi/evm/precompile/registry"
)
// canonicalTestnetUpgradeV47 is the byte-for-byte vendored copy of
// luxfi/genesis configs/testnet/upgrade.json at the v47 precompile-set
// 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.
// canonicalTestnetUpgrade is the byte-for-byte vendored copy of
// luxfi/genesis configs/testnet/upgrade.json. A workspace drift test keeps
// this hermetic copy synchronized.
//
// Sync contract: if luxfi/genesis configs/testnet/upgrade.json changes,
// regenerate this file:
//
// cp ../../../../genesis/configs/testnet/upgrade.json testnet_upgrade_v47.json
// cp ../../../../genesis/configs/testnet/upgrade.json testnet_upgrade.json
//
//go:embed testnet_upgrade_v47.json
var canonicalTestnetUpgradeV47 []byte
//go:embed testnet_upgrade.json
var canonicalTestnetUpgrade []byte
// TestTestnetUpgradeJSON_UnmarshalsAgainstRegistry mirrors the mainnet
// regression gate. Every key in the canonical testnet upgrade.json
@@ -87,8 +76,8 @@ func TestTestnetUpgradeJSON_UnmarshalsAgainstRegistry(t *testing.T) {
// testnet upgrade.json. Mirrors the mainnet helper.
func readCanonicalTestnetUpgradeJSONRaw(t *testing.T) []byte {
t.Helper()
if len(canonicalTestnetUpgradeV47) == 0 {
t.Fatal("embedded canonical testnet upgrade.json is empty — //go:embed testnet_upgrade_v47.json failed at build time")
if len(canonicalTestnetUpgrade) == 0 {
t.Fatal("embedded canonical testnet upgrade.json is empty — //go:embed testnet_upgrade.json failed at build time")
}
return canonicalTestnetUpgradeV47
return canonicalTestnetUpgrade
}
@@ -1,63 +0,0 @@
{
"networkUpgradeOverrides": {
"evmTimestamp": 0,
"durangoTimestamp": 0,
"quasarTimestamp": 0,
"fortunaTimestamp": 0,
"graniteTimestamp": 0,
"strictPQTimestamp": 1766708400
},
"precompileUpgrades": [
{"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": "0x0000000000000000000000000000000000009999",
"v2FactoryAddress": "0x0000000000000000000000000000000000009999"
}},
{"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}},
{"coronaThreshold": {"blockTimestamp": 1766708400}},
{"hqcEncapsulate": {"blockTimestamp": 1766708400}},
{"bls12381G1AddConfig": {"blockTimestamp": 1766708400}},
{"bls12381G1MulConfig": {"blockTimestamp": 1766708400}},
{"bls12381G1MSMConfig": {"blockTimestamp": 1766708400}},
{"bls12381G2AddConfig": {"blockTimestamp": 1766708400}},
{"bls12381G2MulConfig": {"blockTimestamp": 1766708400}},
{"bls12381G2MSMConfig": {"blockTimestamp": 1766708400}},
{"bls12381PairingConfig": {"blockTimestamp": 1766708400}},
{"curve25519Config": {"blockTimestamp": 1766708400}},
{"x25519Config": {"blockTimestamp": 1766708400}},
{"sr25519Verify": {"blockTimestamp": 1766708400}},
{"babyjubjubConfig": {"blockTimestamp": 1766708400}},
{"pedersenConfig": {"blockTimestamp": 1766708400}},
{"poseidonConfig": {"blockTimestamp": 1766708400}},
{"pastaConfig": {"blockTimestamp": 1766708400}},
{"xwingConfig": {"blockTimestamp": 1766708400}},
{"computeMarketConfig": {"blockTimestamp": 1766708400}},
{"bridgeRegistrarConfig": {"blockTimestamp": 1766708400}},
{"stableSwapConfig": {"blockTimestamp": 1766708400}},
{"vrfConfig": {"blockTimestamp": 1766708400}},
{"attestationConfig": {"blockTimestamp": 1766708400}},
{"anchorConfig": {"blockTimestamp": 1766708400}},
{"fixedPointMathConfig": {"blockTimestamp": 1766708400}}
],
"stateUpgrades": []
}
@@ -32,8 +32,10 @@
package extras_e2e_test
import (
"bytes"
_ "embed"
"encoding/json"
"os"
"testing"
"github.com/stretchr/testify/require"
@@ -46,35 +48,21 @@ import (
_ "github.com/luxfi/evm/precompile/registry"
)
// canonicalMainnetUpgradeV46 is the byte-for-byte vendored copy of
// luxfi/genesis configs/mainnet/upgrade.json at the v46 precompile-set
// 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.
// canonicalMainnetUpgrade is the byte-for-byte vendored copy of
// luxfi/genesis configs/mainnet/upgrade.json. Vendoring it removes runtime
// CWD-walking and makes this regression proof hermetic in CI runners that
// clone only luxfi/evm. A workspace drift test keeps the copy synchronized.
//
// Sync contract: if luxfi/genesis configs/mainnet/upgrade.json changes,
// regenerate this file:
//
// cp ../../../../genesis/configs/mainnet/upgrade.json mainnet_upgrade_v46.json
// cp ../../../../genesis/configs/mainnet/upgrade.json mainnet_upgrade.json
//
// The TestVendoredFixtureMatchesCanonical guard (build-tag: requires the
// sibling genesis checkout) detects drift before merge.
//
//go:embed mainnet_upgrade_v46.json
var canonicalMainnetUpgradeV46 []byte
//go:embed mainnet_upgrade.json
var canonicalMainnetUpgrade []byte
// TestMainnetUpgradeJSON_UnmarshalsAgainstRegistry is the end-to-end
// regression gate from Red's MEDIUM (vector 9) finding. It enforces
@@ -198,11 +186,8 @@ func TestMainnetUpgradeJSON_RegistryRejectsUnregisteredKey(t *testing.T) {
}
}
// TestRegressionProof_SimulatedFortyNineEntryCanonicalFails is the
// explicit regression proof requested in Red's MEDIUM (vector 9)
// remediation. It simulates a pre-patch oversized canonical by
// extending the current 45-entry canonical with three unregistered
// keys and asserts the parser refuses the result.
// TestRegressionProof_SimulatedUnregisteredEntriesFail extends the canonical
// schedule with unregistered keys and asserts the parser refuses it.
//
// Concretely: if a future regression introduces any unregistered
// precompile config key into the canonical upgrade.json (a module
@@ -217,24 +202,20 @@ func TestMainnetUpgradeJSON_RegistryRejectsUnregisteredKey(t *testing.T) {
// which luxfi/precompile v0.5.38 now registers — see the history note on
// TestMainnetUpgradeJSON_RegistryRejectsUnregisteredKey. Sentinels keep
// the rejection contract decoupled from real-module registration churn.
func TestRegressionProof_SimulatedFortyNineEntryCanonicalFails(t *testing.T) {
func TestRegressionProof_SimulatedUnregisteredEntriesFail(t *testing.T) {
raw := readCanonicalMainnetUpgradeJSONRaw(t)
// Sanity-check: the post-patch canonical accepted as-is.
var ok extras.UpgradeConfig
require.NoError(t, json.Unmarshal(raw, &ok),
"post-patch canonical (45 entries) must parse cleanly — see TestMainnetUpgradeJSON_UnmarshalsAgainstRegistry",
"canonical upgrade schedule must parse cleanly — see TestMainnetUpgradeJSON_UnmarshalsAgainstRegistry",
)
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.",
require.Lenf(t, ok.PrecompileUpgrades, 49,
"canonical entry count drifted; synchronize the fixture with luxfi/genesis and review the change",
)
// Build a "pre-patch" 49-entry probe by injecting three
// guaranteed-unregistered sentinel keys at a forward-date (46 + 3 = 49).
// Inject three guaranteed-unregistered sentinel keys into the canonical
// schedule. The parser must reject the first unknown key.
var asObj map[string]any
require.NoError(t, json.Unmarshal(raw, &asObj))
upgrades, _ := asObj["precompileUpgrades"].([]any)
@@ -247,12 +228,12 @@ func TestRegressionProof_SimulatedFortyNineEntryCanonicalFails(t *testing.T) {
probe, err := json.Marshal(asObj)
require.NoError(t, err)
// The pre-patch 49-entry shape MUST fail the parser.
// The augmented schedule MUST fail the parser.
var bad extras.UpgradeConfig
err = json.Unmarshal(probe, &bad)
require.Errorf(t, err,
"simulated 49-entry canonical (the pre-patch shape Red flagged in vector 8) was accepted by the parser — the regression guard is broken. "+
"Expected one of the injected unregistered sentinel keys to be rejected as 'unknown precompile config'.",
"canonical schedule with injected unregistered entries was accepted — the regression guard is broken. "+
"Expected one of the injected keys to be rejected as 'unknown precompile config'.",
)
require.Containsf(t, err.Error(), "unknown precompile config",
"expected the canonical 'unknown precompile config' error class, got: %v", err,
@@ -261,7 +242,7 @@ func TestRegressionProof_SimulatedFortyNineEntryCanonicalFails(t *testing.T) {
// readCanonicalMainnetUpgradeJSONRaw returns the vendored canonical
// mainnet upgrade.json. The fixture is embedded at build time via
// //go:embed (see canonicalMainnetUpgradeV46) so the test is hermetic
// //go:embed (see canonicalMainnetUpgrade) so the test is hermetic
// in CI runners that clone only luxfi/evm — closing Red round-2 vector
// V12 (silent t.Skip on relative-path miss).
//
@@ -270,10 +251,39 @@ func TestRegressionProof_SimulatedFortyNineEntryCanonicalFails(t *testing.T) {
// next to the embed directive.
func readCanonicalMainnetUpgradeJSONRaw(t *testing.T) []byte {
t.Helper()
if len(canonicalMainnetUpgradeV46) == 0 {
if len(canonicalMainnetUpgrade) == 0 {
// The embed directive guarantees the file is present at build
// time; a zero-length read here would be a build-system bug.
t.Fatal("embedded canonical mainnet upgrade.json is empty — //go:embed mainnet_upgrade_v46.json failed at build time")
t.Fatal("embedded canonical mainnet upgrade.json is empty — //go:embed mainnet_upgrade.json failed at build time")
}
return canonicalMainnetUpgrade
}
// TestVendoredFixturesMatchCanonicalWorkspace catches stale embedded fixtures
// whenever evm and genesis are checked out as siblings. Standalone module CI
// still exercises the embedded files through the parsing tests above.
func TestVendoredFixturesMatchCanonicalWorkspace(t *testing.T) {
tests := []struct {
name string
fixture []byte
path string
}{
{"mainnet", canonicalMainnetUpgrade, "../../../genesis/configs/mainnet/upgrade.json"},
{"testnet", canonicalTestnetUpgrade, "../../../genesis/configs/testnet/upgrade.json"},
}
found := false
for _, test := range tests {
canonical, err := os.ReadFile(test.path)
if os.IsNotExist(err) {
continue
}
require.NoError(t, err)
found = true
require.Truef(t, bytes.Equal(test.fixture, canonical),
"%s embedded upgrade fixture drifted from %s", test.name, test.path)
}
if !found {
t.Skip("sibling luxfi/genesis checkout not present")
}
return canonicalMainnetUpgradeV46
}