| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | package miner | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"math/big" | 
					
						
							|  |  |  | 	"sort" | 
					
						
							| 
									
										
										
										
											2015-02-15 16:16:27 +01:00
										 |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2015-02-28 23:09:49 +01:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 09:14:58 +01:00
										 |  |  | 	"github.com/ethereum/ethash" | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/ethutil" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/event" | 
					
						
							| 
									
										
										
										
											2015-03-01 16:09:59 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger" | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	"github.com/ethereum/go-ethereum/pow" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/state" | 
					
						
							|  |  |  | 	"gopkg.in/fatih/set.v0" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-01 16:09:59 +01:00
										 |  |  | var jsonlogger = logger.NewJsonLogger() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | type environment struct { | 
					
						
							|  |  |  | 	totalUsedGas *big.Int | 
					
						
							|  |  |  | 	state        *state.StateDB | 
					
						
							|  |  |  | 	coinbase     *state.StateObject | 
					
						
							|  |  |  | 	block        *types.Block | 
					
						
							|  |  |  | 	ancestors    *set.Set | 
					
						
							|  |  |  | 	uncles       *set.Set | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 12:24:51 +01:00
										 |  |  | func env(block *types.Block, eth core.Backend) *environment { | 
					
						
							| 
									
										
										
										
											2015-03-06 18:26:16 +01:00
										 |  |  | 	state := state.New(block.Root(), eth.StateDb()) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	env := &environment{ | 
					
						
							|  |  |  | 		totalUsedGas: new(big.Int), | 
					
						
							|  |  |  | 		state:        state, | 
					
						
							|  |  |  | 		block:        block, | 
					
						
							|  |  |  | 		ancestors:    set.New(), | 
					
						
							|  |  |  | 		uncles:       set.New(), | 
					
						
							|  |  |  | 		coinbase:     state.GetOrNewStateObject(block.Coinbase()), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, ancestor := range eth.ChainManager().GetAncestors(block, 7) { | 
					
						
							|  |  |  | 		env.ancestors.Add(string(ancestor.Hash())) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return env | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | type Work struct { | 
					
						
							| 
									
										
										
										
											2015-02-28 14:58:37 -05:00
										 |  |  | 	Number    uint64 | 
					
						
							| 
									
										
										
										
											2015-03-03 21:04:31 +01:00
										 |  |  | 	Nonce     uint64 | 
					
						
							| 
									
										
										
										
											2015-02-28 14:58:37 -05:00
										 |  |  | 	MixDigest []byte | 
					
						
							|  |  |  | 	SeedHash  []byte | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:05:47 -08:00
										 |  |  | type Agent interface { | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	Work() chan<- *types.Block | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 	SetWorkCh(chan<- Work) | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	Stop() | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 	Start() | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	Pow() pow.PoW | 
					
						
							| 
									
										
										
										
											2015-02-04 15:05:47 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | type worker struct { | 
					
						
							| 
									
										
										
										
											2015-02-15 16:16:27 +01:00
										 |  |  | 	mu     sync.Mutex | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	agents []Agent | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 	recv   chan Work | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	mux    *event.TypeMux | 
					
						
							|  |  |  | 	quit   chan struct{} | 
					
						
							|  |  |  | 	pow    pow.PoW | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 12:24:51 +01:00
										 |  |  | 	eth      core.Backend | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	chain    *core.ChainManager | 
					
						
							|  |  |  | 	proc     *core.BlockProcessor | 
					
						
							|  |  |  | 	coinbase []byte | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	current *environment | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mining bool | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 12:24:51 +01:00
										 |  |  | func newWorker(coinbase []byte, eth core.Backend) *worker { | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	return &worker{ | 
					
						
							|  |  |  | 		eth:      eth, | 
					
						
							|  |  |  | 		mux:      eth.EventMux(), | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 		recv:     make(chan Work), | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 		chain:    eth.ChainManager(), | 
					
						
							|  |  |  | 		proc:     eth.BlockProcessor(), | 
					
						
							|  |  |  | 		coinbase: coinbase, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) start() { | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 	self.mining = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	self.quit = make(chan struct{}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 	// spin up agents | 
					
						
							|  |  |  | 	for _, agent := range self.agents { | 
					
						
							|  |  |  | 		agent.Start() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	go self.update() | 
					
						
							|  |  |  | 	go self.wait() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) stop() { | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 	self.mining = false | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	close(self.quit) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) register(agent Agent) { | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	self.agents = append(self.agents, agent) | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 	agent.SetWorkCh(self.recv) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) update() { | 
					
						
							| 
									
										
										
										
											2015-03-06 15:50:44 +01:00
										 |  |  | 	events := self.mux.Subscribe(core.ChainHeadEvent{}, core.NewMinedBlockEvent{}) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-28 23:09:49 +01:00
										 |  |  | 	timer := time.NewTicker(2 * time.Second) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | out: | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case event := <-events.Chan(): | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 			switch ev := event.(type) { | 
					
						
							| 
									
										
										
										
											2015-03-06 15:50:44 +01:00
										 |  |  | 			case core.ChainHeadEvent: | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 				if self.current.block != ev.Block { | 
					
						
							|  |  |  | 					self.commitNewWork() | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			case core.NewMinedBlockEvent: | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 				self.commitNewWork() | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		case <-self.quit: | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 			// stop all agents | 
					
						
							|  |  |  | 			for _, agent := range self.agents { | 
					
						
							|  |  |  | 				agent.Stop() | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 			break out | 
					
						
							| 
									
										
										
										
											2015-02-28 23:09:49 +01:00
										 |  |  | 		case <-timer.C: | 
					
						
							| 
									
										
										
										
											2015-03-05 09:14:58 +01:00
										 |  |  | 			minerlogger.Infoln("Hash rate:", self.HashRate(), "Khash") | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	events.Unsubscribe() | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | func (self *worker) wait() { | 
					
						
							|  |  |  | 	for { | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 		for work := range self.recv { | 
					
						
							| 
									
										
										
										
											2015-02-28 14:58:37 -05:00
										 |  |  | 			// Someone Successfully Mined! | 
					
						
							| 
									
										
										
										
											2015-02-13 18:15:23 +01:00
										 |  |  | 			block := self.current.block | 
					
						
							| 
									
										
										
										
											2015-03-03 21:04:31 +01:00
										 |  |  | 			if block.Number().Uint64() == work.Number && block.Nonce() == 0 { | 
					
						
							| 
									
										
										
										
											2015-03-03 21:48:05 +01:00
										 |  |  | 				self.current.block.SetNonce(work.Nonce) | 
					
						
							| 
									
										
										
										
											2015-02-28 14:58:37 -05:00
										 |  |  | 				self.current.block.Header().MixDigest = work.MixDigest | 
					
						
							|  |  |  | 				self.current.block.Header().SeedHash = work.SeedHash | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-01 16:09:59 +01:00
										 |  |  | 				jsonlogger.LogJson(&logger.EthMinerNewBlock{ | 
					
						
							|  |  |  | 					BlockHash:     ethutil.Bytes2Hex(block.Hash()), | 
					
						
							|  |  |  | 					BlockNumber:   block.Number(), | 
					
						
							|  |  |  | 					ChainHeadHash: ethutil.Bytes2Hex(block.ParentHeaderHash), | 
					
						
							|  |  |  | 					BlockPrevHash: ethutil.Bytes2Hex(block.ParentHeaderHash), | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2015-03-03 20:30:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 				if err := self.chain.InsertChain(types.Blocks{self.current.block}); err == nil { | 
					
						
							|  |  |  | 					self.mux.Post(core.NewMinedBlockEvent{self.current.block}) | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					self.commitNewWork() | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) push() { | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 	if self.mining { | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 		self.current.block.Header().GasUsed = self.current.totalUsedGas | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 		self.current.block.SetRoot(self.current.state.Root()) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 		// push new work to agents | 
					
						
							| 
									
										
										
										
											2015-02-13 17:23:09 +01:00
										 |  |  | 		for _, agent := range self.agents { | 
					
						
							|  |  |  | 			agent.Work() <- self.current.block | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) commitNewWork() { | 
					
						
							| 
									
										
										
										
											2015-02-15 16:16:27 +01:00
										 |  |  | 	self.mu.Lock() | 
					
						
							|  |  |  | 	defer self.mu.Unlock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 09:14:58 +01:00
										 |  |  | 	block := self.chain.NewBlock(self.coinbase) | 
					
						
							|  |  |  | 	seednum := ethash.GetSeedBlockNum(block.NumberU64()) | 
					
						
							|  |  |  | 	block.Header().SeedHash = self.chain.GetBlockByNumber(seednum).SeedHash() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	self.current = env(block, self.eth) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	parent := self.chain.GetBlock(self.current.block.ParentHash()) | 
					
						
							|  |  |  | 	self.current.coinbase.SetGasPool(core.CalcGasLimit(parent, self.current.block)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	transactions := self.eth.TxPool().GetTransactions() | 
					
						
							|  |  |  | 	sort.Sort(types.TxByNonce{transactions}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 	minerlogger.Infof("committing new work with %d txs\n", len(transactions)) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	// Keep track of transactions which return errors so they can be removed | 
					
						
							|  |  |  | 	var remove types.Transactions | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | gasLimit: | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	for _, tx := range transactions { | 
					
						
							|  |  |  | 		err := self.commitTransaction(tx) | 
					
						
							|  |  |  | 		switch { | 
					
						
							|  |  |  | 		case core.IsNonceErr(err): | 
					
						
							| 
									
										
										
										
											2015-02-15 16:16:27 +01:00
										 |  |  | 			// Remove invalid transactions | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 			remove = append(remove, tx) | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 		case state.IsGasLimitErr(err): | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 			// Break on gas limit | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 			break gasLimit | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			minerlogger.Infoln(err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	self.eth.TxPool().RemoveSet(remove) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | 	self.current.coinbase.AddBalance(core.BlockReward) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 16:52:14 +01:00
										 |  |  | 	self.current.state.Update(ethutil.Big0) | 
					
						
							| 
									
										
										
										
											2015-02-09 16:20:34 +01:00
										 |  |  | 	self.push() | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	inclusionReward = new(big.Int).Div(core.BlockReward, big.NewInt(32)) | 
					
						
							|  |  |  | 	_uncleReward    = new(big.Int).Mul(core.BlockReward, big.NewInt(15)) | 
					
						
							|  |  |  | 	uncleReward     = new(big.Int).Div(_uncleReward, big.NewInt(16)) | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) commitUncle(uncle *types.Header) error { | 
					
						
							|  |  |  | 	if self.current.uncles.Has(string(uncle.Hash())) { | 
					
						
							|  |  |  | 		// Error not unique | 
					
						
							|  |  |  | 		return core.UncleError("Uncle not unique") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	self.current.uncles.Add(string(uncle.Hash())) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !self.current.ancestors.Has(string(uncle.ParentHash)) { | 
					
						
							|  |  |  | 		return core.UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4])) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !self.pow.Verify(types.NewBlockWithHeader(uncle)) { | 
					
						
							| 
									
										
										
										
											2015-03-03 21:04:31 +01:00
										 |  |  | 		return core.ValidationError("Uncle's nonce is invalid (= %x)", uncle.Nonce) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uncleAccount := self.current.state.GetAccount(uncle.Coinbase) | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | 	uncleAccount.AddBalance(uncleReward) | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	self.current.coinbase.AddBalance(uncleReward) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) commitTransaction(tx *types.Transaction) error { | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 	//fmt.Printf("proc %x %v\n", tx.Hash()[:3], tx.Nonce()) | 
					
						
							| 
									
										
										
										
											2015-02-15 16:16:27 +01:00
										 |  |  | 	receipt, _, err := self.proc.ApplyTransaction(self.current.coinbase, self.current.state, self.current.block, tx, self.current.totalUsedGas, true) | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 	if err != nil && (core.IsNonceErr(err) || state.IsGasLimitErr(err)) { | 
					
						
							| 
									
										
										
										
											2015-02-04 05:52:59 -08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	self.current.block.AddTransaction(tx) | 
					
						
							|  |  |  | 	self.current.block.AddReceipt(receipt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-28 23:09:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (self *worker) HashRate() int64 { | 
					
						
							|  |  |  | 	var tot int64 | 
					
						
							|  |  |  | 	for _, agent := range self.agents { | 
					
						
							|  |  |  | 		tot += agent.Pow().GetHashrate() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tot | 
					
						
							|  |  |  | } |