uncle validation
This commit is contained in:
parent
d4d505c868
commit
84a4f761f3
@ -176,10 +176,15 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big
|
||||
state := state.New(parent.Root(), sm.db)
|
||||
|
||||
// Block validation
|
||||
if err = sm.ValidateBlock(block, parent); err != nil {
|
||||
if err = sm.ValidateHeader(block.Header(), parent.Header()); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// There can be at most two uncles
|
||||
if len(block.Uncles()) > 2 {
|
||||
return nil, ValidationError("Block can only contain one uncle (contained %v)", len(block.Uncles()))
|
||||
}
|
||||
|
||||
receipts, err := sm.TransitionState(state, parent, block, false)
|
||||
if err != nil {
|
||||
return
|
||||
@ -238,46 +243,41 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big
|
||||
// Validates the current block. Returns an error if the block was invalid,
|
||||
// an uncle or anything that isn't on the current block chain.
|
||||
// Validation validates easy over difficult (dagger takes longer time = difficult)
|
||||
func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error {
|
||||
if len(block.Header().Extra) > 1024 {
|
||||
return fmt.Errorf("Block extra data too long (%d)", len(block.Header().Extra))
|
||||
func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error {
|
||||
if len(block.Extra) > 1024 {
|
||||
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
|
||||
}
|
||||
|
||||
expd := CalcDifficulty(block, parent)
|
||||
if expd.Cmp(block.Header().Difficulty) != 0 {
|
||||
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd)
|
||||
if expd.Cmp(block.Difficulty) != 0 {
|
||||
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
|
||||
}
|
||||
|
||||
//expl := CalcGasLimit(parent, block)
|
||||
//if expl.Cmp(block.Header().GasLimit) != 0 {
|
||||
|
||||
// block.gasLimit - parent.gasLimit <= parent.gasLimit / 1024
|
||||
a := new(big.Int).Sub(block.Header().GasLimit, parent.Header().GasLimit)
|
||||
b := new(big.Int).Div(parent.Header().GasLimit, big.NewInt(1024))
|
||||
a := new(big.Int).Sub(block.GasLimit, parent.GasLimit)
|
||||
b := new(big.Int).Div(parent.GasLimit, big.NewInt(1024))
|
||||
if a.Cmp(b) > 0 {
|
||||
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.Header().GasLimit, a, b)
|
||||
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
|
||||
}
|
||||
|
||||
// There can be at most one uncle
|
||||
if len(block.Uncles()) > 1 {
|
||||
return ValidationError("Block can only contain one uncle (contained %v)", len(block.Uncles()))
|
||||
if block.Time < parent.Time {
|
||||
return ValidationError("Block timestamp not after prev block (%v - %v)", block.Time, parent.Time)
|
||||
}
|
||||
|
||||
if block.Time() < parent.Time() {
|
||||
return ValidationError("Block timestamp not after prev block (%v - %v)", block.Header().Time, parent.Header().Time)
|
||||
}
|
||||
|
||||
if block.Time() > time.Now().Unix() {
|
||||
if int64(block.Time) > time.Now().Unix() {
|
||||
return BlockFutureErr
|
||||
}
|
||||
|
||||
if new(big.Int).Sub(block.Number(), parent.Number()).Cmp(big.NewInt(1)) != 0 {
|
||||
if new(big.Int).Sub(block.Number, parent.Number).Cmp(big.NewInt(1)) != 0 {
|
||||
return BlockNumberErr
|
||||
}
|
||||
|
||||
// Verify the nonce of the block. Return an error if it's not valid
|
||||
if !sm.Pow.Verify(block) {
|
||||
return ValidationError("Block's nonce is invalid (= %x)", block.Header().Nonce)
|
||||
if !sm.Pow.Verify(types.NewBlockWithHeader(block)) {
|
||||
return ValidationError("Block's nonce is invalid (= %x)", block.Nonce)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -287,23 +287,39 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren
|
||||
reward := new(big.Int).Set(BlockReward)
|
||||
|
||||
ancestors := set.New()
|
||||
uncles := set.New()
|
||||
ancestorHeaders := make(map[string]*types.Header)
|
||||
for _, ancestor := range sm.bc.GetAncestors(block, 7) {
|
||||
ancestors.Add(string(ancestor.Hash()))
|
||||
hash := string(ancestor.Hash())
|
||||
ancestorHeaders[hash] = ancestor.Header()
|
||||
ancestors.Add(hash)
|
||||
// Include ancestors uncles in the uncle set. Uncles must be unique.
|
||||
for _, uncle := range ancestor.Uncles() {
|
||||
uncles.Add(string(uncle.Hash()))
|
||||
}
|
||||
}
|
||||
|
||||
uncles := set.New()
|
||||
uncles.Add(string(block.Hash()))
|
||||
for _, uncle := range block.Uncles() {
|
||||
if uncles.Has(string(uncle.Hash())) {
|
||||
// Error not unique
|
||||
return UncleError("Uncle not unique")
|
||||
}
|
||||
|
||||
uncles.Add(string(uncle.Hash()))
|
||||
|
||||
if ancestors.Has(string(uncle.Hash())) {
|
||||
return UncleError("Uncle is ancestor")
|
||||
}
|
||||
|
||||
if !ancestors.Has(string(uncle.ParentHash)) {
|
||||
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
|
||||
}
|
||||
|
||||
if err := sm.ValidateHeader(uncle, ancestorHeaders[string(uncle.ParentHash)]); err != nil {
|
||||
return ValidationError(fmt.Sprintf("%v", err))
|
||||
}
|
||||
|
||||
if !sm.Pow.Verify(types.NewBlockWithHeader(uncle)) {
|
||||
return ValidationError("Uncle's nonce is invalid (= %x)", uncle.Nonce)
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func newBlockFromParent(addr []byte, parent *types.Block) *types.Block {
|
||||
block.SetReceipts(nil)
|
||||
|
||||
header := block.Header()
|
||||
header.Difficulty = CalcDifficulty(block, parent)
|
||||
header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
|
||||
header.Number = new(big.Int).Add(parent.Header().Number, ethutil.Big1)
|
||||
header.Time = parent.Header().Time + 10
|
||||
header.GasLimit = CalcGasLimit(parent, block)
|
||||
|
@ -28,16 +28,16 @@ type StateQuery interface {
|
||||
GetAccount(addr []byte) *state.StateObject
|
||||
}
|
||||
|
||||
func CalcDifficulty(block, parent *types.Block) *big.Int {
|
||||
func CalcDifficulty(block, parent *types.Header) *big.Int {
|
||||
diff := new(big.Int)
|
||||
|
||||
//adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
|
||||
//if block.Time() >= parent.Time()+8 {
|
||||
adjust := new(big.Int).Div(parent.Difficulty(), big.NewInt(2048))
|
||||
if (block.Time() - parent.Time()) < 8 {
|
||||
diff.Add(parent.Difficulty(), adjust)
|
||||
adjust := new(big.Int).Div(parent.Difficulty, big.NewInt(2048))
|
||||
if (block.Time - parent.Time) < 8 {
|
||||
diff.Add(parent.Difficulty, adjust)
|
||||
} else {
|
||||
diff.Sub(parent.Difficulty(), adjust)
|
||||
diff.Sub(parent.Difficulty, adjust)
|
||||
}
|
||||
|
||||
return diff
|
||||
@ -206,7 +206,7 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
|
||||
parent := bc.currentBlock
|
||||
if parent != nil {
|
||||
header := block.Header()
|
||||
header.Difficulty = CalcDifficulty(block, parent)
|
||||
header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
|
||||
header.Number = new(big.Int).Add(parent.Header().Number, ethutil.Big1)
|
||||
header.GasLimit = CalcGasLimit(parent, block)
|
||||
|
||||
|
@ -147,7 +147,7 @@ func (self *Filter) FilterLogs(logs state.Logs) state.Logs {
|
||||
// Filter the logs for interesting stuff
|
||||
Logs:
|
||||
for _, log := range logs {
|
||||
if !includes(self.address, log.Address()) {
|
||||
if len(self.address) > 0 && !includes(self.address, log.Address()) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user