Skip to content

Commit c7f0556

Browse files
committed
Complete ADR removing support for JSON Tx format
1 parent 62c7723 commit c7f0556

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed
+23-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
slug: 29
2+
slug: 30
33
title: |
4-
29. Use CBOR in external representation of Cardano objects
4+
30. Use CBOR in external representation of Cardano transactions
55
authors: [abailly]
66
tags: []
77
---
@@ -13,26 +13,37 @@ Proposed
1313
## Context
1414

1515
* The [Hydra.Ledger.Cardano](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/Ledger/Cardano.hs#L127] module provides `ToJSON/FromJSON` instances for [Alonzo.Tx](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/Ledger/Cardano/Json.hs#L361)
16-
* These representations are not _canonical_ and therefore require maintenance when the underlying cardano-ledger API changes
17-
* The format is [formally specified](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/json-schemas/api.yaml#L1473) as part of Hydra API
16+
* We have specified this format as part of [Hydra API](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/json-schemas/api.yaml#L1473)
1817
* These instances appear in a few places as part of Hydra API:
1918
* In the [ServerOutput](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/API/ServerOutput.hs#L51) sent by the node to clients
2019
* In the [HydraNodeLog](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/Node.hs#L122) as part of Hydra's logging output
21-
* More importantly, in the [StateChanged](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/HeadLogic/Outcome.hs#L46) events which are persisted and allow hydra-node to restart gracefully after stopping
22-
* In other places the hydra-node produces or expects a CBOR-encoded transaction:
20+
* In the [StateChanged](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/HeadLogic/Outcome.hs#L46) events which are persisted and allow hydra-node to restart gracefully after stopping
21+
* In other places the hydra-node produces, expects, or accepts a CBOR-encoded transaction:
2322
* In the [Network.Message](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/Network/Message.hs#L20) exchanged between the nodes
2423
* In the [ClientInput](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/API/ClientInput.hs#L9) from clients submitting `NewTx` commands
2524
* In the [HTTPServer](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/API/HTTPServer.hs#L297) API
26-
* 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](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/Ledger/Cardano/Json.hs#L388) instance for transactions where 2 different representations are even accepted:
27-
* Either directly a JSON string
28-
* Or using a `TextEnvelope` which wraps the CBOR transaction in a simple JSON object
25+
* 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](https://github.com/input-output-hk/hydra/blob/b2dc5a0da4988631bd2c1e94b66ba6217d5db595/hydra-node/src/Hydra/Ledger/Cardano/Json.hs#L388) instance for transactions where 3 different representations are even accepted:
26+
* JSON object detailing the transaction
27+
* A JSON string representing CBOR-encoding of a transaction
28+
* Or a `TextEnvelope` which wraps the CBOR transaction in a simple JSON object
29+
* Using JSON-based representation of Cardano transactions is problematic because:
30+
* The representation we are providing is not _canonical_ nor widely used, and therefore require maintenance when the underlying cardano-ledger API changes
31+
* **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.
32+
* 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.
2933

3034
## Decision
3135

32-
* Replace JSON representation of Transaction and UTxO by their CBOR representation
33-
* When part of a JSON message, CBOR is hex-encoded
36+
* Drop support of "structured" JSON encoding of transactions in log messages, external APIs, and local storage of a node state
37+
* Require JSON encoding for transactions that consists in:
38+
* A `cborHex` string field containing the base16 CBOR-encoded transaction
39+
* An optional `txId` string field containing the base16 encoding of the Blake2b256 hash of the transaction's bytes
40+
* When present, the `txId` MUST be consistent with the `cborHex`. This will be guaranteed for data produced by Hydra, but input data (eg. through a `NewTx` message) that does not respect this constraint will be rejected
3441

3542
## Consequences
3643

37-
* We no longer have transaction ids inside the Tx representation, so it might need to be provided alongside the CBOR encoding to alleviate the need of clients to decode and compute it "manually"
44+
* 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 the txId themselves
45+
* This is particularly important for monitoring which usually does not care about the details of transactions
46+
* We should point users to existing tools for decoding transactions' content in a human-readable format as this can be useful for troubleshooting:
47+
* `cardano-cli transaction view --tx-file <path to tx enveloppe file>` is one example
3848
* 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
49+
* We should use the [cardanonical](https://github.com/CardanoSolutions/cardanonical) schemas should the need arise to represent transaction in JSON again

0 commit comments

Comments
 (0)