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.
This commit is contained in:
Felix Lange 2015-03-11 23:35:34 +01:00
parent 5a9f712144
commit d7b5a87b3b
8 changed files with 74 additions and 87 deletions

View File

@ -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()
}

View File

@ -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()
}
}

View File

@ -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
// }
// }
}
}

View File

@ -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();

View File

@ -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
}
}

View File

@ -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,
})

View File

@ -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()

View File

@ -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 {