Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DefaultFunctionEncoder calculates offset incorrectly for nested structs #2052

Closed
bladekp opened this issue May 8, 2024 · 2 comments
Closed
Labels
bug A bug in behaviour or functionality

Comments

@bladekp
Copy link

bladekp commented May 8, 2024

DefaultFunctionEncoder calculates offset incorrectly for nested structs

Steps To Reproduce

Minimal example:

  1. Create function which has nested structs as parameters, like:
	var f = new org.web3j.abi.datatypes.Function(
		"myCustomFunction",
		Arrays.asList(
			new StaticStruct(
				new StaticStruct(
					new org.web3j.abi.datatypes.Address("0x1"),
					new org.web3j.abi.datatypes.Address("0x2"))),
			new org.web3j.abi.datatypes.DynamicBytes(new byte[]{1,2,3})),
		Collections.emptyList());

Note that first argument is StaticStruct having one property which is also StaticStruct, nested one have two Address properties, which is important in this example. Also having dynamic type as second argument is important.

  1. Execute FunctionEncoder.encode(f). Result will be:
0x76a4d94f
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000040
0000000000000000000000000000000000000000000000000000000000000003
0102030000000000000000000000000000000000000000000000000000000000
  1. In result, since second argument is dynamic (DynamicBytes type) offset is included.

Expected behavior

Offset value in that case should equal to 0x60.

Actual behavior

Offset value is (as you can see above) 0x40, this is because nested StaticStruct is calculated to have size of 1 (but 2 addresses are inside, so size should be 2).

Environment

  • Web3j version 4.10.3
  • Java 17
  • Operating System Fedora 38 x64, kernel Linux 6.8.7-100.fc38.x86_64

Additional context

My production case, Im attaching two executions:

  • first one with wrong offset (0xe0 in my case), failure:
MethodID: 0x30f28b7a
[0]:  00000000000000000000000002567e4b14b25549331fcee2b56c647a8bab16fd
[1]:  0000000000000000000000000000000000000000000000000de0b6b3a7640000
[2]:  0000000000000000000000000000000000000000000000000000000000000006
[3]:  ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[4]:  000000000000000000000000f909259faf3f052792d7d28fb25ae54c43243041
[5]:  0000000000000000000000000000000000000000000000000de0b6b3a7640000
[6]:  000000000000000000000000d1f92a7f86cc94639ed6f3acd2ed540c742602dc
[7]:  00000000000000000000000000000000000000000000000000000000000000e0
[8]:  0000000000000000000000000000000000000000000000000000000000000041
[9]:  7d117587f7976edc3e9043e2ed79be2aa61b49d4513a410bfcc915b146663854
[10]: 253ccba5465141beb4f92adafdef1ab510a5854a61cdb860a1a3ceb1ae86d971
[11]: 1c00000000000000000000000000000000000000000000000000000000000000
  • second with adjusted offset (0x100), succeeded:
MethodID: 0x30f28b7a
[0]:  00000000000000000000000002567e4b14b25549331fcee2b56c647a8bab16fd
[1]:  0000000000000000000000000000000000000000000000000de0b6b3a7640000
[2]:  0000000000000000000000000000000000000000000000000000000000000006
[3]:  ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[4]:  000000000000000000000000f909259faf3f052792d7d28fb25ae54c43243041
[5]:  0000000000000000000000000000000000000000000000000de0b6b3a7640000
[6]:  000000000000000000000000d1f92a7f86cc94639ed6f3acd2ed540c742602dc
[7]:  0000000000000000000000000000000000000000000000000000000000000100
[8]:  0000000000000000000000000000000000000000000000000000000000000041
[9]:  7d117587f7976edc3e9043e2ed79be2aa61b49d4513a410bfcc915b146663854
[10]: 253ccba5465141beb4f92adafdef1ab510a5854a61cdb860a1a3ceb1ae86d971
[11]: 1c00000000000000000000000000000000000000000000000000000000000000

I think the solution is to make getLength function recursive, and change line:

count += ((StaticArray) type).getValue().size();

to count += getLength(((StaticArray) type).getValue())

@bladekp bladekp added the bug A bug in behaviour or functionality label May 8, 2024
@NickSneo
Copy link
Contributor

Hey @bladekp , thanks for opening the issue.
If you feel to contribute by fixing it, feel free to open up a PR, we will review and merge it.

Thanks

@bladekp
Copy link
Author

bladekp commented May 23, 2024

Looks like fix was prepared by @penuel-leo in #2054 and merged, and was released in https://github.com/hyperledger/web3j/releases/tag/v4.12.0 so I think we can close this issue. Thanks.

@bladekp bladekp closed this as completed May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug in behaviour or functionality
Projects
None yet
Development

No branches or pull requests

2 participants