From 650e3127ad1b0bbc7d5cb73f028cef4fc5c694f1 Mon Sep 17 00:00:00 2001 From: Tangui Clairet Date: Fri, 25 Mar 2022 12:22:52 +0100 Subject: [PATCH 1/3] abi: handle []tuple --- accounts/abi/selector_parser.go | 10 +++++++++- accounts/abi/selector_parser_test.go | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/accounts/abi/selector_parser.go b/accounts/abi/selector_parser.go index 75609b28a6cc2..9319bd05f28b8 100644 --- a/accounts/abi/selector_parser.go +++ b/accounts/abi/selector_parser.go @@ -86,6 +86,9 @@ func parseCompositeType(unescapedSelector string) ([]interface{}, string, error) if len(rest) == 0 || rest[0] != ')' { return nil, "", fmt.Errorf("expected ')', got '%s'", rest) } + if len(rest) >= 3 && rest[1] == '[' && rest[2] == ']' { + return []interface{}{result}, rest[3:], nil + } return result, rest[1:], nil } @@ -112,7 +115,12 @@ func assembleArgs(args []interface{}) ([]ArgumentMarshaling, error) { if err != nil { return nil, fmt.Errorf("failed to assemble components: %v", err) } - arguments = append(arguments, ArgumentMarshaling{name, "tuple", "tuple", subArgs, false}) + if len(subArgs) == 1 && subArgs[0].Type == "tuple" { + subArgs[0].Type, subArgs[0].InternalType = "tuple[]", "tuple[]" + arguments = append(arguments, subArgs[0]) + } else { + arguments = append(arguments, ArgumentMarshaling{name, "tuple", "tuple", subArgs, false}) + } } else { return nil, fmt.Errorf("failed to assemble args: unexpected type %T", arg) } diff --git a/accounts/abi/selector_parser_test.go b/accounts/abi/selector_parser_test.go index 9720c9d5308e3..3e270c2679d78 100644 --- a/accounts/abi/selector_parser_test.go +++ b/accounts/abi/selector_parser_test.go @@ -16,6 +16,8 @@ func TestParseSelector(t *testing.T) { result = append(result, ArgumentMarshaling{name, typeName, typeName, nil, false}) } else if components, ok := typeOrComponents.([]ArgumentMarshaling); ok { result = append(result, ArgumentMarshaling{name, "tuple", "tuple", components, false}) + } else if components, ok := typeOrComponents.([][]ArgumentMarshaling); ok { + result = append(result, ArgumentMarshaling{name, "tuple[]", "tuple[]", components[0], false}) } else { log.Fatalf("unexpected type %T", typeOrComponents) } @@ -34,6 +36,7 @@ func TestParseSelector(t *testing.T) { {"singleNest(bytes32,uint8,(uint256,uint256),address)", "singleNest", mkType("bytes32", "uint8", mkType("uint256", "uint256"), "address")}, {"multiNest(address,(uint256[],uint256),((address,bytes32),uint256))", "multiNest", mkType("address", mkType("uint256[]", "uint256"), mkType(mkType("address", "bytes32"), "uint256"))}, + {"arrayNest((uint256,uint256)[])", "arrayNest", mkType([][]ArgumentMarshaling{mkType("uint256", "uint256")})}, } for i, tt := range tests { selector, err := ParseSelector(tt.input) From 9ea026089709c755b16f8a5021e202823b5b0a56 Mon Sep 17 00:00:00 2001 From: Tangui Clairet Date: Fri, 25 Mar 2022 12:23:48 +0100 Subject: [PATCH 2/3] refactor for more clarity --- accounts/abi/selector_parser.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/accounts/abi/selector_parser.go b/accounts/abi/selector_parser.go index 9319bd05f28b8..e0cf634ba2b9c 100644 --- a/accounts/abi/selector_parser.go +++ b/accounts/abi/selector_parser.go @@ -87,7 +87,7 @@ func parseCompositeType(unescapedSelector string) ([]interface{}, string, error) return nil, "", fmt.Errorf("expected ')', got '%s'", rest) } if len(rest) >= 3 && rest[1] == '[' && rest[2] == ']' { - return []interface{}{result}, rest[3:], nil + return append(result, "[]"), rest[3:], nil } return result, rest[1:], nil } @@ -115,12 +115,12 @@ func assembleArgs(args []interface{}) ([]ArgumentMarshaling, error) { if err != nil { return nil, fmt.Errorf("failed to assemble components: %v", err) } - if len(subArgs) == 1 && subArgs[0].Type == "tuple" { - subArgs[0].Type, subArgs[0].InternalType = "tuple[]", "tuple[]" - arguments = append(arguments, subArgs[0]) - } else { - arguments = append(arguments, ArgumentMarshaling{name, "tuple", "tuple", subArgs, false}) + tupleType := "tuple" + if len(subArgs) != 0 && subArgs[len(subArgs)-1].Type == "[]" { + subArgs = subArgs[:len(subArgs)-1] + tupleType = "tuple[]" } + arguments = append(arguments, ArgumentMarshaling{name, tupleType, tupleType, subArgs, false}) } else { return nil, fmt.Errorf("failed to assemble args: unexpected type %T", arg) } From a8112aa44a2b5258984a7b1fe70b377549e9674e Mon Sep 17 00:00:00 2001 From: Tangui Clairet Date: Tue, 29 Mar 2022 17:26:13 +0200 Subject: [PATCH 3/3] more test cases --- accounts/abi/selector_parser_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/accounts/abi/selector_parser_test.go b/accounts/abi/selector_parser_test.go index 3e270c2679d78..b5be6a3897de5 100644 --- a/accounts/abi/selector_parser_test.go +++ b/accounts/abi/selector_parser_test.go @@ -36,7 +36,13 @@ func TestParseSelector(t *testing.T) { {"singleNest(bytes32,uint8,(uint256,uint256),address)", "singleNest", mkType("bytes32", "uint8", mkType("uint256", "uint256"), "address")}, {"multiNest(address,(uint256[],uint256),((address,bytes32),uint256))", "multiNest", mkType("address", mkType("uint256[]", "uint256"), mkType(mkType("address", "bytes32"), "uint256"))}, - {"arrayNest((uint256,uint256)[])", "arrayNest", mkType([][]ArgumentMarshaling{mkType("uint256", "uint256")})}, + {"arrayNest((uint256,uint256)[],bytes32)", "arrayNest", mkType([][]ArgumentMarshaling{mkType("uint256", "uint256")}, "bytes32")}, + {"multiArrayNest((uint256,uint256)[],(uint256,uint256)[])", "multiArrayNest", + mkType([][]ArgumentMarshaling{mkType("uint256", "uint256")}, [][]ArgumentMarshaling{mkType("uint256", "uint256")})}, + {"singleArrayNestAndArray((uint256,uint256)[],bytes32[])", "singleArrayNestAndArray", + mkType([][]ArgumentMarshaling{mkType("uint256", "uint256")}, "bytes32[]")}, + {"singleArrayNestWithArrayAndArray((uint256[],address[2],uint8[4][][5])[],bytes32[])", "singleArrayNestWithArrayAndArray", + mkType([][]ArgumentMarshaling{mkType("uint256[]", "address[2]", "uint8[4][][5]")}, "bytes32[]")}, } for i, tt := range tests { selector, err := ParseSelector(tt.input)