aboutsummaryrefslogtreecommitdiffstats
path: root/miner
diff options
context:
space:
mode:
Diffstat (limited to 'miner')
-rw-r--r--miner/agent.go16
-rw-r--r--miner/miner.go22
-rw-r--r--miner/remote_agent.go16
-rw-r--r--miner/worker.go81
4 files changed, 117 insertions, 18 deletions
diff --git a/miner/agent.go b/miner/agent.go
index a7d017aa5..8455ed36e 100644
--- a/miner/agent.go
+++ b/miner/agent.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package miner
import (
diff --git a/miner/miner.go b/miner/miner.go
index 7f73f3ee8..173be1a14 100644
--- a/miner/miner.go
+++ b/miner/miner.go
@@ -1,3 +1,20 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+// Package miner implements Ethereum block creation and mining.
package miner
import (
@@ -137,3 +154,8 @@ func (self *Miner) PendingState() *state.StateDB {
func (self *Miner) PendingBlock() *types.Block {
return self.worker.pendingBlock()
}
+
+func (self *Miner) SetEtherbase(addr common.Address) {
+ self.coinbase = addr
+ self.worker.setEtherbase(addr)
+}
diff --git a/miner/remote_agent.go b/miner/remote_agent.go
index 6a44782f6..b05d9c7e0 100644
--- a/miner/remote_agent.go
+++ b/miner/remote_agent.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package miner
import (
diff --git a/miner/worker.go b/miner/worker.go
index f06b6afa1..79514b231 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package miner
import (
@@ -79,9 +95,10 @@ type worker struct {
quit chan struct{}
pow pow.PoW
- eth core.Backend
- chain *core.ChainManager
- proc *core.BlockProcessor
+ eth core.Backend
+ chain *core.ChainManager
+ proc *core.BlockProcessor
+ extraDb common.Database
coinbase common.Address
gasPrice *big.Int
@@ -105,6 +122,7 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
worker := &worker{
eth: eth,
mux: eth.EventMux(),
+ extraDb: eth.ExtraDb(),
recv: make(chan *types.Block),
gasPrice: new(big.Int),
chain: eth.ChainManager(),
@@ -122,6 +140,12 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
return worker
}
+func (self *worker) setEtherbase(addr common.Address) {
+ self.mu.Lock()
+ defer self.mu.Unlock()
+ self.coinbase = addr
+}
+
func (self *worker) pendingState() *state.StateDB {
self.currentMu.Lock()
defer self.currentMu.Unlock()
@@ -233,11 +257,28 @@ func (self *worker) wait() {
continue
}
- _, err := self.chain.WriteBlock(block, false)
+ 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
@@ -252,7 +293,13 @@ func (self *worker) wait() {
glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm)
// broadcast before waiting for validation
- go self.mux.Post(core.NewMinedBlockEvent{block})
+ 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})
+ }
+ }(block, self.current.state.Logs())
self.commitNewWork()
}
@@ -273,8 +320,6 @@ func (self *worker) push() {
if agent.Work() != nil {
agent.Work() <- self.current.block
- } else {
- common.Report(fmt.Sprintf("%v %T\n", agent, agent))
}
}
}
@@ -368,8 +413,8 @@ func (self *worker) commitNewWork() {
tstart := time.Now()
parent := self.chain.CurrentBlock()
tstamp := tstart.Unix()
- if tstamp <= parent.Time() {
- tstamp = parent.Time() + 1
+ if tstamp <= int64(parent.Time()) {
+ tstamp = int64(parent.Time()) + 1
}
// this will ensure we're not going off too far in the future
if now := time.Now().Unix(); tstamp > now+4 {
@@ -382,7 +427,7 @@ func (self *worker) commitNewWork() {
header := &types.Header{
ParentHash: parent.Hash(),
Number: num.Add(num, common.Big1),
- Difficulty: core.CalcDifficulty(tstamp, parent.Time(), parent.Difficulty()),
+ Difficulty: core.CalcDifficulty(int64(tstamp), int64(parent.Time()), parent.Difficulty()),
GasLimit: core.CalcGasLimit(parent),
GasUsed: new(big.Int),
Coinbase: self.coinbase,
@@ -428,7 +473,7 @@ func (self *worker) commitNewWork() {
if atomic.LoadInt32(&self.mining) == 1 {
// commit state root after all state transitions.
core.AccumulateRewards(self.current.state, header, uncles)
- current.state.Update()
+ current.state.SyncObjects()
self.current.state.Sync()
header.Root = current.state.Root()
}
@@ -501,18 +546,18 @@ func (env *environment) commitTransactions(transactions types.Transactions, gasP
err := env.commitTransaction(tx, proc)
switch {
- case core.IsNonceErr(err) || core.IsInvalidTxErr(err):
- env.remove.Add(tx.Hash())
-
- if glog.V(logger.Detail) {
- glog.Infof("TX (%x) failed, will be removed: %v\n", tx.Hash().Bytes()[:4], err)
- }
case state.IsGasLimitErr(err):
// ignore the transactor so no nonce errors will be thrown for this account
// next time the worker is run, they'll be picked up again.
env.ignoredTransactors.Add(from)
glog.V(logger.Detail).Infof("Gas limit reached for (%x) in this block. Continue to try smaller txs\n", from[:4])
+ case err != nil:
+ env.remove.Add(tx.Hash())
+
+ if glog.V(logger.Detail) {
+ glog.Infof("TX (%x) failed, will be removed: %v\n", tx.Hash().Bytes()[:4], err)
+ }
default:
env.tcount++
}
@@ -522,7 +567,7 @@ func (env *environment) commitTransactions(transactions types.Transactions, gasP
func (env *environment) commitTransaction(tx *types.Transaction, proc *core.BlockProcessor) error {
snap := env.state.Copy()
receipt, _, err := proc.ApplyTransaction(env.coinbase, env.state, env.header, tx, env.header.GasUsed, true)
- if err != nil && (core.IsNonceErr(err) || state.IsGasLimitErr(err) || core.IsInvalidTxErr(err)) {
+ if err != nil {
env.state.Set(snap)
return err
}