aboutsummaryrefslogtreecommitdiffstats
path: root/miner/worker.go
diff options
context:
space:
mode:
Diffstat (limited to 'miner/worker.go')
-rw-r--r--miner/worker.go58
1 files changed, 43 insertions, 15 deletions
diff --git a/miner/worker.go b/miner/worker.go
index 4a52a40fe..b4b9cb943 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -24,7 +24,7 @@ type environment struct {
state *state.StateDB
coinbase *state.StateObject
block *types.Block
- ancestors *set.Set
+ family *set.Set
uncles *set.Set
}
@@ -34,13 +34,10 @@ func env(block *types.Block, eth core.Backend) *environment {
totalUsedGas: new(big.Int),
state: state,
block: block,
- ancestors: set.New(),
+ family: set.New(),
uncles: set.New(),
coinbase: state.GetOrNewStateObject(block.Coinbase()),
}
- for _, ancestor := range eth.ChainManager().GetAncestors(block, 7) {
- env.ancestors.Add(ancestor.Hash())
- }
return env
}
@@ -75,17 +72,21 @@ type worker struct {
current *environment
+ uncleMu sync.Mutex
+ possibleUncles map[common.Hash]*types.Block
+
mining bool
}
func newWorker(coinbase common.Address, eth core.Backend) *worker {
return &worker{
- eth: eth,
- mux: eth.EventMux(),
- recv: make(chan Work),
- chain: eth.ChainManager(),
- proc: eth.BlockProcessor(),
- coinbase: coinbase,
+ eth: eth,
+ mux: eth.EventMux(),
+ recv: make(chan Work),
+ chain: eth.ChainManager(),
+ proc: eth.BlockProcessor(),
+ possibleUncles: make(map[common.Hash]*types.Block),
+ coinbase: coinbase,
}
}
@@ -115,7 +116,7 @@ func (self *worker) register(agent Agent) {
}
func (self *worker) update() {
- events := self.mux.Subscribe(core.ChainHeadEvent{}, core.NewMinedBlockEvent{})
+ events := self.mux.Subscribe(core.ChainHeadEvent{}, core.NewMinedBlockEvent{}, core.ChainSideEvent{})
timer := time.NewTicker(2 * time.Second)
@@ -130,6 +131,10 @@ out:
}
case core.NewMinedBlockEvent:
self.commitNewWork()
+ case core.ChainSplitEvent:
+ self.uncleMu.Lock()
+ self.possibleUncles[ev.Block.Hash()] = ev.Block
+ self.uncleMu.Unlock()
}
case <-self.quit:
// stop all agents
@@ -145,6 +150,9 @@ out:
events.Unsubscribe()
}
+func (self *worker) addUncle(uncle *types.Block) {
+}
+
func (self *worker) wait() {
for {
for work := range self.recv {
@@ -191,6 +199,10 @@ func (self *worker) commitNewWork() {
block := self.chain.NewBlock(self.coinbase)
self.current = env(block, self.eth)
+ for _, ancestor := range self.chain.GetAncestors(block, 7) {
+ self.current.family.Add(ancestor.Hash())
+ }
+
parent := self.chain.GetBlock(self.current.block.ParentHash())
self.current.coinbase.SetGasPool(core.CalcGasLimit(parent, self.current.block))
@@ -221,6 +233,22 @@ gasLimit:
}
self.eth.TxPool().RemoveSet(remove)
+ ucount := 0
+ for hash, uncle := range self.possibleUncles {
+ if ucount == 2 {
+ break
+ }
+
+ if err := self.commitUncle(uncle.Header()); err != nil {
+ minerlogger.Infof("Bad uncle found and will be removed (%x)\n", hash[:4])
+ minerlogger.Debugln(uncle)
+ } else {
+ minerlogger.Infof("Commiting %x as uncle\n", hash[:4])
+ ucount++
+ }
+ }
+ minerlogger.Infoln("Included %d uncle(s)")
+
self.current.state.AddBalance(self.coinbase, core.BlockReward)
self.current.state.Update(common.Big0)
@@ -240,12 +268,12 @@ func (self *worker) commitUncle(uncle *types.Header) error {
}
self.current.uncles.Add(uncle.Hash())
- if !self.current.ancestors.Has(uncle.ParentHash) {
+ if !self.current.family.Has(uncle.ParentHash) {
return core.UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
}
- if !self.pow.Verify(types.NewBlockWithHeader(uncle)) {
- return core.ValidationError("Uncle's nonce is invalid (= %x)", uncle.Nonce)
+ if self.current.family.Has(uncle.Hash()) {
+ return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", uncle.Hash()))
}
uncleAccount := self.current.state.GetAccount(uncle.Coinbase)