* core/vm: remove function call for stack validation from evm runloop * core/vm: separate gas calc into static + dynamic * core/vm: optimize push1 * core/vm: reuse pooled bigints for ADDRESS, ORIGIN and CALLER * core/vm: use generic error message for jump/jumpi, to avoid string interpolation * testdata: fix tests for new error message * core/vm: use 64-bit memory calculations * core/vm: fix error in memory calculation * core/vm: address review concerns * core/vm: avoid unnecessary use of big.Int:BitLen()
		
			
				
	
	
		
			1109 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			1109 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2015 The go-ethereum Authors
 | |
| // 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 vm
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 
 | |
| 	"github.com/ethereum/go-ethereum/params"
 | |
| )
 | |
| 
 | |
| type (
 | |
| 	executionFunc func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
 | |
| 	gasFunc       func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
 | |
| 	// memorySizeFunc returns the required size, and whether the operation overflowed a uint64
 | |
| 	memorySizeFunc func(*Stack) (size uint64, overflow bool)
 | |
| )
 | |
| 
 | |
| var errGasUintOverflow = errors.New("gas uint64 overflow")
 | |
| 
 | |
| type operation struct {
 | |
| 	// execute is the operation function
 | |
| 	execute     executionFunc
 | |
| 	constantGas uint64
 | |
| 	dynamicGas  gasFunc
 | |
| 	// minStack tells how many stack items are required
 | |
| 	minStack int
 | |
| 	// maxStack specifies the max length the stack can have for this operation
 | |
| 	// to not overflow the stack.
 | |
| 	maxStack int
 | |
| 
 | |
| 	// memorySize returns the memory size required for the operation
 | |
| 	memorySize memorySizeFunc
 | |
| 
 | |
| 	halts   bool // indicates whether the operation should halt further execution
 | |
| 	jumps   bool // indicates whether the program counter should not increment
 | |
| 	writes  bool // determines whether this a state modifying operation
 | |
| 	valid   bool // indication whether the retrieved operation is valid and known
 | |
| 	reverts bool // determines whether the operation reverts state (implicitly halts)
 | |
| 	returns bool // determines whether the operations sets the return data content
 | |
| }
 | |
| 
 | |
| var (
 | |
| 	frontierInstructionSet       = newFrontierInstructionSet()
 | |
| 	homesteadInstructionSet      = newHomesteadInstructionSet()
 | |
| 	byzantiumInstructionSet      = newByzantiumInstructionSet()
 | |
| 	constantinopleInstructionSet = newConstantinopleInstructionSet()
 | |
| )
 | |
| 
 | |
| // NewConstantinopleInstructionSet returns the frontier, homestead
 | |
| // byzantium and contantinople instructions.
 | |
| func newConstantinopleInstructionSet() [256]operation {
 | |
| 	// instructions that can be executed during the byzantium phase.
 | |
| 	instructionSet := newByzantiumInstructionSet()
 | |
| 	instructionSet[SHL] = operation{
 | |
| 		execute:     opSHL,
 | |
| 		constantGas: GasFastestStep,
 | |
| 		minStack:    minStack(2, 1),
 | |
| 		maxStack:    maxStack(2, 1),
 | |
| 		valid:       true,
 | |
| 	}
 | |
| 	instructionSet[SHR] = operation{
 | |
| 		execute:     opSHR,
 | |
| 		constantGas: GasFastestStep,
 | |
| 		minStack:    minStack(2, 1),
 | |
| 		maxStack:    maxStack(2, 1),
 | |
| 		valid:       true,
 | |
| 	}
 | |
| 	instructionSet[SAR] = operation{
 | |
| 		execute:     opSAR,
 | |
| 		constantGas: GasFastestStep,
 | |
| 		minStack:    minStack(2, 1),
 | |
| 		maxStack:    maxStack(2, 1),
 | |
| 		valid:       true,
 | |
| 	}
 | |
| 	instructionSet[EXTCODEHASH] = operation{
 | |
| 		execute:    opExtCodeHash,
 | |
| 		dynamicGas: gasExtCodeHash,
 | |
| 		minStack:   minStack(1, 1),
 | |
| 		maxStack:   maxStack(1, 1),
 | |
| 		valid:      true,
 | |
| 	}
 | |
| 	instructionSet[CREATE2] = operation{
 | |
| 		execute:    opCreate2,
 | |
| 		dynamicGas: gasCreate2,
 | |
| 		minStack:   minStack(4, 1),
 | |
| 		maxStack:   maxStack(4, 1),
 | |
| 		memorySize: memoryCreate2,
 | |
| 		valid:      true,
 | |
| 		writes:     true,
 | |
| 		returns:    true,
 | |
| 	}
 | |
| 	return instructionSet
 | |
| }
 | |
| 
 | |
| // NewByzantiumInstructionSet returns the frontier, homestead and
 | |
| // byzantium instructions.
 | |
| func newByzantiumInstructionSet() [256]operation {
 | |
| 	// instructions that can be executed during the homestead phase.
 | |
| 	instructionSet := newHomesteadInstructionSet()
 | |
| 	instructionSet[STATICCALL] = operation{
 | |
| 		execute:    opStaticCall,
 | |
| 		dynamicGas: gasStaticCall,
 | |
| 		minStack:   minStack(6, 1),
 | |
| 		maxStack:   maxStack(6, 1),
 | |
| 		memorySize: memoryStaticCall,
 | |
| 		valid:      true,
 | |
| 		returns:    true,
 | |
| 	}
 | |
| 	instructionSet[RETURNDATASIZE] = operation{
 | |
| 		execute:     opReturnDataSize,
 | |
| 		constantGas: GasQuickStep,
 | |
| 		minStack:    minStack(0, 1),
 | |
| 		maxStack:    maxStack(0, 1),
 | |
| 		valid:       true,
 | |
| 	}
 | |
| 	instructionSet[RETURNDATACOPY] = operation{
 | |
| 		execute:    opReturnDataCopy,
 | |
| 		dynamicGas: gasReturnDataCopy,
 | |
| 		minStack:   minStack(3, 0),
 | |
| 		maxStack:   maxStack(3, 0),
 | |
| 		memorySize: memoryReturnDataCopy,
 | |
| 		valid:      true,
 | |
| 	}
 | |
| 	instructionSet[REVERT] = operation{
 | |
| 		execute:    opRevert,
 | |
| 		dynamicGas: gasRevert,
 | |
| 		minStack:   minStack(2, 0),
 | |
| 		maxStack:   maxStack(2, 0),
 | |
| 		memorySize: memoryRevert,
 | |
| 		valid:      true,
 | |
| 		reverts:    true,
 | |
| 		returns:    true,
 | |
| 	}
 | |
| 	return instructionSet
 | |
| }
 | |
| 
 | |
| // NewHomesteadInstructionSet returns the frontier and homestead
 | |
| // instructions that can be executed during the homestead phase.
 | |
| func newHomesteadInstructionSet() [256]operation {
 | |
| 	instructionSet := newFrontierInstructionSet()
 | |
| 	instructionSet[DELEGATECALL] = operation{
 | |
| 		execute:    opDelegateCall,
 | |
| 		dynamicGas: gasDelegateCall,
 | |
| 		minStack:   minStack(6, 1),
 | |
| 		maxStack:   maxStack(6, 1),
 | |
| 		memorySize: memoryDelegateCall,
 | |
| 		valid:      true,
 | |
| 		returns:    true,
 | |
| 	}
 | |
| 	return instructionSet
 | |
| }
 | |
| 
 | |
| // NewFrontierInstructionSet returns the frontier instructions
 | |
| // that can be executed during the frontier phase.
 | |
| func newFrontierInstructionSet() [256]operation {
 | |
| 	return [256]operation{
 | |
| 		STOP: {
 | |
| 			execute:     opStop,
 | |
| 			constantGas: 0,
 | |
| 			minStack:    minStack(0, 0),
 | |
| 			maxStack:    maxStack(0, 0),
 | |
| 			halts:       true,
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		ADD: {
 | |
| 			execute:     opAdd,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		MUL: {
 | |
| 			execute:     opMul,
 | |
| 			constantGas: GasFastStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SUB: {
 | |
| 			execute:     opSub,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DIV: {
 | |
| 			execute:     opDiv,
 | |
| 			constantGas: GasFastStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SDIV: {
 | |
| 			execute:     opSdiv,
 | |
| 			constantGas: GasFastStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		MOD: {
 | |
| 			execute:     opMod,
 | |
| 			constantGas: GasFastStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SMOD: {
 | |
| 			execute:     opSmod,
 | |
| 			constantGas: GasFastStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		ADDMOD: {
 | |
| 			execute:     opAddmod,
 | |
| 			constantGas: GasMidStep,
 | |
| 			minStack:    minStack(3, 1),
 | |
| 			maxStack:    maxStack(3, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		MULMOD: {
 | |
| 			execute:     opMulmod,
 | |
| 			constantGas: GasMidStep,
 | |
| 			minStack:    minStack(3, 1),
 | |
| 			maxStack:    maxStack(3, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		EXP: {
 | |
| 			execute:    opExp,
 | |
| 			dynamicGas: gasExp,
 | |
| 			minStack:   minStack(2, 1),
 | |
| 			maxStack:   maxStack(2, 1),
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		SIGNEXTEND: {
 | |
| 			execute:     opSignExtend,
 | |
| 			constantGas: GasFastStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		LT: {
 | |
| 			execute:     opLt,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		GT: {
 | |
| 			execute:     opGt,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SLT: {
 | |
| 			execute:     opSlt,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SGT: {
 | |
| 			execute:     opSgt,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		EQ: {
 | |
| 			execute:     opEq,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		ISZERO: {
 | |
| 			execute:     opIszero,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(1, 1),
 | |
| 			maxStack:    maxStack(1, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		AND: {
 | |
| 			execute:     opAnd,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		XOR: {
 | |
| 			execute:     opXor,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		OR: {
 | |
| 			execute:     opOr,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		NOT: {
 | |
| 			execute:     opNot,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(1, 1),
 | |
| 			maxStack:    maxStack(1, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		BYTE: {
 | |
| 			execute:     opByte,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(2, 1),
 | |
| 			maxStack:    maxStack(2, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SHA3: {
 | |
| 			execute:    opSha3,
 | |
| 			dynamicGas: gasSha3,
 | |
| 			minStack:   minStack(2, 1),
 | |
| 			maxStack:   maxStack(2, 1),
 | |
| 			memorySize: memorySha3,
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		ADDRESS: {
 | |
| 			execute:     opAddress,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		BALANCE: {
 | |
| 			execute:    opBalance,
 | |
| 			dynamicGas: gasBalance,
 | |
| 			minStack:   minStack(1, 1),
 | |
| 			maxStack:   maxStack(1, 1),
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		ORIGIN: {
 | |
| 			execute:     opOrigin,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		CALLER: {
 | |
| 			execute:     opCaller,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		CALLVALUE: {
 | |
| 			execute:     opCallValue,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		CALLDATALOAD: {
 | |
| 			execute:     opCallDataLoad,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(1, 1),
 | |
| 			maxStack:    maxStack(1, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		CALLDATASIZE: {
 | |
| 			execute:     opCallDataSize,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		CALLDATACOPY: {
 | |
| 			execute:    opCallDataCopy,
 | |
| 			dynamicGas: gasCallDataCopy,
 | |
| 			minStack:   minStack(3, 0),
 | |
| 			maxStack:   maxStack(3, 0),
 | |
| 			memorySize: memoryCallDataCopy,
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		CODESIZE: {
 | |
| 			execute:     opCodeSize,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		CODECOPY: {
 | |
| 			execute:    opCodeCopy,
 | |
| 			dynamicGas: gasCodeCopy,
 | |
| 			minStack:   minStack(3, 0),
 | |
| 			maxStack:   maxStack(3, 0),
 | |
| 			memorySize: memoryCodeCopy,
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		GASPRICE: {
 | |
| 			execute:     opGasprice,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		EXTCODESIZE: {
 | |
| 			execute:    opExtCodeSize,
 | |
| 			dynamicGas: gasExtCodeSize,
 | |
| 			minStack:   minStack(1, 1),
 | |
| 			maxStack:   maxStack(1, 1),
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		EXTCODECOPY: {
 | |
| 			execute:    opExtCodeCopy,
 | |
| 			dynamicGas: gasExtCodeCopy,
 | |
| 			minStack:   minStack(4, 0),
 | |
| 			maxStack:   maxStack(4, 0),
 | |
| 			memorySize: memoryExtCodeCopy,
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		BLOCKHASH: {
 | |
| 			execute:     opBlockhash,
 | |
| 			constantGas: GasExtStep,
 | |
| 			minStack:    minStack(1, 1),
 | |
| 			maxStack:    maxStack(1, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		COINBASE: {
 | |
| 			execute:     opCoinbase,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		TIMESTAMP: {
 | |
| 			execute:     opTimestamp,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		NUMBER: {
 | |
| 			execute:     opNumber,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DIFFICULTY: {
 | |
| 			execute:     opDifficulty,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		GASLIMIT: {
 | |
| 			execute:     opGasLimit,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		POP: {
 | |
| 			execute:     opPop,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(1, 0),
 | |
| 			maxStack:    maxStack(1, 0),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		MLOAD: {
 | |
| 			execute:    opMload,
 | |
| 			dynamicGas: gasMLoad,
 | |
| 			minStack:   minStack(1, 1),
 | |
| 			maxStack:   maxStack(1, 1),
 | |
| 			memorySize: memoryMLoad,
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		MSTORE: {
 | |
| 			execute:    opMstore,
 | |
| 			dynamicGas: gasMStore,
 | |
| 			minStack:   minStack(2, 0),
 | |
| 			maxStack:   maxStack(2, 0),
 | |
| 			memorySize: memoryMStore,
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		MSTORE8: {
 | |
| 			execute:    opMstore8,
 | |
| 			dynamicGas: gasMStore8,
 | |
| 			memorySize: memoryMStore8,
 | |
| 			minStack:   minStack(2, 0),
 | |
| 			maxStack:   maxStack(2, 0),
 | |
| 
 | |
| 			valid: true,
 | |
| 		},
 | |
| 		SLOAD: {
 | |
| 			execute:    opSload,
 | |
| 			dynamicGas: gasSLoad,
 | |
| 			minStack:   minStack(1, 1),
 | |
| 			maxStack:   maxStack(1, 1),
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		SSTORE: {
 | |
| 			execute:    opSstore,
 | |
| 			dynamicGas: gasSStore,
 | |
| 			minStack:   minStack(2, 0),
 | |
| 			maxStack:   maxStack(2, 0),
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 		},
 | |
| 		JUMP: {
 | |
| 			execute:     opJump,
 | |
| 			constantGas: GasMidStep,
 | |
| 			minStack:    minStack(1, 0),
 | |
| 			maxStack:    maxStack(1, 0),
 | |
| 			jumps:       true,
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		JUMPI: {
 | |
| 			execute:     opJumpi,
 | |
| 			constantGas: GasSlowStep,
 | |
| 			minStack:    minStack(2, 0),
 | |
| 			maxStack:    maxStack(2, 0),
 | |
| 			jumps:       true,
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PC: {
 | |
| 			execute:     opPc,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		MSIZE: {
 | |
| 			execute:     opMsize,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		GAS: {
 | |
| 			execute:     opGas,
 | |
| 			constantGas: GasQuickStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		JUMPDEST: {
 | |
| 			execute:     opJumpdest,
 | |
| 			constantGas: params.JumpdestGas,
 | |
| 			minStack:    minStack(0, 0),
 | |
| 			maxStack:    maxStack(0, 0),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH1: {
 | |
| 			execute:     opPush1,
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH2: {
 | |
| 			execute:     makePush(2, 2),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH3: {
 | |
| 			execute:     makePush(3, 3),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH4: {
 | |
| 			execute:     makePush(4, 4),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH5: {
 | |
| 			execute:     makePush(5, 5),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH6: {
 | |
| 			execute:     makePush(6, 6),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH7: {
 | |
| 			execute:     makePush(7, 7),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH8: {
 | |
| 			execute:     makePush(8, 8),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH9: {
 | |
| 			execute:     makePush(9, 9),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH10: {
 | |
| 			execute:     makePush(10, 10),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH11: {
 | |
| 			execute:     makePush(11, 11),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH12: {
 | |
| 			execute:     makePush(12, 12),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH13: {
 | |
| 			execute:     makePush(13, 13),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH14: {
 | |
| 			execute:     makePush(14, 14),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH15: {
 | |
| 			execute:     makePush(15, 15),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH16: {
 | |
| 			execute:     makePush(16, 16),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH17: {
 | |
| 			execute:     makePush(17, 17),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH18: {
 | |
| 			execute:     makePush(18, 18),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH19: {
 | |
| 			execute:     makePush(19, 19),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH20: {
 | |
| 			execute:     makePush(20, 20),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH21: {
 | |
| 			execute:     makePush(21, 21),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH22: {
 | |
| 			execute:     makePush(22, 22),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH23: {
 | |
| 			execute:     makePush(23, 23),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH24: {
 | |
| 			execute:     makePush(24, 24),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH25: {
 | |
| 			execute:     makePush(25, 25),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH26: {
 | |
| 			execute:     makePush(26, 26),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH27: {
 | |
| 			execute:     makePush(27, 27),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH28: {
 | |
| 			execute:     makePush(28, 28),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH29: {
 | |
| 			execute:     makePush(29, 29),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH30: {
 | |
| 			execute:     makePush(30, 30),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH31: {
 | |
| 			execute:     makePush(31, 31),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		PUSH32: {
 | |
| 			execute:     makePush(32, 32),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minStack(0, 1),
 | |
| 			maxStack:    maxStack(0, 1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP1: {
 | |
| 			execute:     makeDup(1),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(1),
 | |
| 			maxStack:    maxDupStack(1),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP2: {
 | |
| 			execute:     makeDup(2),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(2),
 | |
| 			maxStack:    maxDupStack(2),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP3: {
 | |
| 			execute:     makeDup(3),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(3),
 | |
| 			maxStack:    maxDupStack(3),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP4: {
 | |
| 			execute:     makeDup(4),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(4),
 | |
| 			maxStack:    maxDupStack(4),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP5: {
 | |
| 			execute:     makeDup(5),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(5),
 | |
| 			maxStack:    maxDupStack(5),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP6: {
 | |
| 			execute:     makeDup(6),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(6),
 | |
| 			maxStack:    maxDupStack(6),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP7: {
 | |
| 			execute:     makeDup(7),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(7),
 | |
| 			maxStack:    maxDupStack(7),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP8: {
 | |
| 			execute:     makeDup(8),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(8),
 | |
| 			maxStack:    maxDupStack(8),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP9: {
 | |
| 			execute:     makeDup(9),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(9),
 | |
| 			maxStack:    maxDupStack(9),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP10: {
 | |
| 			execute:     makeDup(10),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(10),
 | |
| 			maxStack:    maxDupStack(10),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP11: {
 | |
| 			execute:     makeDup(11),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(11),
 | |
| 			maxStack:    maxDupStack(11),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP12: {
 | |
| 			execute:     makeDup(12),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(12),
 | |
| 			maxStack:    maxDupStack(12),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP13: {
 | |
| 			execute:     makeDup(13),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(13),
 | |
| 			maxStack:    maxDupStack(13),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP14: {
 | |
| 			execute:     makeDup(14),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(14),
 | |
| 			maxStack:    maxDupStack(14),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP15: {
 | |
| 			execute:     makeDup(15),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(15),
 | |
| 			maxStack:    maxDupStack(15),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		DUP16: {
 | |
| 			execute:     makeDup(16),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minDupStack(16),
 | |
| 			maxStack:    maxDupStack(16),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP1: {
 | |
| 			execute:     makeSwap(1),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(2),
 | |
| 			maxStack:    maxSwapStack(2),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP2: {
 | |
| 			execute:     makeSwap(2),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(3),
 | |
| 			maxStack:    maxSwapStack(3),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP3: {
 | |
| 			execute:     makeSwap(3),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(4),
 | |
| 			maxStack:    maxSwapStack(4),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP4: {
 | |
| 			execute:     makeSwap(4),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(5),
 | |
| 			maxStack:    maxSwapStack(5),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP5: {
 | |
| 			execute:     makeSwap(5),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(6),
 | |
| 			maxStack:    maxSwapStack(6),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP6: {
 | |
| 			execute:     makeSwap(6),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(7),
 | |
| 			maxStack:    maxSwapStack(7),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP7: {
 | |
| 			execute:     makeSwap(7),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(8),
 | |
| 			maxStack:    maxSwapStack(8),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP8: {
 | |
| 			execute:     makeSwap(8),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(9),
 | |
| 			maxStack:    maxSwapStack(9),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP9: {
 | |
| 			execute:     makeSwap(9),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(10),
 | |
| 			maxStack:    maxSwapStack(10),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP10: {
 | |
| 			execute:     makeSwap(10),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(11),
 | |
| 			maxStack:    maxSwapStack(11),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP11: {
 | |
| 			execute:     makeSwap(11),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(12),
 | |
| 			maxStack:    maxSwapStack(12),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP12: {
 | |
| 			execute:     makeSwap(12),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(13),
 | |
| 			maxStack:    maxSwapStack(13),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP13: {
 | |
| 			execute:     makeSwap(13),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(14),
 | |
| 			maxStack:    maxSwapStack(14),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP14: {
 | |
| 			execute:     makeSwap(14),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(15),
 | |
| 			maxStack:    maxSwapStack(15),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP15: {
 | |
| 			execute:     makeSwap(15),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(16),
 | |
| 			maxStack:    maxSwapStack(16),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		SWAP16: {
 | |
| 			execute:     makeSwap(16),
 | |
| 			constantGas: GasFastestStep,
 | |
| 			minStack:    minSwapStack(17),
 | |
| 			maxStack:    maxSwapStack(17),
 | |
| 			valid:       true,
 | |
| 		},
 | |
| 		LOG0: {
 | |
| 			execute:    makeLog(0),
 | |
| 			dynamicGas: makeGasLog(0),
 | |
| 			minStack:   minStack(2, 0),
 | |
| 			maxStack:   maxStack(2, 0),
 | |
| 			memorySize: memoryLog,
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 		},
 | |
| 		LOG1: {
 | |
| 			execute:    makeLog(1),
 | |
| 			dynamicGas: makeGasLog(1),
 | |
| 			minStack:   minStack(3, 0),
 | |
| 			maxStack:   maxStack(3, 0),
 | |
| 			memorySize: memoryLog,
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 		},
 | |
| 		LOG2: {
 | |
| 			execute:    makeLog(2),
 | |
| 			dynamicGas: makeGasLog(2),
 | |
| 			minStack:   minStack(4, 0),
 | |
| 			maxStack:   maxStack(4, 0),
 | |
| 			memorySize: memoryLog,
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 		},
 | |
| 		LOG3: {
 | |
| 			execute:    makeLog(3),
 | |
| 			dynamicGas: makeGasLog(3),
 | |
| 			minStack:   minStack(5, 0),
 | |
| 			maxStack:   maxStack(5, 0),
 | |
| 			memorySize: memoryLog,
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 		},
 | |
| 		LOG4: {
 | |
| 			execute:    makeLog(4),
 | |
| 			dynamicGas: makeGasLog(4),
 | |
| 			minStack:   minStack(6, 0),
 | |
| 			maxStack:   maxStack(6, 0),
 | |
| 			memorySize: memoryLog,
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 		},
 | |
| 		CREATE: {
 | |
| 			execute:    opCreate,
 | |
| 			dynamicGas: gasCreate,
 | |
| 			minStack:   minStack(3, 1),
 | |
| 			maxStack:   maxStack(3, 1),
 | |
| 			memorySize: memoryCreate,
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 			returns:    true,
 | |
| 		},
 | |
| 		CALL: {
 | |
| 			execute:    opCall,
 | |
| 			dynamicGas: gasCall,
 | |
| 			minStack:   minStack(7, 1),
 | |
| 			maxStack:   maxStack(7, 1),
 | |
| 			memorySize: memoryCall,
 | |
| 			valid:      true,
 | |
| 			returns:    true,
 | |
| 		},
 | |
| 		CALLCODE: {
 | |
| 			execute:    opCallCode,
 | |
| 			dynamicGas: gasCallCode,
 | |
| 			minStack:   minStack(7, 1),
 | |
| 			maxStack:   maxStack(7, 1),
 | |
| 			memorySize: memoryCall,
 | |
| 			valid:      true,
 | |
| 			returns:    true,
 | |
| 		},
 | |
| 		RETURN: {
 | |
| 			execute:    opReturn,
 | |
| 			dynamicGas: gasReturn,
 | |
| 			minStack:   minStack(2, 0),
 | |
| 			maxStack:   maxStack(2, 0),
 | |
| 			memorySize: memoryReturn,
 | |
| 			halts:      true,
 | |
| 			valid:      true,
 | |
| 		},
 | |
| 		SELFDESTRUCT: {
 | |
| 			execute:    opSuicide,
 | |
| 			dynamicGas: gasSuicide,
 | |
| 			minStack:   minStack(1, 0),
 | |
| 			maxStack:   maxStack(1, 0),
 | |
| 			halts:      true,
 | |
| 			valid:      true,
 | |
| 			writes:     true,
 | |
| 		},
 | |
| 	}
 | |
| }
 |