aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--miner/worker.go51
1 files changed, 33 insertions, 18 deletions
diff --git a/miner/worker.go b/miner/worker.go
index 15395ae0b..48b0b2765 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -117,6 +117,10 @@ type worker struct {
currentMu sync.Mutex
current *Work
+ snapshotMu sync.RWMutex
+ snapshotBlock *types.Block
+ snapshotState *state.StateDB
+
uncleMu sync.Mutex
possibleUncles map[common.Hash]*types.Block
@@ -171,32 +175,28 @@ func (self *worker) setExtra(extra []byte) {
}
func (self *worker) pending() (*types.Block, *state.StateDB) {
- self.currentMu.Lock()
- defer self.currentMu.Unlock()
-
if atomic.LoadInt32(&self.mining) == 0 {
- return types.NewBlock(
- self.current.header,
- self.current.txs,
- nil,
- self.current.receipts,
- ), self.current.state.Copy()
+ // return a snapshot to avoid contention on currentMu mutex
+ self.snapshotMu.RLock()
+ defer self.snapshotMu.RUnlock()
+ return self.snapshotBlock, self.snapshotState.Copy()
}
- return self.current.Block, self.current.state.Copy()
-}
-func (self *worker) pendingBlock() *types.Block {
self.currentMu.Lock()
defer self.currentMu.Unlock()
+ return self.current.Block, self.current.state.Copy()
+}
+func (self *worker) pendingBlock() *types.Block {
if atomic.LoadInt32(&self.mining) == 0 {
- return types.NewBlock(
- self.current.header,
- self.current.txs,
- nil,
- self.current.receipts,
- )
+ // return a snapshot to avoid contention on currentMu mutex
+ self.snapshotMu.RLock()
+ defer self.snapshotMu.RUnlock()
+ return self.snapshotBlock
}
+
+ self.currentMu.Lock()
+ defer self.currentMu.Unlock()
return self.current.Block
}
@@ -268,6 +268,7 @@ func (self *worker) update() {
txset := types.NewTransactionsByPriceAndNonce(self.current.signer, txs)
self.current.commitTransactions(self.mux, txset, self.chain, self.coinbase)
+ self.updateSnapshot()
self.currentMu.Unlock()
} else {
// If we're mining, but nothing is being processed, wake on new transactions
@@ -489,6 +490,7 @@ func (self *worker) commitNewWork() {
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
}
self.push(work)
+ self.updateSnapshot()
}
func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
@@ -506,6 +508,19 @@ func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
return nil
}
+func (self *worker) updateSnapshot() {
+ self.snapshotMu.Lock()
+ defer self.snapshotMu.Unlock()
+
+ self.snapshotBlock = types.NewBlock(
+ self.current.header,
+ self.current.txs,
+ nil,
+ self.current.receipts,
+ )
+ self.snapshotState = self.current.state.Copy()
+}
+
func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsByPriceAndNonce, bc *core.BlockChain, coinbase common.Address) {
gp := new(core.GasPool).AddGas(env.header.GasLimit)