-
Notifications
You must be signed in to change notification settings - Fork 20.5k
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
base: master
Are you sure you want to change the base?
Adding erc7562 tracer #31006
Conversation
There was a problem hiding this 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Copyright 2021 The go-ethereum Authors | |
// Copyright 2025 The go-ethereum Authors |
} | ||
|
||
type callFrameWithOpcodes struct { | ||
Type vm.OpCode `json:"-"` |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//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() { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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{ |
There was a problem hiding this comment.
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
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"` |
There was a problem hiding this comment.
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.
Resolves #30546