-
Notifications
You must be signed in to change notification settings - Fork 20.4k
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
accounts/abi: include fixed array size in offset for dynamic type #15285
Conversation
Barring a change that I have not noticed recently, I'm pretty sure that the ABI length of the static array is inferred from the type name, and thus does not require an offset. If it were a dynamic array however, then yes, it would need that in there. Dynamic array implementation is in this PR as well...lotta stuff here: #14743 |
To clarify I mean that the size of static arrays needs to be taken into account when calculating the offset used for dynamic types. An example: Suppose we have the function
But, the way the offset for dynamic types is currently calculated would instead result in:
The offset for "hello" should be 96 bytes (32 bytes for the offset, 2 * 32 bytes for the static array [1,2]), but it ends up being 64 bytes (32 bytes for the offset, 32 bytes for the static array). |
|
||
// ignore first 4 bytes of the output. This is the function identifier | ||
fixedArrStrPack = fixedArrStrPack[4:] | ||
if !bytes.Equal(fixedArrStrPack, exp) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing the output bytes is useful, but ultimately you should also check that it is possible to unpack what has been packed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that the unpacker interface currently supports unpacking method outputs, but not unpacking method inputs (feel free to correct me if I'm wrong here). Seems like adding support would be a bigger update and not sure if that should be a part of this PR or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, did you see my comment here:#15702 (comment) ?
Yes, unpacking method inputs would be a very useful addition. I'm not sure what the ABI-package status is now, haven't kept track of the various (three?) PR:s that are in progress.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it doesn't have to be part of this PR, though. If we merge the current PR:s, I believe that making abi-unpacking more generic (supporting both input and output) can be added afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me, happy to help out with making abi unpacking more generic in a separate PR if needed as well
@@ -367,6 +367,56 @@ func TestInputVariableInputLength(t *testing.T) { | |||
} | |||
} | |||
|
|||
func TestInputFixedArrayAndVariableInputLength(t *testing.T) { | |||
const definition = `[ | |||
{ "type" : "function", "name" : "fixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would make sense to test more functions, accepting a mixed amount of arguments. For example, put the fixed array first, have several arrays (some dynamic, others not) and so on. You never know what kind of change will come after you.
Didn't have a chance to follow up on this PR until now, but I added additional test cases that include different method input combinations that use fixed and dynamic arrays. Also updated the code in |
Currently, when ABI encoding arguments the offset in bytes to the start of the data area for dynamic types is calculated as
len(method.Inputs)*32 + len(variableInput)
wherelen(method.Inputs)*32
is the number of arguments multiplied by 32 bytes per argument andlen(variableInput)
is the byte length of the output appended to the end of packed output (used for dynamic types i.e strings and bytes). According to the ABI specification, each element of a fixed size array should take up 32 bytes i.e.uint256[0] takes up 32 bytes and uint256[1] takes up 32 bytes`. This not currently reflected in the calculation of the offset in bytes to the start of the data area for dynamic types.This includes a fix for the offset calculation along with a test.