update dispatches blocks.
()
| 229 | |
| 230 | // update dispatches blocks. |
| 231 | func (e *engine) update() { |
| 232 | // Subscribe NewTxsEvent for tx pool |
| 233 | e.txsSub = e.backend.TxPool().SubscribeNewTxsEvent(e.txsCh) |
| 234 | // Subscribe events for blockchain |
| 235 | e.chainLatestSub = e.backend.BlockChain().SubscribeChainLatestEvent(e.chainLatestCh) |
| 236 | e.chainSideSub = e.backend.BlockChain().SubscribeChainSideEvent(e.chainSideCh) |
| 237 | |
| 238 | defer e.chainSideSub.Unsubscribe() |
| 239 | defer e.chainLatestSub.Unsubscribe() |
| 240 | defer e.txsSub.Unsubscribe() |
| 241 | |
| 242 | for { |
| 243 | // A real event arrived, process interesting content |
| 244 | |
| 245 | select { |
| 246 | // a new block has been inserted. we start to mine based on this new tip. |
| 247 | case <-e.chainLatestCh: |
| 248 | |
| 249 | log.Debug("now to commit new work", "now", time.Now()) |
| 250 | |
| 251 | // commitNewWork must run no matter if it is mining, because pending block needs to be updated by commitNewWork |
| 252 | e.commitNewWork() |
| 253 | |
| 254 | if atomic.LoadInt32(&e.mining) == 1 { |
| 255 | // checks and tries to campaign if needed |
| 256 | e.cons.TryCampaign() |
| 257 | } |
| 258 | |
| 259 | // handle chainsideevent |
| 260 | // we don't have uncle blocks |
| 261 | case ev := <-e.chainSideCh: |
| 262 | log.Warn("Got unexpected uncle block ", "hash", ev.Block.Hash().Hex()) |
| 263 | |
| 264 | // Handle NewTxsEvent |
| 265 | // add to the work (transaction set). it's mainly for api use, e.g., pending block. |
| 266 | case ev := <-e.txsCh: |
| 267 | // Apply transactions to the pending state if we're *not* mining. |
| 268 | // Note all transactions received may be compatible with transactions |
| 269 | // already included in the current mining block. These transactions will |
| 270 | // be automatically eliminated. |
| 271 | if atomic.LoadInt32(&e.mining) == 0 { |
| 272 | // critical section for current work |
| 273 | e.currentMu.Lock() |
| 274 | |
| 275 | txs := make(map[common.Address]types.Transactions) |
| 276 | for _, tx := range ev.Txs { |
| 277 | // get the sender account |
| 278 | acc, _ := types.Sender(e.currentWork.signer, tx) |
| 279 | txs[acc] = append(txs[acc], tx) |
| 280 | } |
| 281 | txset := types.NewTransactionsByPriceAndNonce(e.currentWork.signer, txs) |
| 282 | e.currentWork.commitTransactions(e.mux, txset, e.chain, e.coinbase, time.Now().Add(time.Second*10)) |
| 283 | e.updateSnapshot() |
| 284 | e.currentMu.Unlock() |
| 285 | } |
| 286 | // System stopped |
| 287 | case err := <-e.txsSub.Err(): |
| 288 | if err == nil { |
no test coverage detected