Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rude-moons-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@eth-optimism/l2geth": patch
---

CPU Optimization by caching ABI methods
18 changes: 12 additions & 6 deletions l2geth/accounts/abi/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type ABI struct {
Constructor Method
Methods map[string]Method
Events map[string]Event
MethodsById map[[4]byte]*Method
}

// JSON returns a parsed ABI interface and error if it failed.
Expand Down Expand Up @@ -120,6 +121,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
return err
}
abi.Methods = make(map[string]Method)
abi.MethodsById = make(map[[4]byte]*Method)
abi.Events = make(map[string]Event)
for _, field := range fields {
switch field.Type {
Expand All @@ -136,13 +138,17 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
_, ok = abi.Methods[name]
}
isConst := field.Constant || field.StateMutability == "pure" || field.StateMutability == "view"
abi.Methods[name] = Method{
method := Method{
Comment thread
gakonst marked this conversation as resolved.
Name: name,
RawName: field.Name,
Const: isConst,
Inputs: field.Inputs,
Outputs: field.Outputs,
}
abi.Methods[name] = method
// add method to the id cache
sigdata := method.ID()
abi.MethodsById[[4]byte{sigdata[0], sigdata[1], sigdata[2], sigdata[3]}] = &method
case "event":
name := field.Name
_, ok := abi.Events[name]
Expand All @@ -168,12 +174,12 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
if len(sigdata) < 4 {
return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata))
}
for _, method := range abi.Methods {
if bytes.Equal(method.ID(), sigdata[:4]) {
return &method, nil
}

method, exist := abi.MethodsById[[4]byte{sigdata[0], sigdata[1], sigdata[2], sigdata[3]}]
if !exist {
return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
}
return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
return method, nil
}

// EventByID looks an event up by its topic hash in the
Expand Down