Browse Source

finally merged *the missing*

obscuren 10 years ago
parent
commit
0be6d34048
3 changed files with 52 additions and 15 deletions
  1. 5 0
      core/block_cache.go
  2. 4 0
      core/events.go
  3. 43 15
      miner/worker.go

+ 5 - 0
core/block_cache.go

@@ -66,3 +66,8 @@ func (bc *BlockCache) Get(hash common.Hash) *types.Block {
 
 	return nil
 }
+
+func (bc *BlockCache) Has(hash common.Hash) bool {
+	_, ok := bc.blocks[hash]
+	return ok
+}

+ 4 - 0
core/events.go

@@ -38,6 +38,10 @@ type PendingBlockEvent struct {
 	Logs  state.Logs
 }
 
+type ChainUncleEvent struct {
+	Block *types.Block
+}
+
 type ChainHeadEvent struct{ Block *types.Block }
 
 // Mining operation events

+ 43 - 15
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)