mirror of
https://github.com/luxfi/precompile.git
synced 2026-07-27 03:33:45 +00:00
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:
+184
-24
@@ -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
@@ -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 }
|
||||
|
||||
Reference in New Issue
Block a user