From 5992baf543fb1d3ca233196332147ba892ebc036 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Thu, 26 Sep 2024 14:11:23 +0200 Subject: [PATCH] core/vm: added RETURNCONTRACT opcode --- core/vm/eof_instructions.go | 42 ++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/core/vm/eof_instructions.go b/core/vm/eof_instructions.go index 1b91819f87..63b6be366f 100644 --- a/core/vm/eof_instructions.go +++ b/core/vm/eof_instructions.go @@ -18,6 +18,7 @@ package vm import ( "encoding/binary" + "errors" "fmt" "github.com/ethereum/go-ethereum/common/math" @@ -175,7 +176,46 @@ func opEOFCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( // opReturnContract implements the RETURNCONTRACT opcode func opReturnContract(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - panic("not implemented") + if !scope.InitCodeMode { + return nil, errors.New("returncontract in non-initcode mode") + } + var ( + code = scope.Contract.CodeAt(scope.CodeSection) + idx = code[*pc+1] + offset = scope.Stack.pop() + size = scope.Stack.pop() + ) + if int(idx) >= len(scope.Contract.Container.subContainerCodes) { + return nil, fmt.Errorf("invalid subcontainer") + } + ret := scope.Memory.GetPtr(offset.Uint64(), size.Uint64()) + containerCode := scope.Contract.Container.subContainerCodes[idx] + if len(containerCode) == 0 { + return nil, errors.New("nonexistant subcontainer") + } + // Validate the subcontainer + var c Container + if err := c.UnmarshalSubContainer(containerCode, false); err != nil { + return nil, err + } + + // append the auxdata + c.data = append(c.data, ret...) + if len(c.data) < c.dataSize { + return nil, errors.New("incomplete aux data") + } + c.dataSize = len(c.data) + + // probably unneeded as subcontainers are deeply validated + if err := c.ValidateCode(interpreter.tableEOF, false); err != nil { + return nil, err + } + + // Restore context + retCtx := scope.ReturnStack.Pop() + scope.CodeSection = retCtx.Section + *pc = retCtx.Pc - 1 // account for interpreter loop + return c.MarshalBinary(), errStopToken } // opDataLoad implements the DATALOAD opcode