@@ -149,9 +149,10 @@ type worker struct {
149
149
resubmitIntervalCh chan time.Duration
150
150
resubmitAdjustCh chan * intervalAdjust
151
151
152
- current * environment // An environment for current running cycle.
153
- possibleUncles map [common.Hash ]* types.Block // A set of side blocks as the possible uncle blocks.
154
- unconfirmed * unconfirmedBlocks // A set of locally mined blocks pending canonicalness confirmations.
152
+ current * environment // An environment for current running cycle.
153
+ localUncles map [common.Hash ]* types.Block // A set of side blocks generated locally as the possible uncle blocks.
154
+ remoteUncles map [common.Hash ]* types.Block // A set of side blocks as the possible uncle blocks.
155
+ unconfirmed * unconfirmedBlocks // A set of locally mined blocks pending canonicalness confirmations.
155
156
156
157
mu sync.RWMutex // The lock used to protect the coinbase and extra fields
157
158
coinbase common.Address
@@ -168,14 +169,17 @@ type worker struct {
168
169
running int32 // The indicator whether the consensus engine is running or not.
169
170
newTxs int32 // New arrival transaction count since last sealing work submitting.
170
171
172
+ // External functions
173
+ isLocalBlock func (block * types.Block ) bool // Function used to determine whether the specified block is mined by local miner.
174
+
171
175
// Test hooks
172
176
newTaskHook func (* task ) // Method to call upon receiving a new sealing task.
173
177
skipSealHook func (* task ) bool // Method to decide whether skipping the sealing.
174
178
fullTaskHook func () // Method to call before pushing the full sealing task.
175
179
resubmitHook func (time.Duration , time.Duration ) // Method to call upon updating resubmitting interval.
176
180
}
177
181
178
- func newWorker (config * params.ChainConfig , engine consensus.Engine , eth Backend , mux * event.TypeMux , recommit time.Duration , gasFloor , gasCeil uint64 ) * worker {
182
+ func newWorker (config * params.ChainConfig , engine consensus.Engine , eth Backend , mux * event.TypeMux , recommit time.Duration , gasFloor , gasCeil uint64 , isLocalBlock func ( * types. Block ) bool ) * worker {
179
183
worker := & worker {
180
184
config : config ,
181
185
engine : engine ,
@@ -184,7 +188,9 @@ func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend,
184
188
chain : eth .BlockChain (),
185
189
gasFloor : gasFloor ,
186
190
gasCeil : gasCeil ,
187
- possibleUncles : make (map [common.Hash ]* types.Block ),
191
+ isLocalBlock : isLocalBlock ,
192
+ localUncles : make (map [common.Hash ]* types.Block ),
193
+ remoteUncles : make (map [common.Hash ]* types.Block ),
188
194
unconfirmed : newUnconfirmedBlocks (eth .BlockChain (), miningLogAtDepth ),
189
195
pendingTasks : make (map [common.Hash ]* task ),
190
196
txsCh : make (chan core.NewTxsEvent , txChanSize ),
@@ -405,11 +411,19 @@ func (w *worker) mainLoop() {
405
411
w .commitNewWork (req .interrupt , req .noempty , req .timestamp )
406
412
407
413
case ev := <- w .chainSideCh :
408
- if _ , exist := w .possibleUncles [ev .Block .Hash ()]; exist {
414
+ // Short circuit for duplicate side blocks
415
+ if _ , exist := w .localUncles [ev .Block .Hash ()]; exist {
416
+ continue
417
+ }
418
+ if _ , exist := w .remoteUncles [ev .Block .Hash ()]; exist {
409
419
continue
410
420
}
411
- // Add side block to possible uncle block set.
412
- w .possibleUncles [ev .Block .Hash ()] = ev .Block
421
+ // Add side block to possible uncle block set depending on the author.
422
+ if w .isLocalBlock != nil && w .isLocalBlock (ev .Block ) {
423
+ w .localUncles [ev .Block .Hash ()] = ev .Block
424
+ } else {
425
+ w .remoteUncles [ev .Block .Hash ()] = ev .Block
426
+ }
413
427
// If our mining block contains less than 2 uncle blocks,
414
428
// add the new uncle block if valid and regenerate a mining block.
415
429
if w .isRunning () && w .current != nil && w .current .uncles .Cardinality () < 2 {
@@ -421,7 +435,10 @@ func (w *worker) mainLoop() {
421
435
if ! ok {
422
436
return false
423
437
}
424
- uncle , exist := w .possibleUncles [hash ]
438
+ uncle , exist := w .localUncles [hash ]
439
+ if ! exist {
440
+ uncle , exist = w .remoteUncles [hash ]
441
+ }
425
442
if ! exist {
426
443
return false
427
444
}
@@ -651,7 +668,10 @@ func (w *worker) updateSnapshot() {
651
668
if ! ok {
652
669
return false
653
670
}
654
- uncle , exist := w .possibleUncles [hash ]
671
+ uncle , exist := w .localUncles [hash ]
672
+ if ! exist {
673
+ uncle , exist = w .remoteUncles [hash ]
674
+ }
655
675
if ! exist {
656
676
return false
657
677
}
@@ -859,23 +879,29 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
859
879
misc .ApplyDAOHardFork (env .state )
860
880
}
861
881
// Accumulate the uncles for the current block
862
- for hash , uncle := range w .possibleUncles {
863
- if uncle .NumberU64 ()+ staleThreshold <= header .Number .Uint64 () {
864
- delete (w .possibleUncles , hash )
865
- }
866
- }
867
882
uncles := make ([]* types.Header , 0 , 2 )
868
- for hash , uncle := range w .possibleUncles {
869
- if len (uncles ) == 2 {
870
- break
883
+ commitUncles := func (blocks map [common.Hash ]* types.Block ) {
884
+ // Clean up stale uncle blocks first
885
+ for hash , uncle := range blocks {
886
+ if uncle .NumberU64 ()+ staleThreshold <= header .Number .Uint64 () {
887
+ delete (blocks , hash )
888
+ }
871
889
}
872
- if err := w .commitUncle (env , uncle .Header ()); err != nil {
873
- log .Trace ("Possible uncle rejected" , "hash" , hash , "reason" , err )
874
- } else {
875
- log .Debug ("Committing new uncle to block" , "hash" , hash )
876
- uncles = append (uncles , uncle .Header ())
890
+ for hash , uncle := range blocks {
891
+ if len (uncles ) == 2 {
892
+ break
893
+ }
894
+ if err := w .commitUncle (env , uncle .Header ()); err != nil {
895
+ log .Trace ("Possible uncle rejected" , "hash" , hash , "reason" , err )
896
+ } else {
897
+ log .Debug ("Committing new uncle to block" , "hash" , hash )
898
+ uncles = append (uncles , uncle .Header ())
899
+ }
877
900
}
878
901
}
902
+ // Prefer to locally generated uncle
903
+ commitUncles (w .localUncles )
904
+ commitUncles (w .remoteUncles )
879
905
880
906
if ! noempty {
881
907
// Create an empty block based on temporary copied state for sealing in advance without waiting block
0 commit comments