diff --git a/core/vm/common.go b/core/vm/common.go index 658803b820..c057f47e28 100644 --- a/core/vm/common.go +++ b/core/vm/common.go @@ -25,7 +25,7 @@ import ( // calcMemSize64 calculates the required memory size, and returns // the size and whether the result overflowed uint64 -func calcMemSize64(off, l *uint256.Int) (uint64, bool) { +func calcMemSize64(off, l uint256.Int) (uint64, bool) { if !l.IsUint64() { return 0, true } @@ -35,7 +35,7 @@ func calcMemSize64(off, l *uint256.Int) (uint64, bool) { // calcMemSize64WithUint calculates the required memory size, and returns // the size and whether the result overflowed uint64 // Identical to calcMemSize64, but length is a uint64 -func calcMemSize64WithUint(off *uint256.Int, length64 uint64) (uint64, bool) { +func calcMemSize64WithUint(off uint256.Int, length64 uint64) (uint64, bool) { // if length is zero, memsize is always zero, regardless of offset if length64 == 0 { return 0, false diff --git a/core/vm/gas.go b/core/vm/gas.go index 5fe589bce6..be16d0d281 100644 --- a/core/vm/gas.go +++ b/core/vm/gas.go @@ -35,7 +35,7 @@ const ( // // The cost of gas was changed during the homestead price change HF. // As part of EIP 150 (TangerineWhistle), the returned gas is gas - base * 63 / 64. -func callGas(isEip150 bool, availableGas, base uint64, callCost *uint256.Int) (uint64, error) { +func callGas(isEip150 bool, availableGas, base uint64, callCost uint256.Int) (uint64, error) { if isEip150 { availableGas = availableGas - base gas := availableGas - availableGas/64 diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 583ee20f44..3f5bcee35f 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -72,7 +72,8 @@ func memoryCopierGas(stackpos int) gasFunc { return 0, err } // And gas for copying data, charged per word at param.CopyGas - words, overflow := stack.Back(stackpos).Uint64WithOverflow() + size := stack.Back(stackpos) + words, overflow := size.Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -225,7 +226,8 @@ func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m func makeGasLog(n uint64) gasFunc { return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - requestedSize, overflow := stack.Back(1).Uint64WithOverflow() + size := stack.Back(1) + requestedSize, overflow := size.Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -258,7 +260,8 @@ func gasKeccak256(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor if err != nil { return 0, err } - wordGas, overflow := stack.Back(1).Uint64WithOverflow() + size := stack.Back(1) + wordGas, overflow := size.Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -292,7 +295,8 @@ func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memoryS if err != nil { return 0, err } - wordGas, overflow := stack.Back(2).Uint64WithOverflow() + length := stack.Back(2) + wordGas, overflow := length.Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -310,7 +314,8 @@ func gasCreateEip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m if err != nil { return 0, err } - size, overflow := stack.Back(2).Uint64WithOverflow() + length := stack.Back(2) + size, overflow := length.Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -329,7 +334,8 @@ func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if err != nil { return 0, err } - size, overflow := stack.Back(2).Uint64WithOverflow() + length := stack.Back(2) + size, overflow := length.Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -345,7 +351,8 @@ func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, } func gasExpFrontier(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - expByteLen := uint64((stack.Back(1).BitLen() + 7) / 8) + bytes := stack.Back(1) + expByteLen := uint64((bytes.BitLen() + 7) / 8) var ( gas = expByteLen * params.ExpByteFrontier // no overflow check required. Max is 256 * ExpByte gas @@ -358,7 +365,8 @@ func gasExpFrontier(evm *EVM, contract *Contract, stack *Stack, mem *Memory, mem } func gasExpEIP158(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - expByteLen := uint64((stack.Back(1).BitLen() + 7) / 8) + bytes := stack.Back(1) + expByteLen := uint64((bytes.BitLen() + 7) / 8) var ( gas = expByteLen * params.ExpByteEIP158 // no overflow check required. Max is 256 * ExpByte gas @@ -373,8 +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 - transfersValue = !stack.Back(2).IsZero() - address = common.Address(stack.Back(1).Bytes20()) + value, addr = stack.Back(2), stack.Back(1) + transfersValue = !value.IsZero() + address = common.Address(addr.Bytes20()) ) if evm.chainRules.IsEIP158 { if transfersValue && evm.StateDB.Empty(address) { @@ -419,18 +428,19 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory return 0, err } var ( - gas uint64 - overflow bool + gas uint64 + overflow bool + value, addr = stack.Back(2), stack.Back(1) ) - if stack.Back(2).Sign() != 0 && !evm.chainRules.IsEIP4762 { + if value.Sign() != 0 && !evm.chainRules.IsEIP4762 { gas += params.CallValueTransferGas } if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { return 0, ErrGasUintOverflow } if evm.chainRules.IsEIP4762 && !contract.IsSystemCall { - address := common.Address(stack.Back(1).Bytes20()) - transfersValue := !stack.Back(2).IsZero() + address := common.Address(addr.Bytes20()) + transfersValue := !value.IsZero() if transfersValue { gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address)) if overflow { @@ -485,7 +495,8 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me // EIP150 homestead gas reprice fork: if evm.chainRules.IsEIP150 { gas = params.SelfdestructGasEIP150 - var address = common.Address(stack.Back(0).Bytes20()) + addr := stack.Back(0) + var address = common.Address(addr.Bytes20()) if evm.chainRules.IsEIP158 { // if empty and transfers value diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go index 28746042cf..6d32f0be1e 100644 --- a/core/vm/memory_table.go +++ b/core/vm/memory_table.go @@ -50,8 +50,9 @@ func memoryMStore(stack *Stack) (uint64, bool) { func memoryMcopy(stack *Stack) (uint64, bool) { mStart := stack.Back(0) // stack[0]: dest - if stack.Back(1).Gt(mStart) { - mStart = stack.Back(1) // stack[1]: source + source := stack.Back(1) + if source.Gt(&mStart) { + mStart = source // stack[1]: source } return calcMemSize64(mStart, stack.Back(2)) // stack[2]: length } diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 98e2f64348..5a13f6bd0a 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -120,10 +120,11 @@ func gasExtCodeCopyEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memo if err != nil { return 0, err } - addr := common.Address(stack.Back(0).Bytes20()) + addr := stack.Back(0) + address := common.Address(addr.Bytes20()) // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(addr) { - evm.StateDB.AddAddressToAccessList(addr) + if !evm.StateDB.AddressInAccessList(address) { + evm.StateDB.AddAddressToAccessList(address) 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 { @@ -142,11 +143,12 @@ 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 := common.Address(stack.Back(0).Bytes20()) + addr := stack.Back(0) + address := common.Address(addr.Bytes20()) // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(addr) { + if !evm.StateDB.AddressInAccessList(address) { // If the caller cannot afford the cost, this change will be rolled back - evm.StateDB.AddAddressToAccessList(addr) + evm.StateDB.AddAddressToAccessList(address) // The warm storage read cost is already charged as constantGas return params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929, nil } @@ -155,14 +157,15 @@ 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 := common.Address(stack.Back(addressPosition).Bytes20()) + addr := stack.Back(addressPosition) + address := common.Address(addr.Bytes20()) // Check slot presence in the access list - warmAccess := evm.StateDB.AddressInAccessList(addr) + warmAccess := evm.StateDB.AddressInAccessList(address) // 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(addr) + evm.StateDB.AddAddressToAccessList(address) // Charge the remaining difference here already, to correctly calculate available // gas for call if !contract.UseGas(coldCost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { @@ -225,7 +228,8 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { gasFunc := func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( gas uint64 - address = common.Address(stack.Back(0).Bytes20()) + addr = stack.Back(0) + address = common.Address(addr.Bytes20()) ) if !evm.StateDB.AddressInAccessList(address) { // If the caller cannot afford the cost, this change will be rolled back @@ -254,13 +258,14 @@ 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 = common.Address(stack.Back(1).Bytes20()) + total uint64 // total dynamic gas used + addr = stack.Back(1) + address = common.Address(addr.Bytes20()) ) // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(addr) { - evm.StateDB.AddAddressToAccessList(addr) + if !evm.StateDB.AddressInAccessList(address) { + evm.StateDB.AddAddressToAccessList(address) // 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 @@ -273,7 +278,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(addr)); ok { + if target, ok := types.ParseDelegation(evm.StateDB.GetCode(address)); 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 168db7d0a8..c5a6c566ce 100644 --- a/core/vm/operations_verkle.go +++ b/core/vm/operations_verkle.go @@ -25,7 +25,8 @@ import ( ) func gasSStore4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas := evm.AccessEvents.SlotGas(contract.Address(), stack.Back(0).Bytes32(), true) + slot := stack.Back(0) + gas := evm.AccessEvents.SlotGas(contract.Address(), slot.Bytes32(), true) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -33,7 +34,8 @@ func gasSStore4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo } func gasSLoad4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas := evm.AccessEvents.SlotGas(contract.Address(), stack.Back(0).Bytes32(), false) + slot := stack.Back(0) + gas := evm.AccessEvents.SlotGas(contract.Address(), slot.Bytes32(), false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -44,7 +46,8 @@ func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, mem if contract.IsSystemCall { return 0, nil } - address := stack.peek().Bytes20() + addr := stack.Back(0) + address := addr.Bytes20() gas := evm.AccessEvents.BasicDataGas(address, false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 @@ -53,7 +56,8 @@ 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) { - address := stack.Back(0).Bytes20() + addr := stack.Back(0) + address := addr.Bytes20() if _, isPrecompile := evm.precompile(address); isPrecompile { return 0, nil } @@ -71,7 +75,8 @@ func gasExtCodeHash4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if contract.IsSystemCall { return 0, nil } - address := stack.peek().Bytes20() + addr := stack.Back(0) + address := addr.Bytes20() if _, isPrecompile := evm.precompile(address); isPrecompile { return 0, nil } @@ -110,7 +115,8 @@ var ( ) func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - beneficiaryAddr := common.Address(stack.Back(0).Bytes20()) + addr := stack.Back(0) + beneficiaryAddr := common.Address(addr.Bytes20()) if _, isPrecompile := evm.precompile(beneficiaryAddr); isPrecompile { return 0, nil } @@ -161,8 +167,9 @@ func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memo if contract.IsSystemCall { return gas, nil } - addr := common.Address(stack.peek().Bytes20()) - wgas := evm.AccessEvents.BasicDataGas(addr, false) + addr := stack.Back(0) + address := common.Address(addr.Bytes20()) + wgas := evm.AccessEvents.BasicDataGas(address, false) if wgas == 0 { wgas = params.WarmStorageReadCostEIP2929 } diff --git a/core/vm/stack.go b/core/vm/stack.go index 197c88b002..2dc1c80fb6 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -181,11 +181,7 @@ func (s *Stack) dup(n int) { s.size++ } -func (s *Stack) peek() *uint256.Int { - return &s.inner.data[s.bottom+s.size-1] -} - // Back returns the n'th item in stack -func (s *Stack) Back(n int) *uint256.Int { - return &s.inner.data[s.bottom+s.size-n-1] +func (s *Stack) Back(n int) uint256.Int { + return s.inner.data[s.bottom+s.size-n-1] }