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

Consider changing serialization of optional payload #401

Closed
PhilippGackstatter opened this issue Oct 5, 2023 · 6 comments
Closed

Consider changing serialization of optional payload #401

PhilippGackstatter opened this issue Oct 5, 2023 · 6 comments
Labels
team-node Issues for Node Team

Comments

@PhilippGackstatter
Copy link
Contributor

We could consider improving our serialization of optional types in serix, specifically of the optional payload in a Transaction Essence.

The Tagged Data Payload is optional, and the way we implement this optionality is by having a Payload Length prefix of type uint32 that, if 0, indicates that the type is absent. If it's there, the payload length holds the entire length of the optional payload, which is unnecessary. Additionally, we handle this payload specially in serix, which also seems unnecessary, and if removed, would reduce the serializer code size and its complexity.

It would suffice to have a byte indicating whether the type is absent (e.g. 0) or present (e.g. 1), and then continue reading the schema of whatever type is specified since the next byte would be that type's prefix byte. This way, we wouldn't need special code for optional payloads, but would even enable optional types more generically.
See also https://github.com/iotaledger/tips/blob/main/tips/TIP-0020/tip-0020.md#serialized-layout for the layout of the current Transaction and how the optional payload is serialized, which still matches what we have in code today.

@alexsporn
Copy link
Member

You still need a Payload Length in the Transaction, so that you know how many bytes should be read. For an optional field with a fixed size this extra byte you mentioned works, but not for variable size fields, for those we always require the length first.

@PhilippGackstatter
Copy link
Contributor Author

Why would it not be possible to read the bytes on-demand from the stream? You know the layout of a Tagged Data Payload, so if there was an indication that it's present, you can try to

  • read the type byte, and if it's tagged data
  • read the uint8 tag length, then the tag
  • read the uint32 data length, then the data.

I haven't looked into how serix does this exactly, but something similar must be done when reading a Metadata Feature. You only know the Features Count, and based on that you'll try to read each feature. You don't have a "Features Length" or something like that that tells you how long the entire features part is, or the individual one. There is no upfront info on how long the metadata is.

So, without having dove deeper into serix, I don't get why we need the Payload Length specifiying the entire length of the following payload when the tagged data itself has a well-defined layout, just like a Metadata Feature.

@alexsporn
Copy link
Member

That comparison does not work. Because of the Features Count you explicitely know that you will have a certain amount of typed features (all having a type of a specified size (uint8 or uint32)) and after you read all of them you are done reading the whole Features field.
For optional fields how can you know if the byte you are reading is from the object or from the object after that one? Relying on a specific type byte being present is hacky and is not guaranteed to be always safe. Because what happens if the field after the optional one also has a type that can have the same value?

@thibault-martinez
Copy link
Member

I am also in favour of removing the Payload Length. Payload is a type like any other and prefixing the length is not necessary. In the SDK we parse it because the protocol wants it but we don't use it. Payload is self-contained and can be read on demand.

@alexsporn alexsporn added the team-node Issues for Node Team label Jan 11, 2024
@alexsporn alexsporn moved this to Backlog in iota-core Jan 12, 2024
@muXxer
Copy link
Collaborator

muXxer commented Jan 15, 2024

Maybe come to a final conclusion when we do #653 .
The good thing about having a specific Payload Length is, that you can skip the whole payload in the deserialization if you don't want to check the payload itself.

@alexsporn alexsporn moved this from Backlog to Product Backlog in iota-core Jan 23, 2024
@muXxer muXxer moved this from Product Backlog to Discussion needed in iota-core Jan 29, 2024
@muXxer
Copy link
Collaborator

muXxer commented Mar 14, 2024

We decided to keep the payload length, so we can skip parsing the payload if not needed.

@muXxer muXxer closed this as completed Mar 14, 2024
@github-project-automation github-project-automation bot moved this from Discussion needed to Done in iota-core Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-node Issues for Node Team
Projects
Archived in project
Development

No branches or pull requests

4 participants