diff options
author | obscuren <geffobscura@gmail.com> | 2015-04-07 18:32:55 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-04-07 18:32:55 +0800 |
commit | 7b6a8cc9ae56856f1c292243b57d658b67b92621 (patch) | |
tree | e959e2d89dc88c00c288a97ac659843b5e06f0bf /miner | |
parent | 9c55576c7b415954773c062d404a736741fb9794 (diff) | |
download | dexon-7b6a8cc9ae56856f1c292243b57d658b67b92621.tar.gz dexon-7b6a8cc9ae56856f1c292243b57d658b67b92621.tar.zst dexon-7b6a8cc9ae56856f1c292243b57d658b67b92621.zip |
Fixed pending states
Diffstat (limited to 'miner')
-rw-r--r-- | miner/miner.go | 12 | ||||
-rw-r--r-- | miner/worker.go | 72 |
2 files changed, 64 insertions, 20 deletions
diff --git a/miner/miner.go b/miner/miner.go index 23e48db40..aa6c059ba 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -6,6 +6,8 @@ import ( "github.com/ethereum/ethash" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/pow" ) @@ -26,6 +28,7 @@ func New(eth core.Backend, pow pow.PoW, minerThreads int) *Miner { for i := 0; i < minerThreads; i++ { miner.worker.register(NewCpuMiner(i, pow)) } + return miner } @@ -40,6 +43,7 @@ func (self *Miner) Start(coinbase common.Address) { self.pow.(*ethash.Ethash).UpdateDAG() self.worker.start() + self.worker.commitNewWork() } @@ -61,3 +65,11 @@ func (self *Miner) HashRate() int64 { func (self *Miner) SetExtra(extra []byte) { self.worker.extra = extra } + +func (self *Miner) PendingState() *state.StateDB { + return self.worker.pendingState() +} + +func (self *Miner) PendingBlock() *types.Block { + return self.worker.pendingBlock() +} diff --git a/miner/worker.go b/miner/worker.go index da10cf7cd..ffd4af7d3 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -76,16 +76,20 @@ type worker struct { coinbase common.Address extra []byte - current *environment + currentMu sync.Mutex + current *environment uncleMu sync.Mutex possibleUncles map[common.Hash]*types.Block - mining bool + txQueueMu sync.Mutex + txQueue map[common.Hash]*types.Transaction + + mining int64 } func newWorker(coinbase common.Address, eth core.Backend) *worker { - return &worker{ + worker := &worker{ eth: eth, mux: eth.EventMux(), recv: make(chan *types.Block), @@ -93,28 +97,45 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker { proc: eth.BlockProcessor(), possibleUncles: make(map[common.Hash]*types.Block), coinbase: coinbase, + txQueue: make(map[common.Hash]*types.Transaction), } + go worker.update() + go worker.wait() + + worker.quit = make(chan struct{}) + + worker.commitNewWork() + + return worker } -func (self *worker) start() { - self.mining = true +func (self *worker) pendingState() *state.StateDB { + self.currentMu.Lock() + defer self.currentMu.Unlock() + + return self.current.state +} - self.quit = make(chan struct{}) +func (self *worker) pendingBlock() *types.Block { + self.currentMu.Lock() + defer self.currentMu.Unlock() + return self.current.block +} + +func (self *worker) start() { // spin up agents for _, agent := range self.agents { agent.Start() } - go self.update() - go self.wait() + atomic.StoreInt64(&self.mining, 1) } func (self *worker) stop() { - self.mining = false - atomic.StoreInt64(&self.atWork, 0) + atomic.StoreInt64(&self.mining, 0) - close(self.quit) + atomic.StoreInt64(&self.atWork, 0) } func (self *worker) register(agent Agent) { @@ -123,7 +144,7 @@ func (self *worker) register(agent Agent) { } func (self *worker) update() { - events := self.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}) + events := self.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}, core.TxPreEvent{}) timer := time.NewTicker(2 * time.Second) @@ -138,6 +159,10 @@ out: self.uncleMu.Lock() self.possibleUncles[ev.Block.Hash()] = ev.Block self.uncleMu.Unlock() + case core.TxPreEvent: + if atomic.LoadInt64(&self.mining) == 0 { + self.commitNewWork() + } } case <-self.quit: @@ -152,7 +177,7 @@ out: } // XXX In case all mined a possible uncle - if atomic.LoadInt64(&self.atWork) == 0 { + if atomic.LoadInt64(&self.atWork) == 0 && atomic.LoadInt64(&self.mining) == 1 { self.commitNewWork() } } @@ -192,7 +217,7 @@ func (self *worker) wait() { } func (self *worker) push() { - if self.mining { + if atomic.LoadInt64(&self.mining) == 1 { self.current.block.Header().GasUsed = self.current.totalUsedGas self.current.block.SetRoot(self.current.state.Root()) @@ -205,12 +230,7 @@ func (self *worker) push() { } } -func (self *worker) commitNewWork() { - self.mu.Lock() - defer self.mu.Unlock() - self.uncleMu.Lock() - defer self.uncleMu.Unlock() - +func (self *worker) makeCurrent() { block := self.chain.NewBlock(self.coinbase) if block.Time() == self.chain.CurrentBlock().Time() { block.Header().Time++ @@ -224,6 +244,17 @@ func (self *worker) commitNewWork() { parent := self.chain.GetBlock(self.current.block.ParentHash()) self.current.coinbase.SetGasPool(core.CalcGasLimit(parent, self.current.block)) +} + +func (self *worker) commitNewWork() { + self.mu.Lock() + defer self.mu.Unlock() + self.uncleMu.Lock() + defer self.uncleMu.Unlock() + self.currentMu.Lock() + defer self.currentMu.Unlock() + + self.makeCurrent() transactions := self.eth.TxPool().GetTransactions() sort.Sort(types.TxByNonce{transactions}) @@ -287,6 +318,7 @@ gasLimit: core.AccumulateRewards(self.current.state, self.current.block) self.current.state.Update() + self.push() } |