diff --git a/cmd/geth/dao_test.go b/cmd/geth/dao_test.go index 59730b17f..56e77ba0b 100644 --- a/cmd/geth/dao_test.go +++ b/cmd/geth/dao_test.go @@ -116,19 +116,19 @@ func TestDAOInitOldPrivnet(t *testing.T) { testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{}, nil, false) } func TestDAODefaultOldPrivnet(t *testing.T) { - testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, false}}, params.MainNetDAOForkBlock, true) + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, false}}, nil, false) } func TestDAOSupportOldPrivnet(t *testing.T) { - testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}}, params.MainNetDAOForkBlock, true) + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}}, nil, true) } func TestDAOOpposeOldPrivnet(t *testing.T) { - testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}}, params.MainNetDAOForkBlock, false) + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}}, nil, false) } func TestDAOSwitchToSupportOldPrivnet(t *testing.T) { - testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}, {true, false}}, params.MainNetDAOForkBlock, true) + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}, {true, false}}, nil, true) } func TestDAOSwitchToOpposeOldPrivnet(t *testing.T) { - testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}, {false, true}}, params.MainNetDAOForkBlock, false) + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}, {false, true}}, nil, false) } func TestDAOInitNoForkPrivnet(t *testing.T) { testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{}, daoGenesisForkBlock, false) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index abfb4d1e7..edb0873f6 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -781,27 +781,43 @@ func MakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfi Fatalf("Could not make chain configuration: %v", err) } } - // Set any missing fields due to them being unset or system upgrade - if config.HomesteadBlock == nil { - if ctx.GlobalBool(TestNetFlag.Name) { - config.HomesteadBlock = params.TestNetHomesteadBlock - } else { - config.HomesteadBlock = params.MainNetHomesteadBlock + // Check whether we are allowed to set default config params or not: + // - If no genesis is set, we're running either mainnet or testnet (private nets use `geth init`) + // - If a genesis is already set, ensure we have a configuration for it (mainnet or testnet) + defaults := genesis == nil || + (genesis.Hash() == params.MainNetGenesisHash && !ctx.GlobalBool(TestNetFlag.Name)) || + (genesis.Hash() == params.TestNetGenesisHash && ctx.GlobalBool(TestNetFlag.Name)) + + // Set any missing chainConfig fields due to them being unset or system upgrade + if defaults { + if config.HomesteadBlock == nil { + if ctx.GlobalBool(TestNetFlag.Name) { + config.HomesteadBlock = params.TestNetHomesteadBlock + } else { + config.HomesteadBlock = params.MainNetHomesteadBlock + } } - } - if config.DAOForkBlock == nil { - if ctx.GlobalBool(TestNetFlag.Name) { - config.DAOForkBlock = params.TestNetDAOForkBlock - } else { - config.DAOForkBlock = params.MainNetDAOForkBlock + if config.DAOForkBlock == nil { + if ctx.GlobalBool(TestNetFlag.Name) { + config.DAOForkBlock = params.TestNetDAOForkBlock + } else { + config.DAOForkBlock = params.MainNetDAOForkBlock + } + config.DAOForkSupport = true } - config.DAOForkSupport = true - } - if config.HomesteadGasRepriceBlock == nil { - if ctx.GlobalBool(TestNetFlag.Name) { - config.HomesteadGasRepriceBlock = params.TestNetHomesteadGasRepriceBlock - } else { - config.HomesteadGasRepriceBlock = params.MainNetHomesteadGasRepriceBlock + if config.HomesteadGasRepriceBlock == nil { + if ctx.GlobalBool(TestNetFlag.Name) { + config.HomesteadGasRepriceBlock = params.TestNetHomesteadGasRepriceBlock + } else { + config.HomesteadGasRepriceBlock = params.MainNetHomesteadGasRepriceBlock + } + } + if config.HomesteadGasRepriceHash == (common.Hash{}) { + if ctx.GlobalBool(TestNetFlag.Name) { + config.HomesteadGasRepriceHash = params.TestNetHomesteadGasRepriceHash + } else { + config.HomesteadGasRepriceHash = params.MainNetHomesteadGasRepriceHash + } } } // Force override any existing configs if explicitly requested diff --git a/core/block_validator.go b/core/block_validator.go index e5bc6178b..1bb1a9713 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -248,7 +248,15 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare } } // If all checks passed, validate the extra-data field for hard forks - return ValidateDAOHeaderExtraData(config, header) + if err := ValidateDAOHeaderExtraData(config, header); err != nil { + return err + } + if config.HomesteadGasRepriceBlock != nil && config.HomesteadGasRepriceBlock.Cmp(header.Number) == 0 { + if config.HomesteadGasRepriceHash != (common.Hash{}) && config.HomesteadGasRepriceHash != header.Hash() { + return ValidationError("Homestead gas reprice fork hash mismatch: have 0x%x, want 0x%x", header.Hash(), config.HomesteadGasRepriceHash) + } + } + return nil } // CalcDifficulty is the difficulty adjustment algorithm. It returns diff --git a/core/config.go b/core/config.go index 3ab04e520..96e39ea3c 100644 --- a/core/config.go +++ b/core/config.go @@ -20,6 +20,7 @@ import ( "errors" "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" ) @@ -36,7 +37,8 @@ type ChainConfig struct { DAOForkBlock *big.Int `json:"daoForkBlock"` // TheDAO hard-fork switch block (nil = no fork) DAOForkSupport bool `json:"daoForkSupport"` // Whether the nodes supports or opposes the DAO hard-fork - HomesteadGasRepriceBlock *big.Int `json:"homesteadGasRepriceBlock"` // Homestead gas reprice switch block (nil = no fork) + HomesteadGasRepriceBlock *big.Int `json:"homesteadGasRepriceBlock"` // Homestead gas reprice switch block (nil = no fork) + HomesteadGasRepriceHash common.Hash `json:"homesteadGasRepriceHash"` // Homestead gas reprice switch block hash (fast sync aid) VmConfig vm.Config `json:"-"` } diff --git a/params/util.go b/params/util.go index 583cf03bb..63f571a17 100644 --- a/params/util.go +++ b/params/util.go @@ -16,11 +16,22 @@ package params -import "math/big" +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" +) var ( - TestNetHomesteadBlock = big.NewInt(494000) // Testnet homestead block - MainNetHomesteadBlock = big.NewInt(1150000) // Mainnet homestead block - TestNetHomesteadGasRepriceBlock = big.NewInt(1783000) // Test net gas reprice block - MainNetHomesteadGasRepriceBlock = big.NewInt(2463000) // Main net gas reprice block + TestNetGenesisHash = common.HexToHash("0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303") // Testnet genesis hash to enforce below configs on + MainNetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") // Mainnet genesis hash to enforce below configs on + + TestNetHomesteadBlock = big.NewInt(494000) // Testnet homestead block + MainNetHomesteadBlock = big.NewInt(1150000) // Mainnet homestead block + + TestNetHomesteadGasRepriceBlock = big.NewInt(1783000) // Testnet gas reprice block + MainNetHomesteadGasRepriceBlock = big.NewInt(2463000) // Mainnet gas reprice block + + TestNetHomesteadGasRepriceHash = common.HexToHash("0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145") // Testnet gas reprice block hash (used by fast sync) + MainNetHomesteadGasRepriceHash = common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0") // Mainnet gas reprice block hash (used by fast sync) )