Skip to content

Commit

Permalink
API: Full transaction in SnapshotConfirmed (#1685)
Browse files Browse the repository at this point in the history
Updates `SnapshotConfirmed` server output to contain full transactions
(instead of only transaction ids). This also updates TxValid to only
include the transaction id, such that transactions are only submitted
once per client still. Hence, this will not change the overall bandwidth
requirement on websocket clients, but will make their implementation
significantly easier.

Before, if clients wanted to act on transactions this was a lot easier
to do upon seing `TxValid`. However, this was only confirming local
ledger application and not consensus / enforcability of this transaction
onto the L1.

The new API suggests to do the right thing by making it straight-forward
to act upon seeing a transaction in a `SnapshotConfirmed`.

**TBD:** Changed `ServerOutput` field name `snapshotNumber` -> `number`
to be consistent with `version` (and the internal Haskell data type
names). Does anyone like `version` -> `snapshotVersion` better as an
alternative?

**TBD:** The field holding the transaction id in `TxValid` is called
`transactionId` now. The transaction (envelop) itself though contains
`txId`. This feels a bit inconsistent, which of the two should be
renamed?

This will also make #1612 easier (is mentioned as a sub-task there).

---

* [x] CHANGELOG updated
* [x] Documentation updated
* [x] Haddocks updated
* [x] No new TODOs introduced
  • Loading branch information
ch1bo authored Oct 9, 2024
2 parents 5862033 + a125d9b commit 48928b2
Show file tree
Hide file tree
Showing 51 changed files with 28,966 additions and 46,286 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ changes.

- Fix the bug where commit endpoint drops withdraw redeemers [#1643](https://github.com/cardano-scaling/hydra/issues/1643)

- **BREAKING** Change to `SnapshotConfirmed` and `TxValid` server outputs, as
well as to persisted `StateEvent` format:
- Snapshots now contain the full transactions in `confirmed` and field names changed.
- Persisted `StateChanged` events containing a snapshot changed consequently
and are not backward compatible.
- `TxValid` only refers to the transaction by id.
- Overall this results in transactions still to be submitted once per client,
but requires signifanctly less book-keeping on the client-side.

## [0.19.0] - 2024-09-13

- Tested with `cardano-node 9.1.1` and `cardano-cli 9.2.1.0`
Expand Down
22 changes: 10 additions & 12 deletions hydra-cluster/bench/Bench/EndToEnd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import Control.Concurrent.Class.MonadSTM (
tryReadTBQueue,
writeTBQueue,
)
import Control.Lens (to, (^?))
import Control.Lens (to, (^..), (^?))
import Control.Monad.Class.MonadAsync (mapConcurrently)
import Data.Aeson (Result (Error, Success), Value, encode, fromJSON, (.=))
import Data.Aeson.Lens (key, _Array, _JSON, _Number, _String)
import Data.Aeson.Lens (key, values, _JSON, _Number, _String)
import Data.Aeson.Types (parseMaybe)
import Data.List qualified as List
import Data.Map qualified as Map
Expand Down Expand Up @@ -424,7 +424,7 @@ newTx registry client tx = do
data WaitResult
= TxInvalid {transactionId :: TxId, reason :: Text}
| TxValid {transactionId :: TxId}
| SnapshotConfirmed {txIds :: [Value], snapshotNumber :: Scientific}
| SnapshotConfirmed {txIds :: [Value], number :: Scientific}

data Registry tx = Registry
{ processedTxs :: TVar IO (Map.Map TxId Event)
Expand Down Expand Up @@ -486,7 +486,7 @@ waitForAllConfirmations n1 Registry{processedTxs} allIds = do
maybeTxValid v = do
guard (v ^? key "tag" == Just "TxValid")
v
^? key "transaction" . key "txId" . to fromJSON >>= \case
^? key "transactionId" . to fromJSON >>= \case
Error _ -> Nothing
Success txid -> pure $ TxValid txid

Expand All @@ -501,14 +501,12 @@ waitForAllConfirmations n1 Registry{processedTxs} allIds = do
maybeSnapshotConfirmed v = do
guard (v ^? key "tag" == Just "SnapshotConfirmed")
snapshot <- v ^? key "snapshot"
SnapshotConfirmed
<$> snapshot
^? key "confirmedTransactions"
. _Array
. to toList
<*> snapshot
^? key "snapshotNumber"
. _Number
number <- snapshot ^? key "number" . _Number
pure $
SnapshotConfirmed
{ txIds = snapshot ^.. key "confirmed" . values . key "txId"
, number
}

confirmTx ::
TVar IO (Map.Map TxId Event) ->
Expand Down
4 changes: 2 additions & 2 deletions hydra-cluster/src/Hydra/Cluster/Scenarios.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1025,8 +1025,8 @@ respendUTxO client sk delay = do
waitMatch 10 client $ \v -> do
guard $ v ^? key "tag" == Just "SnapshotConfirmed"
guard $
toJSON (txId tx)
`elem` (v ^.. key "snapshot" . key "confirmedTransactions" . values)
toJSON tx
`elem` (v ^.. key "snapshot" . key "confirmed" . values)
v ^? key "snapshot" . key "utxo" >>= parseMaybe parseJSON

-- * Utilities
Expand Down
14 changes: 7 additions & 7 deletions hydra-cluster/test/Test/EndToEndSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -632,12 +632,12 @@ timedTx tmpDir tracer node@RunningNode{networkId, nodeSocket} hydraScriptsTxId =
-- Second submission: now valid
send n1 $ input "NewTx" ["transaction" .= tx]
waitFor hydraTracer 3 [n1] $
output "TxValid" ["transaction" .= tx, "headId" .= headId]
output "TxValid" ["transactionId" .= txId tx, "headId" .= headId]

confirmedTransactions <- waitMatch 3 n1 $ \v -> do
guard $ v ^? key "tag" == Just "SnapshotConfirmed"
v ^? key "snapshot" . key "confirmedTransactions"
confirmedTransactions ^.. values `shouldBe` [toJSON $ txId tx]
v ^? key "snapshot" . key "confirmed"
confirmedTransactions ^.. values `shouldBe` [toJSON tx]

initAndClose :: FilePath -> Tracer IO EndToEndLog -> Int -> TxId -> RunningNode -> IO ()
initAndClose tmpDir tracer clusterIx hydraScriptsTxId node@RunningNode{nodeSocket} = do
Expand Down Expand Up @@ -687,7 +687,7 @@ initAndClose tmpDir tracer clusterIx hydraScriptsTxId node@RunningNode{nodeSocke
aliceExternalSk
send n1 $ input "NewTx" ["transaction" .= tx]
waitFor hydraTracer 10 [n1, n2, n3] $
output "TxValid" ["transaction" .= tx, "headId" .= headId]
output "TxValid" ["transactionId" .= txId tx, "headId" .= headId]

-- The expected new utxo set is the created payment to bob,
-- alice's remaining utxo in head and whatever bot has
Expand Down Expand Up @@ -724,12 +724,12 @@ initAndClose tmpDir tracer clusterIx hydraScriptsTxId node@RunningNode{nodeSocke
waitMatch 10 n1 $ \v -> do
guard $ v ^? key "tag" == Just "SnapshotConfirmed"
guard $ v ^? key "headId" == Just (toJSON headId)
snapshotNumber <- v ^? key "snapshot" . key "snapshotNumber"
snapshotNumber <- v ^? key "snapshot" . key "number"
guard $ snapshotNumber == toJSON expectedSnapshotNumber
utxo <- v ^? key "snapshot" . key "utxo"
guard $ utxo == toJSON newUTxO
confirmedTransactions <- v ^? key "snapshot" . key "confirmedTransactions"
guard $ confirmedTransactions == toJSON [txId tx]
confirmedTransactions <- v ^? key "snapshot" . key "confirmed"
guard $ confirmedTransactions == toJSON [tx]

(toJSON <$> getSnapshotUTxO n1) `shouldReturn` toJSON newUTxO

Expand Down
19,180 changes: 0 additions & 19,180 deletions hydra-node/golden/ReasonablySized (ServerOutput (Tx ConwayEra)).json

This file was deleted.

Loading

0 comments on commit 48928b2

Please sign in to comment.