Commit d7b5a87b authored by Felix Lange's avatar Felix Lange

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.
parent 5a9f7121
...@@ -249,12 +249,14 @@ func (self *jsre) dump(call otto.FunctionCall) otto.Value { ...@@ -249,12 +249,14 @@ func (self *jsre) dump(call otto.FunctionCall) otto.Value {
} }
func (self *jsre) stopMining(call otto.FunctionCall) otto.Value { func (self *jsre) stopMining(call otto.FunctionCall) otto.Value {
self.xeth.Miner().Stop() self.ethereum.StopMining()
return otto.TrueValue() return otto.TrueValue()
} }
func (self *jsre) startMining(call otto.FunctionCall) otto.Value { 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() return otto.TrueValue()
} }
......
...@@ -214,7 +214,7 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) { ...@@ -214,7 +214,7 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
utils.StartRPC(eth, ctx) utils.StartRPC(eth, ctx)
} }
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { if ctx.GlobalBool(utils.MiningEnabledFlag.Name) {
eth.Miner().Start() eth.StartMining()
} }
} }
......
...@@ -55,8 +55,8 @@ Rectangle { ...@@ -55,8 +55,8 @@ Rectangle {
Button { Button {
text: "Start" text: "Start"
onClicked: { onClicked: {
eth.setGasPrice(minGasPrice.text || "10000000000000"); // eth.setGasPrice(minGasPrice.text || "10000000000000");
eth.setExtra(blockExtra.text) // eth.setExtra(blockExtra.text)
if (eth.toggleMining()) { if (eth.toggleMining()) {
this.text = "Stop"; this.text = "Stop";
} else { } else {
...@@ -65,35 +65,35 @@ Rectangle { ...@@ -65,35 +65,35 @@ Rectangle {
} }
} }
Rectangle { // Rectangle {
id: minGasPriceRect // id: minGasPriceRect
anchors.top: parent.top // anchors.top: parent.top
anchors.topMargin: 2 // anchors.topMargin: 2
width: 200 // width: 200
TextField { // TextField {
id: minGasPrice // id: minGasPrice
placeholderText: "Min Gas: 10000000000000" // placeholderText: "Min Gas: 10000000000000"
width: 200 // width: 200
validator: RegExpValidator { regExp: /\d*/ } // validator: RegExpValidator { regExp: /\d*/ }
} // }
} // }
Rectangle { // Rectangle {
width: 300 // width: 300
anchors { // anchors {
left: minGasPriceRect.right // left: minGasPriceRect.right
leftMargin: 5 // leftMargin: 5
top: parent.top // top: parent.top
topMargin: 2 // topMargin: 2
} // }
TextField { // TextField {
id: blockExtra // id: blockExtra
placeholderText: "Extra" // placeholderText: "Extra"
width: parent.width // width: parent.width
maximumLength: 1024 // maximumLength: 1024
} // }
} // }
} }
} }
......
...@@ -93,7 +93,6 @@ Rectangle { ...@@ -93,7 +93,6 @@ Rectangle {
// Check if it's mining and set it accordingly // Check if it's mining and set it accordingly
if (miningSliderValue > 0 && !eth.miner().mining()) { if (miningSliderValue > 0 && !eth.miner().mining()) {
// If the // If the
eth.setGasPrice("10000000000000");
eth.miner().start(); eth.miner().start();
} else if (miningSliderValue == 0 && eth.miner().mining()) { } else if (miningSliderValue == 0 && eth.miner().mining()) {
eth.miner().stop(); eth.miner().stop();
......
...@@ -175,22 +175,12 @@ func (self *UiLib) RemoveLocalTransaction(id int) { ...@@ -175,22 +175,12 @@ func (self *UiLib) RemoveLocalTransaction(id int) {
//self.miner.RemoveLocalTx(id) //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 { func (self *UiLib) ToggleMining() bool {
if !self.Miner().Mining() { if !self.eth.IsMining() {
self.Miner().Start() err := self.eth.StartMining()
return err == nil
return true
} else { } else {
self.Miner().Stop() self.eth.StopMining()
return false return false
} }
} }
......
...@@ -166,18 +166,13 @@ func New(config *Config) (*Ethereum, error) { ...@@ -166,18 +166,13 @@ func New(config *Config) (*Ethereum, error) {
DataDir: config.DataDir, DataDir: config.DataDir,
} }
cb, err := eth.accountManager.Coinbase()
if err != nil {
return nil, err
}
eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux()) eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
pow := ethash.New(eth.chainManager) pow := ethash.New(eth.chainManager)
eth.txPool = core.NewTxPool(eth.EventMux()) eth.txPool = core.NewTxPool(eth.EventMux())
eth.blockProcessor = core.NewBlockProcessor(stateDb, pow, eth.txPool, eth.chainManager, eth.EventMux()) eth.blockProcessor = core.NewBlockProcessor(stateDb, pow, eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor) eth.chainManager.SetProcessor(eth.blockProcessor)
eth.whisper = whisper.New() 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 hasBlock := eth.chainManager.HasBlock
insertChain := eth.chainManager.InsertChain insertChain := eth.chainManager.InsertChain
...@@ -211,6 +206,19 @@ func New(config *Config) (*Ethereum, error) { ...@@ -211,6 +206,19 @@ func New(config *Config) (*Ethereum, error) {
return eth, nil 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) Logger() logger.LogSystem { return s.logger }
func (s *Ethereum) Name() string { return s.net.Name } func (s *Ethereum) Name() string { return s.net.Name }
func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
...@@ -222,7 +230,6 @@ func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper } ...@@ -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) EventMux() *event.TypeMux { return s.eventMux }
func (s *Ethereum) BlockDb() ethutil.Database { return s.blockDb } func (s *Ethereum) BlockDb() ethutil.Database { return s.blockDb }
func (s *Ethereum) StateDb() ethutil.Database { return s.stateDb } 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) IsListening() bool { return true } // Always listening
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() } func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() } func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() }
...@@ -261,7 +268,7 @@ func (s *Ethereum) Start() error { ...@@ -261,7 +268,7 @@ func (s *Ethereum) Start() error {
} }
func (s *Ethereum) StartForTest() { func (s *Ethereum) StartForTest() {
jsonlogger.LogJson(&logger.LogStarting{ jsonlogger.LogJson(&logger.LogStarting{
ClientString: s.net.Name, ClientString: s.net.Name,
ProtocolVersion: ProtocolVersion, ProtocolVersion: ProtocolVersion,
}) })
......
...@@ -17,44 +17,34 @@ type Miner struct { ...@@ -17,44 +17,34 @@ type Miner struct {
MinAcceptedGasPrice *big.Int MinAcceptedGasPrice *big.Int
Extra string Extra string
Coinbase []byte mining bool
mining bool eth core.Backend
pow pow.PoW
pow pow.PoW
} }
func New(coinbase []byte, eth core.Backend, pow pow.PoW, minerThreads int) *Miner { func New(eth core.Backend, pow pow.PoW, minerThreads int) *Miner {
miner := &Miner{ // note: minerThreads is currently ignored because
Coinbase: coinbase, // ethash is not thread safe.
worker: newWorker(coinbase, eth), return &Miner{eth: eth, pow: pow}
pow: pow,
}
minerThreads = 1
for i := 0; i < minerThreads; i++ {
miner.worker.register(NewCpuMiner(i, miner.pow))
}
return miner
} }
func (self *Miner) Mining() bool { func (self *Miner) Mining() bool {
return self.mining return self.mining
} }
func (self *Miner) Start() { func (self *Miner) Start(coinbase []byte) {
self.mining = true self.mining = true
self.worker = newWorker(coinbase, self.eth)
self.worker.register(NewCpuMiner(0, self.pow))
self.pow.(*ethash.Ethash).UpdateDAG() self.pow.(*ethash.Ethash).UpdateDAG()
self.worker.start() self.worker.start()
self.worker.commitNewWork() self.worker.commitNewWork()
} }
func (self *Miner) Stop() { func (self *Miner) Stop() {
self.mining = false self.mining = false
self.worker.stop() self.worker.stop()
//self.pow.(*ethash.Ethash).Stop() //self.pow.(*ethash.Ethash).Stop()
......
...@@ -14,7 +14,6 @@ import ( ...@@ -14,7 +14,6 @@ import (
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/whisper" "github.com/ethereum/go-ethereum/whisper"
...@@ -35,7 +34,10 @@ type Backend interface { ...@@ -35,7 +34,10 @@ type Backend interface {
StateDb() ethutil.Database StateDb() ethutil.Database
EventMux() *event.TypeMux EventMux() *event.TypeMux
Whisper() *whisper.Whisper Whisper() *whisper.Whisper
Miner() *miner.Miner
IsMining() bool
StartMining() error
StopMining()
} }
// Frontend should be implemented by users of XEth. Its methods are // Frontend should be implemented by users of XEth. Its methods are
...@@ -65,7 +67,6 @@ type XEth struct { ...@@ -65,7 +67,6 @@ type XEth struct {
accountManager *accounts.Manager accountManager *accounts.Manager
state *State state *State
whisper *Whisper whisper *Whisper
miner *miner.Miner
frontend Frontend frontend Frontend
} }
...@@ -87,7 +88,6 @@ func New(eth Backend, frontend Frontend) *XEth { ...@@ -87,7 +88,6 @@ func New(eth Backend, frontend Frontend) *XEth {
chainManager: eth.ChainManager(), chainManager: eth.ChainManager(),
accountManager: eth.AccountManager(), accountManager: eth.AccountManager(),
whisper: NewWhisper(eth.Whisper()), whisper: NewWhisper(eth.Whisper()),
miner: eth.Miner(),
frontend: frontend, frontend: frontend,
} }
if frontend == nil { if frontend == nil {
...@@ -104,7 +104,6 @@ func (self *XEth) WithState(statedb *state.StateDB) *XEth { ...@@ -104,7 +104,6 @@ func (self *XEth) WithState(statedb *state.StateDB) *XEth {
blockProcessor: self.blockProcessor, blockProcessor: self.blockProcessor,
chainManager: self.chainManager, chainManager: self.chainManager,
whisper: self.whisper, whisper: self.whisper,
miner: self.miner,
} }
xeth.state = NewState(xeth, statedb) xeth.state = NewState(xeth, statedb)
...@@ -112,8 +111,7 @@ func (self *XEth) WithState(statedb *state.StateDB) *XEth { ...@@ -112,8 +111,7 @@ func (self *XEth) WithState(statedb *state.StateDB) *XEth {
} }
func (self *XEth) State() *State { return self.state } func (self *XEth) State() *State { return self.state }
func (self *XEth) Whisper() *Whisper { return self.whisper } func (self *XEth) Whisper() *Whisper { return self.whisper }
func (self *XEth) Miner() *miner.Miner { return self.miner }
func (self *XEth) BlockByHash(strHash string) *Block { func (self *XEth) BlockByHash(strHash string) *Block {
hash := fromHex(strHash) hash := fromHex(strHash)
...@@ -172,18 +170,19 @@ func (self *XEth) PeerCount() int { ...@@ -172,18 +170,19 @@ func (self *XEth) PeerCount() int {
} }
func (self *XEth) IsMining() bool { func (self *XEth) IsMining() bool {
return self.miner.Mining() return self.eth.IsMining()
} }
func (self *XEth) SetMining(shouldmine bool) bool { func (self *XEth) SetMining(shouldmine bool) bool {
ismining := self.miner.Mining() ismining := self.eth.IsMining()
if shouldmine && !ismining { if shouldmine && !ismining {
self.miner.Start() err := self.eth.StartMining()
return err == nil
} }
if ismining && !shouldmine { if ismining && !shouldmine {
self.miner.Stop() self.eth.StopMining()
} }
return self.miner.Mining() return self.eth.IsMining()
} }
func (self *XEth) IsListening() bool { func (self *XEth) IsListening() bool {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment