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.
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-13 12:31:35 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (v *BlockValidator) ValidateState(block *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
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 |