eth, miner: verify PoW in the remote agent to notify submitter (#3438)

This commit is contained in:
Péter Szilágyi 2016-12-20 03:14:36 +02:00 committed by Felix Lange
parent 1fe67c125d
commit 0ee796632a
2 changed files with 22 additions and 13 deletions

View File

@ -82,7 +82,7 @@ type PublicMinerAPI struct {
// NewPublicMinerAPI create a new PublicMinerAPI instance. // NewPublicMinerAPI create a new PublicMinerAPI instance.
func NewPublicMinerAPI(e *Ethereum) *PublicMinerAPI { func NewPublicMinerAPI(e *Ethereum) *PublicMinerAPI {
agent := miner.NewRemoteAgent() agent := miner.NewRemoteAgent(e.Pow())
e.Miner().Register(agent) e.Miner().Register(agent)
return &PublicMinerAPI{e, agent} return &PublicMinerAPI{e, agent}

View File

@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/pow"
) )
type hashrate struct { type hashrate struct {
@ -41,6 +42,7 @@ type RemoteAgent struct {
workCh chan *Work workCh chan *Work
returnCh chan<- *Result returnCh chan<- *Result
pow pow.PoW
currentWork *Work currentWork *Work
work map[common.Hash]*Work work map[common.Hash]*Work
@ -50,8 +52,9 @@ type RemoteAgent struct {
running int32 // running indicates whether the agent is active. Call atomically running int32 // running indicates whether the agent is active. Call atomically
} }
func NewRemoteAgent() *RemoteAgent { func NewRemoteAgent(pow pow.PoW) *RemoteAgent {
return &RemoteAgent{ return &RemoteAgent{
pow: pow,
work: make(map[common.Hash]*Work), work: make(map[common.Hash]*Work),
hashrate: make(map[common.Hash]hashrate), hashrate: make(map[common.Hash]hashrate),
} }
@ -126,24 +129,30 @@ func (a *RemoteAgent) GetWork() ([3]string, error) {
return res, errors.New("No work available yet, don't panic.") return res, errors.New("No work available yet, don't panic.")
} }
// Returns true or false, but does not indicate if the PoW was correct // SubmitWork tries to inject a PoW solution tinto the remote agent, returning
// whether the solution was acceted or not (not can be both a bad PoW as well as
// any other error, like no work pending).
func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, hash common.Hash) bool { func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, hash common.Hash) bool {
a.mu.Lock() a.mu.Lock()
defer a.mu.Unlock() defer a.mu.Unlock()
// Make sure the work submitted is present // Make sure the work submitted is present
if a.work[hash] != nil { work := a.work[hash]
block := a.work[hash].Block.WithMiningResult(nonce, mixDigest) if work == nil {
a.returnCh <- &Result{a.work[hash], block} glog.V(logger.Info).Infof("Work was submitted for %x but no pending work found", hash)
return false
delete(a.work, hash)
return true
} else {
glog.V(logger.Info).Infof("Work was submitted for %x but no pending work found\n", hash)
} }
// Make sure the PoW solutions is indeed valid
block := work.Block.WithMiningResult(nonce, mixDigest)
if !a.pow.Verify(block) {
glog.V(logger.Warn).Infof("Invalid PoW submitted for %x", hash)
return false
}
// Solutions seems to be valid, return to the miner and notify acceptance
a.returnCh <- &Result{work, block}
delete(a.work, hash)
return false return true
} }
// loop monitors mining events on the work and quit channels, updating the internal // loop monitors mining events on the work and quit channels, updating the internal