mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
parent
fcd9685c87
commit
3742ed7f2f
3 changed files with 33 additions and 15 deletions
|
|
@ -98,6 +98,9 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
if evm.readOnly {
|
||||||
|
return 0, ErrWriteProtection
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
y, x = stack.Back(1), stack.Back(0)
|
y, x = stack.Back(1), stack.Back(0)
|
||||||
current = evm.StateDB.GetState(contract.Address(), x.Bytes32())
|
current = evm.StateDB.GetState(contract.Address(), x.Bytes32())
|
||||||
|
|
@ -180,6 +183,9 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi
|
||||||
// 2.2.2.1. If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter.
|
// 2.2.2.1. If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter.
|
||||||
// 2.2.2.2. Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter.
|
// 2.2.2.2. Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter.
|
||||||
func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
if evm.readOnly {
|
||||||
|
return 0, ErrWriteProtection
|
||||||
|
}
|
||||||
// If we fail the minimum gas availability invariant, fail (0)
|
// If we fail the minimum gas availability invariant, fail (0)
|
||||||
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
||||||
return 0, errors.New("not enough gas for reentrancy sentry")
|
return 0, errors.New("not enough gas for reentrancy sentry")
|
||||||
|
|
@ -375,6 +381,10 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
|
||||||
transfersValue = !stack.Back(2).IsZero()
|
transfersValue = !stack.Back(2).IsZero()
|
||||||
address = common.Address(stack.Back(1).Bytes20())
|
address = common.Address(stack.Back(1).Bytes20())
|
||||||
)
|
)
|
||||||
|
if evm.readOnly && transfersValue {
|
||||||
|
return 0, ErrWriteProtection
|
||||||
|
}
|
||||||
|
|
||||||
if evm.chainRules.IsEIP158 {
|
if evm.chainRules.IsEIP158 {
|
||||||
if transfersValue && evm.StateDB.Empty(address) {
|
if transfersValue && evm.StateDB.Empty(address) {
|
||||||
gas += params.CallNewAccountGas
|
gas += params.CallNewAccountGas
|
||||||
|
|
@ -462,6 +472,10 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
if evm.readOnly {
|
||||||
|
return 0, ErrWriteProtection
|
||||||
|
}
|
||||||
|
|
||||||
var gas uint64
|
var gas uint64
|
||||||
// EIP150 homestead gas reprice fork:
|
// EIP150 homestead gas reprice fork:
|
||||||
if evm.chainRules.IsEIP150 {
|
if evm.chainRules.IsEIP150 {
|
||||||
|
|
|
||||||
|
|
@ -526,9 +526,6 @@ func opSload(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSstore(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
func opSstore(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
if evm.readOnly {
|
|
||||||
return nil, ErrWriteProtection
|
|
||||||
}
|
|
||||||
loc := scope.Stack.pop()
|
loc := scope.Stack.pop()
|
||||||
val := scope.Stack.pop()
|
val := scope.Stack.pop()
|
||||||
evm.StateDB.SetState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32())
|
evm.StateDB.SetState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32())
|
||||||
|
|
@ -680,10 +677,6 @@ func opCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
// Get the arguments from the memory.
|
// Get the arguments from the memory.
|
||||||
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||||
|
|
||||||
if evm.readOnly && !value.IsZero() {
|
|
||||||
return nil, ErrWriteProtection
|
|
||||||
}
|
|
||||||
|
|
||||||
var bigVal = big0
|
var bigVal = big0
|
||||||
// TODO(daniel): use uint256.Int instead of converting with toBig()
|
// TODO(daniel): use uint256.Int instead of converting with toBig()
|
||||||
// By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls),
|
// By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls),
|
||||||
|
|
@ -692,7 +685,6 @@ func opCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
gas += params.CallStipend
|
gas += params.CallStipend
|
||||||
bigVal = value.ToBig()
|
bigVal = value.ToBig()
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, returnGas, err := evm.Call(scope.Contract, toAddr, args, gas, bigVal)
|
ret, returnGas, err := evm.Call(scope.Contract, toAddr, args, gas, bigVal)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -829,9 +821,6 @@ func opStop(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSelfdestruct(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
func opSelfdestruct(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
if evm.readOnly {
|
|
||||||
return nil, ErrWriteProtection
|
|
||||||
}
|
|
||||||
beneficiary := scope.Stack.pop()
|
beneficiary := scope.Stack.pop()
|
||||||
balance := evm.StateDB.GetBalance(scope.Contract.Address())
|
balance := evm.StateDB.GetBalance(scope.Contract.Address())
|
||||||
evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct)
|
evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct)
|
||||||
|
|
@ -848,9 +837,6 @@ func opSelfdestruct(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSelfdestruct6780(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
func opSelfdestruct6780(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
if evm.readOnly {
|
|
||||||
return nil, ErrWriteProtection
|
|
||||||
}
|
|
||||||
beneficiary := scope.Stack.pop()
|
beneficiary := scope.Stack.pop()
|
||||||
balance := evm.StateDB.GetBalance(scope.Contract.Address())
|
balance := evm.StateDB.GetBalance(scope.Contract.Address())
|
||||||
evm.StateDB.SubBalance(scope.Contract.Address(), balance, tracing.BalanceDecreaseSelfdestruct)
|
evm.StateDB.SubBalance(scope.Contract.Address(), balance, tracing.BalanceDecreaseSelfdestruct)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ import (
|
||||||
|
|
||||||
func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
||||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
if evm.readOnly {
|
||||||
|
return 0, ErrWriteProtection
|
||||||
|
}
|
||||||
// If we fail the minimum gas availability invariant, fail (0)
|
// If we fail the minimum gas availability invariant, fail (0)
|
||||||
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
||||||
return 0, errors.New("not enough gas for reentrancy sentry")
|
return 0, errors.New("not enough gas for reentrancy sentry")
|
||||||
|
|
@ -233,6 +236,9 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
|
||||||
gas uint64
|
gas uint64
|
||||||
address = common.Address(stack.peek().Bytes20())
|
address = common.Address(stack.peek().Bytes20())
|
||||||
)
|
)
|
||||||
|
if evm.readOnly {
|
||||||
|
return 0, ErrWriteProtection
|
||||||
|
}
|
||||||
if !evm.StateDB.AddressInAccessList(address) {
|
if !evm.StateDB.AddressInAccessList(address) {
|
||||||
// If the caller cannot afford the cost, this change will be rolled back
|
// If the caller cannot afford the cost, this change will be rolled back
|
||||||
evm.StateDB.AddAddressToAccessList(address)
|
evm.StateDB.AddAddressToAccessList(address)
|
||||||
|
|
@ -255,12 +261,24 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
gasCallEIP7702 = makeCallVariantGasCallEIP7702(gasCall)
|
innerGasCallEIP7702 = makeCallVariantGasCallEIP7702(gasCall)
|
||||||
gasDelegateCallEIP7702 = makeCallVariantGasCallEIP7702(gasDelegateCall)
|
gasDelegateCallEIP7702 = makeCallVariantGasCallEIP7702(gasDelegateCall)
|
||||||
gasStaticCallEIP7702 = makeCallVariantGasCallEIP7702(gasStaticCall)
|
gasStaticCallEIP7702 = makeCallVariantGasCallEIP7702(gasStaticCall)
|
||||||
gasCallCodeEIP7702 = makeCallVariantGasCallEIP7702(gasCallCode)
|
gasCallCodeEIP7702 = makeCallVariantGasCallEIP7702(gasCallCode)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func gasCallEIP7702(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
// Return early if this call attempts to transfer value in a static context.
|
||||||
|
// Although it's checked in `gasCall`, EIP-7702 loads the target's code before
|
||||||
|
// to determine if it is resolving a delegation. This could incorrectly record
|
||||||
|
// the target in the block access list (BAL) if the call later fails.
|
||||||
|
transfersValue := !stack.Back(2).IsZero()
|
||||||
|
if evm.readOnly && transfersValue {
|
||||||
|
return 0, ErrWriteProtection
|
||||||
|
}
|
||||||
|
return innerGasCallEIP7702(evm, contract, stack, mem, memorySize)
|
||||||
|
}
|
||||||
|
|
||||||
func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
|
func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
|
||||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue