| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | // Copyright 2019 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 ( | 
					
						
							|  |  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2020-06-30 10:12:51 +02:00
										 |  |  |  | 	"sort" | 
					
						
							| 
									
										
										
										
											2019-08-08 15:20:28 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | 	"github.com/ethereum/go-ethereum/params" | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  |  | 	"github.com/holiman/uint256" | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-30 10:12:51 +02:00
										 |  |  |  | var activators = map[int]func(*JumpTable){ | 
					
						
							| 
									
										
										
										
											2020-10-23 08:26:57 +02:00
										 |  |  |  | 	2929: enable2929, | 
					
						
							| 
									
										
										
										
											2020-06-30 10:12:51 +02:00
										 |  |  |  | 	2200: enable2200, | 
					
						
							|  |  |  |  | 	1884: enable1884, | 
					
						
							|  |  |  |  | 	1344: enable1344, | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | // EnableEIP enables the given EIP on the config. | 
					
						
							|  |  |  |  | // This operation writes in-place, and callers need to ensure that the globally | 
					
						
							|  |  |  |  | // defined jump tables are not polluted. | 
					
						
							|  |  |  |  | func EnableEIP(eipNum int, jt *JumpTable) error { | 
					
						
							| 
									
										
										
										
											2020-06-30 10:12:51 +02:00
										 |  |  |  | 	enablerFn, ok := activators[eipNum] | 
					
						
							|  |  |  |  | 	if !ok { | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | 		return fmt.Errorf("undefined eip %d", eipNum) | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-06-30 10:12:51 +02:00
										 |  |  |  | 	enablerFn(jt) | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-30 10:12:51 +02:00
										 |  |  |  | func ValidEip(eipNum int) bool { | 
					
						
							|  |  |  |  | 	_, ok := activators[eipNum] | 
					
						
							|  |  |  |  | 	return ok | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | func ActivateableEips() []string { | 
					
						
							|  |  |  |  | 	var nums []string | 
					
						
							|  |  |  |  | 	for k := range activators { | 
					
						
							|  |  |  |  | 		nums = append(nums, fmt.Sprintf("%d", k)) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	sort.Strings(nums) | 
					
						
							|  |  |  |  | 	return nums | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | // enable1884 applies EIP-1884 to the given jump table: | 
					
						
							|  |  |  |  | // - Increase cost of BALANCE to 700 | 
					
						
							|  |  |  |  | // - Increase cost of EXTCODEHASH to 700 | 
					
						
							|  |  |  |  | // - Increase cost of SLOAD to 800 | 
					
						
							|  |  |  |  | // - Define SELFBALANCE, with cost GasFastStep (5) | 
					
						
							|  |  |  |  | func enable1884(jt *JumpTable) { | 
					
						
							|  |  |  |  | 	// Gas cost changes | 
					
						
							| 
									
										
										
										
											2020-02-18 06:07:41 -08:00
										 |  |  |  | 	jt[SLOAD].constantGas = params.SloadGasEIP1884 | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | 	jt[BALANCE].constantGas = params.BalanceGasEIP1884 | 
					
						
							|  |  |  |  | 	jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// New opcode | 
					
						
							| 
									
										
										
										
											2020-07-16 15:32:01 +03:00
										 |  |  |  | 	jt[SELFBALANCE] = &operation{ | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | 		execute:     opSelfBalance, | 
					
						
							|  |  |  |  | 		constantGas: GasFastStep, | 
					
						
							|  |  |  |  | 		minStack:    minStack(0, 1), | 
					
						
							|  |  |  |  | 		maxStack:    maxStack(0, 1), | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-25 10:13:14 +01:00
										 |  |  |  | func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { | 
					
						
							|  |  |  |  | 	balance, _ := uint256.FromBig(interpreter.evm.StateDB.GetBalance(scope.Contract.Address())) | 
					
						
							|  |  |  |  | 	scope.Stack.push(balance) | 
					
						
							| 
									
										
										
										
											2019-08-08 11:07:23 +02:00
										 |  |  |  | 	return nil, nil | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-08-08 15:20:28 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // enable1344 applies EIP-1344 (ChainID Opcode) | 
					
						
							|  |  |  |  | // - Adds an opcode that returns the current chain’s EIP-155 unique identifier | 
					
						
							|  |  |  |  | func enable1344(jt *JumpTable) { | 
					
						
							|  |  |  |  | 	// New opcode | 
					
						
							| 
									
										
										
										
											2020-07-16 15:32:01 +03:00
										 |  |  |  | 	jt[CHAINID] = &operation{ | 
					
						
							| 
									
										
										
										
											2019-08-08 15:20:28 +02:00
										 |  |  |  | 		execute:     opChainID, | 
					
						
							|  |  |  |  | 		constantGas: GasQuickStep, | 
					
						
							|  |  |  |  | 		minStack:    minStack(0, 1), | 
					
						
							|  |  |  |  | 		maxStack:    maxStack(0, 1), | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // opChainID implements CHAINID opcode | 
					
						
							| 
									
										
										
										
											2021-03-25 10:13:14 +01:00
										 |  |  |  | func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  |  | 	chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID) | 
					
						
							| 
									
										
										
										
											2021-03-25 10:13:14 +01:00
										 |  |  |  | 	scope.Stack.push(chainId) | 
					
						
							| 
									
										
										
										
											2019-08-08 15:20:28 +02:00
										 |  |  |  | 	return nil, nil | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-08-19 14:39:38 +03:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // enable2200 applies EIP-2200 (Rebalance net-metered SSTORE) | 
					
						
							|  |  |  |  | func enable2200(jt *JumpTable) { | 
					
						
							| 
									
										
										
										
											2020-02-18 06:07:41 -08:00
										 |  |  |  | 	jt[SLOAD].constantGas = params.SloadGasEIP2200 | 
					
						
							| 
									
										
										
										
											2019-08-19 14:39:38 +03:00
										 |  |  |  | 	jt[SSTORE].dynamicGas = gasSStoreEIP2200 | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 08:26:57 +02:00
										 |  |  |  | // enable2929 enables "EIP-2929: Gas cost increases for state access opcodes" | 
					
						
							|  |  |  |  | // https://eips.ethereum.org/EIPS/eip-2929 | 
					
						
							|  |  |  |  | func enable2929(jt *JumpTable) { | 
					
						
							|  |  |  |  | 	jt[SSTORE].dynamicGas = gasSStoreEIP2929 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[SLOAD].constantGas = 0 | 
					
						
							|  |  |  |  | 	jt[SLOAD].dynamicGas = gasSLoadEIP2929 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[EXTCODECOPY].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[EXTCODESIZE].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[EXTCODEHASH].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[BALANCE].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[BALANCE].dynamicGas = gasEip2929AccountCheck | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[CALL].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[CALL].dynamicGas = gasCallEIP2929 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[CALLCODE].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[CALLCODE].dynamicGas = gasCallCodeEIP2929 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[STATICCALL].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[STATICCALL].dynamicGas = gasStaticCallEIP2929 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	jt[DELEGATECALL].constantGas = WarmStorageReadCostEIP2929 | 
					
						
							|  |  |  |  | 	jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// This was previously part of the dynamic cost, but we're using it as a constantGas | 
					
						
							|  |  |  |  | 	// factor here | 
					
						
							|  |  |  |  | 	jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150 | 
					
						
							|  |  |  |  | 	jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929 | 
					
						
							|  |  |  |  | } |