Merge remote-tracking branch 'upstream/master' into vm-mempool

This commit is contained in:
lmittmann 2024-08-08 12:23:18 +02:00
commit f005557287
3 changed files with 40 additions and 51 deletions

View file

@ -232,7 +232,7 @@ func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte
func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
offset, size := scope.Stack.pop(), scope.Stack.peek() offset, size := scope.Stack.pop(), scope.Stack.peek()
data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
if interpreter.hasher == nil { if interpreter.hasher == nil {
interpreter.hasher = crypto.NewKeccakState() interpreter.hasher = crypto.NewKeccakState()
@ -502,7 +502,7 @@ func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte
func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
v := scope.Stack.peek() v := scope.Stack.peek()
offset := int64(v.Uint64()) offset := v.Uint64()
v.SetBytes(scope.Memory.GetPtr(offset, 32)) v.SetBytes(scope.Memory.GetPtr(offset, 32))
return nil, nil return nil, nil
} }
@ -670,7 +670,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
var ( var (
value = scope.Stack.pop() value = scope.Stack.pop()
offset, size = scope.Stack.pop(), scope.Stack.pop() offset, size = scope.Stack.pop(), scope.Stack.pop()
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64())
gas = scope.Contract.Gas gas = scope.Contract.Gas
) )
if interpreter.evm.chainRules.IsEIP150 { if interpreter.evm.chainRules.IsEIP150 {
@ -714,7 +714,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
endowment = scope.Stack.pop() endowment = scope.Stack.pop()
offset, size = scope.Stack.pop(), scope.Stack.pop() offset, size = scope.Stack.pop(), scope.Stack.pop()
salt = scope.Stack.pop() salt = scope.Stack.pop()
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64())
gas = scope.Contract.Gas gas = scope.Contract.Gas
) )
@ -752,7 +752,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// 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(inOffset.Uint64(), inSize.Uint64())
if interpreter.readOnly && !value.IsZero() { if interpreter.readOnly && !value.IsZero() {
return nil, ErrWriteProtection return nil, ErrWriteProtection
@ -788,7 +788,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// Get arguments from the memory. // Get arguments from the memory.
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
if !value.IsZero() { if !value.IsZero() {
gas += params.CallStipend gas += params.CallStipend
@ -821,7 +821,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// Get arguments from the memory. // Get arguments from the memory.
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas)
if err != nil { if err != nil {
@ -850,7 +850,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// Get arguments from the memory. // Get arguments from the memory.
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas)
if err != nil { if err != nil {
@ -871,14 +871,14 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
offset, size := scope.Stack.pop(), scope.Stack.pop() offset, size := scope.Stack.pop(), scope.Stack.pop()
ret := scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) ret := scope.Memory.GetCopy(offset.Uint64(), size.Uint64())
return ret, errStopToken return ret, errStopToken
} }
func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
offset, size := scope.Stack.pop(), scope.Stack.pop() offset, size := scope.Stack.pop(), scope.Stack.pop()
ret := scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) ret := scope.Memory.GetCopy(offset.Uint64(), size.Uint64())
interpreter.returnData = ret interpreter.returnData = ret
return ret, ErrExecutionReverted return ret, ErrExecutionReverted
@ -947,7 +947,7 @@ func makeLog(size int) executionFunc {
topics[i] = addr.Bytes32() topics[i] = addr.Bytes32()
} }
d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) d := scope.Memory.GetCopy(mStart.Uint64(), mSize.Uint64())
interpreter.evm.StateDB.AddLog(&types.Log{ interpreter.evm.StateDB.AddLog(&types.Log{
Address: scope.Contract.Address(), Address: scope.Contract.Address(),
Topics: topics, Topics: topics,

View file

@ -85,32 +85,25 @@ func (m *Memory) Resize(size uint64) {
} }
// GetCopy returns offset + size as a new slice // GetCopy returns offset + size as a new slice
func (m *Memory) GetCopy(offset, size int64) (cpy []byte) { func (m *Memory) GetCopy(offset, size uint64) (cpy []byte) {
if size == 0 { if size == 0 {
return nil return nil
} }
if len(m.store) > int(offset) { // memory is always resized before being accessed, no need to check bounds
cpy = make([]byte, size) cpy = make([]byte, size)
copy(cpy, m.store[offset:offset+size]) copy(cpy, m.store[offset:offset+size])
return
}
return return
} }
// GetPtr returns the offset + size // GetPtr returns the offset + size
func (m *Memory) GetPtr(offset, size int64) []byte { func (m *Memory) GetPtr(offset, size uint64) []byte {
if size == 0 { if size == 0 {
return nil return nil
} }
if len(m.store) > int(offset) { // memory is always resized before being accessed, no need to check bounds
return m.store[offset : offset+size] return m.store[offset : offset+size]
}
return nil
} }
// Len returns the length of the backing slice // Len returns the length of the backing slice

View file

@ -843,39 +843,35 @@ func (t Types) validate() error {
return nil return nil
} }
// Checks if the primitive value is valid var validPrimitiveTypes = map[string]struct{}{}
func isPrimitiveTypeValid(primitiveType string) bool {
if primitiveType == "address" || // build the set of valid primitive types
primitiveType == "address[]" || func init() {
primitiveType == "bool" || // Types those are trivially valid
primitiveType == "bool[]" || for _, t := range []string{
primitiveType == "string" || "address", "address[]", "bool", "bool[]", "string", "string[]",
primitiveType == "string[]" || "bytes", "bytes[]", "int", "int[]", "uint", "uint[]",
primitiveType == "bytes" || } {
primitiveType == "bytes[]" || validPrimitiveTypes[t] = struct{}{}
primitiveType == "int" ||
primitiveType == "int[]" ||
primitiveType == "uint" ||
primitiveType == "uint[]" {
return true
} }
// For 'bytesN', 'bytesN[]', we allow N from 1 to 32 // For 'bytesN', 'bytesN[]', we allow N from 1 to 32
for n := 1; n <= 32; n++ { for n := 1; n <= 32; n++ {
// e.g. 'bytes28' or 'bytes28[]' validPrimitiveTypes[fmt.Sprintf("bytes%d", n)] = struct{}{}
if primitiveType == fmt.Sprintf("bytes%d", n) || primitiveType == fmt.Sprintf("bytes%d[]", n) { validPrimitiveTypes[fmt.Sprintf("bytes%d[]", n)] = struct{}{}
return true
}
} }
// For 'intN','intN[]' and 'uintN','uintN[]' we allow N in increments of 8, from 8 up to 256 // For 'intN','intN[]' and 'uintN','uintN[]' we allow N in increments of 8, from 8 up to 256
for n := 8; n <= 256; n += 8 { for n := 8; n <= 256; n += 8 {
if primitiveType == fmt.Sprintf("int%d", n) || primitiveType == fmt.Sprintf("int%d[]", n) { validPrimitiveTypes[fmt.Sprintf("int%d", n)] = struct{}{}
return true validPrimitiveTypes[fmt.Sprintf("int%d[]", n)] = struct{}{}
} validPrimitiveTypes[fmt.Sprintf("uint%d", n)] = struct{}{}
if primitiveType == fmt.Sprintf("uint%d", n) || primitiveType == fmt.Sprintf("uint%d[]", n) { validPrimitiveTypes[fmt.Sprintf("uint%d[]", n)] = struct{}{}
return true
}
} }
return false }
// Checks if the primitive value is valid
func isPrimitiveTypeValid(primitiveType string) bool {
_, ok := validPrimitiveTypes[primitiveType]
return ok
} }
// validate checks if the given domain is valid, i.e. contains at least // validate checks if the given domain is valid, i.e. contains at least