| 
									
										
										
										
											2016-04-14 18:18:24 +02:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package core | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/consensus" | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/state" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/params" | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | // BlockValidator is responsible for validating block headers, uncles and | 
					
						
							|  |  |  | // processed state. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // BlockValidator implements Validator. | 
					
						
							|  |  |  | type BlockValidator struct { | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 	config *params.ChainConfig // Chain configuration options | 
					
						
							|  |  |  | 	bc     *BlockChain         // Canonical block chain | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	engine consensus.Engine    // Consensus engine used for validating | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewBlockValidator returns a new block validator which is safe for re-use | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus.Engine) *BlockValidator { | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	validator := &BlockValidator{ | 
					
						
							| 
									
										
										
										
											2016-03-01 23:32:43 +01:00
										 |  |  | 		config: config, | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 		engine: engine, | 
					
						
							| 
									
										
										
										
											2016-03-01 23:32:43 +01:00
										 |  |  | 		bc:     blockchain, | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return validator | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-27 16:49:29 +08:00
										 |  |  | // ValidateBody validates the given block's uncles and verifies the block | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | // header's transaction and uncle roots. The headers are assumed to be already | 
					
						
							|  |  |  | // validated at this point. | 
					
						
							|  |  |  | func (v *BlockValidator) ValidateBody(block *types.Block) error { | 
					
						
							|  |  |  | 	// Check whether the block's known, and if not, that it's linkable | 
					
						
							| 
									
										
										
										
											2018-02-05 18:40:32 +02:00
										 |  |  | 	if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) { | 
					
						
							| 
									
										
										
										
											2017-06-27 15:57:06 +02:00
										 |  |  | 		return ErrKnownBlock | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	// Header validity is known at this point, check the uncles and transactions | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	header := block.Header() | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	if err := v.engine.VerifyUncles(v.bc, block); err != nil { | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash { | 
					
						
							|  |  |  | 		return fmt.Errorf("uncle root hash mismatch: have %x, want %x", hash, header.UncleHash) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	if hash := types.DeriveSha(block.Transactions()); hash != header.TxHash { | 
					
						
							|  |  |  | 		return fmt.Errorf("transaction root hash mismatch: have %x, want %x", hash, header.TxHash) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-07 13:47:11 +01:00
										 |  |  | 	if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) { | 
					
						
							|  |  |  | 		if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) { | 
					
						
							|  |  |  | 			return consensus.ErrUnknownAncestor | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return consensus.ErrPrunedAncestor | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ValidateState validates the various changes that happen after a state | 
					
						
							|  |  |  | // transition, such as amount of used gas, the receipt roots and the state root | 
					
						
							| 
									
										
										
										
											2016-03-15 11:08:18 -07:00
										 |  |  | // itself. ValidateState returns a database batch if the validation was a success | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | // otherwise nil and an error is returned. | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error { | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	header := block.Header() | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	if block.GasUsed() != usedGas { | 
					
						
							|  |  |  | 		return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Validate the received block's bloom with the one derived from the generated receipts. | 
					
						
							|  |  |  | 	// For valid blocks this should always validate to true. | 
					
						
							|  |  |  | 	rbloom := types.CreateBloom(receipts) | 
					
						
							|  |  |  | 	if rbloom != header.Bloom { | 
					
						
							| 
									
										
										
										
											2016-11-23 13:32:25 +01:00
										 |  |  | 		return fmt.Errorf("invalid bloom (remote: %x  local: %x)", header.Bloom, rbloom) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]])) | 
					
						
							|  |  |  | 	receiptSha := types.DeriveSha(receipts) | 
					
						
							|  |  |  | 	if receiptSha != header.ReceiptHash { | 
					
						
							| 
									
										
										
										
											2016-11-23 13:32:25 +01:00
										 |  |  | 		return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Validate the state root against the received state root and throw | 
					
						
							|  |  |  | 	// an error if they don't match. | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 	if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root { | 
					
						
							| 
									
										
										
										
											2016-11-23 13:32:25 +01:00
										 |  |  | 		return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-29 12:21:12 +03:00
										 |  |  | // CalcGasLimit computes the gas limit of the next block after parent. It aims | 
					
						
							|  |  |  | // to keep the baseline gas above the provided floor, and increase it towards the | 
					
						
							|  |  |  | // ceil if the blocks are full. If the ceil is exceeded, it will always decrease | 
					
						
							|  |  |  | // the gas allowance. | 
					
						
							|  |  |  | func CalcGasLimit(parent *types.Block, gasFloor, gasCeil uint64) uint64 { | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | 	// contrib = (parentGasUsed * 3 / 2) / 1024 | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// decay = parentGasLimit / 1024 -1 | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1 | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* | 
					
						
							|  |  |  | 		strategy: gasLimit of block-to-mine is set based on parent's | 
					
						
							|  |  |  | 		gasUsed value.  if parentGasUsed > parentGasLimit * (2/3) then we | 
					
						
							|  |  |  | 		increase it, otherwise lower it (or leave it unchanged if it's right | 
					
						
							|  |  |  | 		at that usage) the amount increased/decreased depends on how far away | 
					
						
							|  |  |  | 		from parentGasLimit * (2/3) parentGasUsed is. | 
					
						
							|  |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	limit := parent.GasLimit() - decay + contrib | 
					
						
							|  |  |  | 	if limit < params.MinGasLimit { | 
					
						
							|  |  |  | 		limit = params.MinGasLimit | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-29 12:21:12 +03:00
										 |  |  | 	// If we're outside our allowed gas range, we try to hone towards them | 
					
						
							|  |  |  | 	if limit < gasFloor { | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 		limit = parent.GasLimit() + decay | 
					
						
							| 
									
										
										
										
											2018-08-29 12:21:12 +03:00
										 |  |  | 		if limit > gasFloor { | 
					
						
							|  |  |  | 			limit = gasFloor | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if limit > gasCeil { | 
					
						
							|  |  |  | 		limit = parent.GasLimit() - decay | 
					
						
							|  |  |  | 		if limit < gasCeil { | 
					
						
							|  |  |  | 			limit = gasCeil | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	return limit | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | } |