mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 13:46:43 +00:00
core/vm: interpreter loop generator PoC
This commit is contained in:
parent
f17df6db91
commit
ae63a92d08
8 changed files with 705 additions and 302 deletions
|
|
@ -18,7 +18,7 @@ package vm
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
stdmath "math"
|
||||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -352,7 +352,7 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
|
|||
)
|
||||
uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
|
||||
if overflow {
|
||||
uint64CodeOffset = math.MaxUint64
|
||||
uint64CodeOffset = stdmath.MaxUint64
|
||||
}
|
||||
addr := common.Address(a.Bytes20())
|
||||
code := interpreter.evm.StateDB.GetCode(addr)
|
||||
|
|
|
|||
|
|
@ -64,8 +64,7 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
|
|||
// MCOPY (stack position 2)
|
||||
// EXTCODECOPY (stack position 3)
|
||||
// RETURNDATACOPY (stack position 2)
|
||||
func memoryCopierGas(stackpos int) gasFunc {
|
||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
func memoryCopierGas(stackpos int, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
// Gas for expanding the memory
|
||||
gas, err := memoryGasCost(mem, memorySize)
|
||||
if err != nil {
|
||||
|
|
@ -85,16 +84,23 @@ func memoryCopierGas(stackpos int) gasFunc {
|
|||
return 0, ErrGasUintOverflow
|
||||
}
|
||||
return gas, nil
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
gasCallDataCopy = memoryCopierGas(2)
|
||||
gasCodeCopy = memoryCopierGas(2)
|
||||
gasMcopy = memoryCopierGas(2)
|
||||
gasExtCodeCopy = memoryCopierGas(3)
|
||||
gasReturnDataCopy = memoryCopierGas(2)
|
||||
)
|
||||
func gasCallDataCopy(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return memoryCopierGas(2, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasCodeCopy(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return memoryCopierGas(2, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasMcopy(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return memoryCopierGas(2, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasExtCodeCopy(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return memoryCopierGas(3, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasReturnDataCopy(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return memoryCopierGas(2, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
|
||||
func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
var (
|
||||
|
|
@ -221,8 +227,7 @@ func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m
|
|||
return params.SloadGasEIP2200, nil // dirty update (2.2)
|
||||
}
|
||||
|
||||
func makeGasLog(n uint64) gasFunc {
|
||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
func makeGasLog(n uint64, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
requestedSize, overflow := stack.Back(1).Uint64WithOverflow()
|
||||
if overflow {
|
||||
return 0, ErrGasUintOverflow
|
||||
|
|
@ -248,7 +253,22 @@ func makeGasLog(n uint64) gasFunc {
|
|||
return 0, ErrGasUintOverflow
|
||||
}
|
||||
return gas, nil
|
||||
}
|
||||
}
|
||||
|
||||
func gasLog0(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeGasLog(0, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasLog1(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeGasLog(1, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasLog2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeGasLog(2, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasLog3(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeGasLog(3, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasLog4(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeGasLog(4, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
|
||||
func gasKeccak256(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
|
|
|
|||
217
core/vm/generator.go
Normal file
217
core/vm/generator.go
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var fSet = token.NewFileSet()
|
||||
|
||||
type opFuncNames struct {
|
||||
memory string
|
||||
gas string
|
||||
execution string
|
||||
}
|
||||
|
||||
func functionName(f any) string {
|
||||
fValue := reflect.ValueOf(f)
|
||||
if fValue.IsNil() {
|
||||
return ""
|
||||
}
|
||||
|
||||
rFunc := runtime.FuncForPC(fValue.Pointer())
|
||||
if rFunc == nil {
|
||||
panic(fmt.Sprint(f, "is not a function"))
|
||||
}
|
||||
ident := rFunc.Name()
|
||||
arr := strings.Split(ident, ".")
|
||||
return arr[len(arr)-1]
|
||||
}
|
||||
|
||||
func collectFuncNames(jt JumpTable) [256]opFuncNames {
|
||||
var funcNames [256]opFuncNames
|
||||
for opCode, entry := range jt {
|
||||
funcNames[opCode] = opFuncNames{
|
||||
memory: functionName(entry.memorySize),
|
||||
gas: functionName(entry.dynamicGas),
|
||||
execution: functionName(entry.execute),
|
||||
}
|
||||
}
|
||||
return funcNames
|
||||
}
|
||||
|
||||
type funcDef struct {
|
||||
decl *ast.FuncDecl
|
||||
source string
|
||||
}
|
||||
|
||||
type opFuncDefs struct {
|
||||
memory funcDef
|
||||
gas funcDef
|
||||
execution funcDef
|
||||
}
|
||||
|
||||
func definitionTargets(name string, funcNames *[256]opFuncNames, funcDefs *[256]opFuncDefs) []*funcDef {
|
||||
targets := []*funcDef{}
|
||||
for op := range funcNames {
|
||||
if funcNames[op].memory == name {
|
||||
targets = append(targets, &funcDefs[op].memory)
|
||||
}
|
||||
if funcNames[op].gas == name {
|
||||
targets = append(targets, &funcDefs[op].gas)
|
||||
}
|
||||
if funcNames[op].execution == name {
|
||||
targets = append(targets, &funcDefs[op].execution)
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
func extractBody(funcDef string) string {
|
||||
start := strings.Index(funcDef, "{")
|
||||
end := strings.LastIndex(funcDef, "}")
|
||||
return funcDef[start : end+1]
|
||||
}
|
||||
|
||||
func collectFuncDefinitions(funcNames [256]opFuncNames) [256]opFuncDefs {
|
||||
pkgs, err := parser.ParseDir(fSet, ".", nil, 0)
|
||||
if err != nil {
|
||||
panic(fmt.Sprint("failed to parse vm package", err))
|
||||
}
|
||||
vmPkg := pkgs["vm"]
|
||||
if vmPkg == nil {
|
||||
panic(fmt.Sprint("vm package not found"))
|
||||
}
|
||||
|
||||
var defs [256]opFuncDefs
|
||||
for _, astFile := range vmPkg.Files {
|
||||
f, err := os.Open(fSet.File(astFile.FileStart).Name())
|
||||
if err != nil {
|
||||
panic(fmt.Sprint("failed to open file package", astFile.Name.Name, err))
|
||||
}
|
||||
|
||||
for _, decl := range astFile.Decls {
|
||||
if fDecl, isFunc := decl.(*ast.FuncDecl); isFunc {
|
||||
defTargets := definitionTargets(fDecl.Name.Name, &funcNames, &defs)
|
||||
if len(defTargets) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
declPos := fSet.Position(fDecl.Pos())
|
||||
declEndPos := fSet.Position(fDecl.End())
|
||||
declSize := declEndPos.Offset - declPos.Offset
|
||||
|
||||
def := make([]byte, declSize)
|
||||
_, err := f.ReadAt(def, int64(declPos.Offset))
|
||||
if err != nil && err != io.EOF {
|
||||
panic(fmt.Sprint("failed to read function def", fDecl.Name.Name, err))
|
||||
}
|
||||
|
||||
for _, defTarget := range defTargets {
|
||||
(*defTarget) = funcDef{
|
||||
source: string(def),
|
||||
decl: fDecl,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return defs
|
||||
}
|
||||
|
||||
func outputMemoryCalc(w io.Writer, op *funcDef) {
|
||||
fmt.Fprintf(w, `
|
||||
_memorySize, _overflow := func (stack *Stack) (uint64, bool) %s(callContext.Stack)
|
||||
if _overflow {
|
||||
return nil, ErrGasUintOverflow
|
||||
}
|
||||
`, extractBody(op.source))
|
||||
}
|
||||
|
||||
func outputDynamicGas(w io.Writer, op *funcDef, hasDynamicMemory bool) {
|
||||
dynamicMemory := "0"
|
||||
if hasDynamicMemory {
|
||||
dynamicMemory = "_memorySize"
|
||||
}
|
||||
fmt.Fprintf(w, `
|
||||
_dynamicGas, _gasErr := func (evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) %s(interpreter.evm, callContext.Contract, callContext.Stack, callContext.Memory, %s)
|
||||
if _gasErr != nil {
|
||||
return nil, ErrOutOfGas
|
||||
}
|
||||
if !callContext.Contract.UseGas(_dynamicGas, nil, tracing.GasChangeIgnored) {
|
||||
return nil, ErrOutOfGas
|
||||
}
|
||||
|
||||
`, extractBody(op.source), dynamicMemory)
|
||||
if hasDynamicMemory {
|
||||
fmt.Fprintf(w, "callContext.Memory.Resize(_memorySize)\n")
|
||||
}
|
||||
}
|
||||
|
||||
func outputExecution(w io.Writer, op *funcDef) {
|
||||
fmt.Fprintf(w, `
|
||||
_, _executionErr := func (pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) %s(&pc, interpreter, callContext)
|
||||
if _executionErr != nil {
|
||||
return nil, _executionErr
|
||||
}
|
||||
`, extractBody(op.source))
|
||||
}
|
||||
|
||||
func GenerateRun() {
|
||||
set := newLondonInstructionSet()
|
||||
funcNames := collectFuncNames(set)
|
||||
funcDefinitions := collectFuncDefinitions(funcNames)
|
||||
|
||||
output, _ := os.Create("out.go")
|
||||
|
||||
fmt.Fprintln(output, `package vm
|
||||
func Run(interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) {
|
||||
|
||||
var pc uint64
|
||||
for {
|
||||
op := callContext.Contract.GetOp(pc)
|
||||
switch op {
|
||||
`)
|
||||
for opCode := range funcDefinitions {
|
||||
fmt.Fprintf(output, `case %d:
|
||||
if !callContext.Contract.UseGas(%d, nil, tracing.GasChangeIgnored) {
|
||||
return nil, ErrOutOfGas
|
||||
}
|
||||
|
||||
if sLen := callContext.Stack.len(); sLen < %d {
|
||||
return nil, &ErrStackUnderflow{stackLen: sLen, required: %d}
|
||||
} else if sLen > %d {
|
||||
return nil, &ErrStackOverflow{stackLen: sLen, limit: %d}
|
||||
}
|
||||
`, opCode, set[opCode].constantGas, set[opCode].minStack, set[opCode].minStack, set[opCode].maxStack, set[opCode].maxStack)
|
||||
if funcDefinitions[opCode].memory.decl != nil {
|
||||
outputMemoryCalc(output, &funcDefinitions[opCode].memory)
|
||||
} else if len(funcNames[opCode].memory) > 0 {
|
||||
panic(fmt.Sprint("failed to get memory handler definition for ", opCodeToString[opCode]))
|
||||
}
|
||||
|
||||
if funcDefinitions[opCode].gas.decl != nil {
|
||||
outputDynamicGas(output, &funcDefinitions[opCode].gas, funcDefinitions[opCode].memory.decl != nil)
|
||||
} else if len(funcNames[opCode].gas) > 0 {
|
||||
panic(fmt.Sprint("failed to get gas handler definition for ", opCodeToString[opCode]))
|
||||
}
|
||||
|
||||
if funcDefinitions[opCode].execution.decl != nil {
|
||||
outputExecution(output, &funcDefinitions[opCode].execution)
|
||||
} else if len(funcNames[opCode].execution) > 0 {
|
||||
panic(fmt.Sprint("failed to get exec handler definition for ", opCodeToString[opCode]))
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(output, `}
|
||||
pc++
|
||||
}}`)
|
||||
output.Close()
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"math"
|
||||
stdmath "math"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
|
|
@ -296,7 +296,7 @@ func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
|
|||
)
|
||||
dataOffset64, overflow := dataOffset.Uint64WithOverflow()
|
||||
if overflow {
|
||||
dataOffset64 = math.MaxUint64
|
||||
dataOffset64 = stdmath.MaxUint64
|
||||
}
|
||||
// These values are checked for overflow during gas cost calculation
|
||||
memOffset64 := memOffset.Uint64()
|
||||
|
|
@ -352,7 +352,7 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
|
|||
)
|
||||
uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
|
||||
if overflow {
|
||||
uint64CodeOffset = math.MaxUint64
|
||||
uint64CodeOffset = stdmath.MaxUint64
|
||||
}
|
||||
|
||||
codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64())
|
||||
|
|
@ -370,7 +370,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
|
|||
)
|
||||
uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
|
||||
if overflow {
|
||||
uint64CodeOffset = math.MaxUint64
|
||||
uint64CodeOffset = stdmath.MaxUint64
|
||||
}
|
||||
addr := common.Address(a.Bytes20())
|
||||
code := interpreter.evm.StateDB.GetCode(addr)
|
||||
|
|
@ -924,8 +924,7 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon
|
|||
// following functions are used by the instruction jump table
|
||||
|
||||
// make log instruction function
|
||||
func makeLog(size int) executionFunc {
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
func doLog(size int, pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
if interpreter.readOnly {
|
||||
return nil, ErrWriteProtection
|
||||
}
|
||||
|
|
@ -948,7 +947,22 @@ func makeLog(size int) executionFunc {
|
|||
})
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func opLog0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doLog(0, pc, interpreter, scope)
|
||||
}
|
||||
func opLog1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doLog(1, pc, interpreter, scope)
|
||||
}
|
||||
func opLog2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doLog(2, pc, interpreter, scope)
|
||||
}
|
||||
func opLog3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doLog(3, pc, interpreter, scope)
|
||||
}
|
||||
func opLog4(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doLog(4, pc, interpreter, scope)
|
||||
}
|
||||
|
||||
// opPush1 is a specialized version of pushN
|
||||
|
|
@ -983,10 +997,9 @@ func opPush2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// make push instruction function
|
||||
func makePush(size uint64, pushByteSize int) executionFunc {
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
func doPush(size uint64, pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
pushByteSize = int(size)
|
||||
codeLen = len(scope.Contract.Code)
|
||||
start = min(codeLen, int(*pc+1))
|
||||
end = min(codeLen, start+pushByteSize)
|
||||
|
|
@ -1000,13 +1013,160 @@ func makePush(size uint64, pushByteSize int) executionFunc {
|
|||
scope.Stack.push(a)
|
||||
*pc += size
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// make dup instruction function
|
||||
func makeDup(size int64) executionFunc {
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(int(size))
|
||||
return nil, nil
|
||||
}
|
||||
func opPush3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(3, pc, interpreter, scope)
|
||||
}
|
||||
func opPush4(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(4, pc, interpreter, scope)
|
||||
}
|
||||
func opPush5(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(5, pc, interpreter, scope)
|
||||
}
|
||||
func opPush6(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(6, pc, interpreter, scope)
|
||||
}
|
||||
func opPush7(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(7, pc, interpreter, scope)
|
||||
}
|
||||
func opPush8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(8, pc, interpreter, scope)
|
||||
}
|
||||
func opPush9(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(9, pc, interpreter, scope)
|
||||
}
|
||||
func opPush10(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(10, pc, interpreter, scope)
|
||||
}
|
||||
func opPush11(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(11, pc, interpreter, scope)
|
||||
}
|
||||
func opPush12(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(12, pc, interpreter, scope)
|
||||
}
|
||||
func opPush13(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(13, pc, interpreter, scope)
|
||||
}
|
||||
func opPush14(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(14, pc, interpreter, scope)
|
||||
}
|
||||
func opPush15(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(15, pc, interpreter, scope)
|
||||
}
|
||||
func opPush16(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(16, pc, interpreter, scope)
|
||||
}
|
||||
func opPush17(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(17, pc, interpreter, scope)
|
||||
}
|
||||
func opPush18(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(18, pc, interpreter, scope)
|
||||
}
|
||||
func opPush19(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(19, pc, interpreter, scope)
|
||||
}
|
||||
func opPush20(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(20, pc, interpreter, scope)
|
||||
}
|
||||
func opPush21(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(21, pc, interpreter, scope)
|
||||
}
|
||||
func opPush22(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(22, pc, interpreter, scope)
|
||||
}
|
||||
func opPush23(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(23, pc, interpreter, scope)
|
||||
}
|
||||
func opPush24(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(24, pc, interpreter, scope)
|
||||
}
|
||||
func opPush25(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(25, pc, interpreter, scope)
|
||||
}
|
||||
func opPush26(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(26, pc, interpreter, scope)
|
||||
}
|
||||
func opPush27(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(27, pc, interpreter, scope)
|
||||
}
|
||||
func opPush28(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(28, pc, interpreter, scope)
|
||||
}
|
||||
func opPush29(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(29, pc, interpreter, scope)
|
||||
}
|
||||
func opPush30(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(30, pc, interpreter, scope)
|
||||
}
|
||||
func opPush31(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(31, pc, interpreter, scope)
|
||||
}
|
||||
func opPush32(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return doPush(32, pc, interpreter, scope)
|
||||
}
|
||||
|
||||
func opDup1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(1)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(2)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(3)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup4(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(4)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup5(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(5)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup6(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(6)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup7(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(7)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(8)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup9(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(9)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup10(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(10)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup11(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(11)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup12(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(12)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup13(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(13)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup14(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(14)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup15(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(15)
|
||||
return nil, nil
|
||||
}
|
||||
func opDup16(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(16)
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -906,7 +906,7 @@ func TestOpMCopy(t *testing.T) {
|
|||
func TestPush(t *testing.T) {
|
||||
code := common.FromHex("0011223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121")
|
||||
|
||||
push32 := makePush(32, 32)
|
||||
push32 := opPush32
|
||||
|
||||
scope := &ScopeContext{
|
||||
Memory: nil,
|
||||
|
|
|
|||
|
|
@ -88,7 +88,6 @@ func BenchmarkInterpreter(b *testing.B) {
|
|||
)
|
||||
stack.push(uint256.NewInt(123))
|
||||
stack.push(uint256.NewInt(123))
|
||||
gasSStoreEIP3529 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP3529)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
gasSStoreEIP3529(evm, contract, stack, mem, 1234)
|
||||
|
|
|
|||
|
|
@ -633,277 +633,277 @@ func newFrontierInstructionSet() JumpTable {
|
|||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH3: {
|
||||
execute: makePush(3, 3),
|
||||
execute: opPush3,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH4: {
|
||||
execute: makePush(4, 4),
|
||||
execute: opPush4,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH5: {
|
||||
execute: makePush(5, 5),
|
||||
execute: opPush5,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH6: {
|
||||
execute: makePush(6, 6),
|
||||
execute: opPush6,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH7: {
|
||||
execute: makePush(7, 7),
|
||||
execute: opPush7,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH8: {
|
||||
execute: makePush(8, 8),
|
||||
execute: opPush8,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH9: {
|
||||
execute: makePush(9, 9),
|
||||
execute: opPush9,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH10: {
|
||||
execute: makePush(10, 10),
|
||||
execute: opPush10,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH11: {
|
||||
execute: makePush(11, 11),
|
||||
execute: opPush11,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH12: {
|
||||
execute: makePush(12, 12),
|
||||
execute: opPush12,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH13: {
|
||||
execute: makePush(13, 13),
|
||||
execute: opPush13,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH14: {
|
||||
execute: makePush(14, 14),
|
||||
execute: opPush14,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH15: {
|
||||
execute: makePush(15, 15),
|
||||
execute: opPush15,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH16: {
|
||||
execute: makePush(16, 16),
|
||||
execute: opPush16,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH17: {
|
||||
execute: makePush(17, 17),
|
||||
execute: opPush17,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH18: {
|
||||
execute: makePush(18, 18),
|
||||
execute: opPush18,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH19: {
|
||||
execute: makePush(19, 19),
|
||||
execute: opPush19,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH20: {
|
||||
execute: makePush(20, 20),
|
||||
execute: opPush20,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH21: {
|
||||
execute: makePush(21, 21),
|
||||
execute: opPush21,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH22: {
|
||||
execute: makePush(22, 22),
|
||||
execute: opPush22,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH23: {
|
||||
execute: makePush(23, 23),
|
||||
execute: opPush23,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH24: {
|
||||
execute: makePush(24, 24),
|
||||
execute: opPush24,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH25: {
|
||||
execute: makePush(25, 25),
|
||||
execute: opPush25,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH26: {
|
||||
execute: makePush(26, 26),
|
||||
execute: opPush26,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH27: {
|
||||
execute: makePush(27, 27),
|
||||
execute: opPush27,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH28: {
|
||||
execute: makePush(28, 28),
|
||||
execute: opPush28,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH29: {
|
||||
execute: makePush(29, 29),
|
||||
execute: opPush29,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH30: {
|
||||
execute: makePush(30, 30),
|
||||
execute: opPush30,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH31: {
|
||||
execute: makePush(31, 31),
|
||||
execute: opPush31,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
PUSH32: {
|
||||
execute: makePush(32, 32),
|
||||
execute: opPush32,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minStack(0, 1),
|
||||
maxStack: maxStack(0, 1),
|
||||
},
|
||||
DUP1: {
|
||||
execute: makeDup(1),
|
||||
execute: opDup1,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(1),
|
||||
maxStack: maxDupStack(1),
|
||||
},
|
||||
DUP2: {
|
||||
execute: makeDup(2),
|
||||
execute: opDup2,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(2),
|
||||
maxStack: maxDupStack(2),
|
||||
},
|
||||
DUP3: {
|
||||
execute: makeDup(3),
|
||||
execute: opDup3,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(3),
|
||||
maxStack: maxDupStack(3),
|
||||
},
|
||||
DUP4: {
|
||||
execute: makeDup(4),
|
||||
execute: opDup4,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(4),
|
||||
maxStack: maxDupStack(4),
|
||||
},
|
||||
DUP5: {
|
||||
execute: makeDup(5),
|
||||
execute: opDup5,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(5),
|
||||
maxStack: maxDupStack(5),
|
||||
},
|
||||
DUP6: {
|
||||
execute: makeDup(6),
|
||||
execute: opDup6,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(6),
|
||||
maxStack: maxDupStack(6),
|
||||
},
|
||||
DUP7: {
|
||||
execute: makeDup(7),
|
||||
execute: opDup7,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(7),
|
||||
maxStack: maxDupStack(7),
|
||||
},
|
||||
DUP8: {
|
||||
execute: makeDup(8),
|
||||
execute: opDup8,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(8),
|
||||
maxStack: maxDupStack(8),
|
||||
},
|
||||
DUP9: {
|
||||
execute: makeDup(9),
|
||||
execute: opDup9,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(9),
|
||||
maxStack: maxDupStack(9),
|
||||
},
|
||||
DUP10: {
|
||||
execute: makeDup(10),
|
||||
execute: opDup10,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(10),
|
||||
maxStack: maxDupStack(10),
|
||||
},
|
||||
DUP11: {
|
||||
execute: makeDup(11),
|
||||
execute: opDup11,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(11),
|
||||
maxStack: maxDupStack(11),
|
||||
},
|
||||
DUP12: {
|
||||
execute: makeDup(12),
|
||||
execute: opDup12,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(12),
|
||||
maxStack: maxDupStack(12),
|
||||
},
|
||||
DUP13: {
|
||||
execute: makeDup(13),
|
||||
execute: opDup13,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(13),
|
||||
maxStack: maxDupStack(13),
|
||||
},
|
||||
DUP14: {
|
||||
execute: makeDup(14),
|
||||
execute: opDup14,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(14),
|
||||
maxStack: maxDupStack(14),
|
||||
},
|
||||
DUP15: {
|
||||
execute: makeDup(15),
|
||||
execute: opDup15,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(15),
|
||||
maxStack: maxDupStack(15),
|
||||
},
|
||||
DUP16: {
|
||||
execute: makeDup(16),
|
||||
execute: opDup16,
|
||||
constantGas: GasFastestStep,
|
||||
minStack: minDupStack(16),
|
||||
maxStack: maxDupStack(16),
|
||||
|
|
@ -1005,36 +1005,36 @@ func newFrontierInstructionSet() JumpTable {
|
|||
maxStack: maxSwapStack(17),
|
||||
},
|
||||
LOG0: {
|
||||
execute: makeLog(0),
|
||||
dynamicGas: makeGasLog(0),
|
||||
execute: opLog0,
|
||||
dynamicGas: gasLog0,
|
||||
minStack: minStack(2, 0),
|
||||
maxStack: maxStack(2, 0),
|
||||
memorySize: memoryLog,
|
||||
},
|
||||
LOG1: {
|
||||
execute: makeLog(1),
|
||||
dynamicGas: makeGasLog(1),
|
||||
execute: opLog1,
|
||||
dynamicGas: gasLog1,
|
||||
minStack: minStack(3, 0),
|
||||
maxStack: maxStack(3, 0),
|
||||
memorySize: memoryLog,
|
||||
},
|
||||
LOG2: {
|
||||
execute: makeLog(2),
|
||||
dynamicGas: makeGasLog(2),
|
||||
execute: opLog2,
|
||||
dynamicGas: gasLog2,
|
||||
minStack: minStack(4, 0),
|
||||
maxStack: maxStack(4, 0),
|
||||
memorySize: memoryLog,
|
||||
},
|
||||
LOG3: {
|
||||
execute: makeLog(3),
|
||||
dynamicGas: makeGasLog(3),
|
||||
execute: opLog3,
|
||||
dynamicGas: gasLog3,
|
||||
minStack: minStack(5, 0),
|
||||
maxStack: maxStack(5, 0),
|
||||
memorySize: memoryLog,
|
||||
},
|
||||
LOG4: {
|
||||
execute: makeLog(4),
|
||||
dynamicGas: makeGasLog(4),
|
||||
execute: opLog4,
|
||||
dynamicGas: gasLog4,
|
||||
minStack: minStack(6, 0),
|
||||
maxStack: maxStack(6, 0),
|
||||
memorySize: memoryLog,
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
func gasSStoreFuncEIP(clearingRefund uint64, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
// If we fail the minimum gas availability invariant, fail (0)
|
||||
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
||||
return 0, errors.New("not enough gas for reentrancy sentry")
|
||||
|
|
@ -87,7 +86,6 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
|||
// EIP-2200 original clause:
|
||||
//return params.SloadGasEIP2200, nil // dirty update (2.2)
|
||||
return cost + params.WarmStorageReadCostEIP2929, nil // dirty update (2.2)
|
||||
}
|
||||
}
|
||||
|
||||
// gasSLoadEIP2929 calculates dynamic gas for SLOAD according to EIP-2929
|
||||
|
|
@ -152,8 +150,7 @@ func gasEip2929AccountCheck(evm *EVM, contract *Contract, stack *Stack, mem *Mem
|
|||
return 0, nil
|
||||
}
|
||||
|
||||
func makeCallVariantGasCallEIP2929(oldCalculator gasFunc, addressPosition int) gasFunc {
|
||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
func makeCallVariantGasCallEIP2929(oldCalculator gasFunc, addressPosition int, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
addr := common.Address(stack.Back(addressPosition).Bytes20())
|
||||
// Check slot presence in the access list
|
||||
warmAccess := evm.StateDB.AddressInAccessList(addr)
|
||||
|
|
@ -188,40 +185,52 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc, addressPosition int) g
|
|||
return 0, ErrGasUintOverflow
|
||||
}
|
||||
return gas, nil
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
gasCallEIP2929 = makeCallVariantGasCallEIP2929(gasCall, 1)
|
||||
gasDelegateCallEIP2929 = makeCallVariantGasCallEIP2929(gasDelegateCall, 1)
|
||||
gasStaticCallEIP2929 = makeCallVariantGasCallEIP2929(gasStaticCall, 1)
|
||||
gasCallCodeEIP2929 = makeCallVariantGasCallEIP2929(gasCallCode, 1)
|
||||
gasSelfdestructEIP2929 = makeSelfdestructGasFn(true)
|
||||
// gasSelfdestructEIP3529 implements the changes in EIP-3529 (no refunds)
|
||||
gasSelfdestructEIP3529 = makeSelfdestructGasFn(false)
|
||||
func gasCallEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeCallVariantGasCallEIP2929(gasCall, 1, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasDelegateCallEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeCallVariantGasCallEIP2929(gasDelegateCall, 1, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasStaticCallEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeCallVariantGasCallEIP2929(gasStaticCall, 1, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasCallCodeEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeCallVariantGasCallEIP2929(gasCallCode, 1, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasSelfdestructEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeSelfdestructGasFn(true, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
func gasSelfdestructEIP3529(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return makeSelfdestructGasFn(false, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
|
||||
// gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929
|
||||
//
|
||||
// When calling SSTORE, check if the (address, storage_key) pair is in accessed_storage_keys.
|
||||
// If it is not, charge an additional COLD_SLOAD_COST gas, and add the pair to accessed_storage_keys.
|
||||
// Additionally, modify the parameters defined in EIP 2200 as follows:
|
||||
//
|
||||
// Parameter Old value New value
|
||||
// SLOAD_GAS 800 = WARM_STORAGE_READ_COST
|
||||
// SSTORE_RESET_GAS 5000 5000 - COLD_SLOAD_COST
|
||||
//
|
||||
//The other parameters defined in EIP 2200 are unchanged.
|
||||
// see gasSStoreEIP2200(...) in core/vm/gas_table.go for more info about how EIP 2200 is specified
|
||||
gasSStoreEIP2929 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP2200)
|
||||
// gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929
|
||||
//
|
||||
// When calling SSTORE, check if the (address, storage_key) pair is in accessed_storage_keys.
|
||||
// If it is not, charge an additional COLD_SLOAD_COST gas, and add the pair to accessed_storage_keys.
|
||||
// Additionally, modify the parameters defined in EIP 2200 as follows:
|
||||
//
|
||||
// Parameter Old value New value
|
||||
// SLOAD_GAS 800 = WARM_STORAGE_READ_COST
|
||||
// SSTORE_RESET_GAS 5000 5000 - COLD_SLOAD_COST
|
||||
//
|
||||
// The other parameters defined in EIP 2200 are unchanged.
|
||||
// see gasSStoreEIP2200(...) in core/vm/gas_table.go for more info about how EIP 2200 is specified
|
||||
func gasSStoreEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return gasSStoreFuncEIP(params.SstoreClearsScheduleRefundEIP2200, evm, contract, stack, mem, memorySize)
|
||||
}
|
||||
|
||||
// gasSStoreEIP3529 implements gas cost for SSTORE according to EIP-3529
|
||||
// Replace `SSTORE_CLEARS_SCHEDULE` with `SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST` (4,800)
|
||||
gasSStoreEIP3529 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP3529)
|
||||
)
|
||||
// gasSStoreEIP3529 implements gas cost for SSTORE according to EIP-3529
|
||||
// Replace `SSTORE_CLEARS_SCHEDULE` with `SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST` (4,800)
|
||||
func gasSStoreEIP3529(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
return gasSStoreFuncEIP(params.SstoreClearsScheduleRefundEIP3529, evm, contract, stack, mem, memorySize)
|
||||
|
||||
}
|
||||
|
||||
// makeSelfdestructGasFn can create the selfdestruct dynamic gas function for EIP-2929 and EIP-3529
|
||||
func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
|
||||
gasFunc := func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
func makeSelfdestructGasFn(refundsEnabled bool, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
var (
|
||||
gas uint64
|
||||
address = common.Address(stack.peek().Bytes20())
|
||||
|
|
@ -239,8 +248,6 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
|
|||
evm.StateDB.AddRefund(params.SelfdestructRefundGas)
|
||||
}
|
||||
return gas, nil
|
||||
}
|
||||
return gasFunc
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
|||
Loading…
Reference in a new issue