logging for possible uncles
This commit is contained in:
parent
524f8199bf
commit
dc3a9379f5
|
@ -166,10 +166,16 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big
|
||||||
// Create a new state based on the parent's root (e.g., create copy)
|
// Create a new state based on the parent's root (e.g., create copy)
|
||||||
state := state.New(parent.Root(), sm.db)
|
state := state.New(parent.Root(), sm.db)
|
||||||
|
|
||||||
|
// track (possible) uncle block
|
||||||
|
var uncle bool
|
||||||
// Block validation
|
// Block validation
|
||||||
if err = sm.ValidateHeader(block.Header(), parent.Header()); err != nil {
|
if err = sm.ValidateHeader(block.Header(), parent.Header()); err != nil {
|
||||||
|
if err != BlockEqualTSErr {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
err = nil
|
||||||
|
uncle = true
|
||||||
|
}
|
||||||
|
|
||||||
// There can be at most two uncles
|
// There can be at most two uncles
|
||||||
if len(block.Uncles()) > 2 {
|
if len(block.Uncles()) > 2 {
|
||||||
|
@ -223,14 +229,22 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big
|
||||||
td = CalculateTD(block, parent)
|
td = CalculateTD(block, parent)
|
||||||
// Sync the current block's state to the database
|
// Sync the current block's state to the database
|
||||||
state.Sync()
|
state.Sync()
|
||||||
|
|
||||||
|
if !uncle {
|
||||||
// Remove transactions from the pool
|
// Remove transactions from the pool
|
||||||
sm.txpool.RemoveSet(block.Transactions())
|
sm.txpool.RemoveSet(block.Transactions())
|
||||||
|
}
|
||||||
|
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
putTx(sm.extraDb, tx)
|
putTx(sm.extraDb, tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if uncle {
|
||||||
|
chainlogger.Infof("found possible uncle block #%d (%x...)\n", header.Number, block.Hash().Bytes()[0:4])
|
||||||
|
return td, nil, BlockEqualTSErr
|
||||||
|
} else {
|
||||||
chainlogger.Infof("processed block #%d (%x...)\n", header.Number, block.Hash().Bytes()[0:4])
|
chainlogger.Infof("processed block #%d (%x...)\n", header.Number, block.Hash().Bytes()[0:4])
|
||||||
|
}
|
||||||
|
|
||||||
return td, state.Logs(), nil
|
return td, state.Logs(), nil
|
||||||
}
|
}
|
||||||
|
@ -255,10 +269,6 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error {
|
||||||
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
|
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
if block.Time <= parent.Time {
|
|
||||||
return ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time)
|
|
||||||
}
|
|
||||||
|
|
||||||
if int64(block.Time) > time.Now().Unix() {
|
if int64(block.Time) > time.Now().Unix() {
|
||||||
return BlockFutureErr
|
return BlockFutureErr
|
||||||
}
|
}
|
||||||
|
@ -272,6 +282,10 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error {
|
||||||
return ValidationError("Block's nonce is invalid (= %x)", block.Nonce)
|
return ValidationError("Block's nonce is invalid (= %x)", block.Nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if block.Time <= parent.Time {
|
||||||
|
return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,14 +321,10 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren
|
||||||
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
|
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash]); err != nil {
|
if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash]); err != nil && err != BlockEqualTSErr {
|
||||||
return ValidationError(fmt.Sprintf("%v", err))
|
return ValidationError(fmt.Sprintf("%v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sm.Pow.Verify(types.NewBlockWithHeader(uncle)) {
|
|
||||||
return ValidationError("Uncle's nonce is invalid (= %x)", uncle.Nonce)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := new(big.Int)
|
r := new(big.Int)
|
||||||
r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
|
r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
|
||||||
|
|
||||||
|
|
|
@ -447,6 +447,11 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err == BlockEqualTSErr {
|
||||||
|
queue[i] = ChainSideEvent{block, logs}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
h := block.Header()
|
h := block.Header()
|
||||||
chainlogger.Infof("INVALID block #%v (%x)\n", h.Number, h.Hash().Bytes()[:4])
|
chainlogger.Infof("INVALID block #%v (%x)\n", h.Number, h.Hash().Bytes()[:4])
|
||||||
chainlogger.Infoln(err)
|
chainlogger.Infoln(err)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
var (
|
var (
|
||||||
BlockNumberErr = errors.New("block number invalid")
|
BlockNumberErr = errors.New("block number invalid")
|
||||||
BlockFutureErr = errors.New("block time is in the future")
|
BlockFutureErr = errors.New("block time is in the future")
|
||||||
|
BlockEqualTSErr = errors.New("block time stamp equal to previous")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parent error. In case a parent is unknown this error will be thrown
|
// Parent error. In case a parent is unknown this error will be thrown
|
||||||
|
|
|
@ -131,7 +131,7 @@ out:
|
||||||
}
|
}
|
||||||
case core.NewMinedBlockEvent:
|
case core.NewMinedBlockEvent:
|
||||||
self.commitNewWork()
|
self.commitNewWork()
|
||||||
case core.ChainSplitEvent:
|
case core.ChainSideEvent:
|
||||||
self.uncleMu.Lock()
|
self.uncleMu.Lock()
|
||||||
self.possibleUncles[ev.Block.Hash()] = ev.Block
|
self.possibleUncles[ev.Block.Hash()] = ev.Block
|
||||||
self.uncleMu.Unlock()
|
self.uncleMu.Unlock()
|
||||||
|
@ -170,6 +170,10 @@ func (self *worker) wait() {
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := self.chain.InsertChain(types.Blocks{self.current.block}); err == nil {
|
if err := self.chain.InsertChain(types.Blocks{self.current.block}); err == nil {
|
||||||
|
for _, uncle := range self.current.block.Uncles() {
|
||||||
|
delete(self.possibleUncles, uncle.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
self.mux.Post(core.NewMinedBlockEvent{self.current.block})
|
self.mux.Post(core.NewMinedBlockEvent{self.current.block})
|
||||||
} else {
|
} else {
|
||||||
self.commitNewWork()
|
self.commitNewWork()
|
||||||
|
@ -233,9 +237,9 @@ gasLimit:
|
||||||
}
|
}
|
||||||
self.eth.TxPool().RemoveSet(remove)
|
self.eth.TxPool().RemoveSet(remove)
|
||||||
|
|
||||||
ucount := 0
|
var uncles []*types.Header
|
||||||
for hash, uncle := range self.possibleUncles {
|
for hash, uncle := range self.possibleUncles {
|
||||||
if ucount == 2 {
|
if len(uncles) == 2 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,11 +247,12 @@ gasLimit:
|
||||||
minerlogger.Infof("Bad uncle found and will be removed (%x)\n", hash[:4])
|
minerlogger.Infof("Bad uncle found and will be removed (%x)\n", hash[:4])
|
||||||
minerlogger.Debugln(uncle)
|
minerlogger.Debugln(uncle)
|
||||||
} else {
|
} else {
|
||||||
minerlogger.Infof("Commiting %x as uncle\n", hash[:4])
|
minerlogger.Infof("commiting %x as uncle\n", hash[:4])
|
||||||
ucount++
|
uncles = append(uncles, uncle.Header())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
minerlogger.Infoln("Included %d uncle(s)")
|
minerlogger.Infoln("Included", len(uncles), "uncle(s)")
|
||||||
|
self.current.block.SetUncles(uncles)
|
||||||
|
|
||||||
self.current.state.AddBalance(self.coinbase, core.BlockReward)
|
self.current.state.AddBalance(self.coinbase, core.BlockReward)
|
||||||
|
|
||||||
|
@ -276,10 +281,8 @@ func (self *worker) commitUncle(uncle *types.Header) error {
|
||||||
return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", uncle.Hash()))
|
return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", uncle.Hash()))
|
||||||
}
|
}
|
||||||
|
|
||||||
uncleAccount := self.current.state.GetAccount(uncle.Coinbase)
|
self.current.state.AddBalance(uncle.Coinbase, uncleReward)
|
||||||
uncleAccount.AddBalance(uncleReward)
|
self.current.state.AddBalance(self.coinbase, inclusionReward)
|
||||||
|
|
||||||
self.current.coinbase.AddBalance(uncleReward)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue