From fec40ae8b9e294ae0a87afe6cdb956e2d8ed621a Mon Sep 17 00:00:00 2001 From: dean65 Date: Wed, 16 Mar 2022 10:59:25 +0800 Subject: [PATCH 1/2] force check that Euler height cannot be a multiple of 200 --- core/genesis.go | 3 ++ params/config.go | 10 ++++ params/config_test.go | 105 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/core/genesis.go b/core/genesis.go index 94bb06dd77..6c7f72f613 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -210,6 +210,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override if err := newcfg.CheckConfigForkOrder(); err != nil { return newcfg, common.Hash{}, err } + if err := newcfg.VerifyForkConfig(); err != nil { + return newcfg, common.Hash{}, err + } storedcfg := rawdb.ReadChainConfig(db, stored) if storedcfg == nil { log.Warn("Found genesis block without chain config") diff --git a/params/config.go b/params/config.go index 2adf76ecca..a5f89e211c 100644 --- a/params/config.go +++ b/params/config.go @@ -18,6 +18,7 @@ package params import ( "encoding/binary" + "errors" "fmt" "math/big" @@ -756,6 +757,15 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi return nil } +func (c *ChainConfig) VerifyForkConfig() error { + if c.EulerBlock != nil && c.EulerBlock.Cmp(common.Big0) != 0 { + if _, mod := new(big.Int).DivMod(c.EulerBlock, big.NewInt(200), new(big.Int)); mod.Cmp(common.Big0) == 0 { + return errors.New("euler height can't be multiple of 200") + } + } + return nil +} + // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to // block s2 because head is already past the fork. func isForkIncompatible(s1, s2, head *big.Int) bool { diff --git a/params/config_test.go b/params/config_test.go index 3c8ebaf4a5..cc07d4b40c 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -20,6 +20,8 @@ import ( "math/big" "reflect" "testing" + + "github.com/ethereum/go-ethereum/common" ) func TestCheckCompatible(t *testing.T) { @@ -96,3 +98,106 @@ func TestCheckCompatible(t *testing.T) { } } } + +func TestChainConfig_VerifyForkConfig(t *testing.T) { + type fields struct { + ChainID *big.Int + HomesteadBlock *big.Int + DAOForkBlock *big.Int + DAOForkSupport bool + EIP150Block *big.Int + EIP150Hash common.Hash + EIP155Block *big.Int + EIP158Block *big.Int + ByzantiumBlock *big.Int + ConstantinopleBlock *big.Int + PetersburgBlock *big.Int + IstanbulBlock *big.Int + MuirGlacierBlock *big.Int + BerlinBlock *big.Int + YoloV3Block *big.Int + EWASMBlock *big.Int + CatalystBlock *big.Int + RamanujanBlock *big.Int + NielsBlock *big.Int + MirrorSyncBlock *big.Int + BrunoBlock *big.Int + EulerBlock *big.Int + Ethash *EthashConfig + Clique *CliqueConfig + Parlia *ParliaConfig + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "Test VerifyForkConfig Case 1", + fields: fields{}, + wantErr: false, + }, + { + name: "Test VerifyForkConfig Case 2", + fields: fields{ + EulerBlock: big.NewInt(0), + }, + wantErr: false, + }, + { + name: "Test VerifyForkConfig Case 3", + fields: fields{ + EulerBlock: big.NewInt(200), + }, + wantErr: true, + }, + { + name: "Test VerifyForkConfig Case 4", + fields: fields{ + EulerBlock: big.NewInt(19231208), + }, + wantErr: false, + }, + { + name: "Test VerifyForkConfig Case 5", + fields: fields{ + EulerBlock: big.NewInt(1998200), + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ChainConfig{ + ChainID: tt.fields.ChainID, + HomesteadBlock: tt.fields.HomesteadBlock, + DAOForkBlock: tt.fields.DAOForkBlock, + DAOForkSupport: tt.fields.DAOForkSupport, + EIP150Block: tt.fields.EIP150Block, + EIP150Hash: tt.fields.EIP150Hash, + EIP155Block: tt.fields.EIP155Block, + EIP158Block: tt.fields.EIP158Block, + ByzantiumBlock: tt.fields.ByzantiumBlock, + ConstantinopleBlock: tt.fields.ConstantinopleBlock, + PetersburgBlock: tt.fields.PetersburgBlock, + IstanbulBlock: tt.fields.IstanbulBlock, + MuirGlacierBlock: tt.fields.MuirGlacierBlock, + BerlinBlock: tt.fields.BerlinBlock, + YoloV3Block: tt.fields.YoloV3Block, + EWASMBlock: tt.fields.EWASMBlock, + CatalystBlock: tt.fields.CatalystBlock, + RamanujanBlock: tt.fields.RamanujanBlock, + NielsBlock: tt.fields.NielsBlock, + MirrorSyncBlock: tt.fields.MirrorSyncBlock, + BrunoBlock: tt.fields.BrunoBlock, + EulerBlock: tt.fields.EulerBlock, + Ethash: tt.fields.Ethash, + Clique: tt.fields.Clique, + Parlia: tt.fields.Parlia, + } + if err := c.VerifyForkConfig(); (err != nil) != tt.wantErr { + t.Errorf("ChainConfig.VerifyForkConfig() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From e58ffe8a590aa58ac8cfb29c39dc642e1de6448f Mon Sep 17 00:00:00 2001 From: dean65 Date: Wed, 16 Mar 2022 11:21:56 +0800 Subject: [PATCH 2/2] fix String() function of ChainConfig --- params/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/config.go b/params/config.go index a5f89e211c..0fb2471317 100644 --- a/params/config.go +++ b/params/config.go @@ -497,7 +497,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, Engine: %v, Euler: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, Euler: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock,