PlutusData fixes and tests#669
Merged
Merged
Conversation
scarmuega
previously approved these changes
Jul 10, 2025
This has been broken for a while, and would ultimately result in all kind of errors and unexpected behaviours and errors. An example is when comparing two data in the Plutus Virtual Machine, they must match regardless of the chosen encoding (if one used an indefinite array and the other used a definite array, that shouldn't matter). It gets really subtle, for example with 'BigInt', as we now need to match the behaviour that's also present in the Haskell node. So for example, a serialized bigint with a payload [14], is equal to a simple serialized int of 14. Because of this, and because it is way too sensitive, we cannot rely on the auto-derived traits for any of the PartialEq and Ord implementations. They have to be carefully crafted to ensure that runtime behaviour closely follows the "specification". Note that I took the approach of preserving the PlutusData representation; which is an arguable choice in itself. An alternative could have been to use Rust data structure that could allow auto-deriving the traits. Although now, re-serializing isn't guaranteed to yield the same bytes and means PlutusData would also require some `KeepRaw` wrapper around. And, it would still demand a lot of care to ensure that the derived PartialEq and Ord traits are valid and remain conform to the Haskell implementation. So all-in-all, it's probably still better to keep hand-written instances.
scarmuega
approved these changes
Jul 12, 2025
scarmuega
pushed a commit
that referenced
this pull request
Jul 12, 2025
Closed
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
It would be really nice if this could also be backported on top of v0.32.0 and released as we (Amaru & Aiken) aren't ready to upgrade to v1.0.0 and those are critical fixes. We can always keep a fork but that prevents publishing to crates.io which is quite annoying.
📍 fix: ensure PlutusData encoding can roundtrip.
📍 fix: PlutusData ordering and equality
This has been broken for a while, and would ultimately result in all kind of errors and unexpected behaviours and errors. An example is when comparing two data in the Plutus Virtual Machine, they must match regardless of the chosen encoding (if one used an indefinite array and the other used a definite array, that shouldn't matter).
It gets really subtle, for example with 'BigInt', as we now need to match the behaviour that's also present in the Haskell node. So for example, a serialized bigint with a payload [14], is equal to a simple serialized int of 14.
Because of this, and because it is way too sensitive, we cannot rely on the auto-derived traits for any of the PartialEq and Ord implementations. They have to be carefully crafted to ensure that runtime behaviour closely follows the "specification".
Note that I took the approach of preserving the PlutusData representation; which is an arguable choice in itself. An alternative could have been to use Rust data structure that could allow auto-deriving the traits. Although now, re-serializing isn't guaranteed to yield the same bytes and means PlutusData would also require some
KeepRawwrapper around. And, it would still demand a lot of care to ensure that the derived PartialEq and Ord traits are valid and remain conform to the Haskell implementation. So all-in-all, it's probably still better to keep hand-written instances.