diff options
author | Péter Szilágyi <peterke@gmail.com> | 2018-08-29 18:59:15 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-29 18:59:15 +0800 |
commit | a4bc2c31e13d7aa7b8715bd707d2460755016414 (patch) | |
tree | 226bc51633853c17a71c3c045b6f014f55884c6c /miner/worker.go | |
parent | 75ae5af62a8dbbc4fc547d2b3b4cce192d783b2d (diff) | |
parent | f751c6ed47db49e0032dfcd0f4c06ce72f3616bb (diff) | |
download | dexon-a4bc2c31e13d7aa7b8715bd707d2460755016414.tar.gz dexon-a4bc2c31e13d7aa7b8715bd707d2460755016414.tar.zst dexon-a4bc2c31e13d7aa7b8715bd707d2460755016414.zip |
Merge pull request #17540 from karalabe/miner-uncle-fix
miner: track uncles more aggressively
Diffstat (limited to 'miner/worker.go')
-rw-r--r-- | miner/worker.go | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/miner/worker.go b/miner/worker.go index 5348cb3f1..629ce5bd2 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -18,7 +18,7 @@ package miner import ( "bytes" - "fmt" + "errors" "math/big" "sync" "sync/atomic" @@ -620,13 +620,16 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error { func (w *worker) commitUncle(env *environment, uncle *types.Header) error { hash := uncle.Hash() if env.uncles.Contains(hash) { - return fmt.Errorf("uncle not unique") + return errors.New("uncle not unique") + } + if env.header.ParentHash == uncle.ParentHash { + return errors.New("uncle is sibling") } if !env.ancestors.Contains(uncle.ParentHash) { - return fmt.Errorf("uncle's parent unknown (%x)", uncle.ParentHash[0:4]) + return errors.New("uncle's parent unknown") } if env.family.Contains(hash) { - return fmt.Errorf("uncle already in family (%x)", hash) + return errors.New("uncle already included") } env.uncles.Add(uncle.Hash()) return nil @@ -852,29 +855,24 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool) { if w.config.DAOForkSupport && w.config.DAOForkBlock != nil && w.config.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(env.state) } - - // compute uncles for the new block. - var ( - uncles []*types.Header - badUncles []common.Hash - ) + // Accumulate the uncles for the current block + for hash, uncle := range w.possibleUncles { + if uncle.NumberU64()+staleThreshold <= header.Number.Uint64() { + delete(w.possibleUncles, hash) + } + } + uncles := make([]*types.Header, 0, 2) for hash, uncle := range w.possibleUncles { if len(uncles) == 2 { break } if err := w.commitUncle(env, uncle.Header()); err != nil { - log.Trace("Bad uncle found and will be removed", "hash", hash) - log.Trace(fmt.Sprint(uncle)) - - badUncles = append(badUncles, hash) + log.Trace("Possible uncle rejected", "hash", hash, "reason", err) } else { log.Debug("Committing new uncle to block", "hash", hash) uncles = append(uncles, uncle.Header()) } } - for _, hash := range badUncles { - delete(w.possibleUncles, hash) - } if !noempty { // Create an empty block based on temporary copied state for sealing in advance without waiting block |