Skip to content

Commit c476460

Browse files
authored
params: check fork ordering when initializing new genesis, fixes #20136 (#20169)
prevent users from misconfiguring their nodes so that fork ordering is not preserved.
1 parent 028af34 commit c476460

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

core/blockchain_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ func TestEIP155Transition(t *testing.T) {
13181318
funds = big.NewInt(1000000000)
13191319
deleteAddr = common.Address{1}
13201320
gspec = &Genesis{
1321-
Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
1321+
Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
13221322
Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
13231323
}
13241324
genesis = gspec.MustCommit(db)
@@ -1389,7 +1389,7 @@ func TestEIP155Transition(t *testing.T) {
13891389
}
13901390

13911391
// generate an invalid chain id transaction
1392-
config := &params.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
1392+
config := &params.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
13931393
blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
13941394
var (
13951395
tx *types.Transaction
@@ -1425,6 +1425,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
14251425
ChainID: big.NewInt(1),
14261426
HomesteadBlock: new(big.Int),
14271427
EIP155Block: new(big.Int),
1428+
EIP150Block: new(big.Int),
14281429
EIP158Block: big.NewInt(2),
14291430
},
14301431
Alloc: GenesisAlloc{address: {Balance: funds}},

core/genesis.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
207207
if overrideIstanbul != nil {
208208
newcfg.IstanbulBlock = overrideIstanbul
209209
}
210+
if err := newcfg.CheckConfigForkOrder(); err != nil {
211+
return newcfg, common.Hash{}, err
212+
}
210213
storedcfg := rawdb.ReadChainConfig(db, stored)
211214
if storedcfg == nil {
212215
log.Warn("Found genesis block without chain config")
@@ -295,18 +298,20 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
295298
if block.Number().Sign() != 0 {
296299
return nil, fmt.Errorf("can't commit genesis block with number > 0")
297300
}
301+
config := g.Config
302+
if config == nil {
303+
config = params.AllEthashProtocolChanges
304+
}
305+
if err := config.CheckConfigForkOrder(); err != nil {
306+
return nil, err
307+
}
298308
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
299309
rawdb.WriteBlock(db, block)
300310
rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
301311
rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
302312
rawdb.WriteHeadBlockHash(db, block.Hash())
303313
rawdb.WriteHeadFastBlockHash(db, block.Hash())
304314
rawdb.WriteHeadHeaderHash(db, block.Hash())
305-
306-
config := g.Config
307-
if config == nil {
308-
config = params.AllEthashProtocolChanges
309-
}
310315
rawdb.WriteChainConfig(db, block.Hash(), config)
311316
return block, nil
312317
}

params/config.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,42 @@ func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *Confi
415415
return lasterr
416416
}
417417

418+
// CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
419+
// to guarantee that forks
420+
func (c *ChainConfig) CheckConfigForkOrder() error {
421+
type fork struct {
422+
name string
423+
block *big.Int
424+
}
425+
var lastFork fork
426+
for _, cur := range []fork{
427+
{"homesteadBlock", c.HomesteadBlock},
428+
{"eip150Block", c.EIP150Block},
429+
{"eip155Block", c.EIP155Block},
430+
{"eip158Block", c.EIP158Block},
431+
{"byzantiumBlock", c.ByzantiumBlock},
432+
{"constantinopleBlock", c.ConstantinopleBlock},
433+
{"petersburgBlock", c.PetersburgBlock},
434+
{"istanbulBlock", c.IstanbulBlock},
435+
} {
436+
if lastFork.name != "" {
437+
// Next one must be higher number
438+
if lastFork.block == nil && cur.block != nil {
439+
return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
440+
lastFork.name, cur.name, cur.block)
441+
}
442+
if lastFork.block != nil && cur.block != nil {
443+
if lastFork.block.Cmp(cur.block) > 0 {
444+
return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
445+
lastFork.name, lastFork.block, cur.name, cur.block)
446+
}
447+
}
448+
}
449+
lastFork = cur
450+
}
451+
return nil
452+
}
453+
418454
func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
419455
if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
420456
return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)

0 commit comments

Comments
 (0)