@@ -117,6 +117,10 @@ type worker struct {
117
117
currentMu sync.Mutex
118
118
current * Work
119
119
120
+ snapshotMu sync.RWMutex
121
+ snapshotBlock * types.Block
122
+ snapshotState * state.StateDB
123
+
120
124
uncleMu sync.Mutex
121
125
possibleUncles map [common.Hash ]* types.Block
122
126
@@ -171,32 +175,28 @@ func (self *worker) setExtra(extra []byte) {
171
175
}
172
176
173
177
func (self * worker ) pending () (* types.Block , * state.StateDB ) {
174
- self .currentMu .Lock ()
175
- defer self .currentMu .Unlock ()
176
-
177
178
if atomic .LoadInt32 (& self .mining ) == 0 {
178
- return types .NewBlock (
179
- self .current .header ,
180
- self .current .txs ,
181
- nil ,
182
- self .current .receipts ,
183
- ), self .current .state .Copy ()
179
+ // return a snapshot to avoid contention on currentMu mutex
180
+ self .snapshotMu .RLock ()
181
+ defer self .snapshotMu .RUnlock ()
182
+ return self .snapshotBlock , self .snapshotState .Copy ()
184
183
}
185
- return self .current .Block , self .current .state .Copy ()
186
- }
187
184
188
- func (self * worker ) pendingBlock () * types.Block {
189
185
self .currentMu .Lock ()
190
186
defer self .currentMu .Unlock ()
187
+ return self .current .Block , self .current .state .Copy ()
188
+ }
191
189
190
+ func (self * worker ) pendingBlock () * types.Block {
192
191
if atomic .LoadInt32 (& self .mining ) == 0 {
193
- return types .NewBlock (
194
- self .current .header ,
195
- self .current .txs ,
196
- nil ,
197
- self .current .receipts ,
198
- )
192
+ // return a snapshot to avoid contention on currentMu mutex
193
+ self .snapshotMu .RLock ()
194
+ defer self .snapshotMu .RUnlock ()
195
+ return self .snapshotBlock
199
196
}
197
+
198
+ self .currentMu .Lock ()
199
+ defer self .currentMu .Unlock ()
200
200
return self .current .Block
201
201
}
202
202
@@ -268,6 +268,7 @@ func (self *worker) update() {
268
268
txset := types .NewTransactionsByPriceAndNonce (self .current .signer , txs )
269
269
270
270
self .current .commitTransactions (self .mux , txset , self .chain , self .coinbase )
271
+ self .updateSnapshot ()
271
272
self .currentMu .Unlock ()
272
273
} else {
273
274
// If we're mining, but nothing is being processed, wake on new transactions
@@ -489,6 +490,7 @@ func (self *worker) commitNewWork() {
489
490
self .unconfirmed .Shift (work .Block .NumberU64 () - 1 )
490
491
}
491
492
self .push (work )
493
+ self .updateSnapshot ()
492
494
}
493
495
494
496
func (self * worker ) commitUncle (work * Work , uncle * types.Header ) error {
@@ -506,6 +508,19 @@ func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
506
508
return nil
507
509
}
508
510
511
+ func (self * worker ) updateSnapshot () {
512
+ self .snapshotMu .Lock ()
513
+ defer self .snapshotMu .Unlock ()
514
+
515
+ self .snapshotBlock = types .NewBlock (
516
+ self .current .header ,
517
+ self .current .txs ,
518
+ nil ,
519
+ self .current .receipts ,
520
+ )
521
+ self .snapshotState = self .current .state .Copy ()
522
+ }
523
+
509
524
func (env * Work ) commitTransactions (mux * event.TypeMux , txs * types.TransactionsByPriceAndNonce , bc * core.BlockChain , coinbase common.Address ) {
510
525
gp := new (core.GasPool ).AddGas (env .header .GasLimit )
511
526
0 commit comments