@@ -117,6 +117,10 @@ type worker struct {
117117 currentMu sync.Mutex
118118 current * Work
119119
120+ snapshotMu sync.RWMutex
121+ snapshotBlock * types.Block
122+ snapshotState * state.StateDB
123+
120124 uncleMu sync.Mutex
121125 possibleUncles map [common.Hash ]* types.Block
122126
@@ -171,32 +175,28 @@ func (self *worker) setExtra(extra []byte) {
171175}
172176
173177func (self * worker ) pending () (* types.Block , * state.StateDB ) {
174- self .currentMu .Lock ()
175- defer self .currentMu .Unlock ()
176-
177178 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 ()
184183 }
185- return self .current .Block , self .current .state .Copy ()
186- }
187184
188- func (self * worker ) pendingBlock () * types.Block {
189185 self .currentMu .Lock ()
190186 defer self .currentMu .Unlock ()
187+ return self .current .Block , self .current .state .Copy ()
188+ }
191189
190+ func (self * worker ) pendingBlock () * types.Block {
192191 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
199196 }
197+
198+ self .currentMu .Lock ()
199+ defer self .currentMu .Unlock ()
200200 return self .current .Block
201201}
202202
@@ -268,6 +268,7 @@ func (self *worker) update() {
268268 txset := types .NewTransactionsByPriceAndNonce (self .current .signer , txs )
269269
270270 self .current .commitTransactions (self .mux , txset , self .chain , self .coinbase )
271+ self .updateSnapshot ()
271272 self .currentMu .Unlock ()
272273 } else {
273274 // If we're mining, but nothing is being processed, wake on new transactions
@@ -489,6 +490,7 @@ func (self *worker) commitNewWork() {
489490 self .unconfirmed .Shift (work .Block .NumberU64 () - 1 )
490491 }
491492 self .push (work )
493+ self .updateSnapshot ()
492494}
493495
494496func (self * worker ) commitUncle (work * Work , uncle * types.Header ) error {
@@ -506,6 +508,19 @@ func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
506508 return nil
507509}
508510
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+
509524func (env * Work ) commitTransactions (mux * event.TypeMux , txs * types.TransactionsByPriceAndNonce , bc * core.BlockChain , coinbase common.Address ) {
510525 gp := new (core.GasPool ).AddGas (env .header .GasLimit )
511526
0 commit comments