github.com/MetalBlockchain/subnet-evm@v0.4.9/core/vm/eips.go (about) 1 // (c) 2019-2020, Ava Labs, Inc. 2 // 3 // This file is a derived work, based on the go-ethereum library whose original 4 // notices appear below. 5 // 6 // It is distributed under a license compatible with the licensing terms of the 7 // original code from which it is derived. 8 // 9 // Much love to the original authors for their work. 10 // ********** 11 // Copyright 2019 The go-ethereum Authors 12 // This file is part of the go-ethereum library. 13 // 14 // The go-ethereum library is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published by 16 // the Free Software Foundation, either version 3 of the License, or 17 // (at your option) any later version. 18 // 19 // The go-ethereum library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 26 27 package vm 28 29 import ( 30 "fmt" 31 "sort" 32 33 "github.com/MetalBlockchain/subnet-evm/params" 34 "github.com/holiman/uint256" 35 ) 36 37 var activators = map[int]func(*JumpTable){ 38 3855: enable3855, 39 3198: enable3198, 40 2929: enable2929, 41 2200: enable2200, 42 1884: enable1884, 43 1344: enable1344, 44 } 45 46 // EnableEIP enables the given EIP on the config. 47 // This operation writes in-place, and callers need to ensure that the globally 48 // defined jump tables are not polluted. 49 func EnableEIP(eipNum int, jt *JumpTable) error { 50 enablerFn, ok := activators[eipNum] 51 if !ok { 52 return fmt.Errorf("undefined eip %d", eipNum) 53 } 54 enablerFn(jt) 55 return nil 56 } 57 58 func ValidEip(eipNum int) bool { 59 _, ok := activators[eipNum] 60 return ok 61 } 62 func ActivateableEips() []string { 63 var nums []string 64 for k := range activators { 65 nums = append(nums, fmt.Sprintf("%d", k)) 66 } 67 sort.Strings(nums) 68 return nums 69 } 70 71 // enable1884 applies EIP-1884 to the given jump table: 72 // - Increase cost of BALANCE to 700 73 // - Increase cost of EXTCODEHASH to 700 74 // - Increase cost of SLOAD to 800 75 // - Define SELFBALANCE, with cost GasFastStep (5) 76 func enable1884(jt *JumpTable) { 77 // Gas cost changes 78 jt[SLOAD].constantGas = params.SloadGasEIP1884 79 jt[BALANCE].constantGas = params.BalanceGasEIP1884 80 jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 81 82 // New opcode 83 jt[SELFBALANCE] = &operation{ 84 execute: opSelfBalance, 85 constantGas: GasFastStep, 86 minStack: minStack(0, 1), 87 maxStack: maxStack(0, 1), 88 } 89 } 90 91 func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 92 balance, _ := uint256.FromBig(interpreter.evm.StateDB.GetBalance(scope.Contract.Address())) 93 scope.Stack.push(balance) 94 return nil, nil 95 } 96 97 // enable1344 applies EIP-1344 (ChainID Opcode) 98 // - Adds an opcode that returns the current chain’s EIP-155 unique identifier 99 func enable1344(jt *JumpTable) { 100 // New opcode 101 jt[CHAINID] = &operation{ 102 execute: opChainID, 103 constantGas: GasQuickStep, 104 minStack: minStack(0, 1), 105 maxStack: maxStack(0, 1), 106 } 107 } 108 109 // opChainID implements CHAINID opcode 110 func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 111 chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID) 112 scope.Stack.push(chainId) 113 return nil, nil 114 } 115 116 // enable2200 applies EIP-2200 (Rebalance net-metered SSTORE) 117 func enable2200(jt *JumpTable) { 118 jt[SLOAD].constantGas = params.SloadGasEIP2200 119 jt[SSTORE].dynamicGas = gasSStoreEIP2200 120 } 121 122 // enable2929 enables "EIP-2929: Gas cost increases for state access opcodes" 123 // https://eips.ethereum.org/EIPS/eip-2929 124 func enable2929(jt *JumpTable) { 125 jt[SSTORE].dynamicGas = gasSStoreEIP2929 126 127 jt[SLOAD].constantGas = 0 128 jt[SLOAD].dynamicGas = gasSLoadEIP2929 129 130 jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929 131 jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929 132 133 jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929 134 jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck 135 136 jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929 137 jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck 138 139 jt[BALANCE].constantGas = params.WarmStorageReadCostEIP2929 140 jt[BALANCE].dynamicGas = gasEip2929AccountCheck 141 142 jt[CALL].constantGas = params.WarmStorageReadCostEIP2929 143 jt[CALL].dynamicGas = gasCallEIP2929 144 145 jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929 146 jt[CALLCODE].dynamicGas = gasCallCodeEIP2929 147 148 jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929 149 jt[STATICCALL].dynamicGas = gasStaticCallEIP2929 150 151 jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929 152 jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929 153 154 // This was previously part of the dynamic cost, but we're using it as a constantGas 155 // factor here 156 jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150 157 jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929 158 } 159 160 // enable3198 applies EIP-3198 (BASEFEE Opcode) 161 // - Adds an opcode that returns the current block's base fee. 162 func enable3198(jt *JumpTable) { 163 // New opcode 164 jt[BASEFEE] = &operation{ 165 execute: opBaseFee, 166 constantGas: GasQuickStep, 167 minStack: minStack(0, 1), 168 maxStack: maxStack(0, 1), 169 } 170 } 171 172 // opBaseFee implements BASEFEE opcode 173 func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 174 baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee) 175 scope.Stack.push(baseFee) 176 return nil, nil 177 } 178 179 // enable3855 applies EIP-3855 (PUSH0 opcode) 180 func enable3855(jt *JumpTable) { 181 // New opcode 182 jt[PUSH0] = &operation{ 183 execute: opPush0, 184 constantGas: GasQuickStep, 185 minStack: minStack(0, 1), 186 maxStack: maxStack(0, 1), 187 } 188 } 189 190 // opPush0 implements the PUSH0 opcode 191 func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 192 scope.Stack.push(new(uint256.Int)) 193 return nil, nil 194 }