From f0cbebb19f3137ee3ba0e66dadd1b5b9dbf98b1c Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Tue, 1 Mar 2016 23:32:43 +0100 Subject: core: added basic chain configuration Added chain configuration options and write out during genesis database insertion. If no "config" was found, nothing is written to the database. Configurations are written on a per genesis base. This means that any chain (which is identified by it's genesis hash) can have their own chain settings. --- cmd/ethtest/main.go | 5 ++-- cmd/evm/main.go | 19 ++++++++------ cmd/geth/js_test.go | 1 + cmd/geth/main.go | 42 ++++++++++++++++++++++++++++--- cmd/geth/usage.go | 1 + cmd/utils/flags.go | 72 +++++++++++++++++++++++++++++++++++++++-------------- 6 files changed, 108 insertions(+), 32 deletions(-) (limited to 'cmd') diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index e19dca86b..3916e297f 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -27,6 +27,7 @@ import ( "github.com/codegangsta/cli" "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/tests" ) @@ -73,9 +74,9 @@ func runTestWithReader(test string, r io.Reader) error { var err error switch strings.ToLower(test) { case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests": - err = tests.RunBlockTestWithReader(r, skipTests) + err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, r, skipTests) case "st", "state", "statetest", "statetests": - err = tests.RunStateTestWithReader(r, skipTests) + err = tests.RunStateTestWithReader(tests.RuleSet{params.MainNetHomesteadBlock}, r, skipTests) case "tx", "transactiontest", "transactiontests": err = tests.RunTransactionTestsWithReader(r, skipTests) case "vm", "vmtest", "vmtests": diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 2cc70d81b..7d9b3a6c3 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -33,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/params" ) var ( @@ -106,9 +105,6 @@ func init() { } func run(ctx *cli.Context) { - vm.ForceJit = ctx.GlobalBool(ForceJitFlag.Name) - vm.EnableJit = !ctx.GlobalBool(DisableJitFlag.Name) - glog.SetToStderr(true) glog.SetV(ctx.GlobalInt(VerbosityFlag.Name)) @@ -118,8 +114,10 @@ func run(ctx *cli.Context) { receiver := statedb.CreateAccount(common.StringToAddress("receiver")) receiver.SetCode(common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name))) - vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(ctx.GlobalString(ValueFlag.Name)), &vm.Config{ - Debug: ctx.GlobalBool(DebugFlag.Name), + vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(ctx.GlobalString(ValueFlag.Name)), vm.Config{ + Debug: ctx.GlobalBool(DebugFlag.Name), + ForceJit: ctx.GlobalBool(ForceJitFlag.Name), + EnableJit: !ctx.GlobalBool(DisableJitFlag.Name), }) tstart := time.Now() @@ -180,8 +178,7 @@ type VMEnv struct { evm *vm.EVM } -func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int, cfg *vm.Config) *VMEnv { - params.HomesteadBlock = new(big.Int) +func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int, cfg vm.Config) *VMEnv { env := &VMEnv{ state: state, transactor: &transactor, @@ -194,6 +191,12 @@ func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int, cfg return env } +// ruleSet implements vm.RuleSet and will always default to the homestead rule set. +type ruleSet struct{} + +func (ruleSet) IsHomestead(*big.Int) bool { return true } + +func (self *VMEnv) RuleSet() vm.RuleSet { return ruleSet{} } func (self *VMEnv) Vm() vm.Vm { return self.evm } func (self *VMEnv) Db() vm.Database { return self.state } func (self *VMEnv) MakeSnapshot() vm.Database { return self.state.Copy() } diff --git a/cmd/geth/js_test.go b/cmd/geth/js_test.go index af435e68c..e0c4dacbc 100644 --- a/cmd/geth/js_test.go +++ b/cmd/geth/js_test.go @@ -106,6 +106,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *nod core.WriteGenesisBlockForTesting(db, core.GenesisAccount{common.HexToAddress(testAddress), common.String2Big(testBalance)}) ethConf := ð.Config{ + ChainConfig: &core.ChainConfig{HomesteadBlock: new(big.Int)}, TestGenesisState: db, AccountManager: accman, DocRoot: "/", diff --git a/cmd/geth/main.go b/cmd/geth/main.go index a21fe71b5..5d5ab4559 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -32,7 +32,9 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -108,7 +110,6 @@ Runs quick benchmark on first GPU found. The output of this command is supposed to be machine-readable. `, }, - { Name: "wallet", Usage: "ethereum presale wallet", @@ -247,6 +248,16 @@ nodes. }, }, }, + { + Action: initGenesis, + Name: "init", + Usage: "bootstraps and initialises a new genesis block (JSON)", + Description: ` +The init command initialises a new genesis block and definition for the network. +This is a destructive action and changes the network in which you will be +participating. +`, + }, { Action: console, Name: "console", @@ -255,7 +266,8 @@ nodes. The Geth console is an interactive shell for the JavaScript runtime environment which exposes a node admin interface as well as the Ðapp JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console -`}, +`, + }, { Action: attach, Name: "attach", @@ -347,7 +359,6 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso go metrics.CollectProcessMetrics(3 * time.Second) utils.SetupNetwork(ctx) - utils.SetupVM(ctx) return nil } @@ -417,6 +428,31 @@ func attach(ctx *cli.Context) { } } +// initGenesis will initialise the given JSON format genesis file and writes it as +// the zero'd block (i.e. genesis) or will fail hard if it can't succeed. +func initGenesis(ctx *cli.Context) { + genesisPath := ctx.Args().First() + if len(genesisPath) == 0 { + utils.Fatalf("must supply path to genesis JSON file") + } + + chainDb, err := ethdb.NewLDBDatabase(filepath.Join(utils.MustMakeDataDir(ctx), "chaindata"), 0, 0) + if err != nil { + utils.Fatalf("could not open database: %v", err) + } + + genesisFile, err := os.Open(genesisPath) + if err != nil { + utils.Fatalf("failed to read genesis file: %v", err) + } + + block, err := core.WriteGenesisBlock(chainDb, genesisFile) + if err != nil { + utils.Fatalf("failed to write genesis block: %v", err) + } + glog.V(logger.Info).Infof("successfully wrote genesis block and/or chain rule set: %x", block.Hash()) +} + // console starts a new geth node, attaching a JavaScript console to it at the // same time. func console(ctx *cli.Context) { diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 55daa63d7..a31532bea 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -121,6 +121,7 @@ var AppHelpFlagGroups = []flagGroup{ Flags: []cli.Flag{ utils.MiningEnabledFlag, utils.MinerThreadsFlag, + utils.TargetGasLimitFlag, utils.MiningGPUFlag, utils.AutoDAGFlag, utils.EtherbaseFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a00466d0a..3f54b40ca 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -34,7 +34,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethdb" @@ -173,6 +172,11 @@ var ( Name: "minergpus", Usage: "List of GPUs to use for mining (e.g. '0,1' will use the first two GPUs found)", } + TargetGasLimitFlag = cli.StringFlag{ + Name: "targetgaslimit", + Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine", + Value: params.GenesisGasLimit.String(), + } AutoDAGFlag = cli.BoolFlag{ Name: "autodag", Usage: "Enable automatic DAG pregeneration", @@ -656,6 +660,7 @@ func MakeSystemNode(name, version string, extra []byte, ctx *cli.Context) *node. accman := MakeAccountManager(ctx) ethConf := ð.Config{ + ChainConfig: MustMakeChainConfig(ctx), Genesis: MakeGenesisBlock(ctx), FastSync: ctx.GlobalBool(FastSyncFlag.Name), BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name), @@ -701,8 +706,6 @@ func MakeSystemNode(name, version string, extra []byte, ctx *cli.Context) *node. ethConf.Genesis = core.TestNetGenesisBlock() } state.StartingNonce = 1048576 // (2**20) - // overwrite homestead block - params.HomesteadBlock = params.TestNetHomesteadBlock case ctx.GlobalBool(DevModeFlag.Name): // Override the base network stack configs @@ -758,25 +761,56 @@ func SetupNetwork(ctx *cli.Context) { core.BlockReward = big.NewInt(1.5e+18) core.ExpDiffPeriod = big.NewInt(math.MaxInt64) } + params.TargetGasLimit = common.String2Big(ctx.GlobalString(TargetGasLimitFlag.Name)) } -// SetupVM configured the VM package's global settings -func SetupVM(ctx *cli.Context) { - vm.EnableJit = ctx.GlobalBool(VMEnableJitFlag.Name) - vm.ForceJit = ctx.GlobalBool(VMForceJitFlag.Name) - vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name)) +// MustMakeChainConfig reads the chain configuration from the given database. +func MustMakeChainConfig(ctx *cli.Context) *core.ChainConfig { + var ( + db = MakeChainDatabase(ctx) + genesis = core.GetBlock(db, core.GetCanonicalHash(db, 0)) + ) + defer db.Close() + + chainConfig, err := core.GetChainConfig(db, genesis.Hash()) + if err != nil { + if err != core.ChainConfigNotFoundErr { + Fatalf("Could not make chain configuration: %v", err) + } + var homesteadBlockNo *big.Int + if ctx.GlobalBool(TestNetFlag.Name) { + homesteadBlockNo = params.TestNetHomesteadBlock + } else { + homesteadBlockNo = params.MainNetHomesteadBlock + } + + chainConfig = &core.ChainConfig{ + HomesteadBlock: homesteadBlockNo, + } + } + return chainConfig } -// MakeChain creates a chain manager from set command line flags. -func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database) { - datadir := MustMakeDataDir(ctx) - cache := ctx.GlobalInt(CacheFlag.Name) - handles := MakeDatabaseHandles() +// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. +func MakeChainDatabase(ctx *cli.Context) ethdb.Database { + var ( + datadir = MustMakeDataDir(ctx) + cache = ctx.GlobalInt(CacheFlag.Name) + handles = MakeDatabaseHandles() + ) - var err error - if chainDb, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache, handles); err != nil { + chainDb, err := ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache, handles) + if err != nil { Fatalf("Could not open database: %v", err) } + return chainDb +} + +// MakeChain creates a chain manager from set command line flags. +func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database) { + var err error + chainDb = MakeChainDatabase(ctx) + if ctx.GlobalBool(OlympicFlag.Name) { _, err := core.WriteTestNetGenesisBlock(chainDb) if err != nil { @@ -784,10 +818,10 @@ func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database } } - eventMux := new(event.TypeMux) - pow := ethash.New() - //genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB) - chain, err = core.NewBlockChain(chainDb, pow, eventMux) + chainConfig := MustMakeChainConfig(ctx) + + var eventMux event.TypeMux + chain, err = core.NewBlockChain(chainDb, chainConfig, ethash.New(), &eventMux) if err != nil { Fatalf("Could not start chainmanager: %v", err) } -- cgit v1.2.3