fix(bls12381): per-sub-config Key() prevents upgrade.json collision

The 7 EIP-2537 bls12381 sub-configs (G1Add, G1Mul, G1MSM, G2Add, G2Mul,
G2MSM, Pairing) shared a single Config struct whose Key() hard-coded
G1AddConfigKey. evm/params/extras/precompile_upgrade.go groups upgrades
by upgrade.Key(), so any upgrade.json listing the 2nd-and-later sub-configs
was treated as a duplicate re-enable of G1Add and rejected with
'PrecompileUpgrade (bls12381G1AddConfig) at [N]: disable should be [true]'.

This forced Lux Neo's PR #114 to drop all bls12381 sub-configs from
mainnet upgrade.json, leaving the PQ precompile suite incomplete.

Fix: one Config type and one Configurator per sub-config (G1AddConfig,
G1MulConfig, ...), each with its own Key() returning its own ConfigKey.
Composition over inheritance — the shared precompileconfig.Upgrade is
embedded by value, the operation-distinguishing identity lives in the
type. JSON round-trip is now guaranteed at the type level.

Tests cover:
- TestConfig_KeyPerSubConfig_NoCollision: 7 unique keys, no collapse
- TestModule_ConfigKey_MatchesConfigKey: Module.ConfigKey ≡ MakeConfig().Key()
- TestConfig_JSONRoundTrip_PerSubConfig: marshal→unmarshal preserves Key+Equal
- TestConfig_Equal_WrongType: cross-type equality is false (type-level guard)

No backwards-compat shim: bls12381.Config and bls12381.configurator are
gone; the new exported types are G1AddConfig..PairingConfig. Downstream
upgrade.json that already only writes the JSON form (key strings) is
unaffected; any Go code constructing bls12381.Config directly must switch
to the per-op type matching its ConfigKey.
This commit is contained in:
Hanzo AI
2026-06-03 11:25:31 -07:00
parent 7302d76d91
commit 29d5b073b5
2 changed files with 411 additions and 49 deletions
+184 -24
View File
@@ -4,64 +4,224 @@
package bls12381
import (
"encoding/json"
"testing"
bls "github.com/consensys/gnark-crypto/ecc/bls12-381"
"github.com/luxfi/precompile/contract"
"github.com/luxfi/precompile/modules"
"github.com/luxfi/precompile/precompileconfig"
"github.com/stretchr/testify/require"
)
// --- Config tests ---
//
// The bls12381 module exposes seven distinct EIP-2537 precompiles. Each must
// have its OWN Config type whose Key() returns the matching ConfigKey constant.
// Sharing a single Config (the pre-v0.5.35 bug) collapsed upgrade-history
// grouping in evm/params/extras/precompile_upgrade.go and caused upgrade.json
// entries for non-G1Add sub-configs to be rejected with
// "PrecompileUpgrade (bls12381G1AddConfig) at [N]: disable should be [true]".
func TestConfig_Key(t *testing.T) {
require.Equal(t, G1AddConfigKey, (&Config{}).Key())
// configCase pairs a per-op Config zero-value-constructor with its expected key
// and the matching Configurator. Test cases iterate this table so adding a new
// sub-config (e.g. MapG1) forces exactly one table-entry edit and zero test
// duplication.
type configCase struct {
name string
make func(ts *uint64, disable bool) precompileconfig.Config
wantKey string
makeOther func(ts *uint64, disable bool) precompileconfig.Config // mismatched type
configurator contract.Configurator
}
var configCases = []configCase{
{"G1Add", func(ts *uint64, d bool) precompileconfig.Config {
return &G1AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, G1AddConfigKey, func(ts *uint64, d bool) precompileconfig.Config {
return &G1MulConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, &g1AddConfigurator{}},
{"G1Mul", func(ts *uint64, d bool) precompileconfig.Config {
return &G1MulConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, G1MulConfigKey, func(ts *uint64, d bool) precompileconfig.Config {
return &G1AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, &g1MulConfigurator{}},
{"G1MSM", func(ts *uint64, d bool) precompileconfig.Config {
return &G1MSMConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, G1MSMConfigKey, func(ts *uint64, d bool) precompileconfig.Config {
return &G1AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, &g1MSMConfigurator{}},
{"G2Add", func(ts *uint64, d bool) precompileconfig.Config {
return &G2AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, G2AddConfigKey, func(ts *uint64, d bool) precompileconfig.Config {
return &G1AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, &g2AddConfigurator{}},
{"G2Mul", func(ts *uint64, d bool) precompileconfig.Config {
return &G2MulConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, G2MulConfigKey, func(ts *uint64, d bool) precompileconfig.Config {
return &G1AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, &g2MulConfigurator{}},
{"G2MSM", func(ts *uint64, d bool) precompileconfig.Config {
return &G2MSMConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, G2MSMConfigKey, func(ts *uint64, d bool) precompileconfig.Config {
return &G1AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, &g2MSMConfigurator{}},
{"Pairing", func(ts *uint64, d bool) precompileconfig.Config {
return &PairingConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, PairingConfigKey, func(ts *uint64, d bool) precompileconfig.Config {
return &G1AddConfig{Upgrade: precompileconfig.Upgrade{BlockTimestamp: ts, Disable: d}}
}, &pairingConfigurator{}},
}
func TestConfig_KeyPerSubConfig_NoCollision(t *testing.T) {
// Hard regression pin for the v0.5.23..v0.5.34 bug: every sub-config must
// report its OWN key. A shared Key() (returning G1AddConfigKey) caused
// upgrade.json to reject the 2nd-and-later bls12381 sub-config entries.
seen := make(map[string]string)
for _, c := range configCases {
key := c.make(nil, false).Key()
require.Equal(t, c.wantKey, key, "%s.Key()", c.name)
if prev, dup := seen[key]; dup {
t.Fatalf("Key collision: %s and %s both return %q", prev, c.name, key)
}
seen[key] = c.name
}
require.Len(t, seen, 7, "expected exactly 7 unique bls12381 config keys")
}
func TestConfig_Timestamp_Nil(t *testing.T) {
require.Nil(t, (&Config{}).Timestamp())
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
require.Nil(t, c.make(nil, false).Timestamp())
})
}
}
func TestConfig_Timestamp_Set(t *testing.T) {
ts := uint64(999)
c := &Config{Upgrade: precompileconfig.Upgrade{BlockTimestamp: &ts}}
require.Equal(t, &ts, c.Timestamp())
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
ts := uint64(999)
require.Equal(t, &ts, c.make(&ts, false).Timestamp())
})
}
}
func TestConfig_IsDisabled(t *testing.T) {
require.False(t, (&Config{}).IsDisabled())
require.True(t, (&Config{Upgrade: precompileconfig.Upgrade{Disable: true}}).IsDisabled())
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
require.False(t, c.make(nil, false).IsDisabled())
require.True(t, c.make(nil, true).IsDisabled())
})
}
}
func TestConfig_Equal_Same(t *testing.T) {
ts := uint64(100)
c1 := &Config{Upgrade: precompileconfig.Upgrade{BlockTimestamp: &ts}}
c2 := &Config{Upgrade: precompileconfig.Upgrade{BlockTimestamp: &ts}}
require.True(t, c1.Equal(c2))
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
ts := uint64(100)
require.True(t, c.make(&ts, false).Equal(c.make(&ts, false)))
})
}
}
func TestConfig_Equal_Different(t *testing.T) {
ts1, ts2 := uint64(100), uint64(200)
c1 := &Config{Upgrade: precompileconfig.Upgrade{BlockTimestamp: &ts1}}
c2 := &Config{Upgrade: precompileconfig.Upgrade{BlockTimestamp: &ts2}}
require.False(t, c1.Equal(c2))
func TestConfig_Equal_DifferentTimestamp(t *testing.T) {
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
ts1, ts2 := uint64(100), uint64(200)
require.False(t, c.make(&ts1, false).Equal(c.make(&ts2, false)))
})
}
}
func TestConfig_Equal_WrongType(t *testing.T) {
require.False(t, (&Config{}).Equal(nil))
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
// Cross-type equality must be false: G1Add ≠ G1Mul even if their
// Upgrade fields match byte-for-byte. This guards the type-level
// separation that the bug previously violated.
ts := uint64(100)
require.False(t, c.make(&ts, false).Equal(c.makeOther(&ts, false)))
require.False(t, c.make(nil, false).Equal(nil))
})
}
}
func TestConfig_Verify(t *testing.T) {
require.NoError(t, (&Config{}).Verify(nil))
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
require.NoError(t, c.make(nil, false).Verify(nil))
})
}
}
func TestConfigurator_MakeConfig(t *testing.T) {
cfg := (&configurator{}).MakeConfig()
_, ok := cfg.(*Config)
require.True(t, ok)
func TestConfigurator_MakeConfig_ReturnsMatchingType(t *testing.T) {
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
cfg := c.configurator.MakeConfig()
require.Equal(t, c.wantKey, cfg.Key(),
"%s configurator MakeConfig().Key() must equal %s", c.name, c.wantKey)
})
}
}
func TestConfigurator_Configure(t *testing.T) {
require.NoError(t, (&configurator{}).Configure(nil, nil, nil, nil))
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
require.NoError(t, c.configurator.Configure(nil, nil, nil, nil))
})
}
}
// TestModule_ConfigKey_MatchesConfigKey is the end-to-end pin: the key under
// which a Module registers in the global registry MUST equal the key its
// MakeConfig().Key() reports. If these diverge, JSON round-trip in
// upgrade.PrecompileUpgrade.UnmarshalJSON → MarshalJSON breaks (the upstream
// failure that surfaced this bug).
func TestModule_ConfigKey_MatchesConfigKey(t *testing.T) {
mods := []struct {
name string
key string
mod modules.Module
}{
{"G1Add", G1AddConfigKey, G1AddModule},
{"G1Mul", G1MulConfigKey, G1MulModule},
{"G1MSM", G1MSMConfigKey, G1MSMModule},
{"G2Add", G2AddConfigKey, G2AddModule},
{"G2Mul", G2MulConfigKey, G2MulModule},
{"G2MSM", G2MSMConfigKey, G2MSMModule},
{"Pairing", PairingConfigKey, PairingModule},
}
for _, m := range mods {
t.Run(m.name, func(t *testing.T) {
require.Equal(t, m.key, m.mod.ConfigKey, "%s Module.ConfigKey", m.name)
require.Equal(t, m.key, m.mod.MakeConfig().Key(),
"%s MakeConfig().Key() must equal Module.ConfigKey — divergence breaks upgrade.json round-trip", m.name)
})
}
}
// TestConfig_JSONRoundTrip_PerSubConfig pins that a real upgrade.json blob for
// each sub-config marshals back to itself. This is the precise reproducer for
// Lux Neo PR #114's "disable should be [true]" surface: with the shared-Key
// bug, the second sub-config in the array round-tripped to G1AddConfig and
// collided in lastPrecompileUpgrades grouping.
func TestConfig_JSONRoundTrip_PerSubConfig(t *testing.T) {
ts := uint64(1766708400) // Quasar activation
for _, c := range configCases {
t.Run(c.name, func(t *testing.T) {
orig := c.make(&ts, false)
// Marshal then unmarshal through the configurator's MakeConfig.
body, err := json.Marshal(orig)
require.NoError(t, err)
rt := c.configurator.MakeConfig()
require.NoError(t, json.Unmarshal(body, rt))
require.Equal(t, c.wantKey, rt.Key())
require.True(t, orig.Equal(rt), "JSON round-trip must preserve Equal")
})
}
}
// --- msmGas discount table ---
+227 -25
View File
@@ -10,9 +10,32 @@ import (
"github.com/luxfi/precompile/precompileconfig"
)
var _ contract.Configurator = (*configurator)(nil)
// Compile-time guarantees that every per-operation configurator satisfies
// contract.Configurator and every per-operation Config satisfies
// precompileconfig.Config. These are intentionally repeated per type so a
// future renaming caught by the compiler instead of by a runtime config-key
// collision (the precise bug this file was rewritten to fix).
var (
_ contract.Configurator = (*g1AddConfigurator)(nil)
_ contract.Configurator = (*g1MulConfigurator)(nil)
_ contract.Configurator = (*g1MSMConfigurator)(nil)
_ contract.Configurator = (*g2AddConfigurator)(nil)
_ contract.Configurator = (*g2MulConfigurator)(nil)
_ contract.Configurator = (*g2MSMConfigurator)(nil)
_ contract.Configurator = (*pairingConfigurator)(nil)
_ precompileconfig.Config = (*G1AddConfig)(nil)
_ precompileconfig.Config = (*G1MulConfig)(nil)
_ precompileconfig.Config = (*G1MSMConfig)(nil)
_ precompileconfig.Config = (*G2AddConfig)(nil)
_ precompileconfig.Config = (*G2MulConfig)(nil)
_ precompileconfig.Config = (*G2MSMConfig)(nil)
_ precompileconfig.Config = (*PairingConfig)(nil)
)
// Config keys for each EIP-2537 operation (unique per module).
// These are the JSON identity of each precompile in upgrade.json. Every
// sub-config returns exactly one of these from its Key() method — one value,
// named at exactly one site.
const (
G1AddConfigKey = "bls12381G1AddConfig"
G1MulConfigKey = "bls12381G1MulConfig"
@@ -23,49 +46,53 @@ const (
PairingConfigKey = "bls12381PairingConfig"
)
// Modules registers one module per EIP-2537 address (0x0B-0x11).
// Modules registers one module per EIP-2537 address (0x0B-0x11). Each
// module gets its own Configurator so MakeConfig() returns a Config whose
// Key() matches the module's ConfigKey — this is what allows upgrade.json
// to list all seven sub-configs without the upgrade-history grouping
// collapsing them into one entry.
var (
G1AddModule = modules.Module{
ConfigKey: G1AddConfigKey,
Address: G1AddAddress,
Contract: &g1AddPrecompile{},
Configurator: &configurator{},
Configurator: &g1AddConfigurator{},
}
G1MulModule = modules.Module{
ConfigKey: G1MulConfigKey,
Address: G1MulAddress,
Contract: &g1MulPrecompile{},
Configurator: &configurator{},
Configurator: &g1MulConfigurator{},
}
G1MSMModule = modules.Module{
ConfigKey: G1MSMConfigKey,
Address: G1MSMAddress,
Contract: &g1MSMPrecompile{},
Configurator: &configurator{},
Configurator: &g1MSMConfigurator{},
}
G2AddModule = modules.Module{
ConfigKey: G2AddConfigKey,
Address: G2AddAddress,
Contract: &g2AddPrecompile{},
Configurator: &configurator{},
Configurator: &g2AddConfigurator{},
}
G2MulModule = modules.Module{
ConfigKey: G2MulConfigKey,
Address: G2MulAddress,
Contract: &g2MulPrecompile{},
Configurator: &configurator{},
Configurator: &g2MulConfigurator{},
}
G2MSMModule = modules.Module{
ConfigKey: G2MSMConfigKey,
Address: G2MSMAddress,
Contract: &g2MSMPrecompile{},
Configurator: &configurator{},
Configurator: &g2MSMConfigurator{},
}
PairingModule = modules.Module{
ConfigKey: PairingConfigKey,
Address: PairingAddress,
Contract: &pairingPrecompile{},
Configurator: &configurator{},
Configurator: &pairingConfigurator{},
}
)
@@ -200,12 +227,131 @@ func (p *pairingPrecompile) Run(
return blsOps.pairing(input, suppliedGas)
}
// configurator is shared across all 7 modules (no per-op config needed).
type configurator struct{}
// Per-operation Config types. Each composes the shared precompileconfig.Upgrade
// (timestamp + disable flag) and overrides Key() to return its own JSON
// identity. All other Config-interface methods are mechanically identical;
// implementing them per-type costs ~10 lines each but keeps the value-naming
// invariant (one Config type, one Key) inviolate at the type level.
func (*configurator) MakeConfig() precompileconfig.Config { return new(Config) }
type G1AddConfig struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
}
func (*configurator) Configure(
func (c *G1AddConfig) Key() string { return G1AddConfigKey }
func (c *G1AddConfig) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *G1AddConfig) IsDisabled() bool { return c.Upgrade.Disable }
func (c *G1AddConfig) Verify(precompileconfig.ChainConfig) error { return nil }
func (c *G1AddConfig) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*G1AddConfig)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
}
type G1MulConfig struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
}
func (c *G1MulConfig) Key() string { return G1MulConfigKey }
func (c *G1MulConfig) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *G1MulConfig) IsDisabled() bool { return c.Upgrade.Disable }
func (c *G1MulConfig) Verify(precompileconfig.ChainConfig) error { return nil }
func (c *G1MulConfig) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*G1MulConfig)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
}
type G1MSMConfig struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
}
func (c *G1MSMConfig) Key() string { return G1MSMConfigKey }
func (c *G1MSMConfig) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *G1MSMConfig) IsDisabled() bool { return c.Upgrade.Disable }
func (c *G1MSMConfig) Verify(precompileconfig.ChainConfig) error { return nil }
func (c *G1MSMConfig) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*G1MSMConfig)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
}
type G2AddConfig struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
}
func (c *G2AddConfig) Key() string { return G2AddConfigKey }
func (c *G2AddConfig) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *G2AddConfig) IsDisabled() bool { return c.Upgrade.Disable }
func (c *G2AddConfig) Verify(precompileconfig.ChainConfig) error { return nil }
func (c *G2AddConfig) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*G2AddConfig)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
}
type G2MulConfig struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
}
func (c *G2MulConfig) Key() string { return G2MulConfigKey }
func (c *G2MulConfig) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *G2MulConfig) IsDisabled() bool { return c.Upgrade.Disable }
func (c *G2MulConfig) Verify(precompileconfig.ChainConfig) error { return nil }
func (c *G2MulConfig) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*G2MulConfig)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
}
type G2MSMConfig struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
}
func (c *G2MSMConfig) Key() string { return G2MSMConfigKey }
func (c *G2MSMConfig) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *G2MSMConfig) IsDisabled() bool { return c.Upgrade.Disable }
func (c *G2MSMConfig) Verify(precompileconfig.ChainConfig) error { return nil }
func (c *G2MSMConfig) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*G2MSMConfig)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
}
type PairingConfig struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
}
func (c *PairingConfig) Key() string { return PairingConfigKey }
func (c *PairingConfig) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *PairingConfig) IsDisabled() bool { return c.Upgrade.Disable }
func (c *PairingConfig) Verify(precompileconfig.ChainConfig) error { return nil }
func (c *PairingConfig) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*PairingConfig)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
}
// Per-operation Configurators. Each MakeConfig() returns the matching Config
// type so JSON unmarshal into upgrade.PrecompileUpgrade lands the right Key().
type g1AddConfigurator struct{}
func (*g1AddConfigurator) MakeConfig() precompileconfig.Config { return new(G1AddConfig) }
func (*g1AddConfigurator) Configure(
chainConfig precompileconfig.ChainConfig,
cfg precompileconfig.Config,
state contract.StateDB,
@@ -214,18 +360,74 @@ func (*configurator) Configure(
return nil
}
type Config struct {
Upgrade precompileconfig.Upgrade `json:"upgrade"`
type g1MulConfigurator struct{}
func (*g1MulConfigurator) MakeConfig() precompileconfig.Config { return new(G1MulConfig) }
func (*g1MulConfigurator) Configure(
chainConfig precompileconfig.ChainConfig,
cfg precompileconfig.Config,
state contract.StateDB,
blockContext contract.ConfigurationBlockContext,
) error {
return nil
}
func (c *Config) Key() string { return G1AddConfigKey }
func (c *Config) Timestamp() *uint64 { return c.Upgrade.Timestamp() }
func (c *Config) IsDisabled() bool { return c.Upgrade.Disable }
func (c *Config) Equal(cfg precompileconfig.Config) bool {
other, ok := cfg.(*Config)
if !ok {
return false
}
return c.Upgrade.Equal(&other.Upgrade)
type g1MSMConfigurator struct{}
func (*g1MSMConfigurator) MakeConfig() precompileconfig.Config { return new(G1MSMConfig) }
func (*g1MSMConfigurator) Configure(
chainConfig precompileconfig.ChainConfig,
cfg precompileconfig.Config,
state contract.StateDB,
blockContext contract.ConfigurationBlockContext,
) error {
return nil
}
type g2AddConfigurator struct{}
func (*g2AddConfigurator) MakeConfig() precompileconfig.Config { return new(G2AddConfig) }
func (*g2AddConfigurator) Configure(
chainConfig precompileconfig.ChainConfig,
cfg precompileconfig.Config,
state contract.StateDB,
blockContext contract.ConfigurationBlockContext,
) error {
return nil
}
type g2MulConfigurator struct{}
func (*g2MulConfigurator) MakeConfig() precompileconfig.Config { return new(G2MulConfig) }
func (*g2MulConfigurator) Configure(
chainConfig precompileconfig.ChainConfig,
cfg precompileconfig.Config,
state contract.StateDB,
blockContext contract.ConfigurationBlockContext,
) error {
return nil
}
type g2MSMConfigurator struct{}
func (*g2MSMConfigurator) MakeConfig() precompileconfig.Config { return new(G2MSMConfig) }
func (*g2MSMConfigurator) Configure(
chainConfig precompileconfig.ChainConfig,
cfg precompileconfig.Config,
state contract.StateDB,
blockContext contract.ConfigurationBlockContext,
) error {
return nil
}
type pairingConfigurator struct{}
func (*pairingConfigurator) MakeConfig() precompileconfig.Config { return new(PairingConfig) }
func (*pairingConfigurator) Configure(
chainConfig precompileconfig.ChainConfig,
cfg precompileconfig.Config,
state contract.StateDB,
blockContext contract.ConfigurationBlockContext,
) error {
return nil
}
func (c *Config) Verify(precompileconfig.ChainConfig) error { return nil }