Files
zeekayandHanzo Dev 9ababce758 A precompile's config key names the precompile
Forty-five of the fifty-six suite modules keyed off <name>Config and eleven did
not, in three other spellings: Verify, Threshold, Encapsulate. The LP-4200
unified PQCrypto block carried four of those conventions across its eight
addresses — two KEMs named differently (mlkemConfig beside hqcEncapsulate) and
two threshold schemes named differently (pulsarVerify beside coronaThreshold) —
so the block that exists to be one thing did not read as one thing.

The deviations also named an OPERATION where a precompile belongs. HQC
decapsulates as well as encapsulates and the Verify precompiles do more than
verify, so hqcEncapsulate was the name of one entry point standing in for the
whole module. A config key selects a precompile; it is not a method selector.

All fifty-six are <name>Config now. There is no compatibility shim: an
upgrade.json naming an old key is naming something that does not exist, which
luxd already refuses loudly, and every chain config in the estate moves with this.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 19:27:25 -07:00

87 lines
3.4 KiB
Go

// Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package frost
import (
"testing"
"github.com/luxfi/geth/common"
"github.com/luxfi/precompile/modules"
"github.com/luxfi/precompile/precompileconfig"
"github.com/stretchr/testify/require"
)
type fakeConfig struct{}
func (f *fakeConfig) Key() string { return "fake" }
func (f *fakeConfig) Timestamp() *uint64 { return nil }
func (f *fakeConfig) IsDisabled() bool { return false }
func (f *fakeConfig) Equal(precompileconfig.Config) bool { return false }
func (f *fakeConfig) Verify(precompileconfig.ChainConfig) error { return nil }
type testChainCfg struct{}
func (t *testChainCfg) IsDurango(uint64) bool { return true }
func TestConfigLifecycle(t *testing.T) {
cfg := &Config{}
require.Equal(t, "frostConfig", cfg.Key())
require.Nil(t, cfg.Timestamp())
require.False(t, cfg.IsDisabled())
require.NoError(t, cfg.Verify(&testChainCfg{}))
require.True(t, cfg.Equal(&Config{}))
require.False(t, cfg.Equal(&fakeConfig{}))
ts := uint64(42)
cfg2 := &Config{Upgrade: precompileconfig.Upgrade{BlockTimestamp: &ts}}
require.Equal(t, &ts, cfg2.Timestamp())
cfg3 := &Config{Upgrade: precompileconfig.Upgrade{Disable: true}}
require.True(t, cfg3.IsDisabled())
}
func TestConfigurator(t *testing.T) {
c := &configurator{}
cfg := c.MakeConfig()
require.NotNil(t, cfg)
require.Equal(t, "frostConfig", cfg.Key())
require.NoError(t, c.Configure(&testChainCfg{}, cfg, nil, nil))
}
// TestModuleRegistration: init() registers the precompile, and the only way to
// see that it did is to look it up. The address and the config key are both
// consensus-visible -- the address is where the EVM dispatches and the key is
// how a chain config turns the precompile on -- so both are asserted, by
// address and by key, and the two lookups must agree.
//
// The duplicate registration asserts the guard init() relies on: a second
// module claiming this address or key is refused rather than silently
// shadowing. init()'s own panic(err) statement cannot be reached from a test
// (it runs once, before any test, and only fires on a collision that cannot
// exist by then), so this is the closest reachable statement of the same
// property.
func TestModuleRegistration(t *testing.T) {
byAddr, ok := modules.GetPrecompileModuleByAddress(ContractFROSTVerifyAddress)
require.True(t, ok, "the FROST module must be registered at its address")
byKey, ok := modules.GetPrecompileModule("frostConfig")
require.True(t, ok, "the FROST module must be registered under its config key")
require.Equal(t, byAddr, byKey, "address and key must name the same module")
require.Equal(t, FROSTVerifyPrecompile, byAddr.Contract)
require.Equal(t, "frostConfig", byAddr.ConfigKey)
require.Error(t, modules.RegisterModule(modules.Module{
ConfigKey: "frostConfig",
Address: common.HexToAddress("0x0800000000000000000000000000000000000042"),
Contract: FROSTVerifyPrecompile,
Configurator: &configurator{},
}), "a second module must not be able to claim this config key")
require.Error(t, modules.RegisterModule(modules.Module{
ConfigKey: "frostVerifyImpostor",
Address: ContractFROSTVerifyAddress,
Contract: FROSTVerifyPrecompile,
Configurator: &configurator{},
}), "a second module must not be able to claim this address")
}