Explorar o código

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

Péter Szilágyi %!s(int64=9) %!d(string=hai) anos
pai
achega
0ee796632a
Modificáronse 2 ficheiros con 22 adicións e 13 borrados
  1. 1 1
      eth/api.go
  2. 21 12
      miner/remote_agent.go

+ 1 - 1
eth/api.go

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

+ 21 - 12
miner/remote_agent.go

@@ -27,6 +27,7 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/logger"
 	"github.com/ethereum/go-ethereum/logger/glog"
+	"github.com/ethereum/go-ethereum/pow"
 )
 
 type hashrate struct {
@@ -41,6 +42,7 @@ type RemoteAgent struct {
 	workCh   chan *Work
 	returnCh chan<- *Result
 
+	pow         pow.PoW
 	currentWork *Work
 	work        map[common.Hash]*Work
 
@@ -50,8 +52,9 @@ type RemoteAgent struct {
 	running int32 // running indicates whether the agent is active. Call atomically
 }
 
-func NewRemoteAgent() *RemoteAgent {
+func NewRemoteAgent(pow pow.PoW) *RemoteAgent {
 	return &RemoteAgent{
+		pow:      pow,
 		work:     make(map[common.Hash]*Work),
 		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.")
 }
 
-// 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 {
 	a.mu.Lock()
 	defer a.mu.Unlock()
 
 	// Make sure the work submitted is present
-	if a.work[hash] != nil {
-		block := a.work[hash].Block.WithMiningResult(nonce, mixDigest)
-		a.returnCh <- &Result{a.work[hash], block}
-
-		delete(a.work, hash)
-
-		return true
-	} else {
-		glog.V(logger.Info).Infof("Work was submitted for %x but no pending work found\n", hash)
+	work := a.work[hash]
+	if work == nil {
+		glog.V(logger.Info).Infof("Work was submitted for %x but no pending work found", hash)
+		return false
+	}
+	// 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