prevent users from misconfiguring their nodes so that fork ordering is not preserved.
This commit is contained in:
parent
028af3457d
commit
c476460cb2
@ -1318,7 +1318,7 @@ func TestEIP155Transition(t *testing.T) {
|
|||||||
funds = big.NewInt(1000000000)
|
funds = big.NewInt(1000000000)
|
||||||
deleteAddr = common.Address{1}
|
deleteAddr = common.Address{1}
|
||||||
gspec = &Genesis{
|
gspec = &Genesis{
|
||||||
Config: ¶ms.ChainConfig{ChainID: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
|
Config: ¶ms.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
|
||||||
Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
|
Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
|
||||||
}
|
}
|
||||||
genesis = gspec.MustCommit(db)
|
genesis = gspec.MustCommit(db)
|
||||||
@ -1389,7 +1389,7 @@ func TestEIP155Transition(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generate an invalid chain id transaction
|
// generate an invalid chain id transaction
|
||||||
config := ¶ms.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
|
config := ¶ms.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
|
||||||
blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
|
blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
|
||||||
var (
|
var (
|
||||||
tx *types.Transaction
|
tx *types.Transaction
|
||||||
@ -1425,6 +1425,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
|
|||||||
ChainID: big.NewInt(1),
|
ChainID: big.NewInt(1),
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
EIP155Block: new(big.Int),
|
EIP155Block: new(big.Int),
|
||||||
|
EIP150Block: new(big.Int),
|
||||||
EIP158Block: big.NewInt(2),
|
EIP158Block: big.NewInt(2),
|
||||||
},
|
},
|
||||||
Alloc: GenesisAlloc{address: {Balance: funds}},
|
Alloc: GenesisAlloc{address: {Balance: funds}},
|
||||||
|
@ -207,6 +207,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
|
|||||||
if overrideIstanbul != nil {
|
if overrideIstanbul != nil {
|
||||||
newcfg.IstanbulBlock = overrideIstanbul
|
newcfg.IstanbulBlock = overrideIstanbul
|
||||||
}
|
}
|
||||||
|
if err := newcfg.CheckConfigForkOrder(); err != nil {
|
||||||
|
return newcfg, common.Hash{}, err
|
||||||
|
}
|
||||||
storedcfg := rawdb.ReadChainConfig(db, stored)
|
storedcfg := rawdb.ReadChainConfig(db, stored)
|
||||||
if storedcfg == nil {
|
if storedcfg == nil {
|
||||||
log.Warn("Found genesis block without chain config")
|
log.Warn("Found genesis block without chain config")
|
||||||
@ -295,6 +298,13 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
|
|||||||
if block.Number().Sign() != 0 {
|
if block.Number().Sign() != 0 {
|
||||||
return nil, fmt.Errorf("can't commit genesis block with number > 0")
|
return nil, fmt.Errorf("can't commit genesis block with number > 0")
|
||||||
}
|
}
|
||||||
|
config := g.Config
|
||||||
|
if config == nil {
|
||||||
|
config = params.AllEthashProtocolChanges
|
||||||
|
}
|
||||||
|
if err := config.CheckConfigForkOrder(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
|
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
|
||||||
rawdb.WriteBlock(db, block)
|
rawdb.WriteBlock(db, block)
|
||||||
rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
|
rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
|
||||||
@ -302,11 +312,6 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
|
|||||||
rawdb.WriteHeadBlockHash(db, block.Hash())
|
rawdb.WriteHeadBlockHash(db, block.Hash())
|
||||||
rawdb.WriteHeadFastBlockHash(db, block.Hash())
|
rawdb.WriteHeadFastBlockHash(db, block.Hash())
|
||||||
rawdb.WriteHeadHeaderHash(db, block.Hash())
|
rawdb.WriteHeadHeaderHash(db, block.Hash())
|
||||||
|
|
||||||
config := g.Config
|
|
||||||
if config == nil {
|
|
||||||
config = params.AllEthashProtocolChanges
|
|
||||||
}
|
|
||||||
rawdb.WriteChainConfig(db, block.Hash(), config)
|
rawdb.WriteChainConfig(db, block.Hash(), config)
|
||||||
return block, nil
|
return block, nil
|
||||||
}
|
}
|
||||||
|
@ -415,6 +415,42 @@ func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *Confi
|
|||||||
return lasterr
|
return lasterr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
|
||||||
|
// to guarantee that forks
|
||||||
|
func (c *ChainConfig) CheckConfigForkOrder() error {
|
||||||
|
type fork struct {
|
||||||
|
name string
|
||||||
|
block *big.Int
|
||||||
|
}
|
||||||
|
var lastFork fork
|
||||||
|
for _, cur := range []fork{
|
||||||
|
{"homesteadBlock", c.HomesteadBlock},
|
||||||
|
{"eip150Block", c.EIP150Block},
|
||||||
|
{"eip155Block", c.EIP155Block},
|
||||||
|
{"eip158Block", c.EIP158Block},
|
||||||
|
{"byzantiumBlock", c.ByzantiumBlock},
|
||||||
|
{"constantinopleBlock", c.ConstantinopleBlock},
|
||||||
|
{"petersburgBlock", c.PetersburgBlock},
|
||||||
|
{"istanbulBlock", c.IstanbulBlock},
|
||||||
|
} {
|
||||||
|
if lastFork.name != "" {
|
||||||
|
// Next one must be higher number
|
||||||
|
if lastFork.block == nil && cur.block != nil {
|
||||||
|
return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
|
||||||
|
lastFork.name, cur.name, cur.block)
|
||||||
|
}
|
||||||
|
if lastFork.block != nil && cur.block != nil {
|
||||||
|
if lastFork.block.Cmp(cur.block) > 0 {
|
||||||
|
return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
|
||||||
|
lastFork.name, lastFork.block, cur.name, cur.block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastFork = cur
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
|
func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
|
||||||
if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
|
if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
|
||||||
return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
|
return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
|
||||||
|
Loading…
Reference in New Issue
Block a user