diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 3f5bcee35f..2334cae5af 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -381,9 +381,9 @@ func gasExpEIP158(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( gas uint64 - value, addr = stack.Back(2), stack.Back(1) + value = stack.Back(2) transfersValue = !value.IsZero() - address = common.Address(addr.Bytes20()) + address = stack.Address(1) ) if evm.chainRules.IsEIP158 { if transfersValue && evm.StateDB.Empty(address) { @@ -428,9 +428,9 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory return 0, err } var ( - gas uint64 - overflow bool - value, addr = stack.Back(2), stack.Back(1) + gas uint64 + overflow bool + value = stack.Back(2) ) if value.Sign() != 0 && !evm.chainRules.IsEIP4762 { gas += params.CallValueTransferGas @@ -439,7 +439,7 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory return 0, ErrGasUintOverflow } if evm.chainRules.IsEIP4762 && !contract.IsSystemCall { - address := common.Address(addr.Bytes20()) + address := stack.Address(1) transfersValue := !value.IsZero() if transfersValue { gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address)) @@ -495,8 +495,7 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me // EIP150 homestead gas reprice fork: if evm.chainRules.IsEIP150 { gas = params.SelfdestructGasEIP150 - addr := stack.Back(0) - var address = common.Address(addr.Bytes20()) + var address = stack.Address(0) if evm.chainRules.IsEIP158 { // if empty and transfers value diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 5a13f6bd0a..ecfd1614f3 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -120,11 +120,10 @@ func gasExtCodeCopyEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memo if err != nil { return 0, err } - addr := stack.Back(0) - address := common.Address(addr.Bytes20()) + addr := stack.Address(0) // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(address) { - evm.StateDB.AddAddressToAccessList(address) + if !evm.StateDB.AddressInAccessList(addr) { + evm.StateDB.AddAddressToAccessList(addr) var overflow bool // We charge (cold-warm), since 'warm' is already charged as constantGas if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929-params.WarmStorageReadCostEIP2929); overflow { @@ -143,12 +142,11 @@ func gasExtCodeCopyEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memo // - extcodesize, // - (ext) balance func gasEip2929AccountCheck(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - addr := stack.Back(0) - address := common.Address(addr.Bytes20()) + addr := stack.Address(0) // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(address) { + if !evm.StateDB.AddressInAccessList(addr) { // If the caller cannot afford the cost, this change will be rolled back - evm.StateDB.AddAddressToAccessList(address) + evm.StateDB.AddAddressToAccessList(addr) // The warm storage read cost is already charged as constantGas return params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929, nil } @@ -157,15 +155,14 @@ func gasEip2929AccountCheck(evm *EVM, contract *Contract, stack *Stack, mem *Mem func makeCallVariantGasCallEIP2929(oldCalculator gasFunc, addressPosition int) gasFunc { return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - addr := stack.Back(addressPosition) - address := common.Address(addr.Bytes20()) + addr := stack.Address(addressPosition) // Check slot presence in the access list - warmAccess := evm.StateDB.AddressInAccessList(address) + warmAccess := evm.StateDB.AddressInAccessList(addr) // The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so // the cost to charge for cold access, if any, is Cold - Warm coldCost := params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929 if !warmAccess { - evm.StateDB.AddAddressToAccessList(address) + evm.StateDB.AddAddressToAccessList(addr) // Charge the remaining difference here already, to correctly calculate available // gas for call if !contract.UseGas(coldCost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { @@ -227,17 +224,16 @@ var ( func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { gasFunc := func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( - gas uint64 - addr = stack.Back(0) - address = common.Address(addr.Bytes20()) + gas uint64 + addr = stack.Address(0) ) - if !evm.StateDB.AddressInAccessList(address) { + if !evm.StateDB.AddressInAccessList(addr) { // If the caller cannot afford the cost, this change will be rolled back - evm.StateDB.AddAddressToAccessList(address) + evm.StateDB.AddAddressToAccessList(addr) gas = params.ColdAccountAccessCostEIP2929 } // if empty and transfers value - if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { + if evm.StateDB.Empty(addr) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { gas += params.CreateBySelfdestructGas } if refundsEnabled && !evm.StateDB.HasSelfDestructed(contract.Address()) { @@ -258,14 +254,13 @@ var ( func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc { return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( - total uint64 // total dynamic gas used - addr = stack.Back(1) - address = common.Address(addr.Bytes20()) + total uint64 // total dynamic gas used + addr = stack.Address(1) ) // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(address) { - evm.StateDB.AddAddressToAccessList(address) + if !evm.StateDB.AddressInAccessList(addr) { + evm.StateDB.AddAddressToAccessList(addr) // The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so // the cost to charge for cold access, if any, is Cold - Warm coldCost := params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929 @@ -278,7 +273,7 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc { } // Check if code is a delegation and if so, charge for resolution. - if target, ok := types.ParseDelegation(evm.StateDB.GetCode(address)); ok { + if target, ok := types.ParseDelegation(evm.StateDB.GetCode(addr)); ok { var cost uint64 if evm.StateDB.AddressInAccessList(target) { cost = params.WarmStorageReadCostEIP2929 diff --git a/core/vm/operations_verkle.go b/core/vm/operations_verkle.go index c5a6c566ce..ae6881de9a 100644 --- a/core/vm/operations_verkle.go +++ b/core/vm/operations_verkle.go @@ -19,7 +19,6 @@ package vm import ( gomath "math" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/params" ) @@ -46,9 +45,8 @@ func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, mem if contract.IsSystemCall { return 0, nil } - addr := stack.Back(0) - address := addr.Bytes20() - gas := evm.AccessEvents.BasicDataGas(address, false) + addr := stack.Address(0) + gas := evm.AccessEvents.BasicDataGas(addr, false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -56,15 +54,14 @@ func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, mem } func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - addr := stack.Back(0) - address := addr.Bytes20() - if _, isPrecompile := evm.precompile(address); isPrecompile { + addr := stack.Address(0) + if _, isPrecompile := evm.precompile(addr); isPrecompile { return 0, nil } if contract.IsSystemCall { return 0, nil } - gas := evm.AccessEvents.BasicDataGas(address, false) + gas := evm.AccessEvents.BasicDataGas(addr, false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -75,12 +72,11 @@ func gasExtCodeHash4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if contract.IsSystemCall { return 0, nil } - addr := stack.Back(0) - address := addr.Bytes20() - if _, isPrecompile := evm.precompile(address); isPrecompile { + addr := stack.Address(0) + if _, isPrecompile := evm.precompile(addr); isPrecompile { return 0, nil } - gas := evm.AccessEvents.CodeHashGas(address, false) + gas := evm.AccessEvents.CodeHashGas(addr, false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -115,8 +111,7 @@ var ( ) func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - addr := stack.Back(0) - beneficiaryAddr := common.Address(addr.Bytes20()) + beneficiaryAddr := stack.Address(0) if _, isPrecompile := evm.precompile(beneficiaryAddr); isPrecompile { return 0, nil } @@ -167,9 +162,8 @@ func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memo if contract.IsSystemCall { return gas, nil } - addr := stack.Back(0) - address := common.Address(addr.Bytes20()) - wgas := evm.AccessEvents.BasicDataGas(address, false) + addr := stack.Address(0) + wgas := evm.AccessEvents.BasicDataGas(addr, false) if wgas == 0 { wgas = params.WarmStorageReadCostEIP2929 } diff --git a/core/vm/stack.go b/core/vm/stack.go index 2dc1c80fb6..848b5745f0 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -19,6 +19,7 @@ package vm import ( "slices" + "github.com/ethereum/go-ethereum/common" "github.com/holiman/uint256" ) @@ -185,3 +186,8 @@ func (s *Stack) dup(n int) { func (s *Stack) Back(n int) uint256.Int { return s.inner.data[s.bottom+s.size-n-1] } + +// Address returns the n'th item in stack turned into an address +func (s *Stack) Address(n int) common.Address { + return common.Address(s.inner.data[s.bottom+s.size-n-1].Bytes20()) +}