github.com/devfans/go-ethereum@v1.5.10-0.20170326212234-7419d0c38291/core/block_validator.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"fmt"
    21  	"math/big"
    22  	"time"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/common/math"
    26  	"github.com/ethereum/go-ethereum/core/state"
    27  	"github.com/ethereum/go-ethereum/core/types"
    28  	"github.com/ethereum/go-ethereum/log"
    29  	"github.com/ethereum/go-ethereum/params"
    30  	"github.com/ethereum/go-ethereum/pow"
    31  	"gopkg.in/fatih/set.v0"
    32  )
    33  
    34  var (
    35  	ExpDiffPeriod = big.NewInt(100000)
    36  	big10         = big.NewInt(10)
    37  	bigMinus99    = big.NewInt(-99)
    38  )
    39  
    40  // BlockValidator is responsible for validating block headers, uncles and
    41  // processed state.
    42  //
    43  // BlockValidator implements Validator.
    44  type BlockValidator struct {
    45  	config *params.ChainConfig // Chain configuration options
    46  	bc     *BlockChain         // Canonical block chain
    47  	Pow    pow.PoW             // Proof of work used for validating
    48  }
    49  
    50  // NewBlockValidator returns a new block validator which is safe for re-use
    51  func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, pow pow.PoW) *BlockValidator {
    52  	validator := &BlockValidator{
    53  		config: config,
    54  		Pow:    pow,
    55  		bc:     blockchain,
    56  	}
    57  	return validator
    58  }
    59  
    60  // ValidateBlock validates the given block's header and uncles and verifies the
    61  // the block header's transaction and uncle roots.
    62  //
    63  // ValidateBlock does not validate the header's pow. The pow work validated
    64  // separately so we can process them in parallel.
    65  //
    66  // ValidateBlock also validates and makes sure that any previous state (or present)
    67  // state that might or might not be present is checked to make sure that fast
    68  // sync has done it's job proper. This prevents the block validator from accepting
    69  // false positives where a header is present but the state is not.
    70  func (v *BlockValidator) ValidateBlock(block *types.Block) error {
    71  	if v.bc.HasBlock(block.Hash()) {
    72  		if _, err := state.New(block.Root(), v.bc.chainDb); err == nil {
    73  			return &KnownBlockError{block.Number(), block.Hash()}
    74  		}
    75  	}
    76  	parent := v.bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
    77  	if parent == nil {
    78  		return ParentError(block.ParentHash())
    79  	}
    80  	if _, err := state.New(parent.Root(), v.bc.chainDb); err != nil {
    81  		return ParentError(block.ParentHash())
    82  	}
    83  
    84  	header := block.Header()
    85  	// validate the block header
    86  	if err := ValidateHeader(v.config, v.Pow, header, parent.Header(), false, false); err != nil {
    87  		return err
    88  	}
    89  	// verify the uncles are correctly rewarded
    90  	if err := v.VerifyUncles(block, parent); err != nil {
    91  		return err
    92  	}
    93  
    94  	// Verify UncleHash before running other uncle validations
    95  	unclesSha := types.CalcUncleHash(block.Uncles())
    96  	if unclesSha != header.UncleHash {
    97  		return fmt.Errorf("invalid uncles root hash (remote: %x local: %x)", header.UncleHash, unclesSha)
    98  	}
    99  
   100  	// The transactions Trie's root (R = (Tr [[i, RLP(T1)], [i, RLP(T2)], ... [n, RLP(Tn)]]))
   101  	// can be used by light clients to make sure they've received the correct Txs
   102  	txSha := types.DeriveSha(block.Transactions())
   103  	if txSha != header.TxHash {
   104  		return fmt.Errorf("invalid transaction root hash (remote: %x local: %x)", header.TxHash, txSha)
   105  	}
   106  
   107  	return nil
   108  }
   109  
   110  // ValidateState validates the various changes that happen after a state
   111  // transition, such as amount of used gas, the receipt roots and the state root
   112  // itself. ValidateState returns a database batch if the validation was a success
   113  // otherwise nil and an error is returned.
   114  func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas *big.Int) (err error) {
   115  	header := block.Header()
   116  	if block.GasUsed().Cmp(usedGas) != 0 {
   117  		return ValidationError(fmt.Sprintf("invalid gas used (remote: %v local: %v)", block.GasUsed(), usedGas))
   118  	}
   119  	// Validate the received block's bloom with the one derived from the generated receipts.
   120  	// For valid blocks this should always validate to true.
   121  	rbloom := types.CreateBloom(receipts)
   122  	if rbloom != header.Bloom {
   123  		return fmt.Errorf("invalid bloom (remote: %x  local: %x)", header.Bloom, rbloom)
   124  	}
   125  	// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
   126  	receiptSha := types.DeriveSha(receipts)
   127  	if receiptSha != header.ReceiptHash {
   128  		return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
   129  	}
   130  	// Validate the state root against the received state root and throw
   131  	// an error if they don't match.
   132  	if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
   133  		return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root)
   134  	}
   135  	return nil
   136  }
   137  
   138  // VerifyUncles verifies the given block's uncles and applies the Ethereum
   139  // consensus rules to the various block headers included; it will return an
   140  // error if any of the included uncle headers were invalid. It returns an error
   141  // if the validation failed.
   142  func (v *BlockValidator) VerifyUncles(block, parent *types.Block) error {
   143  	// validate that there are at most 2 uncles included in this block
   144  	if len(block.Uncles()) > 2 {
   145  		return ValidationError("Block can only contain maximum 2 uncles (contained %v)", len(block.Uncles()))
   146  	}
   147  
   148  	uncles := set.New()
   149  	ancestors := make(map[common.Hash]*types.Block)
   150  	for _, ancestor := range v.bc.GetBlocksFromHash(block.ParentHash(), 7) {
   151  		ancestors[ancestor.Hash()] = ancestor
   152  		// Include ancestors uncles in the uncle set. Uncles must be unique.
   153  		for _, uncle := range ancestor.Uncles() {
   154  			uncles.Add(uncle.Hash())
   155  		}
   156  	}
   157  	ancestors[block.Hash()] = block
   158  	uncles.Add(block.Hash())
   159  
   160  	for i, uncle := range block.Uncles() {
   161  		hash := uncle.Hash()
   162  		if uncles.Has(hash) {
   163  			// Error not unique
   164  			return UncleError("uncle[%d](%x) not unique", i, hash[:4])
   165  		}
   166  		uncles.Add(hash)
   167  
   168  		if ancestors[hash] != nil {
   169  			branch := fmt.Sprintf("  O - %x\n  |\n", block.Hash())
   170  			for h := range ancestors {
   171  				branch += fmt.Sprintf("  O - %x\n  |\n", h)
   172  			}
   173  			log.Warn(branch)
   174  			return UncleError("uncle[%d](%x) is ancestor", i, hash[:4])
   175  		}
   176  
   177  		if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == parent.Hash() {
   178  			return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4])
   179  		}
   180  
   181  		if err := ValidateHeader(v.config, v.Pow, uncle, ancestors[uncle.ParentHash].Header(), true, true); err != nil {
   182  			return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err))
   183  		}
   184  	}
   185  
   186  	return nil
   187  }
   188  
   189  // ValidateHeader validates the given header and, depending on the pow arg,
   190  // checks the proof of work of the given header. Returns an error if the
   191  // validation failed.
   192  func (v *BlockValidator) ValidateHeader(header, parent *types.Header, checkPow bool) error {
   193  	// Short circuit if the parent is missing.
   194  	if parent == nil {
   195  		return ParentError(header.ParentHash)
   196  	}
   197  	// Short circuit if the header's already known or its parent is missing
   198  	if v.bc.HasHeader(header.Hash()) {
   199  		return nil
   200  	}
   201  	return ValidateHeader(v.config, v.Pow, header, parent, checkPow, false)
   202  }
   203  
   204  // Validates a header. Returns an error if the header is invalid.
   205  //
   206  // See YP section 4.3.4. "Block Header Validity"
   207  func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
   208  	if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
   209  		return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
   210  	}
   211  
   212  	if uncle {
   213  		if header.Time.Cmp(math.MaxBig256) == 1 {
   214  			return BlockTSTooBigErr
   215  		}
   216  	} else {
   217  		if header.Time.Cmp(big.NewInt(time.Now().Unix())) == 1 {
   218  			return BlockFutureErr
   219  		}
   220  	}
   221  	if header.Time.Cmp(parent.Time) != 1 {
   222  		return BlockEqualTSErr
   223  	}
   224  
   225  	expd := CalcDifficulty(config, header.Time.Uint64(), parent.Time.Uint64(), parent.Number, parent.Difficulty)
   226  	if expd.Cmp(header.Difficulty) != 0 {
   227  		return fmt.Errorf("Difficulty check failed for header (remote: %v local: %v)", header.Difficulty, expd)
   228  	}
   229  
   230  	a := new(big.Int).Set(parent.GasLimit)
   231  	a = a.Sub(a, header.GasLimit)
   232  	a.Abs(a)
   233  	b := new(big.Int).Set(parent.GasLimit)
   234  	b = b.Div(b, params.GasLimitBoundDivisor)
   235  	if !(a.Cmp(b) < 0) || (header.GasLimit.Cmp(params.MinGasLimit) == -1) {
   236  		return fmt.Errorf("GasLimit check failed for header (remote: %v local_max: %v)", header.GasLimit, b)
   237  	}
   238  
   239  	num := new(big.Int).Set(parent.Number)
   240  	num.Sub(header.Number, num)
   241  	if num.Cmp(big.NewInt(1)) != 0 {
   242  		return BlockNumberErr
   243  	}
   244  
   245  	if checkPow {
   246  		// Verify the nonce of the header. Return an error if it's not valid
   247  		if err := pow.Verify(types.NewBlockWithHeader(header)); err != nil {
   248  			return &BlockNonceErr{header.Number, header.Hash(), header.Nonce.Uint64()}
   249  		}
   250  	}
   251  	// If all checks passed, validate the extra-data field for hard forks
   252  	if err := ValidateDAOHeaderExtraData(config, header); err != nil {
   253  		return err
   254  	}
   255  	if !uncle && config.EIP150Block != nil && config.EIP150Block.Cmp(header.Number) == 0 {
   256  		if config.EIP150Hash != (common.Hash{}) && config.EIP150Hash != header.Hash() {
   257  			return ValidationError("Homestead gas reprice fork hash mismatch: have 0x%x, want 0x%x", header.Hash(), config.EIP150Hash)
   258  		}
   259  	}
   260  	return nil
   261  }
   262  
   263  // CalcDifficulty is the difficulty adjustment algorithm. It returns
   264  // the difficulty that a new block should have when created at time
   265  // given the parent block's time and difficulty.
   266  func CalcDifficulty(config *params.ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
   267  	if config.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
   268  		return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)
   269  	} else {
   270  		return calcDifficultyFrontier(time, parentTime, parentNumber, parentDiff)
   271  	}
   272  }
   273  
   274  func calcDifficultyHomestead(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
   275  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
   276  	// algorithm:
   277  	// diff = (parent_diff +
   278  	//         (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   279  	//        ) + 2^(periodCount - 2)
   280  
   281  	bigTime := new(big.Int).SetUint64(time)
   282  	bigParentTime := new(big.Int).SetUint64(parentTime)
   283  
   284  	// holds intermediate values to make the algo easier to read & audit
   285  	x := new(big.Int)
   286  	y := new(big.Int)
   287  
   288  	// 1 - (block_timestamp -parent_timestamp) // 10
   289  	x.Sub(bigTime, bigParentTime)
   290  	x.Div(x, big10)
   291  	x.Sub(common.Big1, x)
   292  
   293  	// max(1 - (block_timestamp - parent_timestamp) // 10, -99)))
   294  	if x.Cmp(bigMinus99) < 0 {
   295  		x.Set(bigMinus99)
   296  	}
   297  
   298  	// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
   299  	y.Div(parentDiff, params.DifficultyBoundDivisor)
   300  	x.Mul(y, x)
   301  	x.Add(parentDiff, x)
   302  
   303  	// minimum difficulty can ever be (before exponential factor)
   304  	if x.Cmp(params.MinimumDifficulty) < 0 {
   305  		x.Set(params.MinimumDifficulty)
   306  	}
   307  
   308  	// for the exponential factor
   309  	periodCount := new(big.Int).Add(parentNumber, common.Big1)
   310  	periodCount.Div(periodCount, ExpDiffPeriod)
   311  
   312  	// the exponential factor, commonly referred to as "the bomb"
   313  	// diff = diff + 2^(periodCount - 2)
   314  	if periodCount.Cmp(common.Big1) > 0 {
   315  		y.Sub(periodCount, common.Big2)
   316  		y.Exp(common.Big2, y, nil)
   317  		x.Add(x, y)
   318  	}
   319  
   320  	return x
   321  }
   322  
   323  func calcDifficultyFrontier(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
   324  	diff := new(big.Int)
   325  	adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
   326  	bigTime := new(big.Int)
   327  	bigParentTime := new(big.Int)
   328  
   329  	bigTime.SetUint64(time)
   330  	bigParentTime.SetUint64(parentTime)
   331  
   332  	if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 {
   333  		diff.Add(parentDiff, adjust)
   334  	} else {
   335  		diff.Sub(parentDiff, adjust)
   336  	}
   337  	if diff.Cmp(params.MinimumDifficulty) < 0 {
   338  		diff.Set(params.MinimumDifficulty)
   339  	}
   340  
   341  	periodCount := new(big.Int).Add(parentNumber, common.Big1)
   342  	periodCount.Div(periodCount, ExpDiffPeriod)
   343  	if periodCount.Cmp(common.Big1) > 0 {
   344  		// diff = diff + 2^(periodCount - 2)
   345  		expDiff := periodCount.Sub(periodCount, common.Big2)
   346  		expDiff.Exp(common.Big2, expDiff, nil)
   347  		diff.Add(diff, expDiff)
   348  		diff = math.BigMax(diff, params.MinimumDifficulty)
   349  	}
   350  
   351  	return diff
   352  }
   353  
   354  // CalcGasLimit computes the gas limit of the next block after parent.
   355  // The result may be modified by the caller.
   356  // This is miner strategy, not consensus protocol.
   357  func CalcGasLimit(parent *types.Block) *big.Int {
   358  	// contrib = (parentGasUsed * 3 / 2) / 1024
   359  	contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3))
   360  	contrib = contrib.Div(contrib, big.NewInt(2))
   361  	contrib = contrib.Div(contrib, params.GasLimitBoundDivisor)
   362  
   363  	// decay = parentGasLimit / 1024 -1
   364  	decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
   365  	decay.Sub(decay, big.NewInt(1))
   366  
   367  	/*
   368  		strategy: gasLimit of block-to-mine is set based on parent's
   369  		gasUsed value.  if parentGasUsed > parentGasLimit * (2/3) then we
   370  		increase it, otherwise lower it (or leave it unchanged if it's right
   371  		at that usage) the amount increased/decreased depends on how far away
   372  		from parentGasLimit * (2/3) parentGasUsed is.
   373  	*/
   374  	gl := new(big.Int).Sub(parent.GasLimit(), decay)
   375  	gl = gl.Add(gl, contrib)
   376  	gl.Set(math.BigMax(gl, params.MinGasLimit))
   377  
   378  	// however, if we're now below the target (TargetGasLimit) we increase the
   379  	// limit as much as we can (parentGasLimit / 1024 -1)
   380  	if gl.Cmp(params.TargetGasLimit) < 0 {
   381  		gl.Add(parent.GasLimit(), decay)
   382  		gl.Set(math.BigMin(gl, params.TargetGasLimit))
   383  	}
   384  	return gl
   385  }