-
Notifications
You must be signed in to change notification settings - Fork 20.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
consensus/ethash: move remote agent logic to ethash internal #15853
Conversation
00fcdd4
to
1dca875
Compare
9f62c5f
to
137db3f
Compare
137db3f
to
8fbc8f7
Compare
dd58b1d
to
da3d009
Compare
@karalabe PTAL |
da3d009
to
cd478b8
Compare
consensus/ethash/api.go
Outdated
// | ||
// You should have received a copy of the GNU Lesser General Public License | ||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||
package ethash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a newline here, otherwise the copyright text will be interpreted as the package documentation.
consensus/ethash/api.go
Outdated
// GetWork returns a work package for external miner. The work package consists of 3 strings | ||
// result[0], 32 bytes hex encoded current block header pow-hash | ||
// result[1], 32 bytes hex encoded seed hash used for DAG | ||
// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please format the doc a bit cleaner:
// GetWork returns a work package for external miner.
//
// The work package consists of 3 strings:
// result[0] - 32 bytes hex encoded current block header pow-hash
// result[1] - 32 bytes hex encoded seed hash used for DAG
// result[2] - 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
consensus/ethash/api.go
Outdated
"github.com/ethereum/go-ethereum/core/types" | ||
) | ||
|
||
// API exposes ethash related methods for the RPC interface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a .
at the end.
consensus/ethash/api.go
Outdated
// result[0], 32 bytes hex encoded current block header pow-hash | ||
// result[1], 32 bytes hex encoded seed hash used for DAG | ||
// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty | ||
func (s *API) GetWork() ([3]string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please convert s
to api
throughout.
consensus/ethash/api.go
Outdated
return <-workCh, nil | ||
} else { | ||
return [3]string{}, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if err := <-errCh; err == nil {
return <-workCh, nil
}
return [3]string{}, err
consensus/ethash/ethash.go
Outdated
Version: "1.0", | ||
Service: &API{ethash}, | ||
Public: true, | ||
}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to make it nicer for future APIs, lets also advertize these in the ethash
namespace, similar to how clique
is done.
consensus/ethash/ethash_test.go
Outdated
@@ -69,11 +71,55 @@ func verifyTest(wg *sync.WaitGroup, e *Ethash, workerIndex, epochs int) { | |||
const wiggle = 4 * epochLength | |||
r := rand.New(rand.NewSource(int64(workerIndex))) | |||
for epoch := 0; epoch < epochs; epoch++ { | |||
block := int64(epoch)*epochLength - wiggle/2 + r.Int63n(wiggle) | |||
block := int64(epoch) * epochLength - wiggle / 2 + r.Int63n(wiggle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gofmt :P
consensus/ethash/sealer.go
Outdated
var ( | ||
errNoMineWork = errors.New("No mining work available yet, don't panic.") | ||
errInvalidSealResult = errors.New("Invalid or stale proof-of-work solution.") | ||
errUndefinedRemoteOp = errors.New("Undefined remote mining operation.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Errors need to be composable. I.e. don't terminate them with .
and don't capitalize them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You won't need errUndefinedRemoteOp
if you go down the multiple task channel approach.
consensus/ethash/sealer.go
Outdated
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/consensus" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/log" | ||
) | ||
|
||
var ( | ||
errNoMineWork = errors.New("No mining work available yet, don't panic.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
errNoMineWork
-> errNoMiningWork
consensus/ethash/sealer.go
Outdated
@@ -150,3 +164,122 @@ search: | |||
// during sealing so it's not unmapped while being read. | |||
runtime.KeepAlive(dataset) | |||
} | |||
|
|||
// remote starts a standalone goroutine to handle remote mining related stuff. | |||
func (ethash *Ethash) remote(resultCh chan *types.Block) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this take a channel as a parameter? I saw that sometimes you pass in nil
, but wouldn't that be the same as ethash.resultCh
being nil?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we even want to start this goroutine in the first place if there's no result channel?
e290051
to
e6c4652
Compare
e869923
to
9ac699e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It generally looks good to me, but I am not fluent in all the ins and outs regarding channels.
consensus/ethash/sealer.go
Outdated
@@ -43,9 +50,9 @@ func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop | |||
if ethash.shared != nil { | |||
return ethash.shared.Seal(chain, block, stop) | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove empty line
consensus/ethash/sealer.go
Outdated
if ethash.workCh != nil { | ||
ethash.workCh <- block | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls remove empty line
consensus/ethash/sealer.go
Outdated
@@ -64,12 +71,18 @@ func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop | |||
if threads < 0 { | |||
threads = 0 // Allows disabling local mining without extra logic around local/remote | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty line
9ac699e
to
8a9e11c
Compare
8a9e11c
to
e0f84a4
Compare
133895a
to
21a9435
Compare
21a9435
to
64abec0
Compare
consensus/clique/clique.go
Outdated
@@ -672,6 +672,11 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int { | |||
return new(big.Int).Set(diffNoTurn) | |||
} | |||
|
|||
// Close implements consensus.Engine, returning internal error and close the clique. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Close implements consensus.Engine. It's a noop for clique as there is are no background threads.
consensus/consensus.go
Outdated
@@ -96,6 +96,9 @@ type Engine interface { | |||
|
|||
// APIs returns the RPC APIs this consensus engine provides. | |||
APIs(chain ChainReader) []rpc.API | |||
|
|||
// Close closes the consensus engine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Close terminates any background threads maintained by the consensus engine.
consensus/ethash/api.go
Outdated
|
||
var ( | ||
errEthashStopped = errors.New("ethash stopped") | ||
errAPINotSupported = errors.New("the current ethash running mode does not support this API") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really think we need a pre-declared error for this. It's a very special case that won't ever happen. Let's just inline it.
consensus/ethash/api.go
Outdated
func (api *API) GetWork() ([3]string, error) { | ||
if api.ethash.config.PowMode != ModeNormal && api.ethash.config.PowMode != ModeTest { | ||
return [3]string{}, errAPINotSupported | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MHO we can just do errAPINotSupported
-> errors.New("not supported")
.
consensus/ethash/api.go
Outdated
return false | ||
} | ||
|
||
var errCh = make(chan error, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error channels are canonically named errc
throughout all Go code. Please rename.
consensus/ethash/api.go
Outdated
if err = <-errCh; err == nil { | ||
return <-workCh, nil | ||
} | ||
return [3]string{}, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this construct be simpler with:
select {
case work := <-workCh:
return work, nil
case err := <-errCh:
return nil, err
}
Then you wouldn't need to signal first by closing errCh and then retrieve the result from a second channel.
consensus/ethash/sealer.go
Outdated
} else { | ||
close(work.errCh) | ||
work.resCh <- miningWork | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be simpler with:
if err != nil {
work.errCh <- err
} else {
work.resCh <- miningWork
}
consensus/ethash/sealer.go
Outdated
case result := <-ethash.submitWorkCh: | ||
// Verify submitted PoW solution based on maintained mining blocks. | ||
if submitWork(result.nonce, result.mixDigest, result.hash) { | ||
close(result.errCh) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit unorthodox. Lets use result.errCh <- nil
instead. It feels a bit wrong to close an error channel.
consensus/ethash/sealer.go
Outdated
ticker := time.NewTicker(5 * time.Second) | ||
defer ticker.Stop() | ||
|
||
running: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think a label is warranted here, you only use it once. Just do a return :)
consensus/ethash/sealer.go
Outdated
case errCh := <-ethash.exitCh: | ||
// Exit remote loop if ethash is closed and return relevant error. | ||
errCh <- nil | ||
break running |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's simpler to just return
here. Gets rid of the label, simplifies the code flow. Just move the log.Trace
up here too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Lets see how it behaves live.
@karalabe @rjl493456442 @holiman @zsfelfoldi Shouldn't we update the documentation for this new API? https://github.com/ethereum/wiki/wiki/JSON-RPC https://github.com/ethereum/go-ethereum/wiki/Management-APIs |
it seems make the duplicate output log for clique
|
* consensus/ethash: start remote ggoroutine to handle remote mining * consensus/ethash: expose remote miner api * consensus/ethash: expose submitHashrate api * miner, ethash: push empty block to sealer without waiting execution * consensus, internal: add getHashrate API for ethash * consensus: add three method for consensus interface * miner: expose consensus engine running status to miner * eth, miner: specify etherbase when miner created * miner: commit new work when consensus engine is started * consensus, miner: fix some logics * all: delete useless interfaces * consensus: polish a bit
…m#15853) * consensus/ethash: start remote ggoroutine to handle remote mining * consensus/ethash: expose remote miner api * consensus/ethash: expose submitHashrate api * miner, ethash: push empty block to sealer without waiting execution * consensus, internal: add getHashrate API for ethash * consensus: add three method for consensus interface * miner: expose consensus engine running status to miner * eth, miner: specify etherbase when miner created * miner: commit new work when consensus engine is started * consensus, miner: fix some logics * all: delete useless interfaces * consensus: polish a bit
Hi @rjl493456442,
Here's a snippet that can be used to reproduce the above error:
It fails (or sometimes even hangs without the exception) on my machine when run like I'd appreciate any help. |
In this pull request, i move the remote miner relative logics to ethash engine internally. Since this part of logics are PoW characteristic(including remote miner, hashrate submission or statistic). It can make miner package more clear.