Get work / submit work partially implemented.

* WIP missing arguments for submitting new work
* GetWork **done**
This commit is contained in:
obscuren 2015-03-22 15:38:01 +01:00
parent 9682a3ef3e
commit 82956df523
5 changed files with 101 additions and 8 deletions

View File

@ -300,9 +300,9 @@ func (s *Ethereum) StartMining() error {
return nil return nil
} }
func (s *Ethereum) StopMining() { s.miner.Stop() } func (s *Ethereum) StopMining() { s.miner.Stop() }
func (s *Ethereum) IsMining() bool { return s.miner.Mining() } func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
func (s *Ethereum) Miner() *miner.Miner { return s.miner }
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 }

View File

@ -26,7 +26,7 @@ type Miner struct {
func New(eth core.Backend, pow pow.PoW, minerThreads int) *Miner { func New(eth core.Backend, pow pow.PoW, minerThreads int) *Miner {
// note: minerThreads is currently ignored because // note: minerThreads is currently ignored because
// ethash is not thread safe. // ethash is not thread safe.
return &Miner{eth: eth, pow: pow} return &Miner{eth: eth, pow: pow, worker: newWorker(common.Address{}, eth)}
} }
func (self *Miner) Mining() bool { func (self *Miner) Mining() bool {
@ -35,7 +35,7 @@ func (self *Miner) Mining() bool {
func (self *Miner) Start(coinbase common.Address) { func (self *Miner) Start(coinbase common.Address) {
self.mining = true self.mining = true
self.worker = newWorker(coinbase, self.eth) self.worker.coinbase = coinbase
self.worker.register(NewCpuMiner(0, self.pow)) self.worker.register(NewCpuMiner(0, self.pow))
self.pow.(*ethash.Ethash).UpdateDAG() self.pow.(*ethash.Ethash).UpdateDAG()
@ -44,6 +44,10 @@ func (self *Miner) Start(coinbase common.Address) {
self.worker.commitNewWork() self.worker.commitNewWork()
} }
func (self *Miner) Register(agent Agent) {
self.worker.register(agent)
}
func (self *Miner) Stop() { func (self *Miner) Stop() {
self.mining = false self.mining = false
self.worker.stop() self.worker.stop()

View File

@ -17,15 +17,20 @@ type EthereumApi struct {
eth *xeth.XEth eth *xeth.XEth
xethMu sync.RWMutex xethMu sync.RWMutex
db common.Database db common.Database
// Miner agent
agent *Agent
} }
func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi {
// What about when dataDir is empty? // What about when dataDir is empty?
db, _ := ethdb.NewLDBDatabase(path.Join(dataDir, "dapps")) db, _ := ethdb.NewLDBDatabase(path.Join(dataDir, "dapps"))
api := &EthereumApi{ api := &EthereumApi{
eth: eth, eth: eth,
db: db, db: db,
agent: NewAgent(),
} }
eth.Backend().Miner().Register(api.agent)
return api return api
} }
@ -342,7 +347,13 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
} }
opts := toFilterOptions(args) opts := toFilterOptions(args)
*reply = NewLogsRes(p.xeth().AllLogs(opts)) *reply = NewLogsRes(p.xeth().AllLogs(opts))
case "eth_getWork", "eth_submitWork": case "eth_getWork":
*reply = p.getWork()
case "eth_submitWork":
// TODO what is the reply here?
// TODO what are the arguments?
p.agent.SetResult(0, common.Hash{}, common.Hash{})
return NewNotImplementedError(req.Method) return NewNotImplementedError(req.Method)
case "db_putString": case "db_putString":
args := new(DbArgs) args := new(DbArgs)
@ -427,6 +438,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
*reply = p.xeth().Whisper().Messages(args.Id) *reply = p.xeth().Whisper().Messages(args.Id)
// case "eth_register": // case "eth_register":
// // Placeholder for actual type // // Placeholder for actual type
// args := new(HashIndexArgs) // args := new(HashIndexArgs)
@ -454,6 +466,11 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return nil return nil
} }
func (p *EthereumApi) getWork() string {
p.xeth().SetMining(true)
return p.agent.GetWork().Hex()
}
func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions { func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions {
var opts core.FilterOptions var opts core.FilterOptions

70
rpc/miner_agest.go Normal file
View File

@ -0,0 +1,70 @@
package rpc
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/miner"
)
type Agent struct {
work *types.Block
currentWork *types.Block
quit chan struct{}
workCh chan *types.Block
returnCh chan<- miner.Work
}
func NewAgent() *Agent {
agent := &Agent{}
go agent.run()
return agent
}
func (a *Agent) Work() chan<- *types.Block {
return a.workCh
}
func (a *Agent) SetWorkCh(returnCh chan<- miner.Work) {
a.returnCh = returnCh
}
func (a *Agent) Start() {
a.quit = make(chan struct{})
a.workCh = make(chan *types.Block, 1)
}
func (a *Agent) Stop() {
close(a.quit)
close(a.workCh)
}
func (a *Agent) GetHashRate() int64 { return 0 }
func (a *Agent) run() {
out:
for {
select {
case <-a.quit:
break out
case work := <-a.workCh:
a.work = work
}
}
}
func (a *Agent) GetWork() common.Hash {
// XXX Wait here untill work != nil ?
if a.work != nil {
return a.work.HashNoNonce()
}
return common.Hash{}
}
func (a *Agent) SetResult(nonce uint64, mixDigest, seedHash common.Hash) {
// Make sure the external miner was working on the right hash
if a.currentWork.Hash() == a.work.Hash() {
a.returnCh <- miner.Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
}
}

View File

@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/event/filter" "github.com/ethereum/go-ethereum/event/filter"
"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"
@ -43,6 +44,7 @@ type Backend interface {
ExtraDb() common.Database ExtraDb() common.Database
EventMux() *event.TypeMux EventMux() *event.TypeMux
Whisper() *whisper.Whisper Whisper() *whisper.Whisper
Miner() *miner.Miner
IsMining() bool IsMining() bool
StartMining() error StartMining() error