Status
Accepted
Context
- The Hydra.Ledger.Cardano module provides
ToJSON/FromJSON
instances forTx
and AlonzoTx- We have specified this format as part of Hydra API
- These instances appear in a few places as part of Hydra API:
- In the ServerOutput sent by the node to clients
- In the HydraNodeLog as part of Hydra's logging output
- In the StateChanged events which are persisted and allow hydra-node to restart gracefully after stopping
- In other places the hydra-node produces, expects, or accepts a CBOR-encoded transaction:
- In the Network.Message exchanged between the nodes
- In the ClientInput from clients submitting
NewTx
commands - In the HTTPServer API
- Note that in the latter 2 cases, the hydra-node accepts a hex-CBOR-encoded JSON string to represent a transaction and this particular case is handled directly in the FromJSON instance for transactions where 3 different representations are even accepted:
- JSON object detailing the transaction
- A JSON string representing CBOR-encoding of a transaction
- Or a
TextEnvelope
which wraps the CBOR transaction in a simple JSON object
- Using JSON-based representation of Cardano transactions is problematic because:
- The representation we are providing is not canonical nor widely used, and therefore require maintenance when the underlying cardano-ledger API changes
- More importantly the JSON representation contains a
txId
field which is computed from the CBOR encoding of the transaction. When this encoding changes, the transaction id changes even though no other part of the transaction has changed. This implies that we could send and receive transactions with incorrect or inconsistent identifiers.
- This is true for any content-addressable piece of data, eg. any piece of data whose unique identifier is derived from the data itself, but not of say UTxO which is just data.
Decision
- Drop support of "structured" JSON encoding of transactions in log messages, external APIs, and local storage of a node state
- Require JSON encoding for transactions that consists in:
- A
cborHex
string field containing the base16 CBOR-encoded transaction - An optional
txId
string field containing the Cardano transaction id, i.e. the base16 encoded Blake2b256 hash of the transaction body bytes - When present, the
txId
MUST be consistent with thecborHex
. This will be guaranteed for data produced by Hydra, but input data (eg. through aNewTx
message) that does not respect this constraint will be rejected
- A
Consequences
- This is a breaking change and client applications must decode the full transaction CBOR before accessing any part of it
- Hydra clients like
hydraw
,hydra-auction
,hydra-pay
,hydra-poll
and hydra-chess` need to be updated
- Hydra clients like
- By providing a
txId
field alongside the CBOR encoding, we still allow clients to observe the lifecycle of a transaction inside a Head as it gets validated and confirmed without requiring from them to be able to decode the CBOR body and compute thetxId
themselves- This is particularly important for monitoring which usually does not care about the details of transactions
- We should point users to existing tools for decoding transactions' content in a human-readable format as this can be useful for troubleshooting:
cardano-cli transaction view --tx-file <path to tx envelope file>
is one example
- We need to version the data that's persisted and exchanged, e.g the Head state and network messages, in order to ensure nodes can either gracefully migrate stored data or detect explicitly versions inconsistency
- We should use the cardanonical schemas should the need arise to represent transaction in JSON again