Read the warp policy where genesis now keeps it

luxfi/genesis 336c946 removed warpConfig from the mainnet upgrade schedule
and moved requirePrimaryNetworkSigners into the block-zero declaration,
because the EVM refuses to initialise when a live precompile is re-declared
with a different rule — a second declaration is admitted only to disable one.

These tests still asserted the arrangement that commit abandoned, so both
failed against a correct repository: one looked for a warpConfig entry that
is deliberately gone, the other compared a fixture still carrying it.

Red-review finding #8 is unchanged and now checked at its source: warp is
read from configs/mainnet/cchain.json and must require primary-network
signers, and the upgrade schedule must re-declare it nowhere. The mainnet
and testnet fixtures are re-vendored (48 entries each) and the hardcoded
canonical count follows.
This commit is contained in:
2026-09-10 12:48:14 -07:00
parent 2f9a315893
commit 185089c69f
4 changed files with 75 additions and 60 deletions
@@ -132,17 +132,36 @@ func TestMainnetUpgradeJSON_PrecompileTimestampsAreMonotonic(t *testing.T) {
}
// TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners enforces the
// 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 policy from red-review finding #8: every cross-chain warp message must
// be signed by primary-network validators, not just a subnet quorum.
//
// 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
// The rule is read off the GENESIS declaration, because that is where it now
// lives. It used to be scheduled as an upgrade entry as well, and luxfi/genesis
// 336c946 removed that entry: the EVM refuses to initialise when a live
// precompile is re-declared with a different rule, since a second declaration
// is permitted only in order to disable it. A rule that holds from block zero
// belongs in the block-zero declaration.
//
// So this test asserts both halves of that decision — the policy is true where
// it is declared, and it is declared exactly once.
func TestMainnetWarpRequiresPrimaryNetworkSigners(t *testing.T) {
var chain struct {
Config struct {
WarpConfig *struct {
BlockTimestamp uint64 `json:"blockTimestamp"`
QuorumNumerator uint64 `json:"quorumNumerator"`
RequirePrimaryNetworkSigners bool `json:"requirePrimaryNetworkSigners"`
} `json:"warpConfig"`
} `json:"config"`
}
require.NoError(t, json.Unmarshal(readCanonicalMainnetCChainJSONRaw(t), &chain))
warp := chain.Config.WarpConfig
require.NotNil(t, warp, "the mainnet C-chain genesis must declare warpConfig")
require.Equal(t, uint64(67), warp.QuorumNumerator, "warpConfig quorumNumerator must be 67")
require.True(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)",
)
raw := readCanonicalMainnetUpgradeJSONRaw(t)
@@ -151,43 +170,13 @@ func TestMainnetUpgradeJSON_WarpRequiresPrimaryNetworkSigners(t *testing.T) {
}
require.NoError(t, json.Unmarshal(raw, &doc))
var (
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"`
QuorumNumerator uint64 `json:"quorumNumerator"`
RequirePrimaryNetworkSigners bool `json:"requirePrimaryNetworkSigners"`
}
require.NoError(t, json.Unmarshal(warpRaw, &warp))
// 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",
_, ok := entry["warpConfig"]
require.Falsef(t, ok,
"upgrade.json entry %d re-declares warpConfig. Warp is live from genesis, and the EVM admits a second declaration of a live precompile only when it disables one (params/extras/precompile_upgrade.go: \"disable should be [true]\"), so a re-declaration carrying a different rule refuses to initialise. The policy belongs in the genesis declaration, which is what this test reads.",
i,
)
foundWarp = true
require.False(t, warp.Disable, "the canonical warp activation must not be disabled")
require.Equalf(t, 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, 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
@@ -219,23 +208,36 @@ func readPrecompileUpgradeTimestamps(t *testing.T, raw []byte) map[string]uint64
return out
}
// readCanonicalMainnetUpgradeJSONRaw returns the canonical upgrade.json
// bytes. The test resolves the file via the relative path from
// evm/params/extras up to genesis/configs/mainnet — both luxfi/evm and
// luxfi/genesis live in the same `~/work/lux` worktree on CI runners.
// readCanonicalMainnetCChainJSONRaw returns the canonical C-chain genesis
// bytes, resolved the same way as upgrade.json beside it.
func readCanonicalMainnetCChainJSONRaw(t *testing.T) []byte {
t.Helper()
return readCanonicalMainnetFile(t, "cchain.json")
}
// readCanonicalMainnetUpgradeJSONRaw returns the canonical upgrade.json bytes.
func readCanonicalMainnetUpgradeJSONRaw(t *testing.T) []byte {
t.Helper()
return readCanonicalMainnetFile(t, "upgrade.json")
}
// readCanonicalMainnetFile resolves a file in luxfi/genesis configs/mainnet by
// relative path from evm/params/extras — both repos live in the same `~/work/lux`
// worktree on CI runners. Missing means the checkout is not beside this one, which
// is a reason to skip and never a reason to fail.
func readCanonicalMainnetFile(t *testing.T, name string) []byte {
t.Helper()
candidates := []string{
// luxfi/evm running standalone, sibling luxfi/genesis checkout.
"../../../../genesis/configs/mainnet/upgrade.json",
"../../../../genesis/configs/mainnet/" + name,
// monorepo layout (e.g. when both repos are inside the same root).
"../../../genesis/configs/mainnet/upgrade.json",
"../../../genesis/configs/mainnet/" + name,
}
for _, candidate := range candidates {
if data, err := os.ReadFile(candidate); err == nil {
return data
}
}
t.Skipf("canonical mainnet upgrade.json not reachable from cwd — looked in %v; run from a worktree that contains luxfi/genesis alongside luxfi/evm", candidates)
t.Skipf("canonical mainnet %s not reachable from cwd — looked in %v; run from a worktree that contains luxfi/genesis alongside luxfi/evm", name, candidates)
return nil
}
+1 -8
View File
@@ -126,13 +126,6 @@
"blockTimestamp": 1766708400
}
},
{
"warpConfig": {
"blockTimestamp": 1766708400,
"quorumNumerator": 67,
"requirePrimaryNetworkSigners": true
}
},
{
"dexPositionManagerConfig": {
"blockTimestamp": 1766708400
@@ -260,7 +253,7 @@
"0x9011E888251AB053B7bD1cdB598Db4f9DEd94714"
],
"initialRewardConfig": {
"rewardAddress": "0x8E29b816c6C35b13cE1ff68D33E245C2bda8ac3D"
"rewardAddress": "0xF66B025b46844AFA5d6df54cf0C00E1583cE1abA"
}
}
}
+21 -1
View File
@@ -236,7 +236,27 @@
"rewardAddress": "0xEAbCC110fAcBfebabC66Ad6f9E7B67288e720B59"
}
}
},
{
"dexPositionManagerConfig": {
"blockTimestamp": 1766708400
}
},
{
"dexStateViewConfig": {
"blockTimestamp": 1766708400
}
},
{
"dexQuoterConfig": {
"blockTimestamp": 1766708400
}
},
{
"dexSettleConfig": {
"blockTimestamp": 1766708400
}
}
],
"stateUpgrades": []
}
}
@@ -210,7 +210,7 @@ func TestRegressionProof_SimulatedUnregisteredEntriesFail(t *testing.T) {
require.NoError(t, json.Unmarshal(raw, &ok),
"canonical upgrade schedule must parse cleanly — see TestMainnetUpgradeJSON_UnmarshalsAgainstRegistry",
)
require.Lenf(t, ok.PrecompileUpgrades, 49,
require.Lenf(t, ok.PrecompileUpgrades, 48,
"canonical entry count drifted; synchronize the fixture with luxfi/genesis and review the change",
)