func (self *worker) wait() { for { for block := range self.recv { atomic.AddInt32(&self.atWork, -1) if block == nil { continue } parent := self.chain.GetBlock(block.ParentHash()) if parent == nil { glog.V(logger.Error).Infoln("Invalid block found during mining") continue } if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent, true); err != nil && err != core.BlockFutureErr { glog.V(logger.Error).Infoln("Invalid header on mined block:", err) continue } stat, err := self.chain.WriteBlock(block, false) if err != nil { glog.V(logger.Error).Infoln("error writing block to chain", err) continue } // check if canon block and write transactions if stat == core.CanonStatTy { // This puts transactions in a extra db for rpc core.PutTransactions(self.extraDb, block, block.Transactions()) // store the receipts core.PutReceipts(self.extraDb, self.current.receipts) } // check staleness and display confirmation var stale, confirm string canonBlock := self.chain.GetBlockByNumber(block.NumberU64()) if canonBlock != nil && canonBlock.Hash() != block.Hash() { stale = "stale " } else { confirm = "Wait 5 blocks for confirmation" self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks) } glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm) // broadcast before waiting for validation go func(block *types.Block, logs state.Logs) { self.mux.Post(core.NewMinedBlockEvent{block}) self.mux.Post(core.ChainEvent{block, block.Hash(), logs}) if stat == core.CanonStatTy { self.mux.Post(core.ChainHeadEvent{block}) self.mux.Post(logs) } }(block, self.current.state.Logs()) self.commitNewWork() } } }
func (self *worker) wait() { for { for result := range self.recv { atomic.AddInt32(&self.atWork, -1) if result == nil { continue } block := result.Block work := result.Work if self.fullValidation { if _, err := self.chain.InsertChain(types.Blocks{block}); err != nil { glog.V(logger.Error).Infoln("mining err", err) continue } go self.mux.Post(core.NewMinedBlockEvent{block}) } else { work.state.Commit() parent := self.chain.GetBlock(block.ParentHash()) if parent == nil { glog.V(logger.Error).Infoln("Invalid block found during mining") continue } if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent.Header(), true, false); err != nil && err != core.BlockFutureErr { glog.V(logger.Error).Infoln("Invalid header on mined block:", err) continue } stat, err := self.chain.WriteBlock(block) if err != nil { glog.V(logger.Error).Infoln("error writing block to chain", err) continue } // check if canon block and write transactions if stat == core.CanonStatTy { // This puts transactions in a extra db for rpc core.PutTransactions(self.chainDb, block, block.Transactions()) // store the receipts core.PutReceipts(self.chainDb, work.receipts) // Write map map bloom filters core.WriteMipmapBloom(self.chainDb, block.NumberU64(), work.receipts) } // broadcast before waiting for validation go func(block *types.Block, logs vm.Logs, receipts []*types.Receipt) { self.mux.Post(core.NewMinedBlockEvent{block}) self.mux.Post(core.ChainEvent{block, block.Hash(), logs}) if stat == core.CanonStatTy { self.mux.Post(core.ChainHeadEvent{block}) self.mux.Post(logs) } if err := core.PutBlockReceipts(self.chainDb, block.Hash(), receipts); err != nil { glog.V(logger.Warn).Infoln("error writing block receipts:", err) } }(block, work.state.Logs(), work.receipts) } // check staleness and display confirmation var stale, confirm string canonBlock := self.chain.GetBlockByNumber(block.NumberU64()) if canonBlock != nil && canonBlock.Hash() != block.Hash() { stale = "stale " } else { confirm = "Wait 5 blocks for confirmation" work.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), work.localMinedBlocks) } glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm) self.commitNewWork() } } }