From f1027b7c0a5afae1c2ba04e3d3862a285ce593a9 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Tue, 27 Feb 2024 16:51:47 +0100 Subject: [PATCH] fix goja scope object wrappers --- eth/tracers/directory/util.go | 21 ++++++++++++++++- eth/tracers/js/goja.go | 43 ++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/eth/tracers/directory/util.go b/eth/tracers/directory/util.go index 25f95642c8..f5a2cd80d3 100644 --- a/eth/tracers/directory/util.go +++ b/eth/tracers/directory/util.go @@ -18,6 +18,8 @@ package directory import ( "errors" "fmt" + + "github.com/holiman/uint256" ) const ( @@ -40,7 +42,7 @@ func GetMemoryCopyPadded(m []byte, offset, size int64) ([]byte, error) { } cpy := make([]byte, size) if overlap := length - offset; overlap > 0 { - copy(cpy, m[offset:offset+overlap]) + copy(cpy, MemoryPtr(m, offset, overlap)) } return cpy, nil } @@ -59,3 +61,20 @@ func memoryCopy(m []byte, offset, size int64) (cpy []byte) { return } + +func MemoryPtr(m []byte, offset, size int64) []byte { + if size == 0 { + return nil + } + + if len(m) > int(offset) { + return m[offset : offset+size] + } + + return nil +} + +// Back returns the n'th item in stack +func StackBack(st []uint256.Int, n int) *uint256.Int { + return &st[len(st)-n-1] +} diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index 3e0a4b592f..62115f40a2 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers/directory" "github.com/ethereum/go-ethereum/eth/tracers/directory/live" + "github.com/holiman/uint256" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -309,9 +310,9 @@ func (t *jsTracer) CaptureState(pc uint64, op live.OpCode, gas, cost uint64, sco log := t.log log.op.op = vm.OpCode(op) - log.memory.memory = scope.Memory - log.stack.stack = scope.Stack - log.contract.contract = scope.Contract + log.memory.memory = scope.GetMemoryData() + log.stack.stack = scope.GetStackData() + log.contract.scope = scope log.pc = pc log.gas = gas log.cost = cost @@ -587,7 +588,7 @@ func (o *opObj) setupObject() *goja.Object { } type memoryObj struct { - memory *vm.Memory + memory []byte vm *goja.Runtime toBig toBigFn toBuf toBufFn @@ -638,14 +639,14 @@ func (mo *memoryObj) GetUint(addr int64) goja.Value { // getUint returns the 32 bytes at the specified address interpreted as a uint. func (mo *memoryObj) getUint(addr int64) (*big.Int, error) { - if mo.memory.Len() < int(addr)+32 || addr < 0 { - return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", mo.memory.Len(), addr, 32) + if len(mo.memory) < int(addr)+32 || addr < 0 { + return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", len(mo.memory), addr, 32) } - return new(big.Int).SetBytes(mo.memory.GetPtr(addr, 32)), nil + return new(big.Int).SetBytes(directory.MemoryPtr(mo.memory, addr, 32)), nil } func (mo *memoryObj) Length() int { - return mo.memory.Len() + return len(mo.memory) } func (m *memoryObj) setupObject() *goja.Object { @@ -657,7 +658,7 @@ func (m *memoryObj) setupObject() *goja.Object { } type stackObj struct { - stack *vm.Stack + stack []uint256.Int vm *goja.Runtime toBig toBigFn } @@ -678,14 +679,14 @@ func (s *stackObj) Peek(idx int) goja.Value { // peek returns the nth-from-the-top element of the stack. func (s *stackObj) peek(idx int) (*big.Int, error) { - if len(s.stack.Data()) <= idx || idx < 0 { - return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack.Data()), idx) + if len(s.stack) <= idx || idx < 0 { + return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack), idx) } - return s.stack.Back(idx).ToBig(), nil + return directory.StackBack(s.stack, idx).ToBig(), nil } func (s *stackObj) Length() int { - return len(s.stack.Data()) + return len(s.stack) } func (s *stackObj) setupObject() *goja.Object { @@ -788,14 +789,14 @@ func (do *dbObj) setupObject() *goja.Object { } type contractObj struct { - contract *vm.Contract - vm *goja.Runtime - toBig toBigFn - toBuf toBufFn + scope live.ScopeContext + vm *goja.Runtime + toBig toBigFn + toBuf toBufFn } func (co *contractObj) GetCaller() goja.Value { - caller := co.contract.Caller().Bytes() + caller := co.scope.GetCaller().Bytes() res, err := co.toBuf(co.vm, caller) if err != nil { co.vm.Interrupt(err) @@ -805,7 +806,7 @@ func (co *contractObj) GetCaller() goja.Value { } func (co *contractObj) GetAddress() goja.Value { - addr := co.contract.Address().Bytes() + addr := co.scope.GetAddress().Bytes() res, err := co.toBuf(co.vm, addr) if err != nil { co.vm.Interrupt(err) @@ -815,7 +816,7 @@ func (co *contractObj) GetAddress() goja.Value { } func (co *contractObj) GetValue() goja.Value { - value := co.contract.Value() + value := co.scope.GetCallValue() res, err := co.toBig(co.vm, value.String()) if err != nil { co.vm.Interrupt(err) @@ -825,7 +826,7 @@ func (co *contractObj) GetValue() goja.Value { } func (co *contractObj) GetInput() goja.Value { - input := common.CopyBytes(co.contract.Input) + input := common.CopyBytes(co.scope.GetCallInput()) res, err := co.toBuf(co.vm, input) if err != nil { co.vm.Interrupt(err)