-
Notifications
You must be signed in to change notification settings - Fork 5
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
AA-475: include ERC-7562 tracer #47
AA-475: include ERC-7562 tracer #47
Conversation
Rename to erc7562Tracer
eth/tracers/native/erc7562.go
Outdated
memory := scope.MemoryData() | ||
keccak := make([]byte, dataLength) | ||
copy(keccak, memory[dataOffset:dataOffset+dataLength]) | ||
t.Keccak = append(t.Keccak, 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.
saves redundant copies in the keccak array. should built it as a map, and convert to an array only on marshaling.
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.
Ok but note that hexutils.Bytes
(which is []byte
) can't be used as keys for mapping in Go, so it needs to be converted to another type (like string). So it means that now it is map[string]struct{}
. The casting from []byte
to string and vice versa is easy, but I don't know how much more efficient it is. See the commit
func (t *erc7562Tracer) storeKeccak(opcode vm.OpCode, scope tracing.OpContext) { | ||
if opcode == vm.KECCAK256 { | ||
dataOffset := peepStack(scope.StackData(), 0).Uint64() | ||
dataLength := peepStack(scope.StackData(), 1).Uint64() |
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.
this saves all blobs we keccak. that includes creation code, which is useless. need a max size to keep. currently we only handle (exactly) 64 bytes, but technically, maps can use larger blocks. So can have a config param (with default=64), or set it to a sane value, like 256
eth/tracers/native/erc7562.go
Outdated
// count := int(opcode - vm.LOG0) | ||
// ofs := peepStack(scope.StackData(), 0) | ||
// len := peepStack(scope.StackData(), 1) | ||
// memory := scope.MemoryData() | ||
// topics := []hexutil.Bytes{} | ||
// for i := 0; i < count; i++ { | ||
// topics = append(topics, peepStack(scope.StackData(), 2+i).Bytes()) | ||
// //topics = append(topics, scope.Stack.Back(2+i).Bytes()) | ||
// } | ||
// log := make([]byte, len.Uint64()) | ||
// copy(log, memory[ofs.Uint64():ofs.Uint64()+len.Uint64()]) | ||
// t.Logs = append(t.Logs, &logsItem{ | ||
// Data: log, | ||
// Topic: topics, | ||
// }) | ||
//} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
n = 1 | ||
} | ||
addr := common.BytesToAddress(peepStack(scope.StackData(), n).Bytes()) | ||
if _, ok := currentCallFrame.ContractSize[addr]; !ok && !isAllowedPrecompile(addr) { |
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.
no need to check for precompiles: there is a callFrame for them too, so the parser can handle it.
} | ||
|
||
func (f *callFrameWithOpcodes) processOutput(output []byte, err error, reverted bool) { | ||
output = common.CopyBytes(output) |
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.
input/output arrays can be huge (constructor as input, contract code as output). we don't need that for normal tracing so should be able to configure max input/output size
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.
This is taken from call.go. Not sure I want to limit it here if they allow it
revertedSnapshot bool | ||
|
||
AccessedSlots accessedSlots `json:"accessedSlots"` | ||
ExtCodeAccessInfo []common.Address `json:"extCodeAccessInfo"` |
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.
extCodeAccessInfo and "ContractSize" are maps of how we access external addresses.
this should be a bitmap with bits for
- bit for each of extcode* opcode (currently covered by extCodeAccessInfo)
- hasCode (currently we use contractSize, to detect access to no-code address)
- eip7702delegate (currently we don't have a way to detect call to eip-7702 address)
NOTE: in the special "EXTCODESIZE/ISZERO" sequence, the EXTCODESIZE is removed before adding it to the above map. The parser can still detect if the target had code using "hasCode" flag (current parser uses the "ContractSize" for that)
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 don't think we must have bitmaps, do you know what's the performance penalty for that? not sure this is a bottleneck
} | ||
|
||
type accessedSlots struct { | ||
Reads map[string][]string `json:"reads"` |
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.
- counters are useless. they should be boolean.
- reads is a string to keep the value before the TX started, much like "prestateTracer" - the reason is to build sendRawTransactionConditional map during the tracer pass. there is no need to keep an array of strings.
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 kept the old api. We can change it now or later, it doesn't make much difference in this specific case.
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.
Approved.
No description provided.