github.com/ethereum/go-ethereum@v1.14.4-0.20240516095835-473ee8fc07a3/core/vm/operations_verkle.go (about) 1 // Copyright 2024 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/common/math" 22 "github.com/ethereum/go-ethereum/params" 23 ) 24 25 func gasSStore4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 26 gas := evm.AccessEvents.SlotGas(contract.Address(), stack.peek().Bytes32(), true) 27 if gas == 0 { 28 gas = params.WarmStorageReadCostEIP2929 29 } 30 return gas, nil 31 } 32 33 func gasSLoad4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 34 gas := evm.AccessEvents.SlotGas(contract.Address(), stack.peek().Bytes32(), false) 35 if gas == 0 { 36 gas = params.WarmStorageReadCostEIP2929 37 } 38 return gas, nil 39 } 40 41 func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 42 address := stack.peek().Bytes20() 43 gas := evm.AccessEvents.BalanceGas(address, false) 44 if gas == 0 { 45 gas = params.WarmStorageReadCostEIP2929 46 } 47 return gas, nil 48 } 49 50 func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 51 address := stack.peek().Bytes20() 52 if _, isPrecompile := evm.precompile(address); isPrecompile { 53 return 0, nil 54 } 55 gas := evm.AccessEvents.VersionGas(address, false) 56 gas += evm.AccessEvents.CodeSizeGas(address, false) 57 if gas == 0 { 58 gas = params.WarmStorageReadCostEIP2929 59 } 60 return gas, nil 61 } 62 63 func gasExtCodeHash4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 64 address := stack.peek().Bytes20() 65 if _, isPrecompile := evm.precompile(address); isPrecompile { 66 return 0, nil 67 } 68 gas := evm.AccessEvents.CodeHashGas(address, false) 69 if gas == 0 { 70 gas = params.WarmStorageReadCostEIP2929 71 } 72 return gas, nil 73 } 74 75 func makeCallVariantGasEIP4762(oldCalculator gasFunc) gasFunc { 76 return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 77 gas, err := oldCalculator(evm, contract, stack, mem, memorySize) 78 if err != nil { 79 return 0, err 80 } 81 if _, isPrecompile := evm.precompile(contract.Address()); isPrecompile { 82 return gas, nil 83 } 84 witnessGas := evm.AccessEvents.MessageCallGas(contract.Address()) 85 if witnessGas == 0 { 86 witnessGas = params.WarmStorageReadCostEIP2929 87 } 88 return witnessGas + gas, nil 89 } 90 } 91 92 var ( 93 gasCallEIP4762 = makeCallVariantGasEIP4762(gasCall) 94 gasCallCodeEIP4762 = makeCallVariantGasEIP4762(gasCallCode) 95 gasStaticCallEIP4762 = makeCallVariantGasEIP4762(gasStaticCall) 96 gasDelegateCallEIP4762 = makeCallVariantGasEIP4762(gasDelegateCall) 97 ) 98 99 func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 100 beneficiaryAddr := common.Address(stack.peek().Bytes20()) 101 if _, isPrecompile := evm.precompile(beneficiaryAddr); isPrecompile { 102 return 0, nil 103 } 104 contractAddr := contract.Address() 105 statelessGas := evm.AccessEvents.VersionGas(contractAddr, false) 106 statelessGas += evm.AccessEvents.CodeSizeGas(contractAddr, false) 107 statelessGas += evm.AccessEvents.BalanceGas(contractAddr, false) 108 if contractAddr != beneficiaryAddr { 109 statelessGas += evm.AccessEvents.BalanceGas(beneficiaryAddr, false) 110 } 111 // Charge write costs if it transfers value 112 if evm.StateDB.GetBalance(contractAddr).Sign() != 0 { 113 statelessGas += evm.AccessEvents.BalanceGas(contractAddr, true) 114 if contractAddr != beneficiaryAddr { 115 statelessGas += evm.AccessEvents.BalanceGas(beneficiaryAddr, true) 116 } 117 } 118 return statelessGas, nil 119 } 120 121 func gasCodeCopyEip4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 122 gas, err := gasCodeCopy(evm, contract, stack, mem, memorySize) 123 if err != nil { 124 return 0, err 125 } 126 var ( 127 codeOffset = stack.Back(1) 128 length = stack.Back(2) 129 ) 130 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 131 if overflow { 132 uint64CodeOffset = math.MaxUint64 133 } 134 _, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(contract.Code, uint64CodeOffset, length.Uint64()) 135 if !contract.IsDeployment { 136 gas += evm.AccessEvents.CodeChunksRangeGas(contract.Address(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) 137 } 138 return gas, nil 139 } 140 141 func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { 142 // memory expansion first (dynamic part of pre-2929 implementation) 143 gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize) 144 if err != nil { 145 return 0, err 146 } 147 addr := common.Address(stack.peek().Bytes20()) 148 wgas := evm.AccessEvents.VersionGas(addr, false) 149 wgas += evm.AccessEvents.CodeSizeGas(addr, false) 150 if wgas == 0 { 151 wgas = params.WarmStorageReadCostEIP2929 152 } 153 var overflow bool 154 // We charge (cold-warm), since 'warm' is already charged as constantGas 155 if gas, overflow = math.SafeAdd(gas, wgas); overflow { 156 return 0, ErrGasUintOverflow 157 } 158 return gas, nil 159 }