Преглед изворни кода

accounts/abi: fix a bug in getTypeSize method (#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
Fuyang Deng пре 5 година
родитељ
комит
12d8570322
2 измењених фајлова са 37 додато и 1 уклоњено
  1. 1 1
      accounts/abi/type.go
  2. 36 0
      accounts/abi/type_test.go

+ 1 - 1
accounts/abi/type.go

@@ -386,7 +386,7 @@ func isDynamicType(t Type) bool {
 func getTypeSize(t Type) int {
 	if t.T == ArrayTy && !isDynamicType(*t.Elem) {
 		// Recursively calculate type size if it is a nested array
-		if t.Elem.T == ArrayTy {
+		if t.Elem.T == ArrayTy || t.Elem.T == TupleTy {
 			return t.Size * getTypeSize(*t.Elem)
 		}
 		return t.Size * 32

+ 36 - 0
accounts/abi/type_test.go

@@ -330,3 +330,39 @@ func TestInternalType(t *testing.T) {
 		t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(kind)))
 	}
 }
+
+func TestGetTypeSize(t *testing.T) {
+	var testCases = []struct {
+		typ        string
+		components []ArgumentMarshaling
+		typSize    int
+	}{
+		// simple array
+		{"uint256[2]", nil, 32 * 2},
+		{"address[3]", nil, 32 * 3},
+		{"bytes32[4]", nil, 32 * 4},
+		// array array
+		{"uint256[2][3][4]", nil, 32 * (2 * 3 * 4)},
+		// array tuple
+		{"tuple[2]", []ArgumentMarshaling{{Name: "x", Type: "bytes32"}, {Name: "y", Type: "bytes32"}}, (32 * 2) * 2},
+		// simple tuple
+		{"tuple", []ArgumentMarshaling{{Name: "x", Type: "uint256"}, {Name: "y", Type: "uint256"}}, 32 * 2},
+		// tuple array
+		{"tuple", []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}}, 32 * 2},
+		// tuple tuple
+		{"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32"}}}}, 32},
+		{"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}, {Name: "y", Type: "uint256"}}}}, 32 * (2 + 1)},
+	}
+
+	for i, data := range testCases {
+		typ, err := NewType(data.typ, "", data.components)
+		if err != nil {
+			t.Errorf("type %q: failed to parse type string: %v", data.typ, err)
+		}
+
+		result := getTypeSize(typ)
+		if result != data.typSize {
+			t.Errorf("case %d type %q: get type size error: actual: %d expected: %d", i, data.typ, result, data.typSize)
+		}
+	}
+}