Example #1
0
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()
		}
	}
}
Example #2
0
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()
		}
	}
}