Skip to content

Commit 2fac01b

Browse files
authored
Merge pull request #2298 from CortexFoundation/dev
accounts/abi: improve unpack performance
2 parents 6863540 + f8a2008 commit 2fac01b

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

accounts/abi/argument.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (arguments Arguments) Copy(v any, values []any) error {
127127
return arguments.copyAtomic(v, values[0])
128128
}
129129

130-
// unpackAtomic unpacks ( hexdata -> go ) a single value
130+
// copyAtomic copies ( hexdata -> go ) a single value
131131
func (arguments Arguments) copyAtomic(v any, marshalledValues any) error {
132132
dst := reflect.ValueOf(v).Elem()
133133
src := reflect.ValueOf(marshalledValues)
@@ -182,10 +182,16 @@ func (arguments Arguments) copyTuple(v any, marshalledValues []any) error {
182182
// without supplying a struct to unpack into. Instead, this method returns a list containing the
183183
// values. An atomic argument will be a list with one element.
184184
func (arguments Arguments) UnpackValues(data []byte) ([]any, error) {
185-
nonIndexedArgs := arguments.NonIndexed()
186-
retval := make([]any, 0, len(nonIndexedArgs))
187-
virtualArgs := 0
188-
for index, arg := range nonIndexedArgs {
185+
var (
186+
retval = make([]any, 0)
187+
virtualArgs = 0
188+
index = 0
189+
)
190+
191+
for _, arg := range arguments {
192+
if arg.Indexed {
193+
continue
194+
}
189195
marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data)
190196
if err != nil {
191197
return nil, err
@@ -208,6 +214,7 @@ func (arguments Arguments) UnpackValues(data []byte) ([]any, error) {
208214
virtualArgs += getTypeSize(arg.Type)/32 - 1
209215
}
210216
retval = append(retval, marshalledValue)
217+
index++
211218
}
212219
return retval, nil
213220
}

accounts/abi/unpack_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,46 @@ import (
3030
"github.com/stretchr/testify/require"
3131
)
3232

33+
func BenchmarkUnpack(b *testing.B) {
34+
testCases := []struct {
35+
def string
36+
packed string
37+
}{
38+
{
39+
def: `[{"type": "uint32"}]`,
40+
packed: "0000000000000000000000000000000000000000000000000000000000000001",
41+
},
42+
{
43+
def: `[{"type": "uint32[]"}]`,
44+
packed: "0000000000000000000000000000000000000000000000000000000000000020" +
45+
"0000000000000000000000000000000000000000000000000000000000000002" +
46+
"0000000000000000000000000000000000000000000000000000000000000001" +
47+
"0000000000000000000000000000000000000000000000000000000000000002",
48+
},
49+
}
50+
for i, test := range testCases {
51+
b.Run(strconv.Itoa(i), func(b *testing.B) {
52+
def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def)
53+
abi, err := JSON(strings.NewReader(def))
54+
if err != nil {
55+
b.Fatalf("invalid ABI definition %s: %v", def, err)
56+
}
57+
encb, err := hex.DecodeString(test.packed)
58+
if err != nil {
59+
b.Fatalf("invalid hex %s: %v", test.packed, err)
60+
}
61+
62+
b.ResetTimer()
63+
64+
var result any
65+
for range b.N {
66+
result, _ = abi.Unpack("method", encb)
67+
}
68+
_ = result
69+
})
70+
}
71+
}
72+
3373
// TestUnpack tests the general pack/unpack tests in packing_test.go
3474
func TestUnpack(t *testing.T) {
3575
t.Parallel()

0 commit comments

Comments
 (0)