Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding erc7562 tracer #31006

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

shahafn
Copy link

@shahafn shahafn commented Jan 8, 2025

Resolves #30546

@shahafn shahafn requested a review from s1na as a code owner January 8, 2025 14:50
@rjl493456442
Copy link
Member

rjl493456442 commented Jan 9, 2025

Probably relevant with #30546 , @s1na please check it out.

Copy link
Member

@MariusVanDerWijden MariusVanDerWijden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not opposed the idea of adding a 4337 style native tracer, but this one needs a bunch of refactors imo

@@ -0,0 +1,550 @@
// Copyright 2021 The go-ethereum Authors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Copyright 2021 The go-ethereum Authors
// Copyright 2025 The go-ethereum Authors

}

type callFrameWithOpcodes struct {
Type vm.OpCode `json:"-"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about reusing some code from the call tracer?

diff --git a/eth/tracers/native/erc7562.go b/eth/tracers/native/erc7562.go
index cd1a48975f..7f80c7d168 100644
--- a/eth/tracers/native/erc7562.go
+++ b/eth/tracers/native/erc7562.go
@@ -48,20 +48,7 @@ type contractSizeWithOpcode struct {
 }
 
 type callFrameWithOpcodes struct {
-       Type         vm.OpCode       `json:"-"`
-       From         common.Address  `json:"from"`
-       Gas          uint64          `json:"gas"`
-       GasUsed      uint64          `json:"gasUsed"`
-       To           *common.Address `json:"to,omitempty" rlp:"optional"`
-       Input        []byte          `json:"input" rlp:"optional"`
-       Output       []byte          `json:"output,omitempty" rlp:"optional"`
-       Error        string          `json:"error,omitempty" rlp:"optional"`
-       RevertReason string          `json:"revertReason,omitempty"`
-       Logs         []callLog       `json:"logs,omitempty" rlp:"optional"`
-       // Placed at end on purpose. The RLP will be decoded to 0 instead of
-       // nil if there are non-empty elements after in the struct.
-       Value            *big.Int `json:"value,omitempty" rlp:"optional"`
-       revertedSnapshot bool
+       callFrame
 
        AccessedSlots     accessedSlots                              `json:"accessedSlots"`
        ExtCodeAccessInfo []common.Address                           `json:"extCodeAccessInfo"`
@@ -228,12 +215,14 @@ func (t *erc7562Tracer) OnEnter(depth int, typ byte, from common.Address, to com
 
        toCopy := to
        call := callFrameWithOpcodes{
-               Type:  vm.OpCode(typ),
-               From:  from,
-               To:    &toCopy,
-               Input: common.CopyBytes(input),
-               Gas:   gas,
-               Value: value,
+               callFrame: callFrame{
+                       Type:  vm.OpCode(typ),
+                       From:  from,
+                       To:    &toCopy,
+                       Input: common.CopyBytes(input),
+                       Gas:   gas,
+                       Value: value,
+               },
                AccessedSlots: accessedSlots{
                        Reads:           map[string][]string{},
                        Writes:          map[string]uint64{},
                        ```

"github.com/holiman/uint256"
)

//go:generate go run github.com/fjl/gencodec -type callFrameWithOpcodes -field-override callFrameWithOpcodesMarshaling -out gen_callframewithopcodes_json.go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//go:generate go run github.com/fjl/gencodec -type callFrameWithOpcodes -field-override callFrameWithOpcodesMarshaling -out gen_callframewithopcodes_json.go
//go:generate go run github.com/fjl/gencodec -type callFrameWithOpcodes -field-override callFrameMarshaling -out gen_callframewithopcodes_json.go

}

// catchPanic handles panic recovery and logs the panic and stack trace.
func catchPanic() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like this pattern. Your code should be correct, you should not rely on recovering. Rather fail fast and fix quickly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I'd like to second this. Did you need this for debug purposes?

Panics here should not crash the node. API internal has recovery mechanism from panics. If you managed to crash the node then that's an issue we should look at.

return config
}

func newErc7562TracerObject(ctx *tracers.Context, cfg json.RawMessage) (*erc7562Tracer, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func newErc7562TracerObject(ctx *tracers.Context, cfg json.RawMessage) (*erc7562Tracer, error) {
func newErc7562TracerObject(cfg json.RawMessage) (*erc7562Tracer, error) {

ctx is unused here, no need to pass it then

t.callstackWithOpcodes = append(t.callstackWithOpcodes, call)
}

func (t *erc7562Tracer) captureEnd(output []byte, gasUsed uint64, err error, reverted bool) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func (t *erc7562Tracer) captureEnd(output []byte, gasUsed uint64, err error, reverted bool) {
func (t *erc7562Tracer) captureEnd(output []byte, err error, reverted bool) {

gas used is unused

}

func incrementCount[K comparable](m map[K]uint64, k K) {
m[k] = m[k] + 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry what?

for i := 0; i < t.config.StackTopItemsSize && i < stackSize; i++ {
stackTopItems = append(stackTopItems, *peepStack(scope.StackData(), i))
}
opcodeWithStack = &opcodeWithPartialStack{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would switch on the opcode here instead of calling into multiple methods that might or might not do anything

@s1na
Copy link
Contributor

s1na commented Jan 21, 2025

It would be nice to have some spec-compliance tests.

ignoredOpcodes map[vm.OpCode]struct{}
callstackWithOpcodes []callFrameWithOpcodes
lastOpWithStack *opcodeWithPartialStack
Keccak map[string]struct{} `json:"keccak"`
Copy link
Contributor

@s1na s1na Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this field can be un-exported and the json tag is not needed. This struct is not directly serialized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Built-in ERC-4337 tracer
4 participants