github.com/ethereum/go-ethereum@v1.14.4-0.20240516095835-473ee8fc07a3/core/vm/eips.go (about)

     1  // Copyright 2019 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  	"fmt"
    21  	"math"
    22  	"sort"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/core/tracing"
    26  	"github.com/ethereum/go-ethereum/params"
    27  	"github.com/holiman/uint256"
    28  )
    29  
    30  var activators = map[int]func(*JumpTable){
    31  	5656: enable5656,
    32  	6780: enable6780,
    33  	3855: enable3855,
    34  	3860: enable3860,
    35  	3529: enable3529,
    36  	3198: enable3198,
    37  	2929: enable2929,
    38  	2200: enable2200,
    39  	1884: enable1884,
    40  	1344: enable1344,
    41  	1153: enable1153,
    42  	4762: enable4762,
    43  }
    44  
    45  // EnableEIP enables the given EIP on the config.
    46  // This operation writes in-place, and callers need to ensure that the globally
    47  // defined jump tables are not polluted.
    48  func EnableEIP(eipNum int, jt *JumpTable) error {
    49  	enablerFn, ok := activators[eipNum]
    50  	if !ok {
    51  		return fmt.Errorf("undefined eip %d", eipNum)
    52  	}
    53  	enablerFn(jt)
    54  	return nil
    55  }
    56  
    57  func ValidEip(eipNum int) bool {
    58  	_, ok := activators[eipNum]
    59  	return ok
    60  }
    61  func ActivateableEips() []string {
    62  	var nums []string
    63  	for k := range activators {
    64  		nums = append(nums, fmt.Sprintf("%d", k))
    65  	}
    66  	sort.Strings(nums)
    67  	return nums
    68  }
    69  
    70  // enable1884 applies EIP-1884 to the given jump table:
    71  // - Increase cost of BALANCE to 700
    72  // - Increase cost of EXTCODEHASH to 700
    73  // - Increase cost of SLOAD to 800
    74  // - Define SELFBALANCE, with cost GasFastStep (5)
    75  func enable1884(jt *JumpTable) {
    76  	// Gas cost changes
    77  	jt[SLOAD].constantGas = params.SloadGasEIP1884
    78  	jt[BALANCE].constantGas = params.BalanceGasEIP1884
    79  	jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884
    80  
    81  	// New opcode
    82  	jt[SELFBALANCE] = &operation{
    83  		execute:     opSelfBalance,
    84  		constantGas: GasFastStep,
    85  		minStack:    minStack(0, 1),
    86  		maxStack:    maxStack(0, 1),
    87  	}
    88  }
    89  
    90  func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
    91  	balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
    92  	scope.Stack.push(balance)
    93  	return nil, nil
    94  }
    95  
    96  // enable1344 applies EIP-1344 (ChainID Opcode)
    97  // - Adds an opcode that returns the current chain’s EIP-155 unique identifier
    98  func enable1344(jt *JumpTable) {
    99  	// New opcode
   100  	jt[CHAINID] = &operation{
   101  		execute:     opChainID,
   102  		constantGas: GasQuickStep,
   103  		minStack:    minStack(0, 1),
   104  		maxStack:    maxStack(0, 1),
   105  	}
   106  }
   107  
   108  // opChainID implements CHAINID opcode
   109  func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   110  	chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID)
   111  	scope.Stack.push(chainId)
   112  	return nil, nil
   113  }
   114  
   115  // enable2200 applies EIP-2200 (Rebalance net-metered SSTORE)
   116  func enable2200(jt *JumpTable) {
   117  	jt[SLOAD].constantGas = params.SloadGasEIP2200
   118  	jt[SSTORE].dynamicGas = gasSStoreEIP2200
   119  }
   120  
   121  // enable2929 enables "EIP-2929: Gas cost increases for state access opcodes"
   122  // https://eips.ethereum.org/EIPS/eip-2929
   123  func enable2929(jt *JumpTable) {
   124  	jt[SSTORE].dynamicGas = gasSStoreEIP2929
   125  
   126  	jt[SLOAD].constantGas = 0
   127  	jt[SLOAD].dynamicGas = gasSLoadEIP2929
   128  
   129  	jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929
   130  	jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929
   131  
   132  	jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929
   133  	jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck
   134  
   135  	jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929
   136  	jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck
   137  
   138  	jt[BALANCE].constantGas = params.WarmStorageReadCostEIP2929
   139  	jt[BALANCE].dynamicGas = gasEip2929AccountCheck
   140  
   141  	jt[CALL].constantGas = params.WarmStorageReadCostEIP2929
   142  	jt[CALL].dynamicGas = gasCallEIP2929
   143  
   144  	jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929
   145  	jt[CALLCODE].dynamicGas = gasCallCodeEIP2929
   146  
   147  	jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929
   148  	jt[STATICCALL].dynamicGas = gasStaticCallEIP2929
   149  
   150  	jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929
   151  	jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929
   152  
   153  	// This was previously part of the dynamic cost, but we're using it as a constantGas
   154  	// factor here
   155  	jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150
   156  	jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929
   157  }
   158  
   159  // enable3529 enabled "EIP-3529: Reduction in refunds":
   160  // - Removes refunds for selfdestructs
   161  // - Reduces refunds for SSTORE
   162  // - Reduces max refunds to 20% gas
   163  func enable3529(jt *JumpTable) {
   164  	jt[SSTORE].dynamicGas = gasSStoreEIP3529
   165  	jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP3529
   166  }
   167  
   168  // enable3198 applies EIP-3198 (BASEFEE Opcode)
   169  // - Adds an opcode that returns the current block's base fee.
   170  func enable3198(jt *JumpTable) {
   171  	// New opcode
   172  	jt[BASEFEE] = &operation{
   173  		execute:     opBaseFee,
   174  		constantGas: GasQuickStep,
   175  		minStack:    minStack(0, 1),
   176  		maxStack:    maxStack(0, 1),
   177  	}
   178  }
   179  
   180  // enable1153 applies EIP-1153 "Transient Storage"
   181  // - Adds TLOAD that reads from transient storage
   182  // - Adds TSTORE that writes to transient storage
   183  func enable1153(jt *JumpTable) {
   184  	jt[TLOAD] = &operation{
   185  		execute:     opTload,
   186  		constantGas: params.WarmStorageReadCostEIP2929,
   187  		minStack:    minStack(1, 1),
   188  		maxStack:    maxStack(1, 1),
   189  	}
   190  
   191  	jt[TSTORE] = &operation{
   192  		execute:     opTstore,
   193  		constantGas: params.WarmStorageReadCostEIP2929,
   194  		minStack:    minStack(2, 0),
   195  		maxStack:    maxStack(2, 0),
   196  	}
   197  }
   198  
   199  // opTload implements TLOAD opcode
   200  func opTload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   201  	loc := scope.Stack.peek()
   202  	hash := common.Hash(loc.Bytes32())
   203  	val := interpreter.evm.StateDB.GetTransientState(scope.Contract.Address(), hash)
   204  	loc.SetBytes(val.Bytes())
   205  	return nil, nil
   206  }
   207  
   208  // opTstore implements TSTORE opcode
   209  func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   210  	if interpreter.readOnly {
   211  		return nil, ErrWriteProtection
   212  	}
   213  	loc := scope.Stack.pop()
   214  	val := scope.Stack.pop()
   215  	interpreter.evm.StateDB.SetTransientState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32())
   216  	return nil, nil
   217  }
   218  
   219  // opBaseFee implements BASEFEE opcode
   220  func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   221  	baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee)
   222  	scope.Stack.push(baseFee)
   223  	return nil, nil
   224  }
   225  
   226  // enable3855 applies EIP-3855 (PUSH0 opcode)
   227  func enable3855(jt *JumpTable) {
   228  	// New opcode
   229  	jt[PUSH0] = &operation{
   230  		execute:     opPush0,
   231  		constantGas: GasQuickStep,
   232  		minStack:    minStack(0, 1),
   233  		maxStack:    maxStack(0, 1),
   234  	}
   235  }
   236  
   237  // opPush0 implements the PUSH0 opcode
   238  func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   239  	scope.Stack.push(new(uint256.Int))
   240  	return nil, nil
   241  }
   242  
   243  // enable3860 enables "EIP-3860: Limit and meter initcode"
   244  // https://eips.ethereum.org/EIPS/eip-3860
   245  func enable3860(jt *JumpTable) {
   246  	jt[CREATE].dynamicGas = gasCreateEip3860
   247  	jt[CREATE2].dynamicGas = gasCreate2Eip3860
   248  }
   249  
   250  // enable5656 enables EIP-5656 (MCOPY opcode)
   251  // https://eips.ethereum.org/EIPS/eip-5656
   252  func enable5656(jt *JumpTable) {
   253  	jt[MCOPY] = &operation{
   254  		execute:     opMcopy,
   255  		constantGas: GasFastestStep,
   256  		dynamicGas:  gasMcopy,
   257  		minStack:    minStack(3, 0),
   258  		maxStack:    maxStack(3, 0),
   259  		memorySize:  memoryMcopy,
   260  	}
   261  }
   262  
   263  // opMcopy implements the MCOPY opcode (https://eips.ethereum.org/EIPS/eip-5656)
   264  func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   265  	var (
   266  		dst    = scope.Stack.pop()
   267  		src    = scope.Stack.pop()
   268  		length = scope.Stack.pop()
   269  	)
   270  	// These values are checked for overflow during memory expansion calculation
   271  	// (the memorySize function on the opcode).
   272  	scope.Memory.Copy(dst.Uint64(), src.Uint64(), length.Uint64())
   273  	return nil, nil
   274  }
   275  
   276  // opBlobHash implements the BLOBHASH opcode
   277  func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   278  	index := scope.Stack.peek()
   279  	if index.LtUint64(uint64(len(interpreter.evm.TxContext.BlobHashes))) {
   280  		blobHash := interpreter.evm.TxContext.BlobHashes[index.Uint64()]
   281  		index.SetBytes32(blobHash[:])
   282  	} else {
   283  		index.Clear()
   284  	}
   285  	return nil, nil
   286  }
   287  
   288  // opBlobBaseFee implements BLOBBASEFEE opcode
   289  func opBlobBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   290  	blobBaseFee, _ := uint256.FromBig(interpreter.evm.Context.BlobBaseFee)
   291  	scope.Stack.push(blobBaseFee)
   292  	return nil, nil
   293  }
   294  
   295  // enable4844 applies EIP-4844 (BLOBHASH opcode)
   296  func enable4844(jt *JumpTable) {
   297  	jt[BLOBHASH] = &operation{
   298  		execute:     opBlobHash,
   299  		constantGas: GasFastestStep,
   300  		minStack:    minStack(1, 1),
   301  		maxStack:    maxStack(1, 1),
   302  	}
   303  }
   304  
   305  // enable7516 applies EIP-7516 (BLOBBASEFEE opcode)
   306  func enable7516(jt *JumpTable) {
   307  	jt[BLOBBASEFEE] = &operation{
   308  		execute:     opBlobBaseFee,
   309  		constantGas: GasQuickStep,
   310  		minStack:    minStack(0, 1),
   311  		maxStack:    maxStack(0, 1),
   312  	}
   313  }
   314  
   315  // enable6780 applies EIP-6780 (deactivate SELFDESTRUCT)
   316  func enable6780(jt *JumpTable) {
   317  	jt[SELFDESTRUCT] = &operation{
   318  		execute:     opSelfdestruct6780,
   319  		dynamicGas:  gasSelfdestructEIP3529,
   320  		constantGas: params.SelfdestructGasEIP150,
   321  		minStack:    minStack(1, 0),
   322  		maxStack:    maxStack(1, 0),
   323  	}
   324  }
   325  
   326  func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   327  	var (
   328  		stack      = scope.Stack
   329  		a          = stack.pop()
   330  		memOffset  = stack.pop()
   331  		codeOffset = stack.pop()
   332  		length     = stack.pop()
   333  	)
   334  	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
   335  	if overflow {
   336  		uint64CodeOffset = math.MaxUint64
   337  	}
   338  	addr := common.Address(a.Bytes20())
   339  	code := interpreter.evm.StateDB.GetCode(addr)
   340  	contract := &Contract{
   341  		Code: code,
   342  		self: AccountRef(addr),
   343  	}
   344  	paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(code, uint64CodeOffset, length.Uint64())
   345  	statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false)
   346  	if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) {
   347  		scope.Contract.Gas = 0
   348  		return nil, ErrOutOfGas
   349  	}
   350  	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), paddedCodeCopy)
   351  
   352  	return nil, nil
   353  }
   354  
   355  // opPush1EIP4762 handles the special case of PUSH1 opcode for EIP-4762, which
   356  // need not worry about the adjusted bound logic when adding the PUSHDATA to
   357  // the list of access events.
   358  func opPush1EIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   359  	var (
   360  		codeLen = uint64(len(scope.Contract.Code))
   361  		integer = new(uint256.Int)
   362  	)
   363  	*pc += 1
   364  	if *pc < codeLen {
   365  		scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc])))
   366  
   367  		if !scope.Contract.IsDeployment && *pc%31 == 0 {
   368  			// touch next chunk if PUSH1 is at the boundary. if so, *pc has
   369  			// advanced past this boundary.
   370  			contractAddr := scope.Contract.Address()
   371  			statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, *pc+1, uint64(1), uint64(len(scope.Contract.Code)), false)
   372  			if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) {
   373  				scope.Contract.Gas = 0
   374  				return nil, ErrOutOfGas
   375  			}
   376  		}
   377  	} else {
   378  		scope.Stack.push(integer.Clear())
   379  	}
   380  	return nil, nil
   381  }
   382  
   383  func makePushEIP4762(size uint64, pushByteSize int) executionFunc {
   384  	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   385  		var (
   386  			codeLen = len(scope.Contract.Code)
   387  			start   = min(codeLen, int(*pc+1))
   388  			end     = min(codeLen, start+pushByteSize)
   389  		)
   390  		scope.Stack.push(new(uint256.Int).SetBytes(
   391  			common.RightPadBytes(
   392  				scope.Contract.Code[start:end],
   393  				pushByteSize,
   394  			)),
   395  		)
   396  
   397  		if !scope.Contract.IsDeployment {
   398  			contractAddr := scope.Contract.Address()
   399  			statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, uint64(start), uint64(pushByteSize), uint64(len(scope.Contract.Code)), false)
   400  			if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) {
   401  				scope.Contract.Gas = 0
   402  				return nil, ErrOutOfGas
   403  			}
   404  		}
   405  
   406  		*pc += size
   407  		return nil, nil
   408  	}
   409  }
   410  
   411  func enable4762(jt *JumpTable) {
   412  	jt[SSTORE] = &operation{
   413  		dynamicGas: gasSStore4762,
   414  		execute:    opSstore,
   415  		minStack:   minStack(2, 0),
   416  		maxStack:   maxStack(2, 0),
   417  	}
   418  	jt[SLOAD] = &operation{
   419  		dynamicGas: gasSLoad4762,
   420  		execute:    opSload,
   421  		minStack:   minStack(1, 1),
   422  		maxStack:   maxStack(1, 1),
   423  	}
   424  
   425  	jt[BALANCE] = &operation{
   426  		execute:    opBalance,
   427  		dynamicGas: gasBalance4762,
   428  		minStack:   minStack(1, 1),
   429  		maxStack:   maxStack(1, 1),
   430  	}
   431  
   432  	jt[EXTCODESIZE] = &operation{
   433  		execute:    opExtCodeSize,
   434  		dynamicGas: gasExtCodeSize4762,
   435  		minStack:   minStack(1, 1),
   436  		maxStack:   maxStack(1, 1),
   437  	}
   438  
   439  	jt[EXTCODEHASH] = &operation{
   440  		execute:    opExtCodeHash,
   441  		dynamicGas: gasExtCodeHash4762,
   442  		minStack:   minStack(1, 1),
   443  		maxStack:   maxStack(1, 1),
   444  	}
   445  
   446  	jt[EXTCODECOPY] = &operation{
   447  		execute:    opExtCodeCopyEIP4762,
   448  		dynamicGas: gasExtCodeCopyEIP4762,
   449  		minStack:   minStack(4, 0),
   450  		maxStack:   maxStack(4, 0),
   451  		memorySize: memoryExtCodeCopy,
   452  	}
   453  
   454  	jt[CODECOPY] = &operation{
   455  		execute:     opCodeCopy,
   456  		constantGas: GasFastestStep,
   457  		dynamicGas:  gasCodeCopyEip4762,
   458  		minStack:    minStack(3, 0),
   459  		maxStack:    maxStack(3, 0),
   460  		memorySize:  memoryCodeCopy,
   461  	}
   462  
   463  	jt[SELFDESTRUCT] = &operation{
   464  		execute:     opSelfdestruct6780,
   465  		dynamicGas:  gasSelfdestructEIP4762,
   466  		constantGas: params.SelfdestructGasEIP150,
   467  		minStack:    minStack(1, 0),
   468  		maxStack:    maxStack(1, 0),
   469  	}
   470  
   471  	jt[CREATE] = &operation{
   472  		execute:     opCreate,
   473  		constantGas: params.CreateNGasEip4762,
   474  		dynamicGas:  gasCreateEip3860,
   475  		minStack:    minStack(3, 1),
   476  		maxStack:    maxStack(3, 1),
   477  		memorySize:  memoryCreate,
   478  	}
   479  
   480  	jt[CREATE2] = &operation{
   481  		execute:     opCreate2,
   482  		constantGas: params.CreateNGasEip4762,
   483  		dynamicGas:  gasCreate2Eip3860,
   484  		minStack:    minStack(4, 1),
   485  		maxStack:    maxStack(4, 1),
   486  		memorySize:  memoryCreate2,
   487  	}
   488  
   489  	jt[CALL] = &operation{
   490  		execute:    opCall,
   491  		dynamicGas: gasCallEIP4762,
   492  		minStack:   minStack(7, 1),
   493  		maxStack:   maxStack(7, 1),
   494  		memorySize: memoryCall,
   495  	}
   496  
   497  	jt[CALLCODE] = &operation{
   498  		execute:    opCallCode,
   499  		dynamicGas: gasCallCodeEIP4762,
   500  		minStack:   minStack(7, 1),
   501  		maxStack:   maxStack(7, 1),
   502  		memorySize: memoryCall,
   503  	}
   504  
   505  	jt[STATICCALL] = &operation{
   506  		execute:    opStaticCall,
   507  		dynamicGas: gasStaticCallEIP4762,
   508  		minStack:   minStack(6, 1),
   509  		maxStack:   maxStack(6, 1),
   510  		memorySize: memoryStaticCall,
   511  	}
   512  
   513  	jt[DELEGATECALL] = &operation{
   514  		execute:    opDelegateCall,
   515  		dynamicGas: gasDelegateCallEIP4762,
   516  		minStack:   minStack(6, 1),
   517  		maxStack:   maxStack(6, 1),
   518  		memorySize: memoryDelegateCall,
   519  	}
   520  
   521  	jt[PUSH1] = &operation{
   522  		execute:     opPush1EIP4762,
   523  		constantGas: GasFastestStep,
   524  		minStack:    minStack(0, 1),
   525  		maxStack:    maxStack(0, 1),
   526  	}
   527  	for i := 1; i < 32; i++ {
   528  		jt[PUSH1+OpCode(i)] = &operation{
   529  			execute:     makePushEIP4762(uint64(i+1), i+1),
   530  			constantGas: GasFastestStep,
   531  			minStack:    minStack(0, 1),
   532  			maxStack:    maxStack(0, 1),
   533  		}
   534  	}
   535  }