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

[LSP2] Tuple encoding #186

Open
JeneaVranceanu opened this issue Mar 6, 2023 · 1 comment
Open

[LSP2] Tuple encoding #186

JeneaVranceanu opened this issue Mar 6, 2023 · 1 comment

Comments

@JeneaVranceanu
Copy link
Member

JeneaVranceanu commented Mar 6, 2023

We have the following tuple examples in the LSP2 standard:

Screenshot 2023-03-06 at 10 47 49

Screenshot 2023-03-06 at 10 45 12

These examples are valid and work both ways - encoding and decoding.
But using tuples like (address,bytes,string) or (bytes,bytes,bytes8) or anything where we have a dynamic type in any but the last position will not work because values are just "glued together".

And even though we can make this (bytes,bytes8) work by taking last 8 bytes as bytes8 and the rest as bytes it doesn't make sense when it comes to implementation of deocding.

Example:

type = (bytes,string)
values1 = (0xcafe,"not really a cafe, is it?")
values2 = (0xbeeeeeeeeeeeeeef,"some people just love it")

... doing encoding ...

values1Encoded = 0xcafe6e6f74207265616c6c79206120636166652c2069732069743f
values2Encoded = 0xbeeeeeeeeeeeeeef736f6d652070656f706c65206a757374206c6f7665206974

/// ERROR: where in these long blobs the first values start and the second end?
decodeLsp2Values(type, values1Encoded)
decodeLsp2Values(type, values2Encoded)

I suggest we either fallback to using Solidity's way of encoding tuples or add the same 2 bytes for the length of each value (as we have in the CBAs) in the tuple, or even better we use the following idea suggested by @skimaharvey: #172 (comment)

The idea is to have 1 byte that will hold the length of the length of the element, the next 1 or more bytes that describe the length of the element and the next 1 or more bytes should be the element itself:

Screenshot 2023-03-06 at 11 07 10

Using that idea tuples will be encoded in the following manner:

type = (bytes,string)
values1 = (0xcafe,"not really a cafe, is it?")
values2 = (0xbeeeeeeeeeeeeeef,"some people just love it")

... doing encoding ...

values1Encoded = 0x01 02 cafe 01 19 6e6f74207265616c6c79206120636166652c2069732069743f
values2Encoded = 0x01 08 beeeeeeeeeeeeeef 01 18 736f6d652070656f706c65206a757374206c6f7665206974

/// No errors as we know the length! 
/// And it only takes in most cases `2 * tuple.countOfNestedTypes` bytes more per 1 tuple
/// Where `countOfNestedTypes` is the number of types you declare within parentheses `()`.
decodeLsp2Values(type, values1Encoded)
decodeLsp2Values(type, values2Encoded)
@CJ42
Copy link
Member

CJ42 commented Mar 6, 2023

One thing mentioned by @frozeman is that for certain schema, like when valueType is a tuple with two bytes inside as (bytes,bytes).

In such case, the valueContent, should tell. but some combinations are not automatically decodable,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants