-
-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix serialization of (Plutus) 'Data'
The Cardano ledger does not enforce a single serialization format for most of the binary data that can end up on-chain. In CBOR, data-structures like lists or maps can be encoded in two ways: finite (using an explicit length) or indefinite (using begin/end markers). For example, the list [14] can be encoded either as: ``` 8114 # finite; 81 = 80 + 01, indicates a list of length 1 # OR 9F14FF # indefinite; 9F marks the beginning of the list and FF the end). ``` This means that, a same Haskell (or simply, unmarshalled) data-type can have multiple binary representations. The ledger copes with that by memoizing the original binary representation of decoded data, therefore avoiding to reserialize any data into a _different_ representation. Ogmios, and basically any program manipulating binary data from the chain MUST also use the same strategy. There is an example case with the following transaction on the testnet: <https://testnet.cexplorer.io/tx/c8b91a27976836f5ba349275bba3f0b81eb1d51aaf31a4340035ce450fdf83a7> which carries the following datum (<https://testnet.cexplorer.io/datum/06269f665176dc65b334d685b2f64826c092875ca77e15007b5f690ecc9db1af>) ``` D8798441FFD87982D87982D87982D87981581CC279A3FB3B4E62BBC78E2887 83B58045D4AE82A18867D8352D02775AD87981D87981D87981581C121FD22E 0B57AC206FEFC763F8BFA0771919F5218B40691EEA4514D0D87A80D87A801A 002625A0D87983D879801A000F4240D879811A000FA92E ``` Now, the datum reported by CExplorer (using cardano-db-sync) and Ogmios (before this commit) is: ``` D8799F41FFD8799FD8799FD8799FD8799F581CC279A3FB3B4E62BBC78E2887 83B58045D4AE82A18867D8352D02775AFFD8799FD8799FD8799F581C121FD2 2E0B57AC206FEFC763F8BFA0771919F5218B40691EEA4514D0FFFFFFFFD87A 80FFD87A80FF1A002625A0D8799FD879801A000F4240D8799F1A000FA92EFF FFFF ``` Both binary representation deserializes to the same high-level data-type, but the former uses finite data-structure in binary, whereas the latter uses indefinite structures. If one tries to re-calculate the hash digest of the reported datum, one obtains (obviously) something different than expected by the ledger. That's because this raw datum has been re-serialized by the programs consuming it from the chain whereas the hash calculated and used by the ledger is therefore the one corresponding to the original (finite data-structures) datum! This is tricky to reason about and also tricky to discover because, even property tests couldn't catch that (since the ledger's arbitrary instances do generate data only in the indefinite form!). Given the output of CExplorer, it seems that cardano-db-sync is also affected by this bug, and possibly more client applications down the line. Moreover, hardware devices are serializing all data using finite structures, creating this discrepency for applications interacting / using hardware integration.
- Loading branch information
Showing
32 changed files
with
94 additions
and
40 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.