consensus: polish a bit

This commit is contained in:
rjl493456442 2018-08-03 15:44:37 +08:00
parent 1e844fe7a0
commit 2a08b49f49
5 changed files with 35 additions and 40 deletions

View file

@ -672,7 +672,7 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
return new(big.Int).Set(diffNoTurn) return new(big.Int).Set(diffNoTurn)
} }
// Close implements consensus.Engine, returning internal error and close the clique. // Close implements consensus.Engine. It's a noop for clique as there is are no background threads.
func (c *Clique) Close() error { func (c *Clique) Close() error {
return nil return nil
} }

View file

@ -97,7 +97,7 @@ type Engine interface {
// APIs returns the RPC APIs this consensus engine provides. // APIs returns the RPC APIs this consensus engine provides.
APIs(chain ChainReader) []rpc.API APIs(chain ChainReader) []rpc.API
// Close closes the consensus engine. // Close terminates any background threads maintained by the consensus engine.
Close() error Close() error
} }

View file

@ -24,10 +24,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
) )
var ( var errEthashStopped = errors.New("ethash stopped")
errEthashStopped = errors.New("ethash stopped")
errAPINotSupported = errors.New("the current ethash running mode does not support this API")
)
// API exposes ethash related methods for the RPC interface. // API exposes ethash related methods for the RPC interface.
type API struct { type API struct {
@ -42,26 +39,27 @@ type API struct {
// result[2] - 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty // result[2] - 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
func (api *API) GetWork() ([3]string, error) { func (api *API) GetWork() ([3]string, error) {
if api.ethash.config.PowMode != ModeNormal && api.ethash.config.PowMode != ModeTest { if api.ethash.config.PowMode != ModeNormal && api.ethash.config.PowMode != ModeTest {
return [3]string{}, errAPINotSupported return [3]string{}, errors.New("not supported")
} }
var ( var (
workCh = make(chan [3]string, 1) workCh = make(chan [3]string, 1)
errCh = make(chan error, 1) errc = make(chan error, 1)
err error
) )
select { select {
case api.ethash.fetchWorkCh <- &sealWork{errCh: errCh, resCh: workCh}: case api.ethash.fetchWorkCh <- &sealWork{errc: errc, res: workCh}:
case <-api.ethash.exitCh: case <-api.ethash.exitCh:
return [3]string{}, errEthashStopped return [3]string{}, errEthashStopped
} }
if err = <-errCh; err == nil { select {
return <-workCh, nil case work := <-workCh:
} return work, nil
case err := <-errc:
return [3]string{}, err return [3]string{}, err
} }
}
// SubmitWork can be used by external miner to submit their POW solution. // SubmitWork can be used by external miner to submit their POW solution.
// It returns an indication if the work was accepted. // It returns an indication if the work was accepted.
@ -71,20 +69,20 @@ func (api *API) SubmitWork(nonce types.BlockNonce, hash, digest common.Hash) boo
return false return false
} }
var errCh = make(chan error, 1) var errc = make(chan error, 1)
select { select {
case api.ethash.submitWorkCh <- &mineResult{ case api.ethash.submitWorkCh <- &mineResult{
nonce: nonce, nonce: nonce,
mixDigest: digest, mixDigest: digest,
hash: hash, hash: hash,
errCh: errCh, errc: errc,
}: }:
case <-api.ethash.exitCh: case <-api.ethash.exitCh:
return false return false
} }
err := <-errCh err := <-errc
return err == nil return err == nil
} }
@ -99,16 +97,16 @@ func (api *API) SubmitHashRate(rate hexutil.Uint64, id common.Hash) bool {
return false return false
} }
var doneCh = make(chan struct{}, 1) var done = make(chan struct{}, 1)
select { select {
case api.ethash.submitRateCh <- &hashrate{done: doneCh, rate: uint64(rate), id: id}: case api.ethash.submitRateCh <- &hashrate{done: done, rate: uint64(rate), id: id}:
case <-api.ethash.exitCh: case <-api.ethash.exitCh:
return false return false
} }
// Block until hash rate submitted successfully. // Block until hash rate submitted successfully.
<-doneCh <-done
return true return true
} }

View file

@ -397,7 +397,7 @@ type mineResult struct {
mixDigest common.Hash mixDigest common.Hash
hash common.Hash hash common.Hash
errCh chan error errc chan error
} }
// hashrate wraps the hash rate submitted by the remote sealer. // hashrate wraps the hash rate submitted by the remote sealer.
@ -411,8 +411,8 @@ type hashrate struct {
// sealWork wraps a seal work package for remote sealer. // sealWork wraps a seal work package for remote sealer.
type sealWork struct { type sealWork struct {
errCh chan error errc chan error
resCh chan [3]string res chan [3]string
} }
// Ethash is a consensus engine based on proof-of-work implementing the ethash // Ethash is a consensus engine based on proof-of-work implementing the ethash
@ -447,7 +447,7 @@ type Ethash struct {
exitCh chan chan error // Notification channel to exiting backend threads exitCh chan chan error // Notification channel to exiting backend threads
} }
// New creates a full sized ethash PoW scheme. // New creates a full sized ethash PoW scheme and starts a background thread for remote mining.
func New(config Config) *Ethash { func New(config Config) *Ethash {
if config.CachesInMem <= 0 { if config.CachesInMem <= 0 {
log.Warn("One ethash cache must always be in memory", "requested", config.CachesInMem) log.Warn("One ethash cache must always be in memory", "requested", config.CachesInMem)
@ -557,9 +557,9 @@ func (ethash *Ethash) Close() error {
if ethash.exitCh == nil { if ethash.exitCh == nil {
return return
} }
errCh := make(chan error) errc := make(chan error)
ethash.exitCh <- errCh ethash.exitCh <- errc
err = <-errCh err = <-errc
close(ethash.exitCh) close(ethash.exitCh)
}) })
return err return err
@ -644,18 +644,17 @@ func (ethash *Ethash) Hashrate() float64 {
if ethash.config.PowMode != ModeNormal && ethash.config.PowMode != ModeTest { if ethash.config.PowMode != ModeNormal && ethash.config.PowMode != ModeTest {
return ethash.hashrate.Rate1() return ethash.hashrate.Rate1()
} }
var resCh = make(chan uint64, 1) var res = make(chan uint64, 1)
select { select {
case ethash.fetchRateCh <- resCh: case ethash.fetchRateCh <- res:
case <-ethash.exitCh: case <-ethash.exitCh:
// Return local hashrate only if ethash is stopped. // Return local hashrate only if ethash is stopped.
return ethash.hashrate.Rate1() return ethash.hashrate.Rate1()
} }
// Gather total submitted hash rate of remote sealers. // Gather total submitted hash rate of remote sealers.
total := <-resCh return ethash.hashrate.Rate1() + float64(<-res)
return ethash.hashrate.Rate1() + float64(total)
} }
// APIs implements consensus.Engine, returning the user facing RPC APIs. // APIs implements consensus.Engine, returning the user facing RPC APIs.

View file

@ -235,7 +235,6 @@ func (ethash *Ethash) remote() {
ticker := time.NewTicker(5 * time.Second) ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop() defer ticker.Stop()
running:
for { for {
select { select {
case block := <-ethash.workCh: case block := <-ethash.workCh:
@ -251,18 +250,17 @@ running:
// Return current mining work to remote miner. // Return current mining work to remote miner.
miningWork, err := getWork() miningWork, err := getWork()
if err != nil { if err != nil {
work.errCh <- err work.errc <- err
} else { } else {
close(work.errCh) work.res <- miningWork
work.resCh <- miningWork
} }
case result := <-ethash.submitWorkCh: case result := <-ethash.submitWorkCh:
// Verify submitted PoW solution based on maintained mining blocks. // Verify submitted PoW solution based on maintained mining blocks.
if submitWork(result.nonce, result.mixDigest, result.hash) { if submitWork(result.nonce, result.mixDigest, result.hash) {
close(result.errCh) result.errc <- nil
} else { } else {
result.errCh <- errInvalidSealResult result.errc <- errInvalidSealResult
} }
case result := <-ethash.submitRateCh: case result := <-ethash.submitRateCh:
@ -287,11 +285,11 @@ running:
} }
} }
case errCh := <-ethash.exitCh: case errc := <-ethash.exitCh:
// Exit remote loop if ethash is closed and return relevant error. // Exit remote loop if ethash is closed and return relevant error.
errCh <- nil errc <- nil
break running
}
}
log.Trace("Ethash remote sealer is exiting") log.Trace("Ethash remote sealer is exiting")
return
}
}
} }