Skip to content

Commit f4feaeb

Browse files
committed
accounts/abi: fix a bug in getTypeSize method (ethereum#21501)
* accounts/abi: fix a bug in getTypeSize method e.g. for "Tuple[2]" type, the element of the array is a tuple type and the size of the tuple may not be 32. * accounts/abi: add unit test of getTypeSize method
1 parent 089242b commit f4feaeb

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

accounts/abi/type.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ func isDynamicType(t Type) bool {
385385
func getTypeSize(t Type) int {
386386
if t.T == ArrayTy && !isDynamicType(*t.Elem) {
387387
// Recursively calculate type size if it is a nested array
388-
if t.Elem.T == ArrayTy {
388+
if t.Elem.T == ArrayTy || t.Elem.T == TupleTy {
389389
return t.Size * getTypeSize(*t.Elem)
390390
}
391391
return t.Size * 32

accounts/abi/type_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,39 @@ func TestInternalType(t *testing.T) {
330330
t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(kind)))
331331
}
332332
}
333+
334+
func TestGetTypeSize(t *testing.T) {
335+
var testCases = []struct {
336+
typ string
337+
components []ArgumentMarshaling
338+
typSize int
339+
}{
340+
// simple array
341+
{"uint256[2]", nil, 32 * 2},
342+
{"address[3]", nil, 32 * 3},
343+
{"bytes32[4]", nil, 32 * 4},
344+
// array array
345+
{"uint256[2][3][4]", nil, 32 * (2 * 3 * 4)},
346+
// array tuple
347+
{"tuple[2]", []ArgumentMarshaling{{Name: "x", Type: "bytes32"}, {Name: "y", Type: "bytes32"}}, (32 * 2) * 2},
348+
// simple tuple
349+
{"tuple", []ArgumentMarshaling{{Name: "x", Type: "uint256"}, {Name: "y", Type: "uint256"}}, 32 * 2},
350+
// tuple array
351+
{"tuple", []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}}, 32 * 2},
352+
// tuple tuple
353+
{"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32"}}}}, 32},
354+
{"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}, {Name: "y", Type: "uint256"}}}}, 32 * (2 + 1)},
355+
}
356+
357+
for i, data := range testCases {
358+
typ, err := NewType(data.typ, "", data.components)
359+
if err != nil {
360+
t.Errorf("type %q: failed to parse type string: %v", data.typ, err)
361+
}
362+
363+
result := getTypeSize(typ)
364+
if result != data.typSize {
365+
t.Errorf("case %d type %q: get type size error: actual: %d expected: %d", i, data.typ, result, data.typSize)
366+
}
367+
}
368+
}

0 commit comments

Comments
 (0)