From d7b5a87b3bc4a19677877d3a8c8c925211eb25f1 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 11 Mar 2015 23:35:34 +0100 Subject: [PATCH 1/2] miner: provide coinbase when starting the miner This avoids having to query the coinbase when creating the miner, which in turn eliminates the dreaded startup error when no accounts are set up. Later, this will also allow us to simply restart the miner when the user picks a different coinbase. This causes a lot of changes in other packages. These are included in this commit because they're impossible to separate. --- cmd/ethereum/js.go | 6 ++- cmd/ethereum/main.go | 2 +- cmd/mist/assets/qml/views/miner.qml | 58 +++++++++++++-------------- cmd/mist/assets/qml/views/network.qml | 1 - cmd/mist/ui_lib.go | 18 ++------- eth/backend.go | 23 +++++++---- miner/miner.go | 30 +++++--------- xeth/xeth.go | 23 +++++------ 8 files changed, 74 insertions(+), 87 deletions(-) diff --git a/cmd/ethereum/js.go b/cmd/ethereum/js.go index 5432fb9b1..3b98b588e 100644 --- a/cmd/ethereum/js.go +++ b/cmd/ethereum/js.go @@ -249,12 +249,14 @@ func (self *jsre) dump(call otto.FunctionCall) otto.Value { } func (self *jsre) stopMining(call otto.FunctionCall) otto.Value { - self.xeth.Miner().Stop() + self.ethereum.StopMining() return otto.TrueValue() } func (self *jsre) startMining(call otto.FunctionCall) otto.Value { - self.xeth.Miner().Start() + if err := self.ethereum.StartMining(); err != nil { + return otto.FalseValue() + } return otto.TrueValue() } diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 73c67bdc9..0d239f7b4 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -214,7 +214,7 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) { utils.StartRPC(eth, ctx) } if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { - eth.Miner().Start() + eth.StartMining() } } diff --git a/cmd/mist/assets/qml/views/miner.qml b/cmd/mist/assets/qml/views/miner.qml index 4025ff485..ff2bf85ca 100644 --- a/cmd/mist/assets/qml/views/miner.qml +++ b/cmd/mist/assets/qml/views/miner.qml @@ -55,8 +55,8 @@ Rectangle { Button { text: "Start" onClicked: { - eth.setGasPrice(minGasPrice.text || "10000000000000"); - eth.setExtra(blockExtra.text) + // eth.setGasPrice(minGasPrice.text || "10000000000000"); + // eth.setExtra(blockExtra.text) if (eth.toggleMining()) { this.text = "Stop"; } else { @@ -65,35 +65,35 @@ Rectangle { } } - Rectangle { - id: minGasPriceRect - anchors.top: parent.top - anchors.topMargin: 2 - width: 200 - TextField { - id: minGasPrice - placeholderText: "Min Gas: 10000000000000" - width: 200 - validator: RegExpValidator { regExp: /\d*/ } - } - } + // Rectangle { + // id: minGasPriceRect + // anchors.top: parent.top + // anchors.topMargin: 2 + // width: 200 + // TextField { + // id: minGasPrice + // placeholderText: "Min Gas: 10000000000000" + // width: 200 + // validator: RegExpValidator { regExp: /\d*/ } + // } + // } - Rectangle { - width: 300 - anchors { - left: minGasPriceRect.right - leftMargin: 5 - top: parent.top - topMargin: 2 - } + // Rectangle { + // width: 300 + // anchors { + // left: minGasPriceRect.right + // leftMargin: 5 + // top: parent.top + // topMargin: 2 + // } - TextField { - id: blockExtra - placeholderText: "Extra" - width: parent.width - maximumLength: 1024 - } - } + // TextField { + // id: blockExtra + // placeholderText: "Extra" + // width: parent.width + // maximumLength: 1024 + // } + // } } } diff --git a/cmd/mist/assets/qml/views/network.qml b/cmd/mist/assets/qml/views/network.qml index d33b5773c..fe4c7734f 100644 --- a/cmd/mist/assets/qml/views/network.qml +++ b/cmd/mist/assets/qml/views/network.qml @@ -93,7 +93,6 @@ Rectangle { // Check if it's mining and set it accordingly if (miningSliderValue > 0 && !eth.miner().mining()) { // If the - eth.setGasPrice("10000000000000"); eth.miner().start(); } else if (miningSliderValue == 0 && eth.miner().mining()) { eth.miner().stop(); diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index 4198c6316..2679e0f95 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -175,22 +175,12 @@ func (self *UiLib) RemoveLocalTransaction(id int) { //self.miner.RemoveLocalTx(id) } -func (self *UiLib) SetGasPrice(price string) { - self.Miner().MinAcceptedGasPrice = ethutil.Big(price) -} - -func (self *UiLib) SetExtra(extra string) { - self.Miner().Extra = extra -} - func (self *UiLib) ToggleMining() bool { - if !self.Miner().Mining() { - self.Miner().Start() - - return true + if !self.eth.IsMining() { + err := self.eth.StartMining() + return err == nil } else { - self.Miner().Stop() - + self.eth.StopMining() return false } } diff --git a/eth/backend.go b/eth/backend.go index 9e365161d..9c497a586 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -166,18 +166,13 @@ func New(config *Config) (*Ethereum, error) { DataDir: config.DataDir, } - cb, err := eth.accountManager.Coinbase() - if err != nil { - return nil, err - } - eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux()) pow := ethash.New(eth.chainManager) eth.txPool = core.NewTxPool(eth.EventMux()) eth.blockProcessor = core.NewBlockProcessor(stateDb, pow, eth.txPool, eth.chainManager, eth.EventMux()) eth.chainManager.SetProcessor(eth.blockProcessor) eth.whisper = whisper.New() - eth.miner = miner.New(cb, eth, pow, config.MinerThreads) + eth.miner = miner.New(eth, pow, config.MinerThreads) hasBlock := eth.chainManager.HasBlock insertChain := eth.chainManager.InsertChain @@ -211,6 +206,19 @@ func New(config *Config) (*Ethereum, error) { return eth, nil } +func (s *Ethereum) StartMining() error { + cb, err := s.accountManager.Coinbase() + if err != nil { + servlogger.Errorf("Cannot start mining without coinbase: %v\n", err) + return fmt.Errorf("no coinbase: %v", err) + } + s.miner.Start(cb) + return nil +} + +func (s *Ethereum) StopMining() { s.miner.Stop() } +func (s *Ethereum) IsMining() bool { return s.miner.Mining() } + func (s *Ethereum) Logger() logger.LogSystem { return s.logger } func (s *Ethereum) Name() string { return s.net.Name } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } @@ -222,7 +230,6 @@ func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) BlockDb() ethutil.Database { return s.blockDb } func (s *Ethereum) StateDb() ethutil.Database { return s.stateDb } -func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) IsListening() bool { return true } // Always listening func (s *Ethereum) PeerCount() int { return s.net.PeerCount() } func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() } @@ -261,7 +268,7 @@ func (s *Ethereum) Start() error { } func (s *Ethereum) StartForTest() { - jsonlogger.LogJson(&logger.LogStarting{ + jsonlogger.LogJson(&logger.LogStarting{ ClientString: s.net.Name, ProtocolVersion: ProtocolVersion, }) diff --git a/miner/miner.go b/miner/miner.go index d3b1f578a..7bf67a6ec 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -17,44 +17,34 @@ type Miner struct { MinAcceptedGasPrice *big.Int Extra string - Coinbase []byte - mining bool - - pow pow.PoW + mining bool + eth core.Backend + pow pow.PoW } -func New(coinbase []byte, eth core.Backend, pow pow.PoW, minerThreads int) *Miner { - miner := &Miner{ - Coinbase: coinbase, - worker: newWorker(coinbase, eth), - pow: pow, - } - - minerThreads = 1 - for i := 0; i < minerThreads; i++ { - miner.worker.register(NewCpuMiner(i, miner.pow)) - } - - return miner +func New(eth core.Backend, pow pow.PoW, minerThreads int) *Miner { + // note: minerThreads is currently ignored because + // ethash is not thread safe. + return &Miner{eth: eth, pow: pow} } func (self *Miner) Mining() bool { return self.mining } -func (self *Miner) Start() { +func (self *Miner) Start(coinbase []byte) { self.mining = true + self.worker = newWorker(coinbase, self.eth) + self.worker.register(NewCpuMiner(0, self.pow)) self.pow.(*ethash.Ethash).UpdateDAG() self.worker.start() - self.worker.commitNewWork() } func (self *Miner) Stop() { self.mining = false - self.worker.stop() //self.pow.(*ethash.Ethash).Stop() diff --git a/xeth/xeth.go b/xeth/xeth.go index d8dd66aec..70172a1c8 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -14,7 +14,6 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/whisper" @@ -35,7 +34,10 @@ type Backend interface { StateDb() ethutil.Database EventMux() *event.TypeMux Whisper() *whisper.Whisper - Miner() *miner.Miner + + IsMining() bool + StartMining() error + StopMining() } // Frontend should be implemented by users of XEth. Its methods are @@ -65,7 +67,6 @@ type XEth struct { accountManager *accounts.Manager state *State whisper *Whisper - miner *miner.Miner frontend Frontend } @@ -87,7 +88,6 @@ func New(eth Backend, frontend Frontend) *XEth { chainManager: eth.ChainManager(), accountManager: eth.AccountManager(), whisper: NewWhisper(eth.Whisper()), - miner: eth.Miner(), frontend: frontend, } if frontend == nil { @@ -104,7 +104,6 @@ func (self *XEth) WithState(statedb *state.StateDB) *XEth { blockProcessor: self.blockProcessor, chainManager: self.chainManager, whisper: self.whisper, - miner: self.miner, } xeth.state = NewState(xeth, statedb) @@ -112,8 +111,7 @@ func (self *XEth) WithState(statedb *state.StateDB) *XEth { } func (self *XEth) State() *State { return self.state } -func (self *XEth) Whisper() *Whisper { return self.whisper } -func (self *XEth) Miner() *miner.Miner { return self.miner } +func (self *XEth) Whisper() *Whisper { return self.whisper } func (self *XEth) BlockByHash(strHash string) *Block { hash := fromHex(strHash) @@ -172,18 +170,19 @@ func (self *XEth) PeerCount() int { } func (self *XEth) IsMining() bool { - return self.miner.Mining() + return self.eth.IsMining() } func (self *XEth) SetMining(shouldmine bool) bool { - ismining := self.miner.Mining() + ismining := self.eth.IsMining() if shouldmine && !ismining { - self.miner.Start() + err := self.eth.StartMining() + return err == nil } if ismining && !shouldmine { - self.miner.Stop() + self.eth.StopMining() } - return self.miner.Mining() + return self.eth.IsMining() } func (self *XEth) IsListening() bool { From d5aaf413e0307b07597e48a548f0219f4ea8c3be Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 11 Mar 2015 23:41:51 +0100 Subject: [PATCH 2/2] cmd/ethereum: remove extra check for 'no accounts' error This error can no longer be returned from eth.New. --- cmd/ethereum/main.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 0d239f7b4..8b01457e6 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -30,7 +30,6 @@ import ( "time" "github.com/codegangsta/cli" - "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" @@ -158,10 +157,7 @@ func run(ctx *cli.Context) { fmt.Printf("Welcome to the FRONTIER\n") utils.HandleInterrupt() eth, err := utils.GetEthereum(ClientIdentifier, Version, ctx) - if err == accounts.ErrNoKeys { - utils.Fatalf(`No accounts configured. -Please run 'ethereum account new' to create a new account.`) - } else if err != nil { + if err != nil { utils.Fatalf("%v", err) } @@ -172,10 +168,7 @@ Please run 'ethereum account new' to create a new account.`) func runjs(ctx *cli.Context) { eth, err := utils.GetEthereum(ClientIdentifier, Version, ctx) - if err == accounts.ErrNoKeys { - utils.Fatalf(`No accounts configured. -Please run 'ethereum account new' to create a new account.`) - } else if err != nil { + if err != nil { utils.Fatalf("%v", err) }