cmd, consensus, miner: polish

This commit is contained in:
rjl493456442 2018-08-28 20:15:33 +08:00
parent 8b527fa948
commit 8eb568a4d2
5 changed files with 29 additions and 18 deletions

View file

@ -366,12 +366,12 @@ var (
} }
MinerRecommitIntervalFlag = cli.DurationFlag{ MinerRecommitIntervalFlag = cli.DurationFlag{
Name: "miner.recommit", Name: "miner.recommit",
Usage: "Time interval to recreate the block being mined.", Usage: "Time interval to recreate the block being mined",
Value: eth.DefaultConfig.MinerRecommit, Value: eth.DefaultConfig.MinerRecommit,
} }
MinerNoVerfiyFlag = cli.BoolFlag{ MinerNoVerfiyFlag = cli.BoolFlag{
Name: "miner.noverify", Name: "miner.noverify",
Usage: "Disable remote sealing verification.", Usage: "Disable remote sealing verification",
} }
// Account settings // Account settings
UnlockedAccountFlag = cli.StringFlag{ UnlockedAccountFlag = cli.StringFlag{

View file

@ -87,7 +87,10 @@ type Engine interface {
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)
// Seal generates a new sealing request for the given input block and pushes // Seal generates a new sealing request for the given input block and pushes
// the result in the given channel. // the result into the given channel.
//
// Note, the method returns immediately and will send the result async. More
// than one result may also be returned depending on the consensus algorothm.
Seal(chain ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error Seal(chain ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error
// SealHash returns the hash of a block prior to it being sealed. // SealHash returns the hash of a block prior to it being sealed.

View file

@ -55,7 +55,7 @@ func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, resu
select { select {
case results <- block.WithSeal(header): case results <- block.WithSeal(header):
default: default:
log.Warn("Sealing result is not read by miner", "sealhash", ethash.SealHash(block.Header())) log.Warn("Sealing result is not read by miner", "mode", "fake", "sealhash", ethash.SealHash(block.Header()))
} }
return nil return nil
} }
@ -88,14 +88,14 @@ func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, resu
ethash.workCh <- &sealTask{block: block, results: results} ethash.workCh <- &sealTask{block: block, results: results}
} }
var ( var (
pend sync.WaitGroup pend sync.WaitGroup
localResults = make(chan *types.Block) locals = make(chan *types.Block)
) )
for i := 0; i < threads; i++ { for i := 0; i < threads; i++ {
pend.Add(1) pend.Add(1)
go func(id int, nonce uint64) { go func(id int, nonce uint64) {
defer pend.Done() defer pend.Done()
ethash.mine(block, id, nonce, abort, localResults) ethash.mine(block, id, nonce, abort, locals)
}(i, uint64(ethash.rand.Int63())) }(i, uint64(ethash.rand.Int63()))
} }
// Wait until sealing is terminated or a nonce is found // Wait until sealing is terminated or a nonce is found
@ -105,19 +105,20 @@ func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, resu
case <-stop: case <-stop:
// Outside abort, stop all miner threads // Outside abort, stop all miner threads
close(abort) close(abort)
case result = <-localResults: case result = <-locals:
// One of the threads found a block, abort all others // One of the threads found a block, abort all others
select { select {
case results <- result: case results <- result:
default: default:
log.Warn("Sealing result is not read by miner", "sealhash", ethash.SealHash(block.Header())) log.Warn("Sealing result is not read by miner", "mode", "local", "sealhash", ethash.SealHash(block.Header()))
} }
close(abort) close(abort)
case <-ethash.update: case <-ethash.update:
// Thread count was changed on user request, restart // Thread count was changed on user request, restart
close(abort) close(abort)
pend.Wait() if err := ethash.Seal(chain, block, results, stop); err != nil {
ethash.Seal(chain, block, results, stop) log.Error("Failed to restart sealing after update", "err", err)
}
} }
// Wait for all miners to terminate and return the block // Wait for all miners to terminate and return the block
pend.Wait() pend.Wait()
@ -287,12 +288,12 @@ func (ethash *Ethash) remote(notify []string, noverify bool) {
log.Debug("Work submitted is acceptable", "number", solution.NumberU64(), "sealhash", sealhash, "hash", solution.Hash()) log.Debug("Work submitted is acceptable", "number", solution.NumberU64(), "sealhash", sealhash, "hash", solution.Hash())
return true return true
default: default:
log.Warn("Sealing result is not read by miner", "sealhash", sealhash) log.Warn("Sealing result is not read by miner", "mode", "remote", "sealhash", sealhash)
return false return false
} }
} }
// The submitted block is too old to accept, drop it. // The submitted block is too old to accept, drop it.
log.Debug("Work submitted is too old", "number", solution.NumberU64(), "sealhash", sealhash, "hash", solution.Hash()) log.Warn("Work submitted is too old", "number", solution.NumberU64(), "sealhash", sealhash, "hash", solution.Hash())
return false return false
} }

View file

@ -190,7 +190,7 @@ func TestStaleSubmission(t *testing.T) {
t.Errorf("case %d block number mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Number.Uint64(), res.Header().Number.Uint64()) t.Errorf("case %d block number mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Number.Uint64(), res.Header().Number.Uint64())
} }
if res.Header().ParentHash != c.headers[c.submitIndex].ParentHash { if res.Header().ParentHash != c.headers[c.submitIndex].ParentHash {
t.Errorf("case %d block parent hash mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].ParentHash.Hex(), res.Header().ParentHash.Hex()) t.Errorf("case %d block parent hash mismatch, want %s, get %s", id+1, c.headers[c.submitIndex].ParentHash.Hex(), res.Header().ParentHash.Hex())
} }
case <-time.NewTimer(time.Second).C: case <-time.NewTimer(time.Second).C:
t.Errorf("case %d fetch ethash result timeout", id+1) t.Errorf("case %d fetch ethash result timeout", id+1)

View file

@ -524,12 +524,15 @@ func (w *worker) resultLoop() {
if w.chain.HasBlock(block.Hash(), block.NumberU64()) { if w.chain.HasBlock(block.Hash(), block.NumberU64()) {
continue continue
} }
sealhash := w.engine.SealHash(block.Header()) var (
sealhash = w.engine.SealHash(block.Header())
hash = block.Hash()
)
w.pendingMu.RLock() w.pendingMu.RLock()
task, exist := w.pendingTasks[sealhash] task, exist := w.pendingTasks[sealhash]
w.pendingMu.RUnlock() w.pendingMu.RUnlock()
if !exist { if !exist {
log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", block.Hash()) log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", hash)
continue continue
} }
// Different block could share same sealhash, deep copy here to prevent write-write conflict. // Different block could share same sealhash, deep copy here to prevent write-write conflict.
@ -543,9 +546,9 @@ func (w *worker) resultLoop() {
// Update the block hash in all logs since it is now available and not when the // Update the block hash in all logs since it is now available and not when the
// receipt/log of individual transactions were created. // receipt/log of individual transactions were created.
for _, log := range receipt.Logs { for _, log := range receipt.Logs {
log.BlockHash = block.Hash() log.BlockHash = hash
logs = append(logs, log)
} }
logs = append(logs, receipt.Logs...)
} }
// Commit block and state to database. // Commit block and state to database.
stat, err := w.chain.WriteBlockWithState(block, receipts, task.state) stat, err := w.chain.WriteBlockWithState(block, receipts, task.state)
@ -553,8 +556,12 @@ func (w *worker) resultLoop() {
log.Error("Failed writing block to chain", "err", err) log.Error("Failed writing block to chain", "err", err)
continue continue
} }
log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash,
"elapsed", common.PrettyDuration(time.Since(task.createdAt)))
// Broadcast the block and announce chain insertion event // Broadcast the block and announce chain insertion event
w.mux.Post(core.NewMinedBlockEvent{Block: block}) w.mux.Post(core.NewMinedBlockEvent{Block: block})
var events []interface{} var events []interface{}
switch stat { switch stat {
case core.CanonStatTy: case core.CanonStatTy: