From 6b0b0013d607fa31e34f45717dd949543a56d2bc Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Sat, 18 Jul 2026 03:11:50 +0000 Subject: [PATCH 01/62] cardano-wasm demo: staking (certificates, pool picker, stake witnesses) - per-wallet certificate menu: register / register+delegate / delegate-only / unregister; key deposit and refund reflected in the balance - live pool picker from Blockfrost /pools/extended, one page at a time (prev/next; no duplicates possible from shifting offsets) - delegation uses Blockfrost's hex pool id, with a golden-tested pure-Elm bech32 fallback decoder - signing attaches payment witnesses per input wallet and a stake witness (alsoSignWithStakeKey) per certificate wallet - README: full feature list --- .../20260718_cardano_wasm_demo_staking.yml | 9 + cardano-wasm/demo/README.md | 13 + cardano-wasm/demo/src/Bech32.elm | 130 +++++ cardano-wasm/demo/src/Blockfrost.elm | 60 ++- cardano-wasm/demo/src/Main.elm | 3 +- cardano-wasm/demo/src/Net.elm | 1 + cardano-wasm/demo/src/Ports.elm | 5 - cardano-wasm/demo/src/State.elm | 482 ++++++++++++------ cardano-wasm/demo/src/Types.elm | 93 +++- cardano-wasm/demo/src/Update.elm | 203 +++++++- cardano-wasm/demo/src/View.elm | 220 +++++++- cardano-wasm/demo/src/Wasm.elm | 207 +++++--- cardano-wasm/demo/web/ports.js | 48 +- 13 files changed, 1138 insertions(+), 336 deletions(-) create mode 100644 .changes/20260718_cardano_wasm_demo_staking.yml create mode 100644 cardano-wasm/demo/src/Bech32.elm diff --git a/.changes/20260718_cardano_wasm_demo_staking.yml b/.changes/20260718_cardano_wasm_demo_staking.yml new file mode 100644 index 0000000000..0f28b27147 --- /dev/null +++ b/.changes/20260718_cardano_wasm_demo_staking.yml @@ -0,0 +1,9 @@ +project: cardano-wasm + +pr: 1290 + +kind: + - feature + +description: | + Demo: staking certificates (register/delegate/unregister), paginated pool picker, stake witnesses. diff --git a/cardano-wasm/demo/README.md b/cardano-wasm/demo/README.md index ee94d04950..e69ab05bb6 100644 --- a/cardano-wasm/demo/README.md +++ b/cardano-wasm/demo/README.md @@ -6,6 +6,19 @@ signing happen in the wasm engine; chain data (UTxOs, stake pools) and transacti submission go through [Blockfrost](https://blockfrost.io) using a project id the user types into the page (kept in memory only). +What it demonstrates: + +- multiple wallets: generate stake-enabled key pairs, restore from bech32 signing keys +- mainnet / preprod / preview, with addresses re-derived on switch +- UTxOs and balances per wallet; payments with change and validated recipients + (cardano-wasm's `inspectAddress` flags invalid and wrong-network addresses) +- staking: register / register+delegate / delegate-only / unregister, with a paginated + live pool picker and payment + stake witnesses +- fee estimation (`estimateMinFee`) with balance and min-UTxO checks; the tx id is shown + right after signing (`getTxId`) +- submission via Blockfrost (hash cross-checked against the wasm tx id) or a + `cardano-cli` TextEnvelope download + The demo built from `master` is published at: **https://cardano-api.cardano.intersectmbo.org/cardano-wasm/demo/** diff --git a/cardano-wasm/demo/src/Bech32.elm b/cardano-wasm/demo/src/Bech32.elm new file mode 100644 index 0000000000..475deab4b8 --- /dev/null +++ b/cardano-wasm/demo/src/Bech32.elm @@ -0,0 +1,130 @@ +module Bech32 exposing (bech32ToHex) + +{-| PROVISIONAL bech32 → base16 decoder. + +The delegation certificate needs the pool id in base16, while the pool picker +carries the bech32 id from the provider. Blockfrost already returns the hex +directly, so this decoder is only a fallback for pools missing from the loaded +set. It performs no checksum validation. Ideally cardano-wasm would expose this +conversion and this module would disappear. + +-} + +import Bitwise +import Hex + + +bech32Charset : String +bech32Charset = + "qpzry9x8gf2tvdw0s3jn54khce6mua7l" + + +{-| Decode a bech32 string (e.g. "pool1…") to the base16 of its data payload, +dropping the human-readable prefix and the 6-symbol checksum. +No checksum validation — provisional. +-} +bech32ToHex : String -> Maybe String +bech32ToHex input = + let + chars = + String.toList (String.toLower input) + + sep = + lastIndexOfChar '1' chars 0 -1 + + vals = + List.drop (sep + 1) chars |> List.map charIndex + in + if sep < 0 || List.any (\v -> v < 0) vals || List.length vals < 6 then + Nothing + + else + convertBits 5 8 False (List.take (List.length vals - 6) vals) + |> Maybe.map Hex.bytesToHex + + +charIndex : Char -> Int +charIndex c = + indexInList c (String.toList bech32Charset) 0 + + +indexInList : Char -> List Char -> Int -> Int +indexInList c cs i = + case cs of + [] -> + -1 + + x :: rest -> + if x == c then + i + + else + indexInList c rest (i + 1) + + +lastIndexOfChar : Char -> List Char -> Int -> Int -> Int +lastIndexOfChar c cs i best = + case cs of + [] -> + best + + x :: rest -> + lastIndexOfChar c + rest + (i + 1) + (if x == c then + i + + else + best + ) + + +{-| Regroup a bit stream from `from`-bit symbols to `to`-bit symbols (the standard +bech32 5→8 bit conversion). Without padding, leftover bits must be zero. +-} +convertBits : Int -> Int -> Bool -> List Int -> Maybe (List Int) +convertBits from to pad data = + let + maxv = + Bitwise.shiftLeftBy to 1 - 1 + + drain acc bits out = + if bits >= to then + drain acc (bits - to) (Bitwise.and maxv (Bitwise.shiftRightBy (bits - to) acc) :: out) + + else + ( bits, out ) + + step v ( acc, bits, out ) = + let + acc1 = + Bitwise.or (Bitwise.shiftLeftBy from acc) v + + ( bits2, out2 ) = + drain acc1 (bits + from) out + + mask = + Bitwise.shiftLeftBy bits2 1 - 1 + in + ( Bitwise.and mask acc1, bits2, out2 ) + + ( finalAcc, finalBits, revOut ) = + List.foldl step ( 0, 0, [] ) data + in + if pad then + Just + (List.reverse + (if finalBits > 0 then + Bitwise.and maxv (Bitwise.shiftLeftBy (to - finalBits) finalAcc) :: revOut + + else + revOut + ) + ) + + else if finalBits >= from || Bitwise.and maxv (Bitwise.shiftLeftBy (to - finalBits) finalAcc) /= 0 then + Nothing + + else + Just (List.reverse revOut) diff --git a/cardano-wasm/demo/src/Blockfrost.elm b/cardano-wasm/demo/src/Blockfrost.elm index 98d039abb4..90b850a096 100644 --- a/cardano-wasm/demo/src/Blockfrost.elm +++ b/cardano-wasm/demo/src/Blockfrost.elm @@ -1,8 +1,8 @@ -module Blockfrost exposing (fetchUtxos, isBlockfrostNotFound, pageSize, submitTx, utxosDecoder) +module Blockfrost exposing (fetchPools, fetchUtxos, isBlockfrostNotFound, pageSize, submitTx, utxosDecoder) {-| The Blockfrost boundary (plain HTTP, CORS-friendly from a static page). -Supplies UTxOs and submits transactions — authenticated with the per-network -project id the user types into the UI. Deliberately kept +Supplies UTxOs and the pool list, submits transactions — authenticated with +the per-network project id the user types into the UI. Deliberately kept independent of `State`, so state helpers can build on this module without an import cycle. -} @@ -32,6 +32,18 @@ fetchUtxos key network wid addr = (expectUtxos (GotUtxos wid network)) +{-| One page of registered pools (pages are 1-based). The picker appends pages. +-} +fetchPools : String -> Network -> Int -> Cmd Msg +fetchPools key network page = + request key + network + "GET" + ("/pools/extended?count=" ++ String.fromInt pageSize ++ "&page=" ++ String.fromInt page) + Http.emptyBody + (expectPools GotPools) + + {-| POST the signed CBOR. The reply is stamped with the id of the transaction it answers, so a superseded submission's late reply can be told apart. -} @@ -111,6 +123,18 @@ expectUtxos = ) +expectPools : (Result String (List Pool) -> Msg) -> Http.Expect Msg +expectPools = + expectResponse + (\meta body -> + if meta.statusCode >= 200 && meta.statusCode < 300 then + D.decodeString poolsDecoder body |> Result.mapError D.errorToString + + else + Err (statusErrStr meta body) + ) + + {-| /tx/submit returns the tx hash as a JSON string on success, a JSON error otherwise. A 2xx only counts as success when the body actually is a tx hash — a proxy's page or an empty body must not become a confident "submitted". @@ -258,3 +282,33 @@ lovelaceQuantityDecoder = lovelaceIn : List ( String, Int ) -> Int lovelaceIn units = units |> List.filter (\( u, _ ) -> u == "lovelace") |> List.map Tuple.second |> List.sum + + +poolsDecoder : D.Decoder (List Pool) +poolsDecoder = + D.list + (D.map4 Pool + (D.field "pool_id" D.string) + (D.field "hex" D.string) + (D.field "live_stake" (D.nullable lovelaceStringDecoder) |> D.map (Maybe.withDefault 0)) + (D.field "live_saturation" (D.nullable D.float) |> D.map (Maybe.withDefault 0)) + ) + + +{-| Lovelace amounts arrive as strings (or occasionally numbers). +-} +lovelaceStringDecoder : D.Decoder Int +lovelaceStringDecoder = + D.oneOf + [ D.int + , D.string + |> D.andThen + (\s -> + case String.toInt s of + Just n -> + D.succeed n + + Nothing -> + D.fail "bad lovelace" + ) + ] diff --git a/cardano-wasm/demo/src/Main.elm b/cardano-wasm/demo/src/Main.elm index ff1fd2a6c2..d31b4c5159 100644 --- a/cardano-wasm/demo/src/Main.elm +++ b/cardano-wasm/demo/src/Main.elm @@ -7,7 +7,8 @@ module Main exposing (main) - Update — the controller (one branch per Msg) - View — the whole UI - Wasm — the cardano-wasm boundary (port commands + decoders) - - Net / Format — static tables and pure utilities + - Blockfrost — the chain-data boundary (HTTP) + - Net / Format / Hex / Bech32 — static tables and pure utilities - Ports — the raw port declarations (JS side: web/ports.js) -} diff --git a/cardano-wasm/demo/src/Net.elm b/cardano-wasm/demo/src/Net.elm index 09b2b83e3c..a377e2c106 100644 --- a/cardano-wasm/demo/src/Net.elm +++ b/cardano-wasm/demo/src/Net.elm @@ -12,6 +12,7 @@ module Net exposing ) {-| Static tables: the three networks and the two eras. Pure data — no logic +lives here. -} import Types exposing (..) diff --git a/cardano-wasm/demo/src/Ports.elm b/cardano-wasm/demo/src/Ports.elm index d08da8823d..e60a298b67 100644 --- a/cardano-wasm/demo/src/Ports.elm +++ b/cardano-wasm/demo/src/Ports.elm @@ -1,10 +1,5 @@ port module Ports exposing (..) -{-| The raw port declarations — the only holes in the wall between Elm and -JavaScript. The JS side lives in web/ports.js. Payloads are untyped JSON; -Wasm.elm encodes the requests and decodes the replies. --} - import Json.Decode as D import Json.Encode as E diff --git a/cardano-wasm/demo/src/State.elm b/cardano-wasm/demo/src/State.elm index e04c02ed54..b96224fa4a 100644 --- a/cardano-wasm/demo/src/State.elm +++ b/cardano-wasm/demo/src/State.elm @@ -1,5 +1,6 @@ module State exposing ( adaOnlyMinUtxo + , addCert , addWallet , addrFlagged , addrIssue @@ -8,10 +9,13 @@ module State exposing , amountBelowMin , balance , canSign + , certCode + , certMenu , changeAddress , changeRow , computeBalance , currentKey + , depositTotal , deselectInputs , distinct , emptyBookForm @@ -23,19 +27,26 @@ module State exposing , inputsTotal , invalidate , invalidateShape + , isFailed + , loadedPools , log , mapWallet , outputAddressesOk , outputsComplete , ownBook , paymentWalletIds + , poolByIdIn + , poolHex , removeAt , selectedInputs , setBookAddr , setBookAlias + , setCertPool , setCurrentKey , setRestorePay , setRestoreStake + , stakeHashOf + , stakeWalletIds , startFetch , submitLocked , toastNow @@ -47,6 +58,7 @@ module State exposing , updateAt , utxosTruncated , walletBalance + , walletCertAction , witnessCount ) @@ -54,6 +66,7 @@ module State exposing and update read), and the small pure updaters. No commands except the toast timer. -} +import Bech32 import Dict import Format exposing (adaToLovelace) import Net exposing (expectedNetKind) @@ -76,19 +89,24 @@ init protocol = , nextWid = 1 , book = [] , outputs = [] + , certs = [] , era = Conway , fee = NoFee , feeText = "" , tx = Draft , submit = NotSubmitted + , pools = NotAsked + , poolPage = 1 , modal = NoModal - , bfKeys = { mainnet = "", preprod = "", preview = "" } , restore = emptyRestoreForm , bookForm = emptyBookForm , console = - [ LogLine LogInfo "cardano-wasm loaded · post-link module ready" ] + [ LogLine LogInfo "cardano-wasm loaded · post-link module ready" + , LogLine LogInfo "data: Blockfrost (enter a free project id) · pinned protocol params" + ] , toast = Nothing , toastSeq = 0 + , bfKeys = { mainnet = "", preprod = "", preview = "" } , addrChecks = Dict.empty , protocol = protocol } @@ -228,7 +246,7 @@ startFetch w model = {-| The wallet's on-chain ADA. It includes lovelace sitting on token-carrying UTxOs the demo cannot spend: this is the real chain balance, not a spendable -amount (a later slice distinguishes the two when building payments). +amount (inputsTotal below counts only what the payment builder selected). -} walletBalance : Wallet -> Loadable Int walletBalance w = @@ -256,52 +274,6 @@ utxosTruncated w = False - --- CONSOLE & TOAST - - -log : LogLevel -> String -> Model -> Model -log level text model = - let - entries = - model.console ++ [ LogLine level text ] - in - -- keep the last 200 lines only - { model | console = List.drop (List.length entries - 200) entries } - - -{-| Show a toast and schedule its dismissal; the sequence number ignores stale timers. --} -toastNow : String -> Model -> ( Model, Cmd Msg ) -toastNow text model = - let - seq = - model.toastSeq + 1 - in - ( { model | toast = Just text, toastSeq = seq } - , Process.sleep 1900 |> Task.perform (\_ -> ClearToast seq) - ) - - - --- SMALL FORM UPDATERS - - -toggleRestore : RestoreForm -> RestoreForm -toggleRestore r = - { r | open = not r.open } - - -setRestorePay : String -> RestoreForm -> RestoreForm -setRestorePay s r = - { r | paymentSkey = s } - - -setRestoreStake : String -> RestoreForm -> RestoreForm -setRestoreStake s r = - { r | stakeSkey = s } - - {-| The address book shows own wallets first (derived, always current) plus the manually added external entries stored in model.book. -} @@ -444,6 +416,54 @@ explicitOutputsTotal model = |> List.sum +{-| Net deposit: +keyDeposit per registration, −keyDeposit (refund) per unregistration. +-} +depositTotal : Model -> Int +depositTotal model = + model.certs + |> List.map + (\c -> + case c.action of + Register -> + model.protocol.keyDeposit + + RegisterAndDelegate _ -> + model.protocol.keyDeposit + + Unregister -> + negate model.protocol.keyDeposit + + DelegateOnly _ -> + 0 + ) + |> List.sum + + + +-- WITNESSES +-- Payment witnesses come from wallets whose UTxOs are spent; stake witnesses from +-- wallets that carry a certificate. Distinct per wallet. + + +paymentWalletIds : Model -> List WalletId +paymentWalletIds model = + selectedInputs model |> List.map (\( w, _ ) -> w.id) |> distinct + + +stakeWalletIds : Model -> List WalletId +stakeWalletIds model = + model.certs |> List.map .wallet |> distinct + + +witnessCount : Model -> Int +witnessCount model = + List.length (paymentWalletIds model) + List.length (stakeWalletIds model) + + + +-- CHANGE & BALANCE + + {-| The output marked "change" (at most one), if any. -} changeRow : Model -> Maybe Output @@ -451,6 +471,98 @@ changeRow model = model.outputs |> List.filter (\o -> o.amount == Change) |> List.head +{-| Where the remainder goes: the change output if marked, else the first input wallet. +-} +changeAddress : Model -> Maybe String +changeAddress model = + case changeRow model of + Just o -> + Just o.address + + Nothing -> + selectedInputs model |> List.head |> Maybe.map (\( w, _ ) -> w.address) + + +{-| Balance arithmetic: change = inputs − outputs − deposit − fee, plus the +ADA-only min-UTxO check on the change. Plain integer bookkeeping over lovelace +totals — fee estimation, serialisation and signing all happen in cardano-wasm. +-} +computeBalance : Int -> { inputs : Int, outputs : Int, deposit : Int, fee : Int } -> Balance +computeBalance minUtxo t = + let + change = + t.inputs - t.outputs - t.deposit - t.fee + in + if change < 0 then + Insufficient (negate change) + + else if change == 0 then + Balanced 0 + + else if change < minUtxo then + DustChange change minUtxo + + else + Balanced change + + +{-| Minimum lovelace an ADA-only output must hold: +(≈65 B output + 160 B overhead) × coinsPerUtxoByte ≈ 0.97 ₳. +Only valid for ADA-only outputs — with native assets the size (and thus the +minimum) grows, which is one reason this demo blocks token-bearing UTxOs. +-} +adaOnlyMinUtxo : Protocol -> Int +adaOnlyMinUtxo protocol = + protocol.coinsPerUtxoByte * 225 + + +balanceWith : Int -> Model -> Balance +balanceWith fee model = + computeBalance (adaOnlyMinUtxo model.protocol) + { inputs = inputsTotal model + , outputs = explicitOutputsTotal model + , deposit = depositTotal model + , fee = fee + } + + +balance : Model -> Balance +balance model = + case model.fee of + FeeSet fee -> + balanceWith fee model + + _ -> + NoFeeYet + + + +-- READINESS GATES + + +{-| Enough of a transaction to estimate a fee: at least one input, something to do +(outputs or certificates), and no invalid amounts or addresses. +-} +txReady : Model -> Bool +txReady model = + not (List.isEmpty (selectedInputs model)) + && (explicitOutputsTotal model > 0 || changeRow model /= Nothing || not (List.isEmpty model.certs)) + && outputsComplete model + && outputAddressesOk model + + +{-| The sign button (and handler) gate: ready, fee set, balanced, still a draft. +-} +canSign : Model -> Bool +canSign model = + case ( model.fee, balance model, model.tx ) of + ( FeeSet _, Balanced _, Draft ) -> + txReady model + + _ -> + False + + {-| Every non-change output parses to at least the ADA-only min-UTxO amount — the node rejects smaller outputs at submission, so they must not reach signing. -} @@ -541,146 +653,105 @@ addrFlagged model a = addrVerdict model a |> Maybe.andThen (\_ -> addrIssue model a) -toggleBook : BookForm -> BookForm -toggleBook b = - { b | open = not b.open } +-- CERTIFICATES +-- One certificate per wallet, chosen from a small menu. The menu codes below are the +-- single source of truth shared by the view (options) and the update (parsing). -setBookAlias : String -> BookForm -> BookForm -setBookAlias s b = - { b | alias = s } +certMenu : List ( String, String ) +certMenu = + [ ( "", "no certificate" ) + , ( "reg", "Register stake key" ) + , ( "deleg", "Register + delegate" ) + , ( "delegonly", "Delegate only" ) + , ( "unreg", "Unregister stake key" ) + ] -setBookAddr : String -> BookForm -> BookForm -setBookAddr s b = - { b | address = s } +certCode : CertAction -> String +certCode action = + case action of + Register -> + "reg" -removeAt : Int -> List a -> List a -removeAt i xs = - List.indexedMap (\j x -> ( j, x )) xs - |> List.filter (\( j, _ ) -> j /= i) - |> List.map Tuple.second + RegisterAndDelegate _ -> + "deleg" + DelegateOnly _ -> + "delegonly" -updateAt : Int -> (a -> a) -> List a -> List a -updateAt i f xs = - List.indexedMap - (\j x -> - if j == i then - f x - - else - x - ) - xs + Unregister -> + "unreg" - --- WITNESSES --- Payment witnesses come from the wallets whose UTxOs are spent. Distinct per wallet. - - -paymentWalletIds : Model -> List WalletId -paymentWalletIds model = - selectedInputs model |> List.map (\( w, _ ) -> w.id) |> distinct - - -witnessCount : Model -> Int -witnessCount model = - List.length (paymentWalletIds model) - - -{-| Where the remainder goes: the change output if marked, else the first input wallet. +{-| The menu code of the wallet's current certificate ("" = none) — keeps the +per-wallet select in sync with the certificate list. -} -changeAddress : Model -> Maybe String -changeAddress model = - case changeRow model of - Just o -> - Just o.address +walletCertAction : WalletId -> Model -> String +walletCertAction wid model = + List.filter (\c -> c.wallet == wid) model.certs + |> List.head + |> Maybe.map (.action >> certCode) + |> Maybe.withDefault "" - Nothing -> - selectedInputs model |> List.head |> Maybe.map (\( w, _ ) -> w.address) +addCert : Certificate -> Model -> Model +addCert c model = + { model | certs = model.certs ++ [ c ] } |> invalidateShape -{-| Balance arithmetic: change = inputs − outputs − deposit − fee, plus the -ADA-only min-UTxO check on the change. Plain integer bookkeeping over lovelace -totals — fee estimation, serialisation and signing all happen in cardano-wasm. --} -computeBalance : Int -> { inputs : Int, outputs : Int, deposit : Int, fee : Int } -> Balance -computeBalance minUtxo t = - let - change = - t.inputs - t.outputs - t.deposit - t.fee - in - if change < 0 then - Insufficient (negate change) - else if change == 0 then - Balanced 0 +setCertPool : String -> Certificate -> Certificate +setCertPool pid c = + { c + | action = + case c.action of + RegisterAndDelegate _ -> + RegisterAndDelegate pid - else if change < minUtxo then - DustChange change minUtxo + DelegateOnly _ -> + DelegateOnly pid - else - Balanced change - - -{-| Minimum lovelace an ADA-only output must hold: -(≈65 B output + 160 B overhead) × coinsPerUtxoByte ≈ 0.97 ₳. -Only valid for ADA-only outputs — with native assets the size (and thus the -minimum) grows, which is one reason this demo blocks token-bearing UTxOs. --} -adaOnlyMinUtxo : Protocol -> Int -adaOnlyMinUtxo protocol = - protocol.coinsPerUtxoByte * 225 + other -> + other + } -balanceWith : Int -> Model -> Balance -balanceWith fee model = - computeBalance (adaOnlyMinUtxo model.protocol) - { inputs = inputsTotal model - , outputs = explicitOutputsTotal model - , deposit = 0 -- deposits arrive with certificates - , fee = fee - } +stakeHashOf : WalletId -> Model -> String +stakeHashOf wid model = + getWallet wid model |> Maybe.map (\w -> w.keys.stakeKeyHash) |> Maybe.withDefault "" -balance : Model -> Balance -balance model = - case model.fee of - FeeSet fee -> - balanceWith fee model - _ -> - NoFeeYet +-- POOLS +loadedPools : Model -> List Pool +loadedPools model = + case model.pools of + Loaded ps -> + ps --- READINESS GATES + _ -> + [] -{-| Enough of a transaction to estimate a fee: at least one input, something to -send, and no invalid amounts or addresses. --} -txReady : Model -> Bool -txReady model = - not (List.isEmpty (selectedInputs model)) - && (explicitOutputsTotal model > 0 || changeRow model /= Nothing) - && outputsComplete model - && outputAddressesOk model +poolByIdIn : List Pool -> String -> Maybe Pool +poolByIdIn ps pid = + List.filter (\p -> p.idBech32 == pid) ps |> List.head -{-| The sign button (and handler) gate: ready, fee set, balanced, still a draft. +{-| Pool base16 id for the delegation certificate. Prefer Blockfrost's `hex`; fall +back to the provisional Elm bech32 decoder if the pool isn't in the loaded set. -} -canSign : Model -> Bool -canSign model = - case ( model.fee, balance model, model.tx ) of - ( FeeSet _, Balanced _, Draft ) -> - txReady model +poolHex : Model -> String -> String +poolHex model pid = + case poolByIdIn (loadedPools model) pid of + Just p -> + p.idHex - _ -> - False + Nothing -> + Bech32.bech32ToHex pid |> Maybe.withDefault pid @@ -729,6 +800,81 @@ invalidateShape model = { model | tx = Draft, submit = NotSubmitted, fee = NoFee, feeText = "" } + +-- CONSOLE & TOAST + + +log : LogLevel -> String -> Model -> Model +log level text model = + let + entries = + model.console ++ [ LogLine level text ] + in + -- keep the last 200 lines only + { model | console = List.drop (List.length entries - 200) entries } + + +{-| Show a toast and schedule its dismissal; the sequence number ignores stale timers. +-} +toastNow : String -> Model -> ( Model, Cmd Msg ) +toastNow text model = + let + seq = + model.toastSeq + 1 + in + ( { model | toast = Just text, toastSeq = seq } + , Process.sleep 1900 |> Task.perform (\_ -> ClearToast seq) + ) + + + +-- SMALL FORM UPDATERS + + +toggleRestore : RestoreForm -> RestoreForm +toggleRestore r = + { r | open = not r.open } + + +setRestorePay : String -> RestoreForm -> RestoreForm +setRestorePay s r = + { r | paymentSkey = s } + + +setRestoreStake : String -> RestoreForm -> RestoreForm +setRestoreStake s r = + { r | stakeSkey = s } + + +toggleBook : BookForm -> BookForm +toggleBook b = + { b | open = not b.open } + + +setBookAlias : String -> BookForm -> BookForm +setBookAlias s b = + { b | alias = s } + + +setBookAddr : String -> BookForm -> BookForm +setBookAddr s b = + { b | address = s } + + + +-- GENERIC LIST HELPERS + + +isFailed : Loadable a -> Bool +isFailed l = + case l of + Failed _ -> + True + + _ -> + False + + {-| Deduplicate, keeping the first occurrence of each element (stable order). -} distinct : List comparable -> List comparable @@ -743,3 +889,23 @@ distinct xs = ) [] xs + + +removeAt : Int -> List a -> List a +removeAt i xs = + List.indexedMap (\j x -> ( j, x )) xs + |> List.filter (\( j, _ ) -> j /= i) + |> List.map Tuple.second + + +updateAt : Int -> (a -> a) -> List a -> List a +updateAt i f xs = + List.indexedMap + (\j x -> + if j == i then + f x + + else + x + ) + xs diff --git a/cardano-wasm/demo/src/Types.elm b/cardano-wasm/demo/src/Types.elm index 897f4467f8..1ef51a395e 100644 --- a/cardano-wasm/demo/src/Types.elm +++ b/cardano-wasm/demo/src/Types.elm @@ -1,9 +1,5 @@ module Types exposing (..) -{-| Every data type in the application: the Model (all state in one record) -and the Msg (everything that can happen). --} - import Dict exposing (Dict) import Http import Set exposing (Set) @@ -33,7 +29,7 @@ type alias Utxo = { txId : String , txIx : Int , lovelace : Int - , selected : Bool -- ticked as an input in the payment builder + , selected : Bool , hasAssets : Bool -- carries native tokens; unusable as input in this ADA-only demo } @@ -83,20 +79,25 @@ type alias Output = } -{-| Which family of networks an address belongs to. Addresses only encode -mainnet-vs-testnet, so preprod and preview cannot be told apart. --} -type NetKind - = MainKind - | TestKind +type CertAction + = Register + | RegisterAndDelegate String + | DelegateOnly String + | Unregister -{-| Result of cardano-wasm's inspectAddress for one address. --} -type AddrCheck - = CheckInvalid - | CheckValid NetKind - | CheckFailed -- the checker itself errored; not a verdict about the address +type alias Certificate = + { wallet : WalletId + , action : CertAction + } + + +type alias Pool = + { idBech32 : String + , idHex : String + , liveStake : Int + , saturation : Float + } type Era @@ -122,6 +123,22 @@ type alias SignedPayload = { cbor : String, txId : String } +{-| Which family of networks an address belongs to. Addresses only encode +mainnet-vs-testnet, so preprod and preview cannot be told apart. +-} +type NetKind + = MainKind + | TestKind + + +{-| Result of cardano-wasm's inspectAddress for one address. +-} +type AddrCheck + = CheckInvalid + | CheckValid NetKind + | CheckFailed -- the checker itself errored; not a verdict about the address + + type TxState = Draft | Signing @@ -135,19 +152,30 @@ type SubmitState | SubmitFailed String +type DelegKind + = RegThenDeleg + | DelegOnly + + +type PoolPurpose + = ForNewCert WalletId DelegKind + | ForEditCert Int + + type Modal = NoModal + | PoolPicker PoolPurpose String | ForgetDialog WalletId -type alias BookForm = - { open : Bool, alias : String, address : String } - - type alias RestoreForm = { open : Bool, paymentSkey : String, stakeSkey : String } +type alias BookForm = + { open : Bool, alias : String, address : String } + + type LogLevel = LogInfo | LogOk @@ -164,8 +192,8 @@ type alias GenPayload = {-| The two protocol parameters the Elm side needs for its balance arithmetic. -Read from web/pparams.js at startup (see web/ports.js) so the pinned object is -the single source of truth; everything else in it is consumed only by +Read from web/pparams.json at startup (see web/ports.js) so the pinned file is +the single source of truth; everything else in that file is consumed only by cardano-wasm's estimateMinFee. -} type alias Protocol = @@ -187,18 +215,21 @@ type alias Model = , nextWid : Int , book : List BookEntry , outputs : List Output + , certs : List Certificate , era : Era , fee : FeeState , feeText : String , tx : TxState , submit : SubmitState + , pools : Loadable (List Pool) -- the page of pools currently shown in the picker + , poolPage : Int -- its 1-based page number (Blockfrost pages, 100 pools each) , modal : Modal - , bfKeys : BfKeys , restore : RestoreForm , bookForm : BookForm , console : List LogLine , toast : Maybe String , toastSeq : Int + , bfKeys : BfKeys , addrChecks : Dict String AddrCheck -- inspectAddress results, keyed by address , protocol : Protocol } @@ -210,6 +241,7 @@ type alias BfKeys = type Msg = SelectNetwork Network + | UpdateBfKey String | ClickNewWallet | GotGeneratedWallet (Result String GenPayload) | ClickRestoreToggle @@ -224,7 +256,6 @@ type Msg | RequestForget WalletId | ConfirmForget WalletId | CancelForget - | UpdateBfKey String | ClickLoadUtxos WalletId | ClickLoadAll | GotUtxos WalletId Network (Result String UtxoPage) @@ -239,16 +270,26 @@ type Msg | UpdateOutputAmount Int String | ToggleOutputChange Int | DeleteOutput Int + | SetWalletCert WalletId String + | DeleteCertificate Int + | ChangeCertPool Int | ClearInputs | ClearOutputs + | ClearCerts | ClearTx - | GotAddressInspected (Result String ( String, AddrCheck )) + | UpdatePoolSearch String + | PickPool String + | ClosePoolModal + | ClickLoadPools + | ClickPoolPage Int + | GotPools (Result String (List Pool)) | SelectEra Era | ClickEstimateFee | GotFeeEstimated (Result String Int) | UpdateFeeText String | ClickSign | GotTxSigned (Result String SignedPayload) + | GotAddressInspected (Result String ( String, AddrCheck )) | ClickDownloadCli | ClickSubmit | GotSubmitted String (Result String String) diff --git a/cardano-wasm/demo/src/Update.elm b/cardano-wasm/demo/src/Update.elm index 65e515c993..e50b2cefb8 100644 --- a/cardano-wasm/demo/src/Update.elm +++ b/cardano-wasm/demo/src/Update.elm @@ -1,7 +1,7 @@ module Update exposing (update) {-| The controller: every Msg in one `update`. Pure state changes call State -helpers; effects go through Wasm (ports). +helpers; effects go through Wasm (ports), Blockfrost (HTTP), or File.Download. -} import Blockfrost @@ -34,6 +34,37 @@ inspectIfNew model a = Wasm.inspectAddress a +{-| Open the pool picker; fetch the pool list (once) if we have a key and none yet. +-} +openPool : PoolPurpose -> Model -> ( Model, Cmd Msg ) +openPool purpose model = + let + shouldFetch = + currentKey model /= "" && (model.pools == NotAsked || isFailed model.pools) + in + ( { model + | modal = PoolPicker purpose "" + , pools = + if shouldFetch then + Loading + + else + model.pools + , poolPage = + if shouldFetch then + 1 + + else + model.poolPage + } + , if shouldFetch then + Blockfrost.fetchPools (currentKey model) model.network 1 + + else + Cmd.none + ) + + update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of @@ -42,19 +73,29 @@ update msg model = -- ── network ──────────────────────────────────────────────────────────── SelectNetwork n -> - -- Balances are network-specific and swept. Wallet keys survive a network - -- switch; addresses are re-derived below (the bech32 encoding is - -- network-specific, the keys are not). Loads pause while the - -- re-derivation is pending so no request carries a stale address. - ( { model - | network = n - , wallets = List.map (\w -> { w | utxos = NotAsked }) model.wallets - , deriving = not (List.isEmpty model.wallets) - , reloading = Set.empty - , outputs = [] - } - |> invalidateShape - |> log LogInfo ("switched to " ++ netName n) + -- Everything network-specific is swept: balances, tx draft, fee, and the + -- pool list (pools differ per network!). Wallet keys survive; addresses + -- are re-derived below. addrChecks survive too (an address's network kind + -- is intrinsic to the address, not to the selected network). + let + swept = + { model + | network = n + , wallets = List.map (\w -> { w | utxos = NotAsked }) model.wallets + , outputs = [] + , certs = [] + , modal = NoModal + , pools = NotAsked + , poolPage = 1 + + -- loads pause until the new network's addresses arrive + , deriving = not (List.isEmpty model.wallets) + , reloading = Set.empty + } + |> invalidateShape + |> log LogInfo ("switched to " ++ netName n ++ " — cleared inputs, outputs, certs") + in + ( swept , if List.isEmpty model.wallets then Cmd.none @@ -83,6 +124,9 @@ update msg model = GotDerivedAddresses (Err e) -> ( log LogWarn ("derive addresses failed: " ++ e) { model | deriving = False }, Cmd.none ) + UpdateBfKey v -> + ( setCurrentKey v model, Cmd.none ) + -- ── wallets: generate / restore / edit / forget ──────────────────────── ClickNewWallet -> ( log LogCmd "CardanoApi.wallet.generateStakeWallet()" model @@ -135,6 +179,7 @@ update msg model = ConfirmForget wid -> ( { model | wallets = List.filter (\w -> w.id /= wid) model.wallets + , certs = List.filter (\c -> c.wallet /= wid) model.certs , modal = NoModal } |> invalidateShape @@ -143,9 +188,6 @@ update msg model = ) -- ── UTxOs (Blockfrost reads) ─────────────────────────────────────────── - UpdateBfKey v -> - ( setCurrentKey v model, Cmd.none ) - ClickLoadUtxos wid -> case getWallet wid model of Just w -> @@ -322,15 +364,109 @@ update msg model = DeleteOutput i -> ( { model | outputs = removeAt i model.outputs } |> invalidateShape, Cmd.none ) - -- ── clearing ─────────────────────────────────────────────────────────── - ClearInputs -> - ( deselectInputs model |> invalidateShape, Cmd.none ) + -- ── certificates ─────────────────────────────────────────────────────── + SetWalletCert wid raw -> + -- The select is bound to the wallet's current certificate: changing it + -- replaces (or clears) that wallet's cert; "" = no certificate. + let + cleared = + { model | certs = List.filter (\c -> c.wallet /= wid) model.certs } |> invalidateShape + in + case raw of + "reg" -> + ( addCert (Certificate wid Register) cleared |> log LogCmd (aliasOf wid model ++ ": register cert"), Cmd.none ) - ClearOutputs -> - ( { model | outputs = [] } |> invalidateShape, Cmd.none ) + "unreg" -> + ( addCert (Certificate wid Unregister) cleared |> log LogCmd (aliasOf wid model ++ ": unregister cert"), Cmd.none ) - ClearTx -> - ( deselectInputs { model | outputs = [] } |> invalidateShape, Cmd.none ) + "deleg" -> + openPool (ForNewCert wid RegThenDeleg) cleared + + "delegonly" -> + openPool (ForNewCert wid DelegOnly) cleared + + _ -> + ( cleared, Cmd.none ) + + DeleteCertificate i -> + ( { model | certs = removeAt i model.certs } |> invalidateShape, Cmd.none ) + + ChangeCertPool i -> + openPool (ForEditCert i) model + + -- ── pool picker ──────────────────────────────────────────────────────── + UpdatePoolSearch s -> + ( { model + | modal = + case model.modal of + PoolPicker p _ -> + PoolPicker p s + + other -> + other + } + , Cmd.none + ) + + PickPool pid -> + case model.modal of + PoolPicker (ForNewCert wid kind) _ -> + let + action = + case kind of + RegThenDeleg -> + RegisterAndDelegate pid + + DelegOnly -> + DelegateOnly pid + in + ( addCert (Certificate wid action) { model | modal = NoModal } + |> log LogCmd (aliasOf wid model ++ ": delegate to " ++ pid) + , Cmd.none + ) + + PoolPicker (ForEditCert i) _ -> + ( { model | certs = updateAt i (setCertPool pid) model.certs, modal = NoModal } |> invalidateShape, Cmd.none ) + + _ -> + ( model, Cmd.none ) + + ClosePoolModal -> + ( { model | modal = NoModal }, Cmd.none ) + + ClickLoadPools -> + -- (re)load the first page, from inside the picker (e.g. the key was + -- entered after opening it, or the fetch failed) + if currentKey model == "" then + toastNow "Enter a Blockfrost project id first" model + + else + ( { model | pools = Loading, poolPage = 1 } + , Blockfrost.fetchPools (currentKey model) model.network 1 + ) + + ClickPoolPage page -> + -- prev/next navigation: each view is exactly one server page, so shifting + -- offsets can never show duplicates. Only fetched on click. + if page < 1 || currentKey model == "" then + ( model, Cmd.none ) + + else + ( { model | pools = Loading, poolPage = page } + , Blockfrost.fetchPools (currentKey model) model.network page + ) + + GotPools (Ok ps) -> + ( { model | pools = Loaded ps } + |> log LogOk ("loaded " ++ String.fromInt (List.length ps) ++ " pools (page " ++ String.fromInt model.poolPage ++ ")") + , Cmd.none + ) + + GotPools (Err e) -> + ( { model | pools = Failed e } + |> log LogWarn ("pool list failed: " ++ e) + , Cmd.none + ) -- ── era & fee ────────────────────────────────────────────────────────── SelectEra e -> @@ -350,7 +486,7 @@ update msg model = ClickEstimateFee -> if not (txReady model) then - toastNow "Add inputs and a recipient, and fix any flagged issues" model + toastNow "Add inputs and a recipient or certificate, and fix any flagged issues" model else -- a fresh estimate makes any existing signature's fee basis stale @@ -396,7 +532,7 @@ update msg model = , Cmd.none ) - -- ── sign / export ────────────────────────────────────────────────────── + -- ── sign / submit / export ───────────────────────────────────────────── ClickSign -> -- same predicate that enables the button (fee set + balanced + draft + ready) case ( canSign model, model.fee ) of @@ -417,7 +553,7 @@ update msg model = else case result of Ok p -> - ( { model | tx = Signed (SignedTx p.cbor p.txId (List.length (paymentWalletIds model)) 0), submit = NotSubmitted } + ( { model | tx = Signed (SignedTx p.cbor p.txId (List.length (paymentWalletIds model)) (List.length (stakeWalletIds model))), submit = NotSubmitted } |> log LogOk ("transaction signed · txid " ++ p.txId) , Cmd.none ) @@ -523,6 +659,19 @@ update msg model = _ -> ( model, Cmd.none ) + -- ── clearing ─────────────────────────────────────────────────────────── + ClearInputs -> + ( deselectInputs model |> invalidateShape, Cmd.none ) + + ClearOutputs -> + ( { model | outputs = [] } |> invalidateShape, Cmd.none ) + + ClearCerts -> + ( { model | certs = [] } |> invalidateShape, Cmd.none ) + + ClearTx -> + ( deselectInputs { model | outputs = [], certs = [] } |> invalidateShape, Cmd.none ) + -- ── misc ─────────────────────────────────────────────────────────────── Copy t -> let diff --git a/cardano-wasm/demo/src/View.elm b/cardano-wasm/demo/src/View.elm index a6a5ab52e0..69d1ce4b4f 100644 --- a/cardano-wasm/demo/src/View.elm +++ b/cardano-wasm/demo/src/View.elm @@ -1,19 +1,24 @@ module View exposing (view) -{-| The UI: wallets + address book column · transaction builder · inspector + -console column, the forget dialog and the toast. Pure Model → Html. +{-| The entire UI: three columns (wallets + address book · transaction builder · +inspector + console), the pool/forget modals and the toast. Pure Model → Html. -} import Format exposing (ada, adaToLovelace, amountError, lovelaceToAda, shorten) import Html exposing (..) import Html.Attributes exposing (..) -import Html.Events exposing (onClick, onInput, stopPropagationOn) +import Html.Events exposing (on, onClick, onInput, stopPropagationOn, targetValue) import Json.Decode as D import Net exposing (cliFlag, eraTag, expectedNetKind, explorerTx, faucetUrl, netMagic, netName, netTag) import State exposing (..) import Types exposing (..) +onChange : (String -> msg) -> Attribute msg +onChange tagger = + on "change" (D.map tagger targetValue) + + view : Model -> Html Msg view model = div [] @@ -149,6 +154,18 @@ viewWallet model w = ] , button [ class "btn xs danger", onClick (RequestForget w.id) ] [ text "🗑 forget" ] ] + + -- bound to the wallet's current certificate; options come from + -- State.certMenu (the same codes the update parses) + , let + cur = + walletCertAction w.id model + in + select [ class "certsel", onChange (SetWalletCert w.id) ] + (List.map + (\( code, lbl ) -> option [ value code, selected (code == cur) ] [ text lbl ]) + certMenu + ) , viewWalletUtxos w ] @@ -345,6 +362,8 @@ viewBuilder model = , viewInputs model , sectionLabel "Outputs — add recipients from the address book" (not (List.isEmpty model.outputs)) ClearOutputs , viewOutputs model + , sectionLabel "Certificates — pick one in a wallet’s certificate menu" (not (List.isEmpty model.certs)) ClearCerts + , viewCerts model , viewSummary model , div [ class "hrow", style "margin-top" "12px" ] [ button [ class "btn ghost", disabled (not (txReady model)), onClick ClickEstimateFee ] [ text "⚙ estimateMinFee()" ] @@ -475,21 +494,73 @@ viewOutputs model = div [] (List.indexedMap row model.outputs ++ hint) -sectionLabel : String -> Bool -> Msg -> Html Msg -sectionLabel txt canClear clearMsg = - div [ class "seclabel" ] - [ label [] [ text txt ] - , if canClear then - button [ class "btn ghost xs", onClick clearMsg ] [ text "clear" ] +viewCerts : Model -> Html Msg +viewCerts model = + if List.isEmpty model.certs then + div [ class "empty" ] [ text "No certificates yet — pick one in a wallet’s certificate menu" ] - else - text "" - ] + else + div [] + (List.indexedMap + (\i c -> + let + wAlias = + aliasOf c.wallet model + + ( label_, poolMaybe ) = + certLabel (loadedPools model) c.action + in + div [ class "certrow" ] + [ span [ class "wav small", style "background" (getWallet c.wallet model |> Maybe.map .color |> Maybe.withDefault "#555") ] + [ text (String.left 1 wAlias |> String.toUpper) ] + , div [ class "grow" ] + [ b [] [ text wAlias ] + , div [ class "muted small" ] [ text label_ ] + ] + , case poolMaybe of + Just _ -> + button [ class "btn ghost xs", onClick (ChangeCertPool i) ] [ text "pool" ] + + Nothing -> + text "" + , button [ class "x", onClick (DeleteCertificate i) ] [ text "×" ] + ] + ) + model.certs + ) + + +certLabel : List Pool -> CertAction -> ( String, Maybe String ) +certLabel ps action = + let + poolName pid = + case poolByIdIn ps pid of + Just p -> + shorten p.idBech32 + + Nothing -> + shorten pid + in + case action of + Register -> + ( "Register", Nothing ) + + Unregister -> + ( "Unregister", Nothing ) + + DelegateOnly pid -> + ( "Delegate only → " ++ poolName pid, Just pid ) + + RegisterAndDelegate pid -> + ( "Register + delegate → " ++ poolName pid, Just pid ) viewSummary : Model -> Html Msg viewSummary model = let + dep = + depositTotal model + ( changeLabel, changeText ) = case ( model.fee, balance model ) of ( FeeSet _, Balanced ch ) -> @@ -507,6 +578,7 @@ viewSummary model = div [ class "summary" ] [ kv "Input total" (ada (inputsTotal model)) , kv "Output total" (ada (explicitOutputsTotal model)) + , kv "Deposit" (ada dep) , kv "Fee" (feeDisplay model) , kv changeLabel changeText , kv "Witnesses" (witnessSummary model) @@ -547,12 +619,18 @@ witnessSummary model = let pays = paymentWalletIds model |> List.map (\wid -> aliasOf wid model ++ " (payment)") + + stakes = + stakeWalletIds model |> List.map (\wid -> aliasOf wid model ++ " (stake)") + + parts = + pays ++ stakes in - if List.isEmpty pays then + if List.isEmpty parts then "—" else - String.join ", " pays ++ " · " ++ String.fromInt (witnessCount model) + String.join ", " parts ++ " · " ++ String.fromInt (witnessCount model) viewExport : Model -> Html Msg @@ -730,6 +808,18 @@ inspectorText model = ) |> (\explicit -> explicit ++ implicitChange) |> String.join ",\n" + + certs = + model.certs + |> List.map + (\c -> + let + ( lbl, _ ) = + certLabel (loadedPools model) c.action + in + " { stakeKey: \"" ++ aliasOf c.wallet model ++ "\", action: \"" ++ lbl ++ "\" }" + ) + |> String.join ",\n" in "{\n era: \"" ++ eraTag model.era @@ -737,6 +827,8 @@ inspectorText model = ++ ins ++ "\n ],\n outputs: [\n" ++ outs + ++ "\n ],\n certs: [\n" + ++ certs ++ "\n ],\n fee: " ++ specFee ++ ",\n requiredWitnesses: " @@ -744,6 +836,18 @@ inspectorText model = ++ "\n}" +sectionLabel : String -> Bool -> Msg -> Html Msg +sectionLabel txt canClear clearMsg = + div [ class "seclabel" ] + [ label [] [ text txt ] + , if canClear then + button [ class "btn ghost xs", onClick clearMsg ] [ text "clear" ] + + else + text "" + ] + + viewConsole : Model -> Html Msg viewConsole model = div [ class "card" ] @@ -813,6 +917,92 @@ viewModal model = ] ] + PoolPicker _ query -> + div [ class "modal-bg" ] + [ div [ class "modal" ] + [ div [ class "mh" ] + [ h3 [] [ text "Choose a stake pool" ] + , input [ class "poolsearch", placeholder "search ticker or id…", value query, onInput UpdatePoolSearch ] [] + , button [ class "btn ghost x", onClick ClosePoolModal ] [ text "✕" ] + ] + , div [ class "mb" ] (viewPoolList model query) + ] + ] + + +viewPoolList : Model -> String -> List (Html Msg) +viewPoolList model query = + case model.pools of + NotAsked -> + [ div [ class "empty" ] + [ text "pools not loaded — enter a Blockfrost project id, then " + , button [ class "btn ghost xs", onClick ClickLoadPools ] [ text "load pools" ] + ] + ] + + Loading -> + [ div [ class "empty" ] [ text "loading pools from Blockfrost…" ] ] + + Failed e -> + [ div [ class "empty" ] + [ text ("failed: " ++ e ++ " ") + , button [ class "btn ghost xs", onClick (ClickPoolPage model.poolPage) ] [ text "retry" ] + ] + ] + + Loaded ps -> + let + ql = + String.toLower query + + matches = + List.filter (\p -> String.contains ql (String.toLower p.idBech32)) ps + + cards = + if List.isEmpty matches then + [ div [ class "empty" ] [ text "no pools match (search covers this page only)" ] ] + + else + List.map viewPoolCard matches + in + cards ++ [ viewPoolPager model (List.length ps) ] + + +{-| Prev/next pager. A full page (100) means there is probably a next one; a short +page is the end of the list. Pages are only ever fetched on these clicks. +-} +viewPoolPager : Model -> Int -> Html Msg +viewPoolPager model pageSize = + div [ class "empty" ] + [ button + [ class "btn ghost xs", disabled (model.poolPage <= 1), onClick (ClickPoolPage (model.poolPage - 1)) ] + [ text "◂ prev" ] + , text (" page " ++ String.fromInt model.poolPage ++ " · " ++ String.fromInt pageSize ++ " pools ") + , button + [ class "btn ghost xs", disabled (pageSize < 100), onClick (ClickPoolPage (model.poolPage + 1)) ] + [ text "next ▸" ] + ] + + +viewPoolCard : Pool -> Html Msg +viewPoolCard p = + div [ class "poolcard", onClick (PickPool p.idBech32) ] + [ span [ class "tk" ] [ text "◆" ] + , div [ class "pm grow" ] + [ b [ class "mono" ] [ text (shorten p.idBech32) ] + , div [ class "d mono" ] [ text ("hex " ++ String.left 16 p.idHex ++ "…") ] + ] + , div [ class "stats" ] + [ statBox "live ₳" (lovelaceToAda p.liveStake) + , statBox "sat" (String.fromInt (round (p.saturation * 100)) ++ "%") + ] + ] + + +statBox : String -> String -> Html Msg +statBox lbl v = + div [] [ span [] [ text lbl ], text v ] + viewToast : Model -> Html Msg viewToast model = @@ -840,4 +1030,4 @@ kvSecret k v = stopClick : Attribute Msg stopClick = - stopPropagationOn "click" (D.succeed ( NoOp, True )) + Html.Events.stopPropagationOn "click" (D.succeed ( NoOp, True )) diff --git a/cardano-wasm/demo/src/Wasm.elm b/cardano-wasm/demo/src/Wasm.elm index 100b3b9498..a2e8de8174 100644 --- a/cardano-wasm/demo/src/Wasm.elm +++ b/cardano-wasm/demo/src/Wasm.elm @@ -15,9 +15,9 @@ module Wasm exposing {-| The cardano-wasm boundary. Commands encode a request and send it out a port; results come back on the matching incoming port and are decoded here (see the -subscriptions in Main). The Cardano processing itself — key handling, address encoding, transaction -building, fee estimation and signing — happens in web/ports.js through the -cardano-wasm wrapper. +subscriptions in Main). The Cardano processing itself — key handling, transaction +building, fee estimation, signing — happens on the JS side (web/ports.js) through +the cardano-wasm wrapper; the JSON built here just describes the transaction. -} import Format @@ -76,77 +76,6 @@ deriveAddresses net wallets = ) - --- DECODERS (in ← cardano-wasm) - - -{-| Every incoming port payload is either the expected object or { error }. --} -decodeResult : D.Decoder a -> D.Value -> Result String a -decodeResult dec v = - case D.decodeValue (D.field "error" D.string) v of - Ok e -> - Err e - - Err _ -> - D.decodeValue dec v |> Result.mapError D.errorToString - - -genDecoder : D.Decoder GenPayload -genDecoder = - D.map2 GenPayload - (D.field "address" D.string) - (D.field "keys" keysDecoder) - - -keysDecoder : D.Decoder Keys -keysDecoder = - D.map6 Keys - (D.field "paymentVKey" D.string) - (D.field "paymentSKey" D.string) - (D.field "stakeVKey" D.string) - (D.field "stakeSKey" D.string) - (D.field "paymentKeyHash" D.string) - (D.field "stakeKeyHash" D.string) - - -addrsDecoder : D.Decoder (List ( WalletId, String )) -addrsDecoder = - D.list (D.map2 Tuple.pair (D.field "id" D.int) (D.field "address" D.string)) - - -{-| Validate an address and detect its network kind. --} -inspectAddress : String -> Cmd msg -inspectAddress addr = - Ports.wasmInspectAddress (E.object [ ( "address", E.string addr ) ]) - - -inspectedDecoder : D.Decoder ( String, AddrCheck ) -inspectedDecoder = - D.map2 Tuple.pair - (D.field "address" D.string) - (D.field "network" D.string - |> D.map - (\n -> - case n of - "mainnet" -> - CheckValid MainKind - - "testnet" -> - CheckValid TestKind - - "invalid" -> - CheckInvalid - - _ -> - -- unknown answer or checker failure: distinct from a - -- verdict, so a real address is never called invalid - CheckFailed - ) - ) - - {-| Ask for the minimum fee of the currently described transaction. -} estimateFee : Model -> Cmd msg @@ -155,7 +84,7 @@ estimateFee model = (E.object [ ( "spec", encodeSpec Nothing model ) , ( "paymentWits", E.int (List.length (paymentWalletIds model)) ) - , ( "stakeWits", E.int 0 ) -- stake witnesses arrive with certificates + , ( "stakeWits", E.int (List.length (stakeWalletIds model)) ) ] ) @@ -168,15 +97,22 @@ signTx fee model = (E.object [ ( "spec", encodeSpec (Just fee) model ) , ( "paymentKeys", E.list E.string (paymentSigningKeys model) ) - , ( "stakeKeys", E.list E.string [] ) -- stake keys arrive with certificates + , ( "stakeKeys", E.list E.string (stakeSigningKeys model) ) ] ) +{-| Validate an address and detect its network kind. +-} +inspectAddress : String -> Cmd msg +inspectAddress addr = + Ports.wasmInspectAddress (E.object [ ( "address", E.string addr ) ]) + + -- TX SPEC -- The JSON description of the transaction that web/ports.js replays against the --- cardano-wasm builder (newTx → addTxInput → addSimpleTxOut). +-- cardano-wasm builder (newTx → addTxInput → addSimpleTxOut → appendCertificateToTx). encodeSpec : Maybe Int -> Model -> E.Value @@ -189,7 +125,7 @@ encodeSpec maybeFee model = (selectedInputs model) ) , ( "outputs", E.list identity (finalOutputs (Maybe.withDefault 0 maybeFee) model) ) - , ( "certs", E.list identity [] ) -- certificates arrive in a later change + , ( "certs", E.list identity (List.concatMap (certJson model) model.certs) ) , ( "fee", maybeFee |> Maybe.map E.int |> Maybe.withDefault E.null ) ] @@ -217,7 +153,7 @@ finalOutputs feeForChange model = ) chg = - inputsTotal model - explicitOutputsTotal model - feeForChange + inputsTotal model - explicitOutputsTotal model - depositTotal model - feeForChange changeOut = case ( changeAddress model, chg > 0 ) of @@ -235,9 +171,49 @@ outputJson addr lovelace = E.object [ ( "address", E.string addr ), ( "lovelace", E.int lovelace ) ] +{-| A certificate as JSON; "register + delegate" becomes two certificates. +NOTE: the unregistration refund must equal the deposit paid at registration. We use +the current keyDeposit — correct unless the protocol parameter changed in between +(fine for a demo). +-} +certJson : Model -> Certificate -> List E.Value +certJson model c = + let + skh = + stakeHashOf c.wallet model + + reg = + E.object [ ( "action", E.string "register" ), ( "stakeKeyHash", E.string skh ), ( "deposit", E.int model.protocol.keyDeposit ) ] + + unreg = + E.object [ ( "action", E.string "unregister" ), ( "stakeKeyHash", E.string skh ), ( "deposit", E.int model.protocol.keyDeposit ) ] + + deleg pid = + E.object + [ ( "action", E.string "delegate" ) + , ( "stakeKeyHash", E.string skh ) + , ( "poolId", E.string (poolHex model pid) ) + ] + in + case c.action of + Register -> + [ reg ] + + Unregister -> + [ unreg ] + + DelegateOnly pid -> + [ deleg pid ] + + RegisterAndDelegate pid -> + [ reg, deleg pid ] + + -- SIGNING KEYS --- Payment witnesses for the wallets whose UTxOs are spent. +-- Payment witnesses for the wallets whose UTxOs are spent; stake witnesses +-- (alsoSignWithStakeKey) for the wallets that carry a certificate. Registration +-- alone wouldn't need a stake witness, but an extra witness is harmless. paymentSigningKeys : Model -> List String @@ -247,6 +223,52 @@ paymentSigningKeys model = |> List.map (\w -> w.keys.paymentSKey) +stakeSigningKeys : Model -> List String +stakeSigningKeys model = + stakeWalletIds model + |> List.filterMap (\wid -> getWallet wid model) + |> List.map (\w -> w.keys.stakeSKey) + + + +-- DECODERS (in ← cardano-wasm) + + +{-| Every incoming port payload is either the expected object or { error }. +-} +decodeResult : D.Decoder a -> D.Value -> Result String a +decodeResult dec v = + case D.decodeValue (D.field "error" D.string) v of + Ok e -> + Err e + + Err _ -> + D.decodeValue dec v |> Result.mapError D.errorToString + + +genDecoder : D.Decoder GenPayload +genDecoder = + D.map2 GenPayload + (D.field "address" D.string) + (D.field "keys" keysDecoder) + + +keysDecoder : D.Decoder Keys +keysDecoder = + D.map6 Keys + (D.field "paymentVKey" D.string) + (D.field "paymentSKey" D.string) + (D.field "stakeVKey" D.string) + (D.field "stakeSKey" D.string) + (D.field "paymentKeyHash" D.string) + (D.field "stakeKeyHash" D.string) + + +addrsDecoder : D.Decoder (List ( WalletId, String )) +addrsDecoder = + D.list (D.map2 Tuple.pair (D.field "id" D.int) (D.field "address" D.string)) + + feeDecoder : D.Decoder Int feeDecoder = D.field "fee" D.int @@ -257,3 +279,28 @@ signedDecoder = D.map2 SignedPayload (D.field "cbor" D.string) (D.field "txId" D.string) + + +inspectedDecoder : D.Decoder ( String, AddrCheck ) +inspectedDecoder = + D.map2 Tuple.pair + (D.field "address" D.string) + (D.field "network" D.string + |> D.map + (\n -> + case n of + "mainnet" -> + CheckValid MainKind + + "testnet" -> + CheckValid TestKind + + "invalid" -> + CheckInvalid + + _ -> + -- unknown answer or checker failure: distinct from a + -- verdict, so a real address is never called invalid + CheckFailed + ) + ) diff --git a/cardano-wasm/demo/web/ports.js b/cardano-wasm/demo/web/ports.js index 75126c3465..142f6b6fd5 100644 --- a/cardano-wasm/demo/web/ports.js +++ b/cardano-wasm/demo/web/ports.js @@ -1,6 +1,7 @@ -// Port glue: Elm ⇄ cardano-wasm. The wrapper does the Cardano work here — -// key generation and restoration, address encoding and inspection, transaction -// building, fee estimation and signing. +// Port glue: Elm ⇄ cardano-wasm. The Cardano processing — wallet/key generation, +// address derivation, certificate building, tx building, fee estimation, signing, +// address inspection — happens here via the wrapper; Elm sends request objects over +// ports and decodes the results. // Protocol parameters come from a pinned module (pparams.js): estimateMinFee // requires the full cardano-ledger JSON format, which no CORS-friendly provider // serves directly, and the fee-relevant fields are stable across networks. Refresh @@ -30,18 +31,34 @@ async function restoreWallet(api, network, paymentSkey, stakeSkey) { : api.wallet.testnet.restoreStakeWalletFromSigningKeyBech32(magic[network], paymentSkey, stakeSkey); } +async function makeCert(api, era, c) { + const C = era === "dijkstra" ? api.certificate.upcomingEra : api.certificate.mainnetEra; + if (era === "dijkstra") { + if (c.action === "register") return C.makeStakeAddressRegistrationCertificateUpcomingEra(c.stakeKeyHash, BigInt(c.deposit)); + if (c.action === "unregister") return C.makeStakeAddressUnregistrationCertificateUpcomingEra(c.stakeKeyHash, BigInt(c.deposit)); + return C.makeStakeAddressStakeDelegationCertificateUpcomingEra(c.stakeKeyHash, c.poolId); + } + if (c.action === "register") return C.makeStakeAddressRegistrationCertificate(c.stakeKeyHash, BigInt(c.deposit)); + if (c.action === "unregister") return C.makeStakeAddressUnregistrationCertificate(c.stakeKeyHash, BigInt(c.deposit)); + return C.makeStakeAddressStakeDelegationCertificate(c.stakeKeyHash, c.poolId); +} + async function buildUnsigned(api, spec) { // Constructors are async (Promise) — must await. // NOTE: newConwayTx is advertised by getApiInfo but NOT exported by the current wasm build, // so use newTx() for the current era (= Conway). newUpcomingEraTx() works for Dijkstra. let tx = await (spec.era === "dijkstra" ? api.tx.newUpcomingEraTx() : api.tx.newTx()); - // Fluent builders (addTxInput/addSimpleTxOut) are synchronous chainers. + // Fluent builders (addTxInput/addSimpleTxOut/appendCertificateToTx) are synchronous chainers. for (const i of spec.inputs) tx = tx.addTxInput(i.txId, i.txIx); for (const o of spec.outputs) tx = tx.addSimpleTxOut(o.address, BigInt(o.lovelace)); + for (const c of spec.certs) { + const cert = await makeCert(api, spec.era, c); // certificate.* are async (return hex string) + tx = tx.appendCertificateToTx(cert); + } return tx; } -function wire(app, api) { +function wire(app, api, pparams) { app.ports.wasmGenerateWallet.subscribe(async ({ network }) => { try { const w = network === "mainnet" @@ -84,7 +101,7 @@ function wire(app, api) { // Payment witnesses (for the spent inputs) — signWithPaymentKey / alsoSignWithPaymentKey. let signed = await tx.signWithPaymentKey(paymentKeys[0]); // async → SignedTx for (const k of paymentKeys.slice(1)) signed = signed.alsoSignWithPaymentKey(k); // fluent, sync - // Stake witnesses — alsoSignWithStakeKey (used once certificates arrive). + // Stake witnesses (for delegation / unregistration certificates) — alsoSignWithStakeKey. for (const k of stakeKeys) signed = signed.alsoSignWithStakeKey(k); // fluent, sync const cbor = await signed.txToCbor(); // async → hex const txId = await signed.getTxId(); // async → 64-char hex (body hash; witness-independent) @@ -113,22 +130,11 @@ async function boot() { // pinned object, so there is a single source of truth. flags: { keyDeposit: pparams.stakeAddressDeposit, coinsPerUtxoByte: pparams.utxoCostPerByte }, }); - wire(app, api); + wire(app, api, pparams); } boot().catch((e) => { - const app = document.getElementById("app"); - if (!app) return; - - const msg = document.createElement("div"); - msg.style.cssText = "color:#e6edff;font-family:sans-serif;padding:30px"; - msg.append("Failed to load cardano-wasm:"); - - const pre = document.createElement("pre"); - pre.textContent = String(e); - msg.appendChild(document.createElement("br")); - msg.appendChild(pre); - msg.append("Make sure the page is served over http(s), not opened as a file://"); - - app.replaceChildren(msg); + document.getElementById("app").innerHTML = + '
Failed to load cardano-wasm:
' +
+    String(e) + "
Make sure the page is served over http(s), not opened as a file://
"; }); From a9d18a338601578db7bd552b891546e6b256ff73 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 12 Aug 2026 02:05:22 +0000 Subject: [PATCH 02/62] cardano-wasm demo: address review feedback - pin the pool's Blockfrost hex (and ticker) into the certificate at pick time instead of re-resolving it from the currently loaded picker page at estimate/sign time; drop the poolHex fallback path - stamp GotPools with the network and page it answers and drop stale replies, matching the GotUtxos landing-guard idiom - validate fully in Bech32.bech32ToHex (BIP-173 checksum, pool prefix, 28-byte payload, no mixed case); fix the fetchPools docstring (pages replace, not append) - show the pending menu choice while the pool picker is open and replace the wallet's certificate only on a confirmed pick, so cancelling rolls back and the DOM select stays in sync - decode and show metadata.ticker in the pool picker; search matches it - compute the pager's has-more flag at the fetch boundary; toast on retry without a project id; log pool fetches like other Blockfrost calls; use LogInfo for cert edits - ports.js: build the boot error message from DOM nodes/textContent instead of innerHTML; fail loudly on an empty payment-key list instead of wedging the wasm instance - docs: restore the Types/Ports module docstrings, pparams.js (not .json), certificate building in the Wasm module doc, the real stake-witness rule, and an honest certMenu comment --- cardano-wasm/demo/src/Bech32.elm | 87 +++++++++++++++--- cardano-wasm/demo/src/Blockfrost.elm | 20 +++-- cardano-wasm/demo/src/Ports.elm | 5 ++ cardano-wasm/demo/src/State.elm | 52 +++++------ cardano-wasm/demo/src/Types.elm | 42 +++++++-- cardano-wasm/demo/src/Update.elm | 127 ++++++++++++++++----------- cardano-wasm/demo/src/View.elm | 88 +++++++++++-------- cardano-wasm/demo/src/Wasm.elm | 28 +++--- cardano-wasm/demo/web/ports.js | 20 ++++- 9 files changed, 315 insertions(+), 154 deletions(-) diff --git a/cardano-wasm/demo/src/Bech32.elm b/cardano-wasm/demo/src/Bech32.elm index 475deab4b8..df2cbf12ce 100644 --- a/cardano-wasm/demo/src/Bech32.elm +++ b/cardano-wasm/demo/src/Bech32.elm @@ -1,12 +1,14 @@ module Bech32 exposing (bech32ToHex) -{-| PROVISIONAL bech32 → base16 decoder. +{-| Bech32 → base16 decoder for pool ids. -The delegation certificate needs the pool id in base16, while the pool picker -carries the bech32 id from the provider. Blockfrost already returns the hex -directly, so this decoder is only a fallback for pools missing from the loaded -set. It performs no checksum validation. Ideally cardano-wasm would expose this -conversion and this module would disappear. +The delegation certificate needs the pool id in base16; the picker pins +Blockfrost's hex at pick time, so the application no longer performs this +conversion itself. The module is kept as the safe path should a manual pool-id +entry ever be added: it validates fully (checksum, `pool` prefix, 28-byte +payload, no mixed case), so a mistyped id can never silently decode to a +different pool. Ideally cardano-wasm would expose this conversion and this +module would disappear. -} @@ -19,28 +21,89 @@ bech32Charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" -{-| Decode a bech32 string (e.g. "pool1…") to the base16 of its data payload, -dropping the human-readable prefix and the 6-symbol checksum. -No checksum validation — provisional. +{-| Decode a `pool1…` id to the base16 of its data payload, dropping the +prefix and the 6-symbol checksum. Full BIP-173 validation: rejects mixed case, +a prefix other than `pool`, a bad checksum, and any payload that is not +exactly the 28 bytes of a pool key hash. -} bech32ToHex : String -> Maybe String bech32ToHex input = let + lower = + String.toLower input + chars = - String.toList (String.toLower input) + String.toList lower sep = lastIndexOfChar '1' chars 0 -1 + hrp = + List.take sep chars + vals = List.drop (sep + 1) chars |> List.map charIndex + + -- BIP-173: a string must be all-lowercase or all-uppercase + mixedCase = + input /= lower && input /= String.toUpper input in - if sep < 0 || List.any (\v -> v < 0) vals || List.length vals < 6 then + if mixedCase || sep < 0 || List.any (\v -> v < 0) vals || List.length vals < 6 then + Nothing + + else if hrp /= String.toList "pool" || polymod (hrpExpand hrp ++ vals) /= 1 then Nothing else convertBits 5 8 False (List.take (List.length vals - 6) vals) - |> Maybe.map Hex.bytesToHex + |> Maybe.andThen + (\bytes -> + if List.length bytes == 28 then + Just (Hex.bytesToHex bytes) + + else + Nothing + ) + + +{-| The BIP-173 checksum: over `hrpExpand hrp ++ data` (data including the +6 checksum symbols) a valid bech32 string yields exactly 1. +-} +polymod : List Int -> Int +polymod values = + let + generator = + [ 0x3B6A57B2, 0x26508E6D, 0x1EA119FA, 0x3D4233DD, 0x2A1462B3 ] + + step v chk = + let + b = + Bitwise.shiftRightZfBy 25 chk + + shifted = + Bitwise.xor (Bitwise.shiftLeftBy 5 (Bitwise.and chk 0x01FFFFFF)) v + in + List.foldl + (\( i, g ) acc -> + if Bitwise.and (Bitwise.shiftRightZfBy i b) 1 == 1 then + Bitwise.xor acc g + + else + acc + ) + shifted + (List.indexedMap Tuple.pair generator) + in + List.foldl step 1 values + + +hrpExpand : List Char -> List Int +hrpExpand hrp = + let + codes = + List.map Char.toCode hrp + in + List.map (Bitwise.shiftRightBy 5) codes ++ [ 0 ] ++ List.map (Bitwise.and 31) codes charIndex : Char -> Int diff --git a/cardano-wasm/demo/src/Blockfrost.elm b/cardano-wasm/demo/src/Blockfrost.elm index 90b850a096..1a7e7176f6 100644 --- a/cardano-wasm/demo/src/Blockfrost.elm +++ b/cardano-wasm/demo/src/Blockfrost.elm @@ -1,4 +1,4 @@ -module Blockfrost exposing (fetchPools, fetchUtxos, isBlockfrostNotFound, pageSize, submitTx, utxosDecoder) +module Blockfrost exposing (fetchPools, fetchUtxos, isBlockfrostNotFound, pageSize, poolsDecoder, submitTx, utxosDecoder) {-| The Blockfrost boundary (plain HTTP, CORS-friendly from a static page). Supplies UTxOs and the pool list, submits transactions — authenticated with @@ -32,7 +32,10 @@ fetchUtxos key network wid addr = (expectUtxos (GotUtxos wid network)) -{-| One page of registered pools (pages are 1-based). The picker appends pages. +{-| One page of registered pools (pages are 1-based; each reply replaces the +shown page). The result is stamped with the network and page it was requested +for, so a late reply that lands after a network switch or another page click +can be dropped. -} fetchPools : String -> Network -> Int -> Cmd Msg fetchPools key network page = @@ -41,7 +44,7 @@ fetchPools key network page = "GET" ("/pools/extended?count=" ++ String.fromInt pageSize ++ "&page=" ++ String.fromInt page) Http.emptyBody - (expectPools GotPools) + (expectPools (GotPools network page)) {-| POST the signed CBOR. The reply is stamped with the id of the transaction @@ -123,12 +126,14 @@ expectUtxos = ) -expectPools : (Result String (List Pool) -> Msg) -> Http.Expect Msg +expectPools : (Result String PoolPage -> Msg) -> Http.Expect Msg expectPools = expectResponse (\meta body -> if meta.statusCode >= 200 && meta.statusCode < 300 then - D.decodeString poolsDecoder body |> Result.mapError D.errorToString + D.decodeString poolsDecoder body + |> Result.map (\ps -> { pools = ps, hasMore = List.length ps == pageSize }) + |> Result.mapError D.errorToString else Err (statusErrStr meta body) @@ -287,9 +292,12 @@ lovelaceIn units = poolsDecoder : D.Decoder (List Pool) poolsDecoder = D.list - (D.map4 Pool + (D.map5 Pool (D.field "pool_id" D.string) (D.field "hex" D.string) + -- `metadata` is null for pools that never registered any, and `ticker` + -- is nullable within it — D.maybe absorbs every shape + (D.maybe (D.at [ "metadata", "ticker" ] D.string)) (D.field "live_stake" (D.nullable lovelaceStringDecoder) |> D.map (Maybe.withDefault 0)) (D.field "live_saturation" (D.nullable D.float) |> D.map (Maybe.withDefault 0)) ) diff --git a/cardano-wasm/demo/src/Ports.elm b/cardano-wasm/demo/src/Ports.elm index e60a298b67..d08da8823d 100644 --- a/cardano-wasm/demo/src/Ports.elm +++ b/cardano-wasm/demo/src/Ports.elm @@ -1,5 +1,10 @@ port module Ports exposing (..) +{-| The raw port declarations — the only holes in the wall between Elm and +JavaScript. The JS side lives in web/ports.js. Payloads are untyped JSON; +Wasm.elm encodes the requests and decodes the replies. +-} + import Json.Decode as D import Json.Encode as E diff --git a/cardano-wasm/demo/src/State.elm b/cardano-wasm/demo/src/State.elm index b96224fa4a..374cef1edb 100644 --- a/cardano-wasm/demo/src/State.elm +++ b/cardano-wasm/demo/src/State.elm @@ -15,6 +15,7 @@ module State exposing , changeRow , computeBalance , currentKey + , delegKindCode , depositTotal , deselectInputs , distinct @@ -35,8 +36,6 @@ module State exposing , outputsComplete , ownBook , paymentWalletIds - , poolByIdIn - , poolHex , removeAt , selectedInputs , setBookAddr @@ -66,7 +65,6 @@ module State exposing and update read), and the small pure updaters. No commands except the toast timer. -} -import Bech32 import Dict import Format exposing (adaToLovelace) import Net exposing (expectedNetKind) @@ -655,8 +653,9 @@ addrFlagged model a = -- CERTIFICATES --- One certificate per wallet, chosen from a small menu. The menu codes below are the --- single source of truth shared by the view (options) and the update (parsing). +-- One certificate per wallet, chosen from a small menu. The menu codes below feed +-- the view's options; Update.SetWalletCert matches on the same literals, and +-- certCode/delegKindCode map the model types back to them. certMenu : List ( String, String ) @@ -685,6 +684,19 @@ certCode action = "unreg" +{-| The menu code a delegation pick would commit to — used by the view to show +the pending choice while the pool picker is open. +-} +delegKindCode : DelegKind -> String +delegKindCode kind = + case kind of + RegThenDeleg -> + "deleg" + + DelegOnly -> + "delegonly" + + {-| The menu code of the wallet's current certificate ("" = none) — keeps the per-wallet select in sync with the certificate list. -} @@ -701,16 +713,16 @@ addCert c model = { model | certs = model.certs ++ [ c ] } |> invalidateShape -setCertPool : String -> Certificate -> Certificate -setCertPool pid c = +setCertPool : PoolRef -> Certificate -> Certificate +setCertPool ref c = { c | action = case c.action of RegisterAndDelegate _ -> - RegisterAndDelegate pid + RegisterAndDelegate ref DelegateOnly _ -> - DelegateOnly pid + DelegateOnly ref other -> other @@ -729,31 +741,13 @@ stakeHashOf wid model = loadedPools : Model -> List Pool loadedPools model = case model.pools of - Loaded ps -> - ps + Loaded page -> + page.pools _ -> [] -poolByIdIn : List Pool -> String -> Maybe Pool -poolByIdIn ps pid = - List.filter (\p -> p.idBech32 == pid) ps |> List.head - - -{-| Pool base16 id for the delegation certificate. Prefer Blockfrost's `hex`; fall -back to the provisional Elm bech32 decoder if the pool isn't in the loaded set. --} -poolHex : Model -> String -> String -poolHex model pid = - case poolByIdIn (loadedPools model) pid of - Just p -> - p.idHex - - Nothing -> - Bech32.bech32ToHex pid |> Maybe.withDefault pid - - -- STALENESS -- A signed tx is a snapshot: any later edit makes it stale. diff --git a/cardano-wasm/demo/src/Types.elm b/cardano-wasm/demo/src/Types.elm index 1ef51a395e..e9491da5b6 100644 --- a/cardano-wasm/demo/src/Types.elm +++ b/cardano-wasm/demo/src/Types.elm @@ -1,5 +1,9 @@ module Types exposing (..) +{-| Every data type in the application: the Model (all state in one record) +and the Msg (everything that can happen). +-} + import Dict exposing (Dict) import Http import Set exposing (Set) @@ -81,11 +85,23 @@ type alias Output = type CertAction = Register - | RegisterAndDelegate String - | DelegateOnly String + | RegisterAndDelegate PoolRef + | DelegateOnly PoolRef | Unregister +{-| What a certificate remembers about its pool, captured at pick time: the +bech32 id and ticker for display, and Blockfrost's authoritative hex, which is +what goes into the certificate. Pinning these here means a certificate never +depends on which picker page happens to be loaded later. +-} +type alias PoolRef = + { bech32 : String + , hex : String + , ticker : Maybe String + } + + type alias Certificate = { wallet : WalletId , action : CertAction @@ -95,11 +111,21 @@ type alias Certificate = type alias Pool = { idBech32 : String , idHex : String + , ticker : Maybe String -- pools without registered metadata have none , liveStake : Int , saturation : Float } +{-| One fetched page of the pool list. `hasMore` is computed at the fetch +boundary: a full Blockfrost page means a next one probably exists. +-} +type alias PoolPage = + { pools : List Pool + , hasMore : Bool + } + + type Era = Conway | Dijkstra @@ -192,8 +218,8 @@ type alias GenPayload = {-| The two protocol parameters the Elm side needs for its balance arithmetic. -Read from web/pparams.json at startup (see web/ports.js) so the pinned file is -the single source of truth; everything else in that file is consumed only by +Read from web/pparams.js at startup (see web/ports.js) so the pinned object is +the single source of truth; everything else in it is consumed only by cardano-wasm's estimateMinFee. -} type alias Protocol = @@ -221,8 +247,8 @@ type alias Model = , feeText : String , tx : TxState , submit : SubmitState - , pools : Loadable (List Pool) -- the page of pools currently shown in the picker - , poolPage : Int -- its 1-based page number (Blockfrost pages, 100 pools each) + , pools : Loadable PoolPage -- the page of pools currently shown in the picker + , poolPage : Int -- its 1-based page number (one server page per view) , modal : Modal , restore : RestoreForm , bookForm : BookForm @@ -278,11 +304,11 @@ type Msg | ClearCerts | ClearTx | UpdatePoolSearch String - | PickPool String + | PickPool PoolRef | ClosePoolModal | ClickLoadPools | ClickPoolPage Int - | GotPools (Result String (List Pool)) + | GotPools Network Int (Result String PoolPage) | SelectEra Era | ClickEstimateFee | GotFeeEstimated (Result String Int) diff --git a/cardano-wasm/demo/src/Update.elm b/cardano-wasm/demo/src/Update.elm index e50b2cefb8..d628891ae1 100644 --- a/cardano-wasm/demo/src/Update.elm +++ b/cardano-wasm/demo/src/Update.elm @@ -39,30 +39,17 @@ inspectIfNew model a = openPool : PoolPurpose -> Model -> ( Model, Cmd Msg ) openPool purpose model = let - shouldFetch = - currentKey model /= "" && (model.pools == NotAsked || isFailed model.pools) + opened = + { model | modal = PoolPicker purpose "" } in - ( { model - | modal = PoolPicker purpose "" - , pools = - if shouldFetch then - Loading + if currentKey model /= "" && (model.pools == NotAsked || isFailed model.pools) then + ( { opened | pools = Loading, poolPage = 1 } + |> log LogInfo "GET blockfrost /pools/extended · page 1" + , Blockfrost.fetchPools (currentKey model) model.network 1 + ) - else - model.pools - , poolPage = - if shouldFetch then - 1 - - else - model.poolPage - } - , if shouldFetch then - Blockfrost.fetchPools (currentKey model) model.network 1 - - else - Cmd.none - ) + else + ( opened, Cmd.none ) update : Msg -> Model -> ( Model, Cmd Msg ) @@ -366,27 +353,35 @@ update msg model = -- ── certificates ─────────────────────────────────────────────────────── SetWalletCert wid raw -> - -- The select is bound to the wallet's current certificate: changing it - -- replaces (or clears) that wallet's cert; "" = no certificate. + -- The select is bound to the wallet's current certificate: "reg"/"unreg" + -- and "" replace or clear it immediately; the delegation entries only + -- open the picker — the replacement happens at PickPool, so cancelling + -- the picker leaves the previous certificate (and the fee) untouched. let - cleared = - { model | certs = List.filter (\c -> c.wallet /= wid) model.certs } |> invalidateShape + without = + List.filter (\c -> c.wallet /= wid) model.certs in case raw of "reg" -> - ( addCert (Certificate wid Register) cleared |> log LogCmd (aliasOf wid model ++ ": register cert"), Cmd.none ) + ( addCert (Certificate wid Register) { model | certs = without } + |> log LogInfo (aliasOf wid model ++ ": register cert") + , Cmd.none + ) "unreg" -> - ( addCert (Certificate wid Unregister) cleared |> log LogCmd (aliasOf wid model ++ ": unregister cert"), Cmd.none ) + ( addCert (Certificate wid Unregister) { model | certs = without } + |> log LogInfo (aliasOf wid model ++ ": unregister cert") + , Cmd.none + ) "deleg" -> - openPool (ForNewCert wid RegThenDeleg) cleared + openPool (ForNewCert wid RegThenDeleg) model "delegonly" -> - openPool (ForNewCert wid DelegOnly) cleared + openPool (ForNewCert wid DelegOnly) model _ -> - ( cleared, Cmd.none ) + ( { model | certs = without } |> invalidateShape, Cmd.none ) DeleteCertificate i -> ( { model | certs = removeAt i model.certs } |> invalidateShape, Cmd.none ) @@ -408,25 +403,31 @@ update msg model = , Cmd.none ) - PickPool pid -> + PickPool ref -> case model.modal of PoolPicker (ForNewCert wid kind) _ -> let action = case kind of RegThenDeleg -> - RegisterAndDelegate pid + RegisterAndDelegate ref DelegOnly -> - DelegateOnly pid + DelegateOnly ref in - ( addCert (Certificate wid action) { model | modal = NoModal } - |> log LogCmd (aliasOf wid model ++ ": delegate to " ++ pid) + -- the wallet's previous certificate is replaced only now, on a + -- confirmed pick — closing the picker instead leaves it as it was + ( addCert (Certificate wid action) + { model + | certs = List.filter (\c -> c.wallet /= wid) model.certs + , modal = NoModal + } + |> log LogInfo (aliasOf wid model ++ ": delegate to " ++ ref.bech32) , Cmd.none ) PoolPicker (ForEditCert i) _ -> - ( { model | certs = updateAt i (setCertPool pid) model.certs, modal = NoModal } |> invalidateShape, Cmd.none ) + ( { model | certs = updateAt i (setCertPool ref) model.certs, modal = NoModal } |> invalidateShape, Cmd.none ) _ -> ( model, Cmd.none ) @@ -442,31 +443,45 @@ update msg model = else ( { model | pools = Loading, poolPage = 1 } + |> log LogInfo "GET blockfrost /pools/extended · page 1" , Blockfrost.fetchPools (currentKey model) model.network 1 ) ClickPoolPage page -> -- prev/next navigation: each view is exactly one server page, so shifting -- offsets can never show duplicates. Only fetched on click. - if page < 1 || currentKey model == "" then + if currentKey model == "" then + toastNow "Enter a Blockfrost project id first" model + + else if page < 1 then ( model, Cmd.none ) else ( { model | pools = Loading, poolPage = page } + |> log LogInfo ("GET blockfrost /pools/extended · page " ++ String.fromInt page) , Blockfrost.fetchPools (currentKey model) model.network page ) - GotPools (Ok ps) -> - ( { model | pools = Loaded ps } - |> log LogOk ("loaded " ++ String.fromInt (List.length ps) ++ " pools (page " ++ String.fromInt model.poolPage ++ ")") - , Cmd.none - ) + GotPools network page result -> + -- accepted only for the network and page currently asked for: a reply + -- that was in flight across a network switch (or a second page click) + -- must not resurface as the shown list (the GotUtxos stamp idiom) + if network /= model.network || page /= model.poolPage then + ( model |> log LogWarn "dropped a stale pool list (network or page changed)", Cmd.none ) - GotPools (Err e) -> - ( { model | pools = Failed e } - |> log LogWarn ("pool list failed: " ++ e) - , Cmd.none - ) + else + case result of + Ok pp -> + ( { model | pools = Loaded pp } + |> log LogOk ("loaded " ++ String.fromInt (List.length pp.pools) ++ " pools (page " ++ String.fromInt page ++ ")") + , Cmd.none + ) + + Err e -> + ( { model | pools = Failed e } + |> log LogWarn ("pool list failed: " ++ e) + , Cmd.none + ) -- ── era & fee ────────────────────────────────────────────────────────── SelectEra e -> @@ -623,8 +638,22 @@ update msg model = else log LogWarn ("txid mismatch! wasm said " ++ expected ++ " but Blockfrost returned " ++ txid) + + -- an already-executed certificate left in the builder makes + -- the NEXT transaction invalid outright — worth a nudge + certReminder = + if List.isEmpty model.certs then + identity + + else + log LogInfo "certificates stay in the builder — clear them before building the next transaction" in - ( { model | submit = Submitted txid } |> log LogOk ("submitted · txid " ++ txid) |> consistency, Cmd.none ) + ( { model | submit = Submitted txid } + |> log LogOk ("submitted · txid " ++ txid) + |> consistency + |> certReminder + , Cmd.none + ) Err e -> let diff --git a/cardano-wasm/demo/src/View.elm b/cardano-wasm/demo/src/View.elm index 69d1ce4b4f..6412a34826 100644 --- a/cardano-wasm/demo/src/View.elm +++ b/cardano-wasm/demo/src/View.elm @@ -158,8 +158,21 @@ viewWallet model w = -- bound to the wallet's current certificate; options come from -- State.certMenu (the same codes the update parses) , let + -- While the picker is open for this wallet, show the pending + -- choice: the certificate itself only changes at PickPool, so on + -- cancel `cur` falls back and the vdom re-syncs the DOM select + -- (a `selected` property is only patched when this value changes). cur = - walletCertAction w.id model + case model.modal of + PoolPicker (ForNewCert wid kind) _ -> + if wid == w.id then + delegKindCode kind + + else + walletCertAction w.id model + + _ -> + walletCertAction w.id model in select [ class "certsel", onChange (SetWalletCert w.id) ] (List.map @@ -507,8 +520,8 @@ viewCerts model = wAlias = aliasOf c.wallet model - ( label_, poolMaybe ) = - certLabel (loadedPools model) c.action + ( label_, hasPool ) = + certLabel c.action in div [ class "certrow" ] [ span [ class "wav small", style "background" (getWallet c.wallet model |> Maybe.map .color |> Maybe.withDefault "#555") ] @@ -517,12 +530,11 @@ viewCerts model = [ b [] [ text wAlias ] , div [ class "muted small" ] [ text label_ ] ] - , case poolMaybe of - Just _ -> - button [ class "btn ghost xs", onClick (ChangeCertPool i) ] [ text "pool" ] + , if hasPool then + button [ class "btn ghost xs", onClick (ChangeCertPool i) ] [ text "pool" ] - Nothing -> - text "" + else + text "" , button [ class "x", onClick (DeleteCertificate i) ] [ text "×" ] ] ) @@ -530,29 +542,27 @@ viewCerts model = ) -certLabel : List Pool -> CertAction -> ( String, Maybe String ) -certLabel ps action = +{-| Label + whether the action carries a pool (and so can offer a "pool" button). +The pool is named by the ticker pinned at pick time, or its shortened bech32 id. +-} +certLabel : CertAction -> ( String, Bool ) +certLabel action = let - poolName pid = - case poolByIdIn ps pid of - Just p -> - shorten p.idBech32 - - Nothing -> - shorten pid + poolName ref = + Maybe.withDefault (shorten ref.bech32) ref.ticker in case action of Register -> - ( "Register", Nothing ) + ( "Register", False ) Unregister -> - ( "Unregister", Nothing ) + ( "Unregister", False ) - DelegateOnly pid -> - ( "Delegate only → " ++ poolName pid, Just pid ) + DelegateOnly ref -> + ( "Delegate only → " ++ poolName ref, True ) - RegisterAndDelegate pid -> - ( "Register + delegate → " ++ poolName pid, Just pid ) + RegisterAndDelegate ref -> + ( "Register + delegate → " ++ poolName ref, True ) viewSummary : Model -> Html Msg @@ -815,7 +825,7 @@ inspectorText model = (\c -> let ( lbl, _ ) = - certLabel (loadedPools model) c.action + certLabel c.action in " { stakeKey: \"" ++ aliasOf c.wallet model ++ "\", action: \"" ++ lbl ++ "\" }" ) @@ -950,13 +960,18 @@ viewPoolList model query = ] ] - Loaded ps -> + Loaded page -> let ql = String.toLower query matches = - List.filter (\p -> String.contains ql (String.toLower p.idBech32)) ps + List.filter + (\p -> + String.contains ql (String.toLower p.idBech32) + || String.contains ql (String.toLower (Maybe.withDefault "" p.ticker)) + ) + page.pools cards = if List.isEmpty matches then @@ -965,29 +980,30 @@ viewPoolList model query = else List.map viewPoolCard matches in - cards ++ [ viewPoolPager model (List.length ps) ] + cards ++ [ viewPoolPager model (List.length page.pools) page.hasMore ] -{-| Prev/next pager. A full page (100) means there is probably a next one; a short -page is the end of the list. Pages are only ever fetched on these clicks. +{-| Prev/next pager. `hasMore` was computed where the page was fetched (a full +Blockfrost page means a next one probably exists); a short page is the end of +the list. Pages are only ever fetched on these clicks. -} -viewPoolPager : Model -> Int -> Html Msg -viewPoolPager model pageSize = +viewPoolPager : Model -> Int -> Bool -> Html Msg +viewPoolPager model count hasMore = div [ class "empty" ] [ button [ class "btn ghost xs", disabled (model.poolPage <= 1), onClick (ClickPoolPage (model.poolPage - 1)) ] [ text "◂ prev" ] - , text (" page " ++ String.fromInt model.poolPage ++ " · " ++ String.fromInt pageSize ++ " pools ") + , text (" page " ++ String.fromInt model.poolPage ++ " · " ++ String.fromInt count ++ " pools ") , button - [ class "btn ghost xs", disabled (pageSize < 100), onClick (ClickPoolPage (model.poolPage + 1)) ] + [ class "btn ghost xs", disabled (not hasMore), onClick (ClickPoolPage (model.poolPage + 1)) ] [ text "next ▸" ] ] viewPoolCard : Pool -> Html Msg viewPoolCard p = - div [ class "poolcard", onClick (PickPool p.idBech32) ] - [ span [ class "tk" ] [ text "◆" ] + div [ class "poolcard", onClick (PickPool { bech32 = p.idBech32, hex = p.idHex, ticker = p.ticker }) ] + [ span [ class "tk" ] [ text (Maybe.withDefault "◆" p.ticker) ] , div [ class "pm grow" ] [ b [ class "mono" ] [ text (shorten p.idBech32) ] , div [ class "d mono" ] [ text ("hex " ++ String.left 16 p.idHex ++ "…") ] @@ -1030,4 +1046,4 @@ kvSecret k v = stopClick : Attribute Msg stopClick = - Html.Events.stopPropagationOn "click" (D.succeed ( NoOp, True )) + stopPropagationOn "click" (D.succeed ( NoOp, True )) diff --git a/cardano-wasm/demo/src/Wasm.elm b/cardano-wasm/demo/src/Wasm.elm index a2e8de8174..1dd7504dcd 100644 --- a/cardano-wasm/demo/src/Wasm.elm +++ b/cardano-wasm/demo/src/Wasm.elm @@ -1,5 +1,6 @@ module Wasm exposing ( addrsDecoder + , certJson , decodeResult , deriveAddresses , estimateFee @@ -15,9 +16,10 @@ module Wasm exposing {-| The cardano-wasm boundary. Commands encode a request and send it out a port; results come back on the matching incoming port and are decoded here (see the -subscriptions in Main). The Cardano processing itself — key handling, transaction -building, fee estimation, signing — happens on the JS side (web/ports.js) through -the cardano-wasm wrapper; the JSON built here just describes the transaction. +subscriptions in Main). The Cardano processing itself — key handling, certificate +building, transaction building, fee estimation, signing — happens on the JS side +(web/ports.js) through the cardano-wasm wrapper; the JSON built here just +describes the transaction. -} import Format @@ -188,11 +190,13 @@ certJson model c = unreg = E.object [ ( "action", E.string "unregister" ), ( "stakeKeyHash", E.string skh ), ( "deposit", E.int model.protocol.keyDeposit ) ] - deleg pid = + deleg ref = E.object [ ( "action", E.string "delegate" ) , ( "stakeKeyHash", E.string skh ) - , ( "poolId", E.string (poolHex model pid) ) + + -- Blockfrost's hex, pinned into the certificate at pick time + , ( "poolId", E.string ref.hex ) ] in case c.action of @@ -202,18 +206,20 @@ certJson model c = Unregister -> [ unreg ] - DelegateOnly pid -> - [ deleg pid ] + DelegateOnly ref -> + [ deleg ref ] - RegisterAndDelegate pid -> - [ reg, deleg pid ] + RegisterAndDelegate ref -> + [ reg, deleg ref ] -- SIGNING KEYS -- Payment witnesses for the wallets whose UTxOs are spent; stake witnesses --- (alsoSignWithStakeKey) for the wallets that carry a certificate. Registration --- alone wouldn't need a stake witness, but an extra witness is harmless. +-- (alsoSignWithStakeKey) for the wallets that carry a certificate. All of them +-- need one: our registration certificates carry an explicit deposit, and that +-- form requires the credential's witness just like delegation and +-- unregistration do. paymentSigningKeys : Model -> List String diff --git a/cardano-wasm/demo/web/ports.js b/cardano-wasm/demo/web/ports.js index 142f6b6fd5..7d63d4945d 100644 --- a/cardano-wasm/demo/web/ports.js +++ b/cardano-wasm/demo/web/ports.js @@ -98,6 +98,9 @@ function wire(app, api, pparams) { try { let tx = await buildUnsigned(api, spec); tx = tx.setFee(BigInt(spec.fee)); // fluent, synchronous + // An empty key list would pass undefined into the wrapper, whose promise then + // never settles (wedging this instance's certificate path) — fail loudly instead. + if (!paymentKeys.length) throw new Error("no payment keys (select at least one input)"); // Payment witnesses (for the spent inputs) — signWithPaymentKey / alsoSignWithPaymentKey. let signed = await tx.signWithPaymentKey(paymentKeys[0]); // async → SignedTx for (const k of paymentKeys.slice(1)) signed = signed.alsoSignWithPaymentKey(k); // fluent, sync @@ -134,7 +137,18 @@ async function boot() { } boot().catch((e) => { - document.getElementById("app").innerHTML = - '
Failed to load cardano-wasm:
' +
-    String(e) + "
Make sure the page is served over http(s), not opened as a file://
"; + const app = document.getElementById("app"); + if (!app) return; + + const msg = document.createElement("div"); + msg.style.cssText = "color:#e6edff;font-family:sans-serif;padding:30px"; + msg.append("Failed to load cardano-wasm:"); + + const pre = document.createElement("pre"); + pre.textContent = String(e); + msg.appendChild(document.createElement("br")); + msg.appendChild(pre); + msg.append("Make sure the page is served over http(s), not opened as a file://"); + + app.replaceChildren(msg); }); From 363eb0d346f5bb8823ef9771a18f60557d8e4601 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 18 Aug 2026 00:55:08 +0000 Subject: [PATCH 03/62] Complete the era eons for Dijkstra Mostly interpolation of the previous eras: every eon dictionary and case eliminator gets its Dijkstra arm (the Allegra/Mary/Babbage/Conway-onwards dictionaries return `id`), plus the `IsAllegra/Mary/Alonzo/BabbageBasedEra` instances, `TestEquality` on `CardanoEra`, the experimental `Era`'s `Eon` instance, the `ToJSON` `DijkstraLedgerPredFailure` instance the `ShelleyBasedEra` bundle needs, the Dijkstra arms in the `TxOut` conversions and tx-body lenses that the relaxation below makes reachable, and a Dijkstra arm mirroring Conway in `makeStakeAddressDelegationCertificate`. Two real changes. First, the ledger gates Shelley-style certificates to `AtMostEra "Conway"`, so the eon constraint bundles no longer provide `ShelleyEraTxCert` or `TxCert ~ ConwayTxCert` (breaking); call sites that need them now require them explicitly. Second, Dijkstra replaced required signer hashes with guards, so `reqSignerHashesTxBodyL` has no working Dijkstra arm (mirroring the ledger's own gate) and `createTransactionBody` instead translates `TxExtraKeyWitnesses` into appended key-hash guards. Simple scripts stay unsupported in Dijkstra: they need the era's new guard construct in `SimpleScript` first. That also keeps `txOutParseJson` unsupported, since Dijkstra tx outs can carry reference scripts of the new native-script type. Co-Authored-By: Sebastian Nagel Co-Authored-By: kderme Co-Authored-By: Konstantinos Lambrou-Latreille Co-Authored-By: John Lotoski Co-Authored-By: Mateusz Galazyn --- ...dano-api_palas_dijkstra_eon_completion.yml | 13 +++++++++ .../src/Cardano/Api/Era/Internal/Case.hs | 6 ++-- .../src/Cardano/Api/Era/Internal/Core.hs | 1 + .../Api/Era/Internal/Eon/AllegraEraOnwards.hs | 10 +++++-- .../Api/Era/Internal/Eon/AlonzoEraOnwards.hs | 3 ++ .../Api/Era/Internal/Eon/BabbageEraOnwards.hs | 8 +++-- .../Api/Era/Internal/Eon/ConwayEraOnwards.hs | 5 +--- .../Api/Era/Internal/Eon/MaryEraOnwards.hs | 10 +++++-- .../Api/Era/Internal/Eon/ShelleyBasedEra.hs | 10 +++++-- .../src/Cardano/Api/Experimental/Era.hs | 1 + .../Tx/Internal/Certificate/Compatible.hs | 12 ++++++-- .../Api/Internal/Orphans/Serialisation.hs | 5 ++++ cardano-api/src/Cardano/Api/LedgerState.hs | 1 + .../src/Cardano/Api/Tx/Internal/Body.hs | 14 +++++++-- .../src/Cardano/Api/Tx/Internal/Body/Lens.hs | 14 +++++---- .../src/Cardano/Api/Tx/Internal/Output.hs | 29 +++++++++++++++++++ 16 files changed, 115 insertions(+), 27 deletions(-) create mode 100644 .changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml diff --git a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml new file mode 100644 index 0000000000..b46cbe9bfd --- /dev/null +++ b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml @@ -0,0 +1,13 @@ +description: | + `DijkstraEra` now works everywhere the API dispatches on eras: the era helpers and instances that used to error out or not exist for Dijkstra are implemented. + + Extra key witnesses keep working in Dijkstra: the era replaces required signer hashes with guards, so `TxExtraKeyWitnesses` becomes key-hash guards. The effect is the same — those keys must sign. + + Simple scripts are still unsupported in Dijkstra. + + Breaking: the era constraint bundles (`AllegraEraOnwardsConstraints`, `MaryEraOnwardsConstraints`, `BabbageEraOnwardsConstraints`, `ConwayEraOnwardsConstraints`) no longer provide `ShelleyEraTxCert` or `TxCert era ~ ConwayTxCert era`, because Dijkstra does not support those certificates. If your code needs them, add the constraint explicitly. +kind: + - feature + - breaking +pr: 1298 +project: cardano-api diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs b/cardano-api/src/Cardano/Api/Era/Internal/Case.hs index 31605ace12..d8dd947ed0 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Case.hs @@ -36,7 +36,7 @@ caseByronOrShelleyBasedEra l r = \case AlonzoEra -> r ShelleyBasedEraAlonzo BabbageEra -> r ShelleyBasedEraBabbage ConwayEra -> r ShelleyBasedEraConway - DijkstraEra -> error "TODO Dijkstra: caseByronOrShelleyBasedEra: era not supported" + DijkstraEra -> r ShelleyBasedEraDijkstra -- | @caseShelleyEraOnlyOrAllegraEraOnwards f g era@ applies @f@ to shelley; -- and applies @g@ to allegra and later eras. @@ -53,7 +53,7 @@ caseShelleyEraOnlyOrAllegraEraOnwards l r = \case ShelleyBasedEraAlonzo -> r AllegraEraOnwardsAlonzo ShelleyBasedEraBabbage -> r AllegraEraOnwardsBabbage ShelleyBasedEraConway -> r AllegraEraOnwardsConway - ShelleyBasedEraDijkstra -> error "TODO Dijkstra: caseShelleyEraOnlyOrAllegraEraOnwards: era not supported" + ShelleyBasedEraDijkstra -> r AllegraEraOnwardsDijkstra -- | @caseShelleyToBabbageOrConwayEraOnwards f g era@ applies @f@ to eras before conway; -- and applies @g@ to conway and later eras. @@ -70,4 +70,4 @@ caseShelleyToBabbageOrConwayEraOnwards l r = \case ShelleyBasedEraAlonzo -> l ShelleyToBabbageEraAlonzo ShelleyBasedEraBabbage -> l ShelleyToBabbageEraBabbage ShelleyBasedEraConway -> r ConwayEraOnwardsConway - ShelleyBasedEraDijkstra -> error "TODO Dijkstra: caseShelleyToBabbageOrConwayEraOnwards: era not supported" + ShelleyBasedEraDijkstra -> r ConwayEraOnwardsDijkstra diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Core.hs b/cardano-api/src/Cardano/Api/Era/Internal/Core.hs index ed2187a90e..62e2d518e9 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Core.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Core.hs @@ -304,6 +304,7 @@ instance TestEquality CardanoEra where testEquality AlonzoEra AlonzoEra = Just Refl testEquality BabbageEra BabbageEra = Just Refl testEquality ConwayEra ConwayEra = Just Refl + testEquality DijkstraEra DijkstraEra = Just Refl testEquality _ _ = Nothing instance Eon CardanoEra where diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs index fae4bc6620..08df3f2953 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs @@ -97,7 +97,10 @@ type AllegraEraOnwardsConstraints era = , L.EraTxOut (ShelleyLedgerEra era) , L.HashAnnotated (L.TxBody L.TopTx (ShelleyLedgerEra era)) L.EraIndependentTxBody , L.AllegraEraTxBody (ShelleyLedgerEra era) - , L.ShelleyEraTxCert (ShelleyLedgerEra era) + , -- L.ShelleyEraTxCert dropped: gated by AtMostEra "Conway" in the ledger, so + -- Dijkstra cannot satisfy it. Callsites needing Shelley-style certs must + -- require ShelleyEraTxCert (ShelleyLedgerEra era) explicitly. + L.EraTxCert (ShelleyLedgerEra era) , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) , FromCBOR (DebugLedgerState era) , IsCardanoEra era @@ -119,7 +122,7 @@ allegraEraOnwardsConstraints = \case AllegraEraOnwardsAlonzo -> id AllegraEraOnwardsBabbage -> id AllegraEraOnwardsConway -> id - _ -> const $ error "TODO Dijkstra: allegraEraOnwardsConstraints: era not supported" + AllegraEraOnwardsDijkstra -> id class IsShelleyBasedEra era => IsAllegraBasedEra era where allegraBasedEra :: AllegraEraOnwards era @@ -138,3 +141,6 @@ instance IsAllegraBasedEra BabbageEra where instance IsAllegraBasedEra ConwayEra where allegraBasedEra = AllegraEraOnwardsConway + +instance IsAllegraBasedEra DijkstraEra where + allegraBasedEra = AllegraEraOnwardsDijkstra diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/AlonzoEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/AlonzoEraOnwards.hs index 9cb2eee666..2ae29ebc5d 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/AlonzoEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/AlonzoEraOnwards.hs @@ -141,3 +141,6 @@ instance IsAlonzoBasedEra BabbageEra where instance IsAlonzoBasedEra ConwayEra where alonzoBasedEra = AlonzoEraOnwardsConway + +instance IsAlonzoBasedEra DijkstraEra where + alonzoBasedEra = AlonzoEraOnwardsDijkstra diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs index 9af6f7fd4b..0da8540490 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs @@ -115,7 +115,8 @@ type BabbageEraOnwardsConstraints era = , L.MaryEraTxBody (ShelleyLedgerEra era) , L.Script (ShelleyLedgerEra era) ~ L.AlonzoScript (ShelleyLedgerEra era) , L.ScriptsNeeded (ShelleyLedgerEra era) ~ L.AlonzoScriptsNeeded (ShelleyLedgerEra era) - , L.ShelleyEraTxCert (ShelleyLedgerEra era) + , -- L.ShelleyEraTxCert dropped: gated by AtMostEra "Conway" in the ledger. + L.EraTxCert (ShelleyLedgerEra era) , L.TxOut (ShelleyLedgerEra era) ~ L.BabbageTxOut (ShelleyLedgerEra era) , L.Value (ShelleyLedgerEra era) ~ L.MaryValue , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) @@ -136,7 +137,7 @@ babbageEraOnwardsConstraints babbageEraOnwardsConstraints = \case BabbageEraOnwardsBabbage -> id BabbageEraOnwardsConway -> id - BabbageEraOnwardsDijkstra -> const $ error "TODO Dijkstra: babbageEraOnwardsConstraints: era not supported" + BabbageEraOnwardsDijkstra -> id class IsAlonzoBasedEra era => IsBabbageBasedEra era where babbageBasedEra :: BabbageEraOnwards era @@ -146,3 +147,6 @@ instance IsBabbageBasedEra BabbageEra where instance IsBabbageBasedEra ConwayEra where babbageBasedEra = BabbageEraOnwardsConway + +instance IsBabbageBasedEra DijkstraEra where + babbageBasedEra = BabbageEraOnwardsDijkstra diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ConwayEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ConwayEraOnwards.hs index dbbeca2f63..5e9955f5d1 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ConwayEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ConwayEraOnwards.hs @@ -37,7 +37,6 @@ import Cardano.Ledger.BaseTypes qualified as L import Cardano.Ledger.Conway.Core qualified as L import Cardano.Ledger.Conway.Governance qualified as L import Cardano.Ledger.Conway.State qualified as L -import Cardano.Ledger.Conway.TxCert qualified as L import Cardano.Ledger.Mary.Value qualified as L import Cardano.Protocol.Crypto qualified as L import Ouroboros.Consensus.Protocol.Abstract qualified as Consensus @@ -123,8 +122,6 @@ type ConwayEraOnwardsConstraints era = , L.MaryEraTxBody (ShelleyLedgerEra era) , L.Script (ShelleyLedgerEra era) ~ L.AlonzoScript (ShelleyLedgerEra era) , L.ScriptsNeeded (ShelleyLedgerEra era) ~ L.AlonzoScriptsNeeded (ShelleyLedgerEra era) - , L.ShelleyEraTxCert (ShelleyLedgerEra era) - , L.TxCert (ShelleyLedgerEra era) ~ L.ConwayTxCert (ShelleyLedgerEra era) , L.Value (ShelleyLedgerEra era) ~ L.MaryValue , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) , FromCBOR (DebugLedgerState era) @@ -143,7 +140,7 @@ conwayEraOnwardsConstraints -> a conwayEraOnwardsConstraints = \case ConwayEraOnwardsConway -> id - _ -> const $ error "TODO Dijkstra: conwayEraOnwardsConstraints: era not supported" + ConwayEraOnwardsDijkstra -> id class IsBabbageBasedEra era => IsConwayBasedEra era where conwayBasedEra :: ConwayEraOnwards era diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs index 707fd1a1a2..c0eed3d551 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs @@ -98,8 +98,9 @@ type MaryEraOnwardsConstraints era = , L.EraUTxO (ShelleyLedgerEra era) , L.HashAnnotated (L.TxBody L.TopTx (ShelleyLedgerEra era)) L.EraIndependentTxBody , L.MaryEraTxBody (ShelleyLedgerEra era) - , L.ShelleyEraTxCert (ShelleyLedgerEra era) - , L.Value (ShelleyLedgerEra era) ~ L.MaryValue + , -- L.ShelleyEraTxCert dropped: Dijkstra cannot satisfy AtMostEra "Conway". + -- Callsites that need it must add it explicitly. + L.Value (ShelleyLedgerEra era) ~ L.MaryValue , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) , FromCBOR (DebugLedgerState era) , IsCardanoEra era @@ -120,7 +121,7 @@ maryEraOnwardsConstraints = \case MaryEraOnwardsAlonzo -> id MaryEraOnwardsBabbage -> id MaryEraOnwardsConway -> id - MaryEraOnwardsDijkstra -> const $ error "TODO Dijkstra: maryEraOnwardsConstraints: era not supported" + MaryEraOnwardsDijkstra -> id class IsAllegraBasedEra era => IsMaryBasedEra era where maryBasedEra :: MaryEraOnwards era @@ -136,3 +137,6 @@ instance IsMaryBasedEra BabbageEra where instance IsMaryBasedEra ConwayEra where maryBasedEra = MaryEraOnwardsConway + +instance IsMaryBasedEra DijkstraEra where + maryBasedEra = MaryEraOnwardsDijkstra diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs index ff09062dce..beae6316a5 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs @@ -160,6 +160,7 @@ instance TestEquality ShelleyBasedEra where testEquality ShelleyBasedEraAlonzo ShelleyBasedEraAlonzo = Just Refl testEquality ShelleyBasedEraBabbage ShelleyBasedEraBabbage = Just Refl testEquality ShelleyBasedEraConway ShelleyBasedEraConway = Just Refl + testEquality ShelleyBasedEraDijkstra ShelleyBasedEraDijkstra = Just Refl testEquality _ _ = Nothing instance Eon ShelleyBasedEra where @@ -236,8 +237,11 @@ type ShelleyBasedEraConstraints era = , L.EraCertState (ShelleyLedgerEra era) , L.EraAccounts (ShelleyLedgerEra era) , L.EraGov (ShelleyLedgerEra era) - , L.ShelleyEraTxCert (ShelleyLedgerEra era) - , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) + , -- L.ShelleyEraTxCert dropped: gated by AtMostEra "Conway" in the ledger, so + -- Dijkstra cannot satisfy it. Callsites that construct Shelley-style certs + -- must require ShelleyEraTxCert (ShelleyLedgerEra era) explicitly — that + -- naturally excludes Dijkstra at the type level. + FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) , FromCBOR (L.TxCert (ShelleyLedgerEra era)) , HasTypeProxy era , IsCardanoEra era @@ -261,7 +265,7 @@ shelleyBasedEraConstraints = \case ShelleyBasedEraAlonzo -> id ShelleyBasedEraBabbage -> id ShelleyBasedEraConway -> id - ShelleyBasedEraDijkstra -> const $ error "TODO Dijkstra: shelleyBasedEraConstraints: era not supported" + ShelleyBasedEraDijkstra -> id data AnyShelleyBasedEra where AnyShelleyBasedEra diff --git a/cardano-api/src/Cardano/Api/Experimental/Era.hs b/cardano-api/src/Cardano/Api/Experimental/Era.hs index d40a8c62de..9212b3b7ff 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Era.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Era.hs @@ -160,6 +160,7 @@ instance FromJSON (Some Era) where instance Eon Era where inEonForEra v f = \case Api.ConwayEra -> f ConwayEra + Api.DijkstraEra -> f DijkstraEra _ -> v -- | A temporary compatibility instance for easier conversion between the experimental and old APIs. diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs index 005f188555..a51335964c 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs @@ -71,10 +71,14 @@ makeStakeAddressDelegationCertificate sCred delegatee = e@ShelleyBasedEraMary -> cert e delegatee e@ShelleyBasedEraAllegra -> cert e delegatee e@ShelleyBasedEraShelley -> cert e delegatee - ShelleyBasedEraDijkstra -> error "TODO Dijkstra: makeStakeAddressDelegationCertificate: era not supported" + ShelleyBasedEraDijkstra -> + Certificate $ + Ledger.mkDelegTxCert (toShelleyStakeCredential sCred) delegatee where cert - :: Delegatee era ~ Api.Hash Api.StakePoolKey + :: ( Delegatee era ~ Api.Hash Api.StakePoolKey + , Ledger.ShelleyEraTxCert (ShelleyLedgerEra era) + ) => ShelleyBasedEra era -> Delegatee era -> Certificate (ShelleyLedgerEra era) cert e delegatee' = shelleyBasedEraConstraints e $ @@ -125,7 +129,9 @@ makeStakeAddressRegistrationCertificate scred = makeStakeAddressUnregistrationCertificate :: forall era - . IsShelleyBasedEra era + . ( IsShelleyBasedEra era + , Ledger.ShelleyEraTxCert (ShelleyLedgerEra era) + ) => StakeCredential -> Certificate (ShelleyLedgerEra era) makeStakeAddressUnregistrationCertificate scred = shelleyBasedEraConstraints (shelleyBasedEra @era) $ diff --git a/cardano-api/src/Cardano/Api/Internal/Orphans/Serialisation.hs b/cardano-api/src/Cardano/Api/Internal/Orphans/Serialisation.hs index 524cd9dfb3..9507cce3a5 100644 --- a/cardano-api/src/Cardano/Api/Internal/Orphans/Serialisation.hs +++ b/cardano-api/src/Cardano/Api/Internal/Orphans/Serialisation.hs @@ -292,6 +292,11 @@ deriving via instance Show (L.DijkstraMempoolPredFailure ledgerera) => ToJSON (L.DijkstraMempoolPredFailure ledgerera) +deriving via + ShowOf (L.DijkstraLedgerPredFailure ledgerera) + instance + Show (L.DijkstraLedgerPredFailure ledgerera) => ToJSON (L.DijkstraLedgerPredFailure ledgerera) + deriving via ShowOf (L.ShelleyDelegsPredFailure ledgerera) instance diff --git a/cardano-api/src/Cardano/Api/LedgerState.hs b/cardano-api/src/Cardano/Api/LedgerState.hs index 65dc3b63de..d3e1af57e5 100644 --- a/cardano-api/src/Cardano/Api/LedgerState.hs +++ b/cardano-api/src/Cardano/Api/LedgerState.hs @@ -2101,6 +2101,7 @@ nextEpochEligibleLeadershipSlots sbe sGen serCurrEpochState ptclState poolid (Vr ShelleyBasedEraAlonzo -> pp ^. Core.ppExtraEntropyL ShelleyBasedEraBabbage -> Ledger.NeutralNonce ShelleyBasedEraConway -> Ledger.NeutralNonce + ShelleyBasedEraDijkstra -> Ledger.NeutralNonce nextEpochsNonce = candidateNonce ⭒ previousLabNonce ⭒ extraEntropy diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index 1821706a3c..a53555392d 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -1329,8 +1329,18 @@ createTransactionBody sbe bc = setCollateralInputs <- monoidForEraInEonA era $ \w -> pure $ Endo $ A.collateralInputsTxBodyL w .~ collTxIns - setReqSignerHashes <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.reqSignerHashesTxBodyL w .~ convExtraKeyWitnesses apiExtraKeyWitnesses + setReqSignerHashes <- + let keyWits = convExtraKeyWitnesses apiExtraKeyWitnesses + in monoidForEraInEonA era $ \w -> case w of + -- Dijkstra replaced required signer hashes with guards, and a key-hash + -- guard makes the ledger demand that key's signature: translate, appending + -- so any other guards stay intact. (The 'A.reqSignerHashesTxBodyL' arm + -- fails for Dijkstra, like the ledger lens.) + AlonzoEraOnwardsDijkstra -> + pure . Endo $ + A.txBodyL . L.guardsTxBodyL + %~ (<> OSet.fromSet (Set.map Shelley.KeyHashObj keyWits)) + _ -> pure $ Endo $ A.reqSignerHashesTxBodyL w .~ keyWits setReferenceInputs <- monoidForEraInEonA era $ \w -> pure $ Endo $ A.referenceInputsTxBodyL w .~ refTxIns diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs index a3f90ed9d2..a6e890fd2e 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs @@ -48,11 +48,13 @@ import Cardano.Api.Era.Internal.Case import Cardano.Api.Era.Internal.Eon.AllegraEraOnwards import Cardano.Api.Era.Internal.Eon.AlonzoEraOnwards import Cardano.Api.Era.Internal.Eon.BabbageEraOnwards +import Cardano.Api.Era.Internal.Eon.Convert (Convert (convert)) import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards import Cardano.Api.Era.Internal.Eon.MaryEraOnwards import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra import Cardano.Api.Era.Internal.Eon.ShelleyEraOnly import Cardano.Api.Era.Internal.Eon.ShelleyToBabbageEra +import Cardano.Api.Experimental.Era (obtainCommonConstraints) import Cardano.Api.Internal.Orphans () import Cardano.Ledger.Allegra.Core qualified as L @@ -169,7 +171,9 @@ reqSignerHashesTxBodyL reqSignerHashesTxBodyL w@AlonzoEraOnwardsAlonzo = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL reqSignerHashesTxBodyL w@AlonzoEraOnwardsBabbage = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL reqSignerHashesTxBodyL w@AlonzoEraOnwardsConway = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL -reqSignerHashesTxBodyL AlonzoEraOnwardsDijkstra = error "TODO Dijkstra: reqSignerHashesTxBodyL: era not supported" +-- Dijkstra replaced required signer hashes with guards; the ledger gates its +-- lens to @AtMostEra "Conway"@ and stubs the instance with 'L.notSupportedInThisEraL'. +reqSignerHashesTxBodyL AlonzoEraOnwardsDijkstra = L.notSupportedInThisEraL referenceInputsTxBodyL :: BabbageEraOnwards era -> Lens' (LedgerTxBody era) (Set L.TxIn) @@ -188,18 +192,18 @@ certsTxBodyL w = shelleyBasedEraConstraints w $ txBodyL . L.certsTxBodyL votingProceduresTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) (L.VotingProcedures (ShelleyLedgerEra era)) -votingProceduresTxBodyL w = conwayEraOnwardsConstraints w $ txBodyL . L.votingProceduresTxBodyL +votingProceduresTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.votingProceduresTxBodyL proposalProceduresTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) (L.OSet (L.ProposalProcedure (ShelleyLedgerEra era))) -proposalProceduresTxBodyL w = conwayEraOnwardsConstraints w $ txBodyL . L.proposalProceduresTxBodyL +proposalProceduresTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.proposalProceduresTxBodyL currentTreasuryValueTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) (StrictMaybe L.Coin) -currentTreasuryValueTxBodyL w = conwayEraOnwardsConstraints w $ txBodyL . L.currentTreasuryValueTxBodyL +currentTreasuryValueTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.currentTreasuryValueTxBodyL treasuryDonationTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) L.Coin -treasuryDonationTxBodyL w = conwayEraOnwardsConstraints w $ txBodyL . L.treasuryDonationTxBodyL +treasuryDonationTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.treasuryDonationTxBodyL mkAdaOnlyTxOut :: ShelleyBasedEra era diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs index 7bc12fc9a0..01672f7338 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs @@ -813,6 +813,12 @@ toShelleyTxOut sbe = shelleyBasedEraConstraints sbe $ \case .~ toBabbageTxOutDatumUTxO txoutdata & L.referenceScriptTxOutL .~ refScriptToShelleyScript sbe refScript + AlonzoEraOnwardsDijkstra -> + L.mkBasicTxOut (toShelleyAddr addr) value + & L.datumTxOutL + .~ toBabbageTxOutDatumUTxO txoutdata + & L.referenceScriptTxOutL + .~ refScriptToShelleyScript sbe refScript ) -- | A variant of 'toShelleyTxOutAny that is used only internally to this module @@ -847,6 +853,12 @@ toShelleyTxOutAny sbe = shelleyBasedEraConstraints sbe $ \case .~ toBabbageTxOutDatum txoutdata & L.referenceScriptTxOutL .~ refScriptToShelleyScript sbe refScript + AlonzoEraOnwardsDijkstra -> + L.mkBasicTxOut (toShelleyAddr addr) value + & L.datumTxOutL + .~ toBabbageTxOutDatum txoutdata + & L.referenceScriptTxOutL + .~ refScriptToShelleyScript sbe refScript ) fromShelleyTxOut @@ -908,6 +920,23 @@ fromShelleyTxOut sbe ledgerTxOut = shelleyBasedEraConstraints sbe $ do where datum = ledgerTxOut ^. L.datumTxOutL mRefScript = ledgerTxOut ^. L.referenceScriptTxOutL + ShelleyBasedEraDijkstra -> + TxOut + addressInEra + txOutValue + ( fromBabbageTxOutDatum + AlonzoEraOnwardsDijkstra + BabbageEraOnwardsDijkstra + datum + ) + ( case mRefScript of + SNothing -> ReferenceScriptNone + SJust refScript -> + fromShelleyScriptToReferenceScript ShelleyBasedEraDijkstra refScript + ) + where + datum = ledgerTxOut ^. L.datumTxOutL + mRefScript = ledgerTxOut ^. L.referenceScriptTxOutL -- ---------------------------------------------------------------------------- -- Transaction output values (era-dependent) From 84ea31702c646025e161f3b447295933dfbda353 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 19 Aug 2026 20:33:07 +0000 Subject: [PATCH 04/62] haskell-wasm CI: add archive.org fallback for the ghc-wasm-meta input gitlab.haskell.org is the only non-GitHub host among our flake inputs, and an outage breaks this workflow at `nix develop` time. Pre-fetch the ghc-wasm-meta input before the first nix invocation; if gitlab.haskell.org does not respond, fetch a byte-identical mirror of the pinned tarball from archive.org instead. The input's narHash from flake.lock is enforced on both sources, so the fallback cannot alter the build inputs; once the content is in the local store, the later nix invocations resolve the locked input without contacting gitlab. Mirror: https://archive.org/details/ghc-wasm-meta-c662c34d608dc9d2ff599b007f2e3c46138efaab If the input is re-pinned, upload the new GitLab archive tarball to an archive.org item named ghc-wasm-meta- (keeping GitLab's file name) to keep the fallback working; the step fails with instructions otherwise --- ..._wasm_ci_ghc_wasm_meta_mirror_fallback.yml | 6 +++++ .github/workflows/haskell-wasm.yml | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 .changes/20260819_210000_cardano-wasm_palas_wasm_ci_ghc_wasm_meta_mirror_fallback.yml diff --git a/.changes/20260819_210000_cardano-wasm_palas_wasm_ci_ghc_wasm_meta_mirror_fallback.yml b/.changes/20260819_210000_cardano-wasm_palas_wasm_ci_ghc_wasm_meta_mirror_fallback.yml new file mode 100644 index 0000000000..99fd50592d --- /dev/null +++ b/.changes/20260819_210000_cardano-wasm_palas_wasm_ci_ghc_wasm_meta_mirror_fallback.yml @@ -0,0 +1,6 @@ +description: | + Made the WASM CI job resilient to gitlab.haskell.org outages by pre-fetching the ghc-wasm-meta flake input with a fallback to a byte-identical, narHash-verified mirror on archive.org +kind: + - maintenance +pr: 1304 +project: cardano-wasm diff --git a/.github/workflows/haskell-wasm.yml b/.github/workflows/haskell-wasm.yml index cb556d2ff8..9505acd1b0 100644 --- a/.github/workflows/haskell-wasm.yml +++ b/.github/workflows/haskell-wasm.yml @@ -60,6 +60,29 @@ jobs: extra_nix_config: | accept-flake-config = true + # ghc-wasm-meta is the only flake input hosted on gitlab.haskell.org, whose + # availability is flaky, and an outage breaks every nix invocation below. + # Pre-fetch that input, falling back to a byte-identical mirror on + # archive.org. The narHash taken from flake.lock guarantees that whichever + # source responds yields exactly the locked content, and the nix + # invocations below then resolve the input locally without re-downloading. + - name: Fetch ghc-wasm-meta flake input (with archive.org mirror fallback) + run: | + rev=$(jq -r '.nodes["ghc-wasm-meta"].locked.rev' flake.lock) + narHash=$(jq -r '.nodes["ghc-wasm-meta"].locked.narHash' flake.lock) + hashQuery=${narHash//=/%3D} + if nix flake prefetch --option connect-timeout 60 --option download-attempts 2 \ + "gitlab:haskell-wasm/ghc-wasm-meta/${rev}?host=gitlab.haskell.org&narHash=${hashQuery}"; then + echo "Fetched ghc-wasm-meta@${rev} from gitlab.haskell.org" + else + echo "::warning::gitlab.haskell.org is unavailable, falling back to the archive.org mirror of ghc-wasm-meta@${rev}" + nix flake prefetch \ + "tarball+https://archive.org/download/ghc-wasm-meta-${rev}/ghc-wasm-meta-${rev}-${rev}.tar.gz?narHash=${hashQuery}" || { + echo "::error::The archive.org mirror does not serve ghc-wasm-meta@${rev}. If the flake input was re-pinned, upload the new GitLab archive tarball to an archive.org item named ghc-wasm-meta-${rev} (keeping GitLab's file name), or wait for gitlab.haskell.org to recover." + exit 1 + } + fi + - uses: rrbutani/use-nix-shell-action@v1 with: devShell: .#wasm From 5ec7ba85090d9edd385501d98b7ddf42ab872bf7 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 19 Aug 2026 23:06:39 +0000 Subject: [PATCH 05/62] Address review feedback Drop the four constraint comments, deprecate cardano-api's reqSignerHashesTxBodyL in favour of the ledger's lens and getter (the old-API construction site now uses the ledger lens per era), pattern match explicitly instead of using a wildcard in createTransactionBody's required-signers case, and fix the Enum (Some Era) roundtrip (toEnum 1 = Some DijkstraEra) while keeping maxBound at Conway. --- ...20100_cardano-api_palas_dijkstra_eon_completion.yml | 2 ++ .../Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs | 5 +---- .../Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs | 3 +-- .../src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs | 4 +--- .../Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs | 6 +----- cardano-api/src/Cardano/Api/Experimental/Era.hs | 1 + cardano-api/src/Cardano/Api/Tx/Internal/Body.hs | 10 +++++++--- cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs | 4 ++++ 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml index b46cbe9bfd..3c4afbfbcc 100644 --- a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml +++ b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml @@ -5,6 +5,8 @@ description: | Simple scripts are still unsupported in Dijkstra. + The cardano-api lens `reqSignerHashesTxBodyL` is deprecated: use the same-named ledger lens (or `reqSignerHashesTxBodyG` for reads) from `Cardano.Api.Ledger`. + Breaking: the era constraint bundles (`AllegraEraOnwardsConstraints`, `MaryEraOnwardsConstraints`, `BabbageEraOnwardsConstraints`, `ConwayEraOnwardsConstraints`) no longer provide `ShelleyEraTxCert` or `TxCert era ~ ConwayTxCert era`, because Dijkstra does not support those certificates. If your code needs them, add the constraint explicitly. kind: - feature diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs index 08df3f2953..8796470e7a 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/AllegraEraOnwards.hs @@ -97,10 +97,7 @@ type AllegraEraOnwardsConstraints era = , L.EraTxOut (ShelleyLedgerEra era) , L.HashAnnotated (L.TxBody L.TopTx (ShelleyLedgerEra era)) L.EraIndependentTxBody , L.AllegraEraTxBody (ShelleyLedgerEra era) - , -- L.ShelleyEraTxCert dropped: gated by AtMostEra "Conway" in the ledger, so - -- Dijkstra cannot satisfy it. Callsites needing Shelley-style certs must - -- require ShelleyEraTxCert (ShelleyLedgerEra era) explicitly. - L.EraTxCert (ShelleyLedgerEra era) + , L.EraTxCert (ShelleyLedgerEra era) , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) , FromCBOR (DebugLedgerState era) , IsCardanoEra era diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs index 0da8540490..91eba999d5 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/BabbageEraOnwards.hs @@ -115,8 +115,7 @@ type BabbageEraOnwardsConstraints era = , L.MaryEraTxBody (ShelleyLedgerEra era) , L.Script (ShelleyLedgerEra era) ~ L.AlonzoScript (ShelleyLedgerEra era) , L.ScriptsNeeded (ShelleyLedgerEra era) ~ L.AlonzoScriptsNeeded (ShelleyLedgerEra era) - , -- L.ShelleyEraTxCert dropped: gated by AtMostEra "Conway" in the ledger. - L.EraTxCert (ShelleyLedgerEra era) + , L.EraTxCert (ShelleyLedgerEra era) , L.TxOut (ShelleyLedgerEra era) ~ L.BabbageTxOut (ShelleyLedgerEra era) , L.Value (ShelleyLedgerEra era) ~ L.MaryValue , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs index c0eed3d551..9176402e10 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/MaryEraOnwards.hs @@ -98,9 +98,7 @@ type MaryEraOnwardsConstraints era = , L.EraUTxO (ShelleyLedgerEra era) , L.HashAnnotated (L.TxBody L.TopTx (ShelleyLedgerEra era)) L.EraIndependentTxBody , L.MaryEraTxBody (ShelleyLedgerEra era) - , -- L.ShelleyEraTxCert dropped: Dijkstra cannot satisfy AtMostEra "Conway". - -- Callsites that need it must add it explicitly. - L.Value (ShelleyLedgerEra era) ~ L.MaryValue + , L.Value (ShelleyLedgerEra era) ~ L.MaryValue , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) , FromCBOR (DebugLedgerState era) , IsCardanoEra era diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs index beae6316a5..53cf718e70 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs @@ -237,11 +237,7 @@ type ShelleyBasedEraConstraints era = , L.EraCertState (ShelleyLedgerEra era) , L.EraAccounts (ShelleyLedgerEra era) , L.EraGov (ShelleyLedgerEra era) - , -- L.ShelleyEraTxCert dropped: gated by AtMostEra "Conway" in the ledger, so - -- Dijkstra cannot satisfy it. Callsites that construct Shelley-style certs - -- must require ShelleyEraTxCert (ShelleyLedgerEra era) explicitly — that - -- naturally excludes Dijkstra at the type level. - FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) + , FromCBOR (Consensus.ChainDepState (ConsensusProtocol era)) , FromCBOR (L.TxCert (ShelleyLedgerEra era)) , HasTypeProxy era , IsCardanoEra era diff --git a/cardano-api/src/Cardano/Api/Experimental/Era.hs b/cardano-api/src/Cardano/Api/Experimental/Era.hs index 9212b3b7ff..325fc57a0c 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Era.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Era.hs @@ -134,6 +134,7 @@ instance Bounded (Some Era) where instance Enum (Some Era) where toEnum 0 = Some ConwayEra + toEnum 1 = Some DijkstraEra toEnum i = error $ "Enum.toEnum: invalid argument " <> show i <> " - does not correspond to any era" fromEnum (Some ConwayEra) = 0 fromEnum (Some DijkstraEra) = 1 diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index a53555392d..87d42ea852 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -1334,13 +1334,17 @@ createTransactionBody sbe bc = in monoidForEraInEonA era $ \w -> case w of -- Dijkstra replaced required signer hashes with guards, and a key-hash -- guard makes the ledger demand that key's signature: translate, appending - -- so any other guards stay intact. (The 'A.reqSignerHashesTxBodyL' arm - -- fails for Dijkstra, like the ledger lens.) + -- so any other guards stay intact. AlonzoEraOnwardsDijkstra -> pure . Endo $ A.txBodyL . L.guardsTxBodyL %~ (<> OSet.fromSet (Set.map Shelley.KeyHashObj keyWits)) - _ -> pure $ Endo $ A.reqSignerHashesTxBodyL w .~ keyWits + AlonzoEraOnwardsAlonzo -> + pure $ Endo $ A.txBodyL . L.reqSignerHashesTxBodyL .~ keyWits + AlonzoEraOnwardsBabbage -> + pure $ Endo $ A.txBodyL . L.reqSignerHashesTxBodyL .~ keyWits + AlonzoEraOnwardsConway -> + pure $ Endo $ A.txBodyL . L.reqSignerHashesTxBodyL .~ keyWits setReferenceInputs <- monoidForEraInEonA era $ \w -> pure $ Endo $ A.referenceInputsTxBodyL w .~ refTxIns diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs index a6e890fd2e..5423fd3c16 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs @@ -166,6 +166,10 @@ collateralInputsTxBodyL :: AlonzoEraOnwards era -> Lens' (LedgerTxBody era) (Set L.TxIn) collateralInputsTxBodyL w = alonzoEraOnwardsConstraints w $ txBodyL . L.collateralInputsTxBodyL +{-# DEPRECATED + reqSignerHashesTxBodyL + "Use reqSignerHashesTxBodyL from Cardano.Api.Ledger (via txBodyL) instead, or reqSignerHashesTxBodyG for reads. The required-signer-hashes field does not exist in the Dijkstra era, where this lens errors." + #-} reqSignerHashesTxBodyL :: AlonzoEraOnwards era -> Lens' (LedgerTxBody era) (Set (L.KeyHash L.Guard)) reqSignerHashesTxBodyL w@AlonzoEraOnwardsAlonzo = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL From 5e8c7bb9a0cff2c2310bb93d70cbd96bbbc79146 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 19 Aug 2026 23:18:17 +0000 Subject: [PATCH 06/62] Deprecate the LedgerTxBody wrapper lenses that have ledger equivalents Every wrapper that just re-dresses a ledger lens is deprecated in favour of the ledger's own, and createTransactionBody now uses the ledger lenses directly. Cardano.Api.Ledger gains the re-exports the migration needs: the era tx-body classes, the affected lenses, valueTxOutL and coinTxOutL. Kept undeprecated: the validity-interval compatibility lenses, adaAssetL and multiAssetL, which have no ledger equivalent (and adaAssetL is still used by cardano-testnet). --- ...dano-api_palas_dijkstra_eon_completion.yml | 2 +- .../Cardano/Api/Ledger/Internal/Reexport.hs | 34 ++++++++++- .../src/Cardano/Api/Tx/Internal/Body.hs | 45 ++++++++++---- .../src/Cardano/Api/Tx/Internal/Body/Lens.hs | 59 ++++++++++++++++++- .../src/Cardano/Api/Tx/Internal/Output.hs | 2 +- 5 files changed, 126 insertions(+), 16 deletions(-) diff --git a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml index 3c4afbfbcc..adf47489ad 100644 --- a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml +++ b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml @@ -5,7 +5,7 @@ description: | Simple scripts are still unsupported in Dijkstra. - The cardano-api lens `reqSignerHashesTxBodyL` is deprecated: use the same-named ledger lens (or `reqSignerHashesTxBodyG` for reads) from `Cardano.Api.Ledger`. + Most `LedgerTxBody` wrapper lenses are deprecated: use the same-named ledger lenses from `Cardano.Api.Ledger` (through `txBodyL`). `coinTxOutL` replaces `valueTxOutAdaAssetL`, and `reqSignerHashesTxBodyG` covers era-generic reads. `Cardano.Api.Ledger` now also re-exports the era tx-body classes and these lenses. The validity-interval lenses, `adaAssetL` and `multiAssetL` stay: the ledger has no equivalent for them. Breaking: the era constraint bundles (`AllegraEraOnwardsConstraints`, `MaryEraOnwardsConstraints`, `BabbageEraOnwardsConstraints`, `ConwayEraOnwardsConstraints`) no longer provide `ShelleyEraTxCert` or `TxCert era ~ ConwayTxCert era`, because Dijkstra does not support those certificates. If your code needs them, add the constraint explicitly. kind: diff --git a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs index 2b6ce58c43..0ff4e1f774 100644 --- a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs +++ b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs @@ -142,6 +142,22 @@ module Cardano.Api.Ledger.Internal.Reexport -- Babbage , CoinPerByte (..) , referenceScriptTxOutL + , ShelleyEraTxBody + , updateTxBodyL + , AllegraEraTxBody + , MaryEraTxBody + , mintTxBodyL + , BabbageEraTxBody + , referenceInputsTxBodyL + , collateralReturnTxBodyL + , totalCollateralTxBodyL + , ConwayEraTxBody + , votingProceduresTxBodyL + , proposalProceduresTxBodyL + , currentTreasuryValueTxBodyL + , treasuryDonationTxBodyL + , valueTxOutL + , coinTxOutL -- Alonzo , AlonzoEraTxBody (..) , AlonzoEraScript (..) @@ -249,11 +265,27 @@ import Cardano.Ledger.Alonzo.Scripts import Cardano.Ledger.Alonzo.TxWits (Redeemers (..), TxDats (..)) import Cardano.Ledger.Alonzo.UTxO (AlonzoScriptsNeeded (..)) import Cardano.Ledger.Api - ( BabbageEraTxOut (referenceScriptTxOutL) + ( AllegraEraTxBody + , BabbageEraTxBody + , BabbageEraTxOut (referenceScriptTxOutL) , Constitution (..) + , ConwayEraTxBody , GovAction (..) , GovPurposeId (..) + , MaryEraTxBody + , ShelleyEraTxBody + , coinTxOutL + , collateralReturnTxBodyL + , currentTreasuryValueTxBodyL + , mintTxBodyL + , proposalProceduresTxBodyL + , referenceInputsTxBodyL + , totalCollateralTxBodyL + , treasuryDonationTxBodyL , unRedeemers + , updateTxBodyL + , valueTxOutL + , votingProceduresTxBodyL ) import Cardano.Ledger.Api.Tx.Cert ( pattern AuthCommitteeHotKeyTxCert diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index 87d42ea852..ef801a0409 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -1313,21 +1313,24 @@ createTransactionBody sbe bc = treasuryDonation = maybe 0 unFeatured $ txTreasuryDonation bc setUpdateProposal <- monoidForEraInEonA era $ \w -> - pure . Endo $ A.updateTxBodyL w .~ convTxUpdateProposal sbe (txUpdateProposal bc) + pure . Endo $ + shelleyToBabbageEraConstraints w $ + A.txBodyL . L.updateTxBodyL .~ convTxUpdateProposal sbe (txUpdateProposal bc) setInvalidBefore <- monoidForEraInEonA era $ \w -> pure $ Endo $ A.invalidBeforeTxBodyL w .~ convValidityLowerBound (txValidityLowerBound bc) setMint <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.mintTxBodyL w .~ convMintValue apiMintValue + pure $ Endo $ maryEraOnwardsConstraints w $ A.txBodyL . L.mintTxBodyL .~ convMintValue apiMintValue setScriptIntegrityHash <- monoidForEraInEonA era $ \w -> pure $ Endo $ - A.scriptIntegrityHashTxBodyL w .~ mScriptIntegrityHash + alonzoEraOnwardsConstraints w $ + A.txBodyL . L.scriptIntegrityHashTxBodyL .~ mScriptIntegrityHash setCollateralInputs <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.collateralInputsTxBodyL w .~ collTxIns + pure $ Endo $ alonzoEraOnwardsConstraints w $ A.txBodyL . L.collateralInputsTxBodyL .~ collTxIns setReqSignerHashes <- let keyWits = convExtraKeyWitnesses apiExtraKeyWitnesses @@ -1347,29 +1350,47 @@ createTransactionBody sbe bc = pure $ Endo $ A.txBodyL . L.reqSignerHashesTxBodyL .~ keyWits setReferenceInputs <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.referenceInputsTxBodyL w .~ refTxIns + pure $ Endo $ babbageEraOnwardsConstraints w $ A.txBodyL . L.referenceInputsTxBodyL .~ refTxIns setCollateralReturn <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.collateralReturnTxBodyL w .~ returnCollateral + pure $ + Endo $ + babbageEraOnwardsConstraints w $ + A.txBodyL . L.collateralReturnTxBodyL .~ returnCollateral setTotalCollateral <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.totalCollateralTxBodyL w .~ totalCollateral + pure $ + Endo $ + babbageEraOnwardsConstraints w $ + A.txBodyL . L.totalCollateralTxBodyL .~ totalCollateral setProposalProcedures <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.proposalProceduresTxBodyL w .~ proposalProcedures + pure $ + Endo $ + conwayEraOnwardsConstraints w $ + A.txBodyL . L.proposalProceduresTxBodyL .~ proposalProcedures setVotingProcedures <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.votingProceduresTxBodyL w .~ votingProcedures + pure $ + Endo $ + conwayEraOnwardsConstraints w $ + A.txBodyL . L.votingProceduresTxBodyL .~ votingProcedures setCurrentTreasuryValue <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.currentTreasuryValueTxBodyL w .~ currentTreasuryValue + pure $ + Endo $ + conwayEraOnwardsConstraints w $ + A.txBodyL . L.currentTreasuryValueTxBodyL .~ currentTreasuryValue setTreasuryDonation <- monoidForEraInEonA era $ \w -> - pure $ Endo $ A.treasuryDonationTxBodyL w .~ treasuryDonation + pure $ + Endo $ + conwayEraOnwardsConstraints w $ + A.txBodyL . L.treasuryDonationTxBodyL .~ treasuryDonation let ledgerTxBody = mkCommonTxBody sbe (txIns bc) (txOuts bc) (txFee bc) (txWithdrawals bc) txAuxData - & A.certsTxBodyL sbe + & shelleyBasedEraConstraints sbe (A.txBodyL . L.certsTxBodyL) .~ certs & A.invalidHereAfterTxBodyL sbe .~ convValidityUpperBound sbe (txValidityUpperBound bc) diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs index 5423fd3c16..99b12ee32a 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs @@ -4,7 +4,8 @@ {- HLINT ignore "Eta reduce" -} --- TODO: Deprecate all the lenses that use eons. Explore parameterizing them on `Era era` instead. +-- TODO: Deprecate the remaining eon lenses (the validity-interval compatibility +-- lenses, adaAssetL and multiAssetL) once the ledger provides equivalents. module Cardano.Api.Tx.Internal.Body.Lens ( -- * Types @@ -151,17 +152,33 @@ invalidHereAfterStrictL = lens g s s :: L.ValidityInterval -> StrictMaybe SlotNo -> L.ValidityInterval s (L.ValidityInterval a _) b = L.ValidityInterval a b +{-# DEPRECATED + updateTxBodyL + "Use updateTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} updateTxBodyL :: ShelleyToBabbageEra era -> Lens' (LedgerTxBody era) (StrictMaybe (L.Update (ShelleyLedgerEra era))) updateTxBodyL w = shelleyToBabbageEraConstraints w $ txBodyL . L.updateTxBodyL +{-# DEPRECATED + mintTxBodyL + "Use mintTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} mintTxBodyL :: MaryEraOnwards era -> Lens' (LedgerTxBody era) L.MultiAsset mintTxBodyL w = maryEraOnwardsConstraints w $ txBodyL . L.mintTxBodyL +{-# DEPRECATED + scriptIntegrityHashTxBodyL + "Use scriptIntegrityHashTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} scriptIntegrityHashTxBodyL :: AlonzoEraOnwards era -> Lens' (LedgerTxBody era) (StrictMaybe L.ScriptIntegrityHash) scriptIntegrityHashTxBodyL w = alonzoEraOnwardsConstraints w $ txBodyL . L.scriptIntegrityHashTxBodyL +{-# DEPRECATED + collateralInputsTxBodyL + "Use collateralInputsTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} collateralInputsTxBodyL :: AlonzoEraOnwards era -> Lens' (LedgerTxBody era) (Set L.TxIn) collateralInputsTxBodyL w = alonzoEraOnwardsConstraints w $ txBodyL . L.collateralInputsTxBodyL @@ -179,33 +196,65 @@ reqSignerHashesTxBodyL w@AlonzoEraOnwardsConway = alonzoEraOnwardsConstraints w -- lens to @AtMostEra "Conway"@ and stubs the instance with 'L.notSupportedInThisEraL'. reqSignerHashesTxBodyL AlonzoEraOnwardsDijkstra = L.notSupportedInThisEraL +{-# DEPRECATED + referenceInputsTxBodyL + "Use referenceInputsTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} referenceInputsTxBodyL :: BabbageEraOnwards era -> Lens' (LedgerTxBody era) (Set L.TxIn) referenceInputsTxBodyL w = babbageEraOnwardsConstraints w $ txBodyL . L.referenceInputsTxBodyL +{-# DEPRECATED + collateralReturnTxBodyL + "Use collateralReturnTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} collateralReturnTxBodyL :: BabbageEraOnwards era -> Lens' (LedgerTxBody era) (StrictMaybe (L.TxOut (ShelleyLedgerEra era))) collateralReturnTxBodyL w = babbageEraOnwardsConstraints w $ txBodyL . L.collateralReturnTxBodyL +{-# DEPRECATED + totalCollateralTxBodyL + "Use totalCollateralTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} totalCollateralTxBodyL :: BabbageEraOnwards era -> Lens' (LedgerTxBody era) (StrictMaybe L.Coin) totalCollateralTxBodyL w = babbageEraOnwardsConstraints w $ txBodyL . L.totalCollateralTxBodyL +{-# DEPRECATED + certsTxBodyL + "Use certsTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} certsTxBodyL :: ShelleyBasedEra era -> Lens' (LedgerTxBody era) (L.StrictSeq (L.TxCert (ShelleyLedgerEra era))) certsTxBodyL w = shelleyBasedEraConstraints w $ txBodyL . L.certsTxBodyL +{-# DEPRECATED + votingProceduresTxBodyL + "Use votingProceduresTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} votingProceduresTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) (L.VotingProcedures (ShelleyLedgerEra era)) votingProceduresTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.votingProceduresTxBodyL +{-# DEPRECATED + proposalProceduresTxBodyL + "Use proposalProceduresTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} proposalProceduresTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) (L.OSet (L.ProposalProcedure (ShelleyLedgerEra era))) proposalProceduresTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.proposalProceduresTxBodyL +{-# DEPRECATED + currentTreasuryValueTxBodyL + "Use currentTreasuryValueTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} currentTreasuryValueTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) (StrictMaybe L.Coin) currentTreasuryValueTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.currentTreasuryValueTxBodyL +{-# DEPRECATED + treasuryDonationTxBodyL + "Use treasuryDonationTxBodyL from Cardano.Api.Ledger (via txBodyL) instead." + #-} treasuryDonationTxBodyL :: ConwayEraOnwards era -> Lens' (LedgerTxBody era) L.Coin treasuryDonationTxBodyL w = obtainCommonConstraints (convert w) $ txBodyL . L.treasuryDonationTxBodyL @@ -245,9 +294,17 @@ multiAssetL w = (\(L.MaryValue _ ma) -> ma) (\(L.MaryValue c _) ma -> L.MaryValue c ma) +{-# DEPRECATED + valueTxOutL + "Use valueTxOutL from Cardano.Api.Ledger instead." + #-} valueTxOutL :: ShelleyBasedEra era -> Lens' (L.TxOut (ShelleyLedgerEra era)) (L.Value (ShelleyLedgerEra era)) valueTxOutL sbe = shelleyBasedEraConstraints sbe L.valueTxOutL +{-# DEPRECATED + valueTxOutAdaAssetL + "Use coinTxOutL from Cardano.Api.Ledger instead." + #-} valueTxOutAdaAssetL :: ShelleyBasedEra era -> Lens' (L.TxOut (ShelleyLedgerEra era)) L.Coin valueTxOutAdaAssetL sbe = valueTxOutL sbe . adaAssetL sbe diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs index 01672f7338..a3a872a7ee 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs @@ -868,7 +868,7 @@ fromShelleyTxOut -> L.TxOut (ShelleyLedgerEra era) -> TxOut ctx era fromShelleyTxOut sbe ledgerTxOut = shelleyBasedEraConstraints sbe $ do - let txOutValue = TxOutValueShelleyBased sbe $ ledgerTxOut ^. A.valueTxOutL sbe + let txOutValue = TxOutValueShelleyBased sbe $ ledgerTxOut ^. L.valueTxOutL let addressInEra = fromShelleyAddr sbe $ ledgerTxOut ^. L.addrTxOutL case sbe of From 5eb13aaa1cf1a1f9ca3cdf00eab0555b40e3c01c Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Thu, 20 Aug 2026 00:49:39 +0000 Subject: [PATCH 07/62] Fix the build on GHC 9.6 and 9.10 After the lens migration, mScriptIntegrityHash's only type-fixing use sits under alonzoEraOnwardsConstraints, and older GHCs refuse to unify the outer type variable there (it is untouchable under the constraint implication); GHC 9.12+ solves it anyway. Pin the type at the binder instead. --- cardano-api/src/Cardano/Api/Tx/Internal/Body.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index ef801a0409..c2b7e4faa8 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -1274,7 +1274,7 @@ createTransactionBody sbe bc = | (_, AnyScriptWitness scriptwitness) <- collectTxBodyScriptWitnesses sbe bc ] - return (TxBodyNoScriptData, SNothing, scripts) + return (TxBodyNoScriptData, SNothing :: StrictMaybe L.ScriptIntegrityHash, scripts) ) ( \aeon -> alonzoEraOnwardsConstraints aeon $ do TxScriptWitnessRequirements languages scripts dats redeemers <- From 8157d70b2e66e8837fadb20ffabceceea0311f80 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 21 Aug 2026 02:54:57 +0000 Subject: [PATCH 08/62] Make the Eon Era instance exhaustive and sort the ledger re-exports Address the two comments from the approving review: Spell out the pre-Conway eras in the experimental `Eon Era` instance instead of a wildcard, like the canonical eon instances do. The wildcard would have silently classified any future era as outside the eon; with explicit arms the next era forces a decision here at compile time. File the ledger re-exports added by the lens deprecation under their era demarcations in Cardano.Api.Ledger.Internal.Reexport: they were all appended to the Babbage section. This adds the missing Mary section; valueTxOutL and coinTxOutL are core EraTxOut lenses, so they go under Core. --- .../src/Cardano/Api/Experimental/Era.hs | 7 +++++- .../Cardano/Api/Ledger/Internal/Reexport.hs | 25 ++++++++++--------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Experimental/Era.hs b/cardano-api/src/Cardano/Api/Experimental/Era.hs index 325fc57a0c..2bc889d094 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Era.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Era.hs @@ -160,9 +160,14 @@ instance FromJSON (Some Era) where -- | A temporary compatibility instance for easier conversion between the experimental and old APIs. instance Eon Era where inEonForEra v f = \case + Api.ByronEra -> v + Api.ShelleyEra -> v + Api.AllegraEra -> v + Api.MaryEra -> v + Api.AlonzoEra -> v + Api.BabbageEra -> v Api.ConwayEra -> f ConwayEra Api.DijkstraEra -> f DijkstraEra - _ -> v -- | A temporary compatibility instance for easier conversion between the experimental and old APIs. instance Api.ToCardanoEra Era where diff --git a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs index 0ff4e1f774..f60f1d66de 100644 --- a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs +++ b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs @@ -73,6 +73,8 @@ module Cardano.Api.Ledger.Internal.Reexport , castSafeHash , getScriptsNeeded , mkBasicTxOut + , coinTxOutL + , valueTxOutL , toDeltaCoin , toEraCBOR , toSLanguage @@ -119,6 +121,11 @@ module Cardano.Api.Ledger.Internal.Reexport , drepAnchorL , drepDepositL , csCommitteeCredsL + , ConwayEraTxBody + , votingProceduresTxBodyL + , proposalProceduresTxBodyL + , currentTreasuryValueTxBodyL + , treasuryDonationTxBodyL -- Byron , Annotated (..) , byronProtVer @@ -136,28 +143,22 @@ module Cardano.Api.Ledger.Internal.Reexport , casReservesL , NewEpochState (..) , ShelleyGenesisStaking (..) + , ShelleyEraTxBody + , updateTxBodyL -- Allegra , AllegraEraScript (..) , Timelock (..) - -- Babbage - , CoinPerByte (..) - , referenceScriptTxOutL - , ShelleyEraTxBody - , updateTxBodyL , AllegraEraTxBody + -- Mary , MaryEraTxBody , mintTxBodyL + -- Babbage + , CoinPerByte (..) + , referenceScriptTxOutL , BabbageEraTxBody , referenceInputsTxBodyL , collateralReturnTxBodyL , totalCollateralTxBodyL - , ConwayEraTxBody - , votingProceduresTxBodyL - , proposalProceduresTxBodyL - , currentTreasuryValueTxBodyL - , treasuryDonationTxBodyL - , valueTxOutL - , coinTxOutL -- Alonzo , AlonzoEraTxBody (..) , AlonzoEraScript (..) From 74143257fd664d4331955a6d023ffac28ac05b76 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 21 Aug 2026 20:54:55 +0000 Subject: [PATCH 09/62] Type-gate the deprecated reqSignerHashesTxBodyL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The deprecated lens now carries the ledger's AtMostEra "Conway" constraint, so Dijkstra misuse is a compile error instead of a runtime one — which also collapses the lens back to a single equation with no error arm. --- ...00_cardano-api_palas_dijkstra_eon_completion.yml | 2 +- .../src/Cardano/Api/Tx/Internal/Body/Lens.hs | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml index adf47489ad..13dc599996 100644 --- a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml +++ b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml @@ -5,7 +5,7 @@ description: | Simple scripts are still unsupported in Dijkstra. - Most `LedgerTxBody` wrapper lenses are deprecated: use the same-named ledger lenses from `Cardano.Api.Ledger` (through `txBodyL`). `coinTxOutL` replaces `valueTxOutAdaAssetL`, and `reqSignerHashesTxBodyG` covers era-generic reads. `Cardano.Api.Ledger` now also re-exports the era tx-body classes and these lenses. The validity-interval lenses, `adaAssetL` and `multiAssetL` stay: the ledger has no equivalent for them. + Most `LedgerTxBody` wrapper lenses are deprecated: use the same-named ledger lenses from `Cardano.Api.Ledger` (through `txBodyL`). `coinTxOutL` replaces `valueTxOutAdaAssetL`, and `reqSignerHashesTxBodyG` covers era-generic reads. `Cardano.Api.Ledger` now also re-exports the era tx-body classes and these lenses. The validity-interval lenses, `adaAssetL` and `multiAssetL` stay: the ledger has no equivalent for them. `reqSignerHashesTxBodyL` now also carries the ledger's `AtMostEra "Conway"` constraint, so using it in Dijkstra is a compile error. Breaking: the era constraint bundles (`AllegraEraOnwardsConstraints`, `MaryEraOnwardsConstraints`, `BabbageEraOnwardsConstraints`, `ConwayEraOnwardsConstraints`) no longer provide `ShelleyEraTxCert` or `TxCert era ~ ConwayTxCert era`, because Dijkstra does not support those certificates. If your code needs them, add the constraint explicitly. kind: diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs index 99b12ee32a..9092c64403 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs @@ -185,16 +185,13 @@ collateralInputsTxBodyL w = alonzoEraOnwardsConstraints w $ txBodyL . L.collater {-# DEPRECATED reqSignerHashesTxBodyL - "Use reqSignerHashesTxBodyL from Cardano.Api.Ledger (via txBodyL) instead, or reqSignerHashesTxBodyG for reads. The required-signer-hashes field does not exist in the Dijkstra era, where this lens errors." + "Use reqSignerHashesTxBodyL from Cardano.Api.Ledger (via txBodyL) instead, or reqSignerHashesTxBodyG for reads. The required-signer-hashes field does not exist in the Dijkstra era, which this lens excludes at the type level." #-} reqSignerHashesTxBodyL - :: AlonzoEraOnwards era -> Lens' (LedgerTxBody era) (Set (L.KeyHash L.Guard)) -reqSignerHashesTxBodyL w@AlonzoEraOnwardsAlonzo = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL -reqSignerHashesTxBodyL w@AlonzoEraOnwardsBabbage = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL -reqSignerHashesTxBodyL w@AlonzoEraOnwardsConway = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL --- Dijkstra replaced required signer hashes with guards; the ledger gates its --- lens to @AtMostEra "Conway"@ and stubs the instance with 'L.notSupportedInThisEraL'. -reqSignerHashesTxBodyL AlonzoEraOnwardsDijkstra = L.notSupportedInThisEraL + :: L.AtMostEra "Conway" (ShelleyLedgerEra era) + => AlonzoEraOnwards era + -> Lens' (LedgerTxBody era) (Set (L.KeyHash L.Guard)) +reqSignerHashesTxBodyL w = alonzoEraOnwardsConstraints w $ txBodyL . L.reqSignerHashesTxBodyL {-# DEPRECATED referenceInputsTxBodyL From c852c35b92c990db8543671edd77b66a7a004653 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 18 Aug 2026 00:55:23 +0000 Subject: [PATCH 10/62] Support Dijkstra protocol parameters Add DijkstraEraBasedProtocolParametersUpdate with IntroducedInDijkstraPParams (the reference-script size and cost parameters new in Dijkstra), the fromLedgerPParamsUpdate conversion back into it, a Semigroup instance for DijkstraPParams updates and generators. The protocol version itself is not updatable in Dijkstra. Co-Authored-By: Konstantinos Lambrou-Latreille --- ...api_palas_dijkstra_protocol_parameters.yml | 6 ++ .../Gen/Cardano/Api/ProtocolParameters.hs | 21 +++++- .../src/Cardano/Api/Internal/Orphans/Misc.hs | 45 +++++++++++++ .../src/Cardano/Api/ProtocolParameters.hs | 64 ++++++++++++++++++- 4 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 .changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml diff --git a/.changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml b/.changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml new file mode 100644 index 0000000000..fdd19d7503 --- /dev/null +++ b/.changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml @@ -0,0 +1,6 @@ +description: | + Protocol-parameter updates can now be created and inspected for `DijkstraEra`, via the new `DijkstraEraBasedProtocolParametersUpdate`. It adds the four parameters introduced in Dijkstra: the maximum reference-script size per block and per transaction, and the reference-script cost stride and multiplier. +kind: + - feature +pr: 1309 +project: cardano-api diff --git a/cardano-api/gen/Test/Gen/Cardano/Api/ProtocolParameters.hs b/cardano-api/gen/Test/Gen/Cardano/Api/ProtocolParameters.hs index 5985a353c8..7a0de50a90 100644 --- a/cardano-api/gen/Test/Gen/Cardano/Api/ProtocolParameters.hs +++ b/cardano-api/gen/Test/Gen/Cardano/Api/ProtocolParameters.hs @@ -10,6 +10,7 @@ import Cardano.Api.Ledger import Test.Cardano.Ledger.Alonzo.Arbitrary () import Test.Cardano.Ledger.Conway.Arbitrary () import Test.Cardano.Ledger.Core.Arbitrary (genEraProtVer) +import Test.Cardano.Ledger.Dijkstra.Arbitrary () import Hedgehog (MonadGen) import Hedgehog.Gen qualified as Gen @@ -102,7 +103,7 @@ genEraBasedProtocolParametersUpdate era = AlonzoEra -> genAlonzoEraBasedProtocolParametersUpdate BabbageEra -> genBabbageEraBasedProtocolParametersUpdate ConwayEra -> genConwayEraBasedProtocolParametersUpdate - DijkstraEra -> error "TODO Dijkstra: genEraBasedProtocolParametersUpdate: era not supported" + DijkstraEra -> genDijkstraEraBasedProtocolParametersUpdate genShelleyEraBasedProtocolParametersUpdate :: MonadGen m => m (EraBasedProtocolParametersUpdate ShelleyEra) @@ -157,3 +158,21 @@ genConwayEraBasedProtocolParametersUpdate = <*> genAlonzoOnwardsPParams <*> genIntroducedInBabbagePParams <*> genIntroducedInConwayPParams + +genIntroducedInDijkstraPParams :: MonadGen m => m (IntroducedInDijkstraPParams era) +genIntroducedInDijkstraPParams = + IntroducedInDijkstraPParams + <$> genStrictMaybe Q.arbitrary + <*> genStrictMaybe Q.arbitrary + <*> genStrictMaybe Q.arbitrary + <*> genStrictMaybe Q.arbitrary + +genDijkstraEraBasedProtocolParametersUpdate + :: MonadGen m => m (EraBasedProtocolParametersUpdate DijkstraEra) +genDijkstraEraBasedProtocolParametersUpdate = + DijkstraEraBasedProtocolParametersUpdate + <$> genCommonProtocolParametersUpdate + <*> genAlonzoOnwardsPParams + <*> genIntroducedInBabbagePParams + <*> genIntroducedInConwayPParams + <*> genIntroducedInDijkstraPParams diff --git a/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs b/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs index 1378661809..4f5154577e 100644 --- a/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs +++ b/cardano-api/src/Cardano/Api/Internal/Orphans/Misc.hs @@ -27,6 +27,7 @@ import Cardano.Ledger.Binary import Cardano.Ledger.Binary qualified as CBOR import Cardano.Ledger.Coin qualified as L import Cardano.Ledger.Conway.PParams qualified as Ledger +import Cardano.Ledger.Dijkstra.PParams qualified as Ledger import Cardano.Ledger.HKD (NoUpdate (..)) import Cardano.Ledger.Plutus.Language qualified as L import Cardano.Ledger.Shelley.PParams qualified as Ledger @@ -273,6 +274,50 @@ instance Semigroup (Ledger.ConwayPParams StrictMaybe era) where lastMappendWithTHKD Ledger.cppMinFeeRefScriptCostPerByte p1 p2 } +instance Semigroup (Ledger.DijkstraPParams StrictMaybe era) where + (<>) p1 p2 = + Ledger.DijkstraPParams + { Ledger.dppTxFeePerByte = lastMappendWithTHKD Ledger.dppTxFeePerByte p1 p2 + , Ledger.dppTxFeeFixed = lastMappendWithTHKD Ledger.dppTxFeeFixed p1 p2 + , Ledger.dppMaxBBSize = lastMappendWithTHKD Ledger.dppMaxBBSize p1 p2 + , Ledger.dppMaxTxSize = lastMappendWithTHKD Ledger.dppMaxTxSize p1 p2 + , Ledger.dppMaxBHSize = lastMappendWithTHKD Ledger.dppMaxBHSize p1 p2 + , Ledger.dppKeyDeposit = lastMappendWithTHKD Ledger.dppKeyDeposit p1 p2 + , Ledger.dppPoolDeposit = lastMappendWithTHKD Ledger.dppPoolDeposit p1 p2 + , Ledger.dppEMax = lastMappendWithTHKD Ledger.dppEMax p1 p2 + , Ledger.dppNOpt = lastMappendWithTHKD Ledger.dppNOpt p1 p2 + , Ledger.dppA0 = lastMappendWithTHKD Ledger.dppA0 p1 p2 + , Ledger.dppRho = lastMappendWithTHKD Ledger.dppRho p1 p2 + , Ledger.dppTau = lastMappendWithTHKD Ledger.dppTau p1 p2 + , Ledger.dppProtocolVersion = NoUpdate -- For Dijkstra, protocol version cannot be changed via PParamsUpdate + , Ledger.dppMinPoolCost = lastMappendWithTHKD Ledger.dppMinPoolCost p1 p2 + , Ledger.dppCoinsPerUTxOByte = lastMappendWithTHKD Ledger.dppCoinsPerUTxOByte p1 p2 + , Ledger.dppCostModels = lastMappendWithTHKD Ledger.dppCostModels p1 p2 + , Ledger.dppPrices = lastMappendWithTHKD Ledger.dppPrices p1 p2 + , Ledger.dppMaxTxExUnits = lastMappendWithTHKD Ledger.dppMaxTxExUnits p1 p2 + , Ledger.dppMaxBlockExUnits = lastMappendWithTHKD Ledger.dppMaxBlockExUnits p1 p2 + , Ledger.dppMaxValSize = lastMappendWithTHKD Ledger.dppMaxValSize p1 p2 + , Ledger.dppCollateralPercentage = lastMappendWithTHKD Ledger.dppCollateralPercentage p1 p2 + , Ledger.dppMaxCollateralInputs = lastMappendWithTHKD Ledger.dppMaxCollateralInputs p1 p2 + , Ledger.dppPoolVotingThresholds = lastMappendWithTHKD Ledger.dppPoolVotingThresholds p1 p2 + , Ledger.dppDRepVotingThresholds = lastMappendWithTHKD Ledger.dppDRepVotingThresholds p1 p2 + , Ledger.dppCommitteeMinSize = lastMappendWithTHKD Ledger.dppCommitteeMinSize p1 p2 + , Ledger.dppCommitteeMaxTermLength = lastMappendWithTHKD Ledger.dppCommitteeMaxTermLength p1 p2 + , Ledger.dppGovActionLifetime = lastMappendWithTHKD Ledger.dppGovActionLifetime p1 p2 + , Ledger.dppGovActionDeposit = lastMappendWithTHKD Ledger.dppGovActionDeposit p1 p2 + , Ledger.dppDRepDeposit = lastMappendWithTHKD Ledger.dppDRepDeposit p1 p2 + , Ledger.dppDRepActivity = lastMappendWithTHKD Ledger.dppDRepActivity p1 p2 + , Ledger.dppMinFeeRefScriptCostPerByte = + lastMappendWithTHKD Ledger.dppMinFeeRefScriptCostPerByte p1 p2 + , Ledger.dppMaxRefScriptSizePerBlock = + lastMappendWithTHKD Ledger.dppMaxRefScriptSizePerBlock p1 p2 + , Ledger.dppMaxRefScriptSizePerTx = + lastMappendWithTHKD Ledger.dppMaxRefScriptSizePerTx p1 p2 + , Ledger.dppRefScriptCostStride = lastMappendWithTHKD Ledger.dppRefScriptCostStride p1 p2 + , Ledger.dppRefScriptCostMultiplier = + lastMappendWithTHKD Ledger.dppRefScriptCostMultiplier p1 p2 + } + lastMappendWithTHKD :: (a -> Ledger.THKD g StrictMaybe b) -> a -> a -> Ledger.THKD g StrictMaybe b lastMappendWithTHKD f a b = Ledger.THKD $ lastMappendWith (Ledger.unTHKD . f) a b diff --git a/cardano-api/src/Cardano/Api/ProtocolParameters.hs b/cardano-api/src/Cardano/Api/ProtocolParameters.hs index a69c6ae95f..ece4afcbb2 100644 --- a/cardano-api/src/Cardano/Api/ProtocolParameters.hs +++ b/cardano-api/src/Cardano/Api/ProtocolParameters.hs @@ -39,6 +39,7 @@ module Cardano.Api.ProtocolParameters , ShelleyToAlonzoPParams (..) , IntroducedInBabbagePParams (..) , IntroducedInConwayPParams (..) + , IntroducedInDijkstraPParams (..) , createEraBasedProtocolParamUpdate , createPParams @@ -112,6 +113,7 @@ import Cardano.Ledger.Babbage.Core qualified as Ledger import Cardano.Ledger.BaseTypes qualified as Ledger import Cardano.Ledger.Coin qualified as L import Cardano.Ledger.Conway.PParams qualified as Ledger +import Cardano.Ledger.Dijkstra.PParams qualified as Ledger import Cardano.Ledger.Hashes (HASH) import Cardano.Ledger.Plutus.CostModels qualified as Plutus import Cardano.Ledger.Plutus.Language qualified as Plutus @@ -214,6 +216,13 @@ data EraBasedProtocolParametersUpdate era where -> IntroducedInBabbagePParams ConwayEra -> IntroducedInConwayPParams (ShelleyLedgerEra ConwayEra) -> EraBasedProtocolParametersUpdate ConwayEra + DijkstraEraBasedProtocolParametersUpdate + :: CommonProtocolParametersUpdate + -> AlonzoOnwardsPParams DijkstraEra + -> IntroducedInBabbagePParams DijkstraEra + -> IntroducedInConwayPParams (ShelleyLedgerEra DijkstraEra) + -> IntroducedInDijkstraPParams (ShelleyLedgerEra DijkstraEra) + -> EraBasedProtocolParametersUpdate DijkstraEra deriving instance Show (EraBasedProtocolParametersUpdate era) @@ -276,6 +285,38 @@ pparamsUpdateToIntroducedInConwayPParams ppupdate = , icMinFeeRefScriptCostPerByte = ppupdate ^. Ledger.ppuMinFeeRefScriptCostPerByteL } +data IntroducedInDijkstraPParams era + = IntroducedInDijkstraPParams + { idMaxRefScriptSizePerBlock :: StrictMaybe Word32 + , idMaxRefScriptSizePerTx :: StrictMaybe Word32 + , idRefScriptCostStride :: StrictMaybe (Ledger.NonZero Word32) + , idRefScriptCostMultiplier :: StrictMaybe Ledger.PositiveInterval + } + deriving (Eq, Show) + +createIntroducedInDijkstraPParams + :: (Ledger.ConwayEraPParams ledgerera, Ledger.DijkstraEraPParams ledgerera) + => IntroducedInDijkstraPParams ledgerera + -> Ledger.PParamsUpdate ledgerera +createIntroducedInDijkstraPParams IntroducedInDijkstraPParams{..} = + Ledger.emptyPParamsUpdate + & Ledger.ppuMaxRefScriptSizePerBlockL .~ idMaxRefScriptSizePerBlock + & Ledger.ppuMaxRefScriptSizePerTxL .~ idMaxRefScriptSizePerTx + & Ledger.ppuRefScriptCostStrideL .~ idRefScriptCostStride + & Ledger.ppuRefScriptCostMultiplierL .~ idRefScriptCostMultiplier + +pparamsUpdateToIntroducedInDijkstraPParams + :: Ledger.DijkstraEraPParams ledgerera + => Ledger.PParamsUpdate ledgerera + -> IntroducedInDijkstraPParams ledgerera +pparamsUpdateToIntroducedInDijkstraPParams ppupdate = + IntroducedInDijkstraPParams + { idMaxRefScriptSizePerBlock = ppupdate ^. Ledger.ppuMaxRefScriptSizePerBlockL + , idMaxRefScriptSizePerTx = ppupdate ^. Ledger.ppuMaxRefScriptSizePerTxL + , idRefScriptCostStride = ppupdate ^. Ledger.ppuRefScriptCostStrideL + , idRefScriptCostMultiplier = ppupdate ^. Ledger.ppuRefScriptCostMultiplierL + } + createEraBasedProtocolParamUpdate :: ShelleyBasedEra era -> EraBasedProtocolParametersUpdate era @@ -318,6 +359,18 @@ createEraBasedProtocolParamUpdate sbe eraPParamsUpdate = Ledger.PParamsUpdate inBab = createIntroducedInBabbagePParams BabbageEraOnwardsConway introInBabbage Ledger.PParamsUpdate inCon = createIntroducedInConwayPParams introInConway in Ledger.PParamsUpdate $ common <> inAlonzoPParams <> inBab <> inCon + DijkstraEraBasedProtocolParametersUpdate + c + introInAlonzo + introInBabbage + introInConway + introInDijkstra -> + let Ledger.PParamsUpdate common = createCommonPParamsUpdate c + Ledger.PParamsUpdate inAlonzoPParams = createPParamsUpdateIntroducedInAlonzo AlonzoEraOnwardsDijkstra introInAlonzo + Ledger.PParamsUpdate inBab = createIntroducedInBabbagePParams BabbageEraOnwardsDijkstra introInBabbage + Ledger.PParamsUpdate inCon = createIntroducedInConwayPParams introInConway + Ledger.PParamsUpdate inDij = createIntroducedInDijkstraPParams introInDijkstra + in Ledger.PParamsUpdate $ common <> inAlonzoPParams <> inBab <> inCon <> inDij -- | Protocol parameters common to each era. This can only ever be reduced -- if parameters are deprecated. @@ -1011,7 +1064,16 @@ fromLedgerPParamsUpdate sbe ppup = introInConway = pparamsUpdateToIntroducedInConwayPParams ppup in ConwayEraBasedProtocolParametersUpdate common introInAlonzo introInBabbage introInConway ShelleyBasedEraDijkstra -> - error "TODO Dijkstra: fromLedgerPParamsUpdate: era not supported" + let introInAlonzo = pparamsUpdateToAlonzoOnwardsPParams AlonzoEraOnwardsDijkstra ppup + introInBabbage = pparamsUpdateToIntroducedInBabbagePParams BabbageEraOnwardsDijkstra ppup + introInConway = pparamsUpdateToIntroducedInConwayPParams ppup + introInDijkstra = pparamsUpdateToIntroducedInDijkstraPParams ppup + in DijkstraEraBasedProtocolParametersUpdate + common + introInAlonzo + introInBabbage + introInConway + introInDijkstra data ProtocolParametersError = PParamsErrorMissingMinUTxoValue !AnyCardanoEra From bbf01be17e921a6d34b0676a42b660873b36186c Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 18 Aug 2026 00:55:40 +0000 Subject: [PATCH 11/62] Dispatch ledger queries in the Dijkstra era Route all Conway-onwards queries (constitution, governance state, DRep/SPO state and stake distributions, committee state, vote delegatees, proposals, ratification and future parameters, default votes and DRep delegations) through caseShelleyToBabbageOrConwayEraOnwards with obtainCommonConstraints, so they work in Dijkstra as well. Co-Authored-By: Mateusz Galazyn Co-Authored-By: Sebastian Nagel Co-Authored-By: John Lotoski --- ...dano-api_palas_dijkstra_ledger_queries.yml | 6 ++ .../Api/Query/Internal/Type/QueryInMode.hs | 71 ++++++++++++------- 2 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 .changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml diff --git a/.changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml b/.changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml new file mode 100644 index 0000000000..0d11bb70e0 --- /dev/null +++ b/.changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml @@ -0,0 +1,6 @@ +description: | + All Conway-onwards ledger queries can now be run in the Dijkstra era: constitution, governance state, DRep and SPO state and stake distributions, committee state, vote delegatees, proposals, ratification state and future protocol parameters, default votes, and DRep delegations. Previously they errored for Dijkstra. +kind: + - feature +pr: 1310 +project: cardano-api diff --git a/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs b/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs index e467998d74..e89e0d0b1b 100644 --- a/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs +++ b/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs @@ -73,8 +73,10 @@ import Cardano.Api.Certificate.Internal import Cardano.Api.Consensus.Internal.Mode import Cardano.Api.Era.Internal.Case import Cardano.Api.Era.Internal.Core -import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards +import Cardano.Api.Era.Internal.Eon.Convert (Convert (convert)) +import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards () import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra +import Cardano.Api.Experimental.Era (obtainCommonConstraints) import Cardano.Api.Genesis.Internal.Parameters import Cardano.Api.HasTypeProxy (HasTypeProxy (..)) import Cardano.Api.Key.Internal @@ -586,7 +588,9 @@ toConsensusQueryShelleyBased sbe = \case QueryConstitution -> caseShelleyToBabbageOrConwayEraOnwards (const $ error "toConsensusQueryShelleyBased: QueryConstitution is only available in the Conway era") - (const $ Some (consensusQueryInEraInMode era Consensus.GetConstitution)) + ( \w -> + obtainCommonConstraints (convert w) $ Some (consensusQueryInEraInMode era Consensus.GetConstitution) + ) sbe QueryGenesisParameters -> Some (consensusQueryInEraInMode era Consensus.GetGenesisConfig) @@ -657,20 +661,26 @@ toConsensusQueryShelleyBased sbe = \case QueryRatifyState -> caseShelleyToBabbageOrConwayEraOnwards (const $ error "toConsensusQueryShelleyBased: QueryRatifyState is only available in the Conway era") - (const $ Some (consensusQueryInEraInMode era Consensus.GetRatifyState)) + ( \w -> + obtainCommonConstraints (convert w) $ Some (consensusQueryInEraInMode era Consensus.GetRatifyState) + ) sbe QueryFuturePParams -> caseShelleyToBabbageOrConwayEraOnwards ( const $ error "toConsensusQueryShelleyBased: QueryFuturePParams is only available in the Conway era onwards" ) - (const $ Some (consensusQueryInEraInMode era Consensus.GetFuturePParams)) + ( \w -> + obtainCommonConstraints (convert w) $ + Some (consensusQueryInEraInMode era Consensus.GetFuturePParams) + ) sbe QueryDRepState creds -> caseShelleyToBabbageOrConwayEraOnwards (const $ error "toConsensusQueryShelleyBased: QueryDRepState is only available in the Conway era") ( \w -> - Some (consensusQueryInEraInMode era (conwayEraOnwardsConstraints w $ Consensus.GetDRepState creds)) + obtainCommonConstraints (convert w) $ + Some (consensusQueryInEraInMode era (Consensus.GetDRepState creds)) ) sbe QueryDRepStakeDistr dreps -> @@ -678,23 +688,30 @@ toConsensusQueryShelleyBased sbe = \case ( const $ error "toConsensusQueryShelleyBased: QueryDRepStakeDistr is only available in the Conway era" ) - (const $ Some (consensusQueryInEraInMode era (Consensus.GetDRepStakeDistr dreps))) + ( \w -> + obtainCommonConstraints (convert w) $ + Some (consensusQueryInEraInMode era (Consensus.GetDRepStakeDistr dreps)) + ) sbe QuerySPOStakeDistr spos -> caseShelleyToBabbageOrConwayEraOnwards ( const $ error "toConsensusQueryShelleyBased: QuerySPOStakeDistr is only available in the Conway era" ) - (const $ Some (consensusQueryInEraInMode era (Consensus.GetSPOStakeDistr spos))) + ( \w -> + obtainCommonConstraints (convert w) $ + Some (consensusQueryInEraInMode era (Consensus.GetSPOStakeDistr spos)) + ) sbe QueryCommitteeMembersState coldCreds hotCreds statuses -> caseShelleyToBabbageOrConwayEraOnwards ( const $ error "toConsensusQueryShelleyBased: QueryCommitteeMembersState is only available in the Conway era" ) - ( const $ - Some - (consensusQueryInEraInMode era (Consensus.GetCommitteeMembersState coldCreds hotCreds statuses)) + ( \w -> + obtainCommonConstraints (convert w) $ + Some + (consensusQueryInEraInMode era (Consensus.GetCommitteeMembersState coldCreds hotCreds statuses)) ) sbe QueryStakeVoteDelegatees creds -> @@ -702,12 +719,13 @@ toConsensusQueryShelleyBased sbe = \case ( const $ error "toConsensusQueryShelleyBased: QueryStakeVoteDelegatees is only available in the Conway era" ) - ( const $ - Some - ( consensusQueryInEraInMode - era - (Consensus.GetFilteredVoteDelegatees creds') - ) + ( \w -> + obtainCommonConstraints (convert w) $ + Some + ( consensusQueryInEraInMode + era + (Consensus.GetFilteredVoteDelegatees creds') + ) ) sbe where @@ -718,9 +736,10 @@ toConsensusQueryShelleyBased sbe = \case ( const $ error "toConsensusQueryShelleyBased: QueryProposals is only available in the Conway era" ) - ( const $ - Some - (consensusQueryInEraInMode era (Consensus.GetProposals govActs)) + ( \w -> + obtainCommonConstraints (convert w) $ + Some + (consensusQueryInEraInMode era (Consensus.GetProposals govActs)) ) sbe QueryLedgerPeerSnapshot peerKind -> @@ -731,9 +750,10 @@ toConsensusQueryShelleyBased sbe = \case ( const $ error "toConsensusQueryShelleyBased: QueryStakePoolDefaultVote is only available in the Conway era" ) - ( const $ - Some - (consensusQueryInEraInMode era (Consensus.QueryStakePoolDefaultVote govActs)) + ( \w -> + obtainCommonConstraints (convert w) $ + Some + (consensusQueryInEraInMode era (Consensus.QueryStakePoolDefaultVote govActs)) ) sbe GetDRepDelegations dreps -> @@ -741,9 +761,10 @@ toConsensusQueryShelleyBased sbe = \case ( const $ error "toConsensusQueryShelleyBased: GetDRepDelegations is only available in the Conway era" ) - ( const $ - Some - (consensusQueryInEraInMode era (Consensus.GetDRepDelegations dreps)) + ( \w -> + obtainCommonConstraints (convert w) $ + Some + (consensusQueryInEraInMode era (Consensus.GetDRepDelegations dreps)) ) sbe where From ab1cfc377398d6b40ba04a3a42bc9b351224fe77 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Sat, 22 Aug 2026 01:34:30 +0000 Subject: [PATCH 12/62] Fix the era wording in the Conway-onwards query error messages These queries now dispatch in Conway and later eras, but the pre-Conway error arms still claimed "only available in the Conway era"; say "only available from the Conway era onwards" instead, and align the QueryFuturePParams message, which had its own variant of the wording. --- .../Api/Query/Internal/Type/QueryInMode.hs | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs b/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs index e89e0d0b1b..671a787d3b 100644 --- a/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs +++ b/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs @@ -587,7 +587,10 @@ toConsensusQueryShelleyBased sbe = \case Some (consensusQueryInEraInMode era Consensus.GetEpochNo) QueryConstitution -> caseShelleyToBabbageOrConwayEraOnwards - (const $ error "toConsensusQueryShelleyBased: QueryConstitution is only available in the Conway era") + ( const $ + error + "toConsensusQueryShelleyBased: QueryConstitution is only available from the Conway era onwards" + ) ( \w -> obtainCommonConstraints (convert w) $ Some (consensusQueryInEraInMode era Consensus.GetConstitution) ) @@ -660,7 +663,9 @@ toConsensusQueryShelleyBased sbe = \case Some (consensusQueryInEraInMode era Consensus.GetGovState) QueryRatifyState -> caseShelleyToBabbageOrConwayEraOnwards - (const $ error "toConsensusQueryShelleyBased: QueryRatifyState is only available in the Conway era") + ( const $ + error "toConsensusQueryShelleyBased: QueryRatifyState is only available from the Conway era onwards" + ) ( \w -> obtainCommonConstraints (convert w) $ Some (consensusQueryInEraInMode era Consensus.GetRatifyState) ) @@ -668,7 +673,8 @@ toConsensusQueryShelleyBased sbe = \case QueryFuturePParams -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: QueryFuturePParams is only available in the Conway era onwards" + error + "toConsensusQueryShelleyBased: QueryFuturePParams is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ @@ -677,7 +683,9 @@ toConsensusQueryShelleyBased sbe = \case sbe QueryDRepState creds -> caseShelleyToBabbageOrConwayEraOnwards - (const $ error "toConsensusQueryShelleyBased: QueryDRepState is only available in the Conway era") + ( const $ + error "toConsensusQueryShelleyBased: QueryDRepState is only available from the Conway era onwards" + ) ( \w -> obtainCommonConstraints (convert w) $ Some (consensusQueryInEraInMode era (Consensus.GetDRepState creds)) @@ -686,7 +694,8 @@ toConsensusQueryShelleyBased sbe = \case QueryDRepStakeDistr dreps -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: QueryDRepStakeDistr is only available in the Conway era" + error + "toConsensusQueryShelleyBased: QueryDRepStakeDistr is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ @@ -696,7 +705,8 @@ toConsensusQueryShelleyBased sbe = \case QuerySPOStakeDistr spos -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: QuerySPOStakeDistr is only available in the Conway era" + error + "toConsensusQueryShelleyBased: QuerySPOStakeDistr is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ @@ -706,7 +716,8 @@ toConsensusQueryShelleyBased sbe = \case QueryCommitteeMembersState coldCreds hotCreds statuses -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: QueryCommitteeMembersState is only available in the Conway era" + error + "toConsensusQueryShelleyBased: QueryCommitteeMembersState is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ @@ -717,7 +728,8 @@ toConsensusQueryShelleyBased sbe = \case QueryStakeVoteDelegatees creds -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: QueryStakeVoteDelegatees is only available in the Conway era" + error + "toConsensusQueryShelleyBased: QueryStakeVoteDelegatees is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ @@ -734,7 +746,7 @@ toConsensusQueryShelleyBased sbe = \case QueryProposals govActs -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: QueryProposals is only available in the Conway era" + error "toConsensusQueryShelleyBased: QueryProposals is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ @@ -748,7 +760,8 @@ toConsensusQueryShelleyBased sbe = \case QueryStakePoolDefaultVote govActs -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: QueryStakePoolDefaultVote is only available in the Conway era" + error + "toConsensusQueryShelleyBased: QueryStakePoolDefaultVote is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ @@ -759,7 +772,8 @@ toConsensusQueryShelleyBased sbe = \case GetDRepDelegations dreps -> caseShelleyToBabbageOrConwayEraOnwards ( const $ - error "toConsensusQueryShelleyBased: GetDRepDelegations is only available in the Conway era" + error + "toConsensusQueryShelleyBased: GetDRepDelegations is only available from the Conway era onwards" ) ( \w -> obtainCommonConstraints (convert w) $ From c808d7cecfce6b484342edce47bfd88c1e4e3106 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 18 Aug 2026 02:03:46 +0000 Subject: [PATCH 13/62] Enable Dijkstra-era transaction construction and balancing The experimental makeUnsignedTx builds Dijkstra transaction bodies, translating extra key witnesses into appended key-hash guards (the era's replacement for required signer hashes); fee estimation, auto-balancing and execution-unit substitution for proposals gain Dijkstra support; BalanceIsNegative carries the era's UnsignedTx instead of a hardcoded Conway one; and vote witness extraction handles Dijkstra in both APIs. Co-Authored-By: John Lotoski Co-Authored-By: Mateusz Galazyn Co-Authored-By: kderme --- ...ano-api_palas_dijkstra_tx_construction.yml | 9 + .../Tx/Internal/BodyContent/New.hs | 55 +++--- .../Api/Experimental/Tx/Internal/Fee.hs | 156 +++++++++--------- .../src/Cardano/Api/Tx/Internal/Body.hs | 3 +- .../src/Cardano/Api/Tx/Internal/Fee.hs | 3 +- 5 files changed, 118 insertions(+), 108 deletions(-) create mode 100644 .changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml diff --git a/.changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml b/.changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml new file mode 100644 index 0000000000..c5ff7f3a49 --- /dev/null +++ b/.changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml @@ -0,0 +1,9 @@ +description: | + Dijkstra transactions can now be built, fee-estimated and auto-balanced with the experimental API (`makeUnsignedTx`, `estimateBalancedTxBody`, `makeTransactionBodyAutoBalance`). Extra key witnesses become key-hash guards, the era's replacement for required signer hashes — the same keys must sign. + + Breaking: `BalanceIsNegative` now carries the era's `UnsignedTx` instead of a Conway-specific one; code matching on it needs the more general type. +kind: + - feature + - breaking +pr: 1312 +project: cardano-api diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs index 3d80128174..7d27525a79 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs @@ -187,8 +187,7 @@ makeUnsignedTx . Era era -> TxBodyContent (LedgerEra era) -> Either MakeUnsignedTxError (UnsignedTx (LedgerEra era)) -makeUnsignedTx DijkstraEra _ = error "TODO Dijkstra: makeUnsignedTx: era not supported" -makeUnsignedTx era@ConwayEra bc = obtainCommonConstraints era $ do +makeUnsignedTx era bc = obtainCommonConstraints era $ do let TxScriptWitnessRequirements languages scripts datums redeemers = collectTxBodyScriptWitnessRequirements bc -- cardano-api types @@ -219,23 +218,31 @@ makeUnsignedTx era@ConwayEra bc = obtainCommonConstraints era $ do let setMint = convMintValue apiMintValue setReqSignerHashes = convExtraKeyWitnesses apiExtraKeyWitnesses + -- reqSignerHashesTxBodyL is gated AtMostEra "Conway" in the ledger; + -- Dijkstra replaced required signer hashes with guards, and a key-hash + -- guard makes the ledger demand that key's signature: translate, + -- appending so any other guards stay intact. + applyReqSignerHashes b = case era of + ConwayEra -> b & L.reqSignerHashesTxBodyL .~ setReqSignerHashes + DijkstraEra -> + b & L.guardsTxBodyL %~ (<> OSet.fromSet (Set.map L.KeyHashObj setReqSignerHashes)) ledgerTxBody = - L.mkBasicTxBody - & L.inputsTxBodyL .~ txins - & L.collateralInputsTxBodyL .~ collTxIns - & L.referenceInputsTxBodyL .~ refTxIns - & L.outputsTxBodyL .~ outs - & L.totalCollateralTxBodyL .~ L.maybeToStrictMaybe totCollateral - & L.collateralReturnTxBodyL .~ L.maybeToStrictMaybe retCollateral - & L.feeTxBodyL .~ fee - & L.vldtTxBodyL . L.invalidBeforeL .~ L.maybeToStrictMaybe (txValidityLowerBound bc) - & L.vldtTxBodyL . L.invalidHereAfterL .~ L.maybeToStrictMaybe (txValidityUpperBound bc) - & L.reqSignerHashesTxBodyL .~ setReqSignerHashes - & L.scriptIntegrityHashTxBodyL .~ scriptIntegrityHash - & L.withdrawalsTxBodyL .~ withdrawals - & L.certsTxBodyL .~ certs - & L.mintTxBodyL .~ setMint - & L.auxDataHashTxBodyL .~ L.maybeToStrictMaybe (Ledger.hashTxAuxData <$> txAuxData) + applyReqSignerHashes $ + L.mkBasicTxBody + & L.inputsTxBodyL .~ txins + & L.collateralInputsTxBodyL .~ collTxIns + & L.referenceInputsTxBodyL .~ refTxIns + & L.outputsTxBodyL .~ outs + & L.totalCollateralTxBodyL .~ L.maybeToStrictMaybe totCollateral + & L.collateralReturnTxBodyL .~ L.maybeToStrictMaybe retCollateral + & L.feeTxBodyL .~ fee + & L.vldtTxBodyL . L.invalidBeforeL .~ L.maybeToStrictMaybe (txValidityLowerBound bc) + & L.vldtTxBodyL . L.invalidHereAfterL .~ L.maybeToStrictMaybe (txValidityUpperBound bc) + & L.scriptIntegrityHashTxBodyL .~ scriptIntegrityHash + & L.withdrawalsTxBodyL .~ withdrawals + & L.certsTxBodyL .~ certs + & L.mintTxBodyL .~ setMint + & L.auxDataHashTxBodyL .~ L.maybeToStrictMaybe (Ledger.hashTxAuxData <$> txAuxData) scriptWitnesses = L.mkBasicTxWits @@ -910,13 +917,11 @@ extractWitnessableVotes -> [(Witnessable VoterItem (LedgerEra era), AnyWitness (LedgerEra era))] extractWitnessableVotes Nothing = [] extractWitnessableVotes (Just txVoteProc) = - case useEra @era of - DijkstraEra -> error "TODO Dijkstra: extractWitnessableVotes: era not supported" - ConwayEra -> - List.nub - [ (WitVote vote, wit) - | (vote, wit) <- getVotes txVoteProc - ] + obtainCommonConstraints (useEra @era) $ + List.nub + [ (WitVote vote, wit) + | (vote, wit) <- getVotes txVoteProc + ] where getVotes :: TxVotingProcedures (LedgerEra era) diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs index e79cb995c4..692113827b 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs @@ -132,7 +132,7 @@ data TxBodyErrorAutoBalance era | BalanceIsNegative L.Coin -- ^ Negative balance - (UnsignedTx (LedgerEra ConwayEra)) + (UnsignedTx era) -- ^ The transaction body | NotEnoughAdaInUTxO L.MaryValue @@ -442,42 +442,40 @@ estimateBalancedTxBody' balanceTxOut = obtainCommonConstraints (useEra @era) $ TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) balance) - case useEra @era of - DijkstraEra -> error "TODO Dijkstra: estimateBalancedTxBody: era not supported for fee estimation" - ConwayEra -> do - when (coinBalance < 0) $ - Left $ - TxFeeEstimationBalanceError $ - BalanceIsNegative coinBalance txbody2 - - -- Step 6. Check all txouts have the min required UTxO value - -- TOOD: Fix me. You need a new error type to accomodate your new types - first (TxFeeEstimationBalanceError . uncurry TxBodyErrorMinUTxONotMet) - . mapM_ (checkMinUTxOValue pparams) - $ txOuts txbodycontent1 - - -- check if the balance is positive or negative - -- in one case we can produce change, in the other the inputs are insufficient - finalTxOuts <- - first TxFeeEstimationBalanceError $ - checkAndIncludeChange pparams balanceTxOut (txOuts txbodycontent1) - - -- Step 7. - - -- Create the txbody with the final fee and change output. This should work - -- provided that the fee and change are less than 2^32-1, and so will - -- fit within the encoding size we picked above when calculating the fee. - -- Yes this could be an over-estimate by a few bytes if the fee or change - -- would fit within 2^16-1. That's a possible optimisation. - let finalTxBodyContent = - txbodycontent1 - { txFee = fee - , txOuts = finalTxOuts - , txReturnCollateral = maybeReturnTxCollateral - , txTotalCollateral = maybeTotalTxCollateral - } - - return finalTxBodyContent + obtainCommonConstraints (useEra @era) $ do + when (coinBalance < 0) $ + Left $ + TxFeeEstimationBalanceError $ + BalanceIsNegative coinBalance txbody2 + + -- Step 6. Check all txouts have the min required UTxO value + -- TOOD: Fix me. You need a new error type to accomodate your new types + first (TxFeeEstimationBalanceError . uncurry TxBodyErrorMinUTxONotMet) + . mapM_ (checkMinUTxOValue pparams) + $ txOuts txbodycontent1 + + -- check if the balance is positive or negative + -- in one case we can produce change, in the other the inputs are insufficient + finalTxOuts <- + first TxFeeEstimationBalanceError $ + checkAndIncludeChange pparams balanceTxOut (txOuts txbodycontent1) + + -- Step 7. + + -- Create the txbody with the final fee and change output. This should work + -- provided that the fee and change are less than 2^32-1, and so will + -- fit within the encoding size we picked above when calculating the fee. + -- Yes this could be an over-estimate by a few bytes if the fee or change + -- would fit within 2^16-1. That's a possible optimisation. + let finalTxBodyContent = + txbodycontent1 + { txFee = fee + , txOuts = finalTxOuts + , txReturnCollateral = maybeReturnTxCollateral + , txTotalCollateral = maybeTotalTxCollateral + } + + return finalTxBodyContent data IsEmpty = Empty | NonEmpty deriving (Eq, Show) @@ -1684,49 +1682,47 @@ makeTransactionBodyAutoBalance , txTotalCollateral = maybeTotalTxCollateral } - case useEra @era of - DijkstraEra -> error "TODO Dijkstra: makeTransactionBodyAutoBalance: era not supported" - ConwayEra -> do - let balance :: L.MaryValue = evaluateTransactionBalance pp poolids stakeDelegDeposits utxo txbody2 - adaBalance = getAda (useEra @era) balance - when (adaBalance < 0) $ - Left $ - BalanceIsNegative adaBalance txbodyForChange - - let - -- The multiasset output of evaluateTransactionBalance will be negative when - -- minting a multiasset. Therefore we must make the multiasset balance positive - balanceTxOut :: TxOut (LedgerEra era) = - obtainCommonConstraints (useEra @era) $ - TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) balance) - first (uncurry TxBodyErrorMinUTxONotMet) - . mapM_ (checkMinUTxOValue pp) - $ txOuts txbodycontent1 - - -- check if change meets txout criteria, and include if non-zero - finalTxOuts <- checkAndIncludeChange pp balanceTxOut (txOuts txbodycontent1) - - -- TODO: we could add the extra fee for the CBOR encoding of the change, - -- now that we know the magnitude of the change: i.e. 1-8 bytes extra. - -- The txbody with the final fee and change output. This should work - -- provided that the fee and change are less than 2^32-1, and so will - -- fit within the encoding size we picked above when calculating the fee. - -- Yes this could be an over-estimate by a few bytes if the fee or change - -- would fit within 2^16-1. That's a possible optimisation. - let finalTxBodyContent = - txbodycontent1 - { txFee = fee - , txOuts = finalTxOuts - , txReturnCollateral = maybeReturnTxCollateral - , txTotalCollateral = maybeTotalTxCollateral - } - txbody3 <- - first TxBodyErrorMakeUnsignedTx $ - makeUnsignedTx - useEra - finalTxBodyContent - return - (txbody3, finalTxBodyContent) + obtainCommonConstraints (useEra @era) $ do + let balance :: L.MaryValue = evaluateTransactionBalance pp poolids stakeDelegDeposits utxo txbody2 + adaBalance = getAda (useEra @era) balance + when (adaBalance < 0) $ + Left $ + BalanceIsNegative adaBalance txbodyForChange + + let + -- The multiasset output of evaluateTransactionBalance will be negative when + -- minting a multiasset. Therefore we must make the multiasset balance positive + balanceTxOut :: TxOut (LedgerEra era) = + obtainCommonConstraints (useEra @era) $ + TxOut (L.mkBasicTxOut (toShelleyAddr changeaddr) balance) + first (uncurry TxBodyErrorMinUTxONotMet) + . mapM_ (checkMinUTxOValue pp) + $ txOuts txbodycontent1 + + -- check if change meets txout criteria, and include if non-zero + finalTxOuts <- checkAndIncludeChange pp balanceTxOut (txOuts txbodycontent1) + + -- TODO: we could add the extra fee for the CBOR encoding of the change, + -- now that we know the magnitude of the change: i.e. 1-8 bytes extra. + -- The txbody with the final fee and change output. This should work + -- provided that the fee and change are less than 2^32-1, and so will + -- fit within the encoding size we picked above when calculating the fee. + -- Yes this could be an over-estimate by a few bytes if the fee or change + -- would fit within 2^16-1. That's a possible optimisation. + let finalTxBodyContent = + txbodycontent1 + { txFee = fee + , txOuts = finalTxOuts + , txReturnCollateral = maybeReturnTxCollateral + , txTotalCollateral = maybeTotalTxCollateral + } + txbody3 <- + first TxBodyErrorMakeUnsignedTx $ + makeUnsignedTx + useEra + finalTxBodyContent + return + (txbody3, finalTxBodyContent) getAda :: Era era -> L.Value (LedgerEra era) -> L.Coin getAda e val = case e of diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index c2b7e4faa8..adad880507 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -2499,8 +2499,7 @@ extractWitnessableVotes :: ConwayEraOnwards era -> Maybe (Featured eon era (TxVotingProcedures BuildTx era)) -> [(Witnessable VoterItem (ShelleyLedgerEra era), BuildTxWith BuildTx (Witness WitCtxStake era))] -extractWitnessableVotes ConwayEraOnwardsDijkstra _ = error "TODO Dijkstra: extractWitnessableVotes: era not supported" -extractWitnessableVotes e@ConwayEraOnwardsConway txVotingProcedures = +extractWitnessableVotes e txVotingProcedures = List.nub [ (conwayEraOnwardsConstraints e $ WitVote vote, BuildTxWith wit) | (vote, wit) <- getVotes $ maybe TxVotingProceduresNone unFeatured txVotingProcedures diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Fee.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Fee.hs index cf6b96f95f..b3bd2197b7 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Fee.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Fee.hs @@ -67,6 +67,7 @@ import Cardano.Api.Era.Internal.Eon.MaryEraOnwards import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra import Cardano.Api.Era.Internal.Feature import Cardano.Api.Error +import Cardano.Api.Experimental.Era (obtainCommonConstraints) import Cardano.Api.Experimental.Tx.Internal.Certificate qualified as Exp import Cardano.Api.Ledger.Internal.Reexport qualified as L import Cardano.Api.Plutus @@ -1639,7 +1640,7 @@ substituteExecutionUnits pure $ Just $ Featured era $ - conwayEraOnwardsConstraints era $ + obtainCommonConstraints (convert era) $ mkTxProposalProcedures substitutedExecutionUnits mapScriptWitnessesMinting From a47d58ce6a82b438aff4449399ca58e0c80afa82 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 18 Aug 2026 02:03:46 +0000 Subject: [PATCH 14/62] Serialise and witness Dijkstra-era transactions Add the "Tx DijkstraEra" text envelope types, generalize the compatible-transaction path over Conway-onwards, declare Plutus V1-V3 script support in Dijkstra (V3 is the era's ledger maximum for now), reexport DijkstraTxCert, and teach the generators that Dijkstra drops IsValid False by design; the now-redundant direct DijkstraTxCert import in cardano-rpc goes away. Co-Authored-By: kderme Co-Authored-By: Mateusz Galazyn Co-Authored-By: Konstantinos Lambrou-Latreille --- ...254_cardano-api_palas_dijkstra_tx_serialisation.yml | 6 ++++++ ...123958_cardano-rpc_palas_dijkstra_txcert_import.yml | 6 ++++++ cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs | 10 +++++++++- cardano-api/src/Cardano/Api/Compatible/Tx.hs | 7 ++++--- .../src/Cardano/Api/Ledger/Internal/Reexport.hs | 2 ++ cardano-api/src/Cardano/Api/Plutus/Internal/Script.hs | 6 ++++++ .../src/Cardano/Api/Serialise/TextEnvelope/Internal.hs | 6 ++++++ .../Api/Serialise/TextEnvelope/Internal/Cddl.hs | 4 ++++ .../Rpc/Server/Internal/UtxoRpc/Type/Certificate.hs | 3 +-- 9 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 .changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml create mode 100644 .changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml diff --git a/.changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml b/.changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml new file mode 100644 index 0000000000..c28f22e25f --- /dev/null +++ b/.changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml @@ -0,0 +1,6 @@ +description: | + Dijkstra transactions can now be serialised and witnessed: the `Tx DijkstraEra` text-envelope types work (witnessed and unwitnessed), Plutus V1-V3 scripts are supported in the era (the ledger's maximum for Dijkstra is V3 for now), and `createCompatibleTx` handles Dijkstra. By the era's design, transactions cannot be marked script-invalid in Dijkstra. +kind: + - feature +pr: 1313 +project: cardano-api diff --git a/.changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml b/.changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml new file mode 100644 index 0000000000..3724d61b8f --- /dev/null +++ b/.changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml @@ -0,0 +1,6 @@ +description: | + cardano-rpc now gets `DijkstraTxCert` through `cardano-api`'s reexport instead of importing it directly from the ledger; no user-facing changes. +kind: + - refactoring +pr: 1313 +project: cardano-rpc diff --git a/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs b/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs index c64649af1d..ef3ab6d609 100644 --- a/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs +++ b/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs @@ -1171,7 +1171,15 @@ genTxScriptValidity :: CardanoEra era -> Gen (TxScriptValidity era) genTxScriptValidity = inEonForEra (pure TxScriptValidityNone) - (\w -> TxScriptValidity w <$> genScriptValidity) + ( \w -> + TxScriptValidity w <$> case w of + AlonzoEraOnwardsAlonzo -> genScriptValidity + AlonzoEraOnwardsBabbage -> genScriptValidity + AlonzoEraOnwardsConway -> genScriptValidity + -- Dijkstra does not support IsValid False: the CBOR encoding omits the + -- isValid flag entirely and decoding always yields IsValid True. + AlonzoEraOnwardsDijkstra -> pure ScriptValid + ) genScriptValidity :: Gen ScriptValidity genScriptValidity = Gen.element [ScriptInvalid, ScriptValid] diff --git a/cardano-api/src/Cardano/Api/Compatible/Tx.hs b/cardano-api/src/Cardano/Api/Compatible/Tx.hs index b18ea339e7..6ec4714250 100644 --- a/cardano-api/src/Cardano/Api/Compatible/Tx.hs +++ b/cardano-api/src/Cardano/Api/Compatible/Tx.hs @@ -18,6 +18,7 @@ where import Cardano.Api.Address (StakeCredential) import Cardano.Api.Era import Cardano.Api.Experimental.AnyScriptWitness +import Cardano.Api.Experimental.Era (obtainCommonConstraints) import Cardano.Api.Experimental.Tx qualified as Exp import Cardano.Api.Experimental.Tx.Internal.AnyWitness import Cardano.Api.Experimental.Tx.Internal.AnyWitness qualified as Exp @@ -114,7 +115,7 @@ createCompatibleTx sbe ins outs extraDatums txFee' anyProtocolUpdate anyVote txC ] -- append proposal reference inputs & set proposal procedures updateTxBody :: Endo (L.TxBody L.TopTx (ShelleyLedgerEra era)) = - conwayEraOnwardsConstraints conwayOnwards $ + obtainCommonConstraints (convert conwayOnwards) $ Endo $ (L.referenceInputsTxBodyL %~ (<> fromList referenceInputs)) . (L.proposalProceduresTxBodyL .~ proposals) @@ -171,7 +172,7 @@ createCompatibleTx sbe ins outs extraDatums txFee' anyProtocolUpdate anyVote txC -> L.Tx L.TopTx (ShelleyLedgerEra era) -> L.Tx L.TopTx (ShelleyLedgerEra era) overwriteVotingProcedures conwayOnwards votingProcedures = - conwayEraOnwardsConstraints conwayOnwards $ + obtainCommonConstraints (convert conwayOnwards) $ (L.bodyTxL . L.votingProceduresTxBodyL) .~ votingProcedures indexedTxCerts @@ -319,7 +320,7 @@ indexWitnessedTxProposalProcedures ) ] indexWitnessedTxProposalProcedures cOnwards (Exp.TxProposalProcedures proposals) = do - let allProposalsList = zip [0 ..] $ conwayEraOnwardsConstraints cOnwards $ toList proposals + let allProposalsList = zip [0 ..] $ obtainCommonConstraints (convert cOnwards) $ toList proposals [ (proposal, (ScriptWitnessIndexProposing ix, anyWitness)) | (ix, (proposal, anyWitness)) <- allProposalsList ] diff --git a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs index f60f1d66de..bc10ce4fae 100644 --- a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs +++ b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs @@ -85,6 +85,7 @@ module Cardano.Api.Ledger.Internal.Reexport , valueFromList -- Dijkstra , DijkstraPlutusPurpose (..) + , DijkstraTxCert (..) -- Conway , Anchor (..) , Committee (..) @@ -397,6 +398,7 @@ import Cardano.Ledger.Core import Cardano.Ledger.Credential (Credential (..), credToText) import Cardano.Ledger.DRep (DRep (..), drepAnchorL, drepDepositL, drepExpiryL) import Cardano.Ledger.Dijkstra.Scripts (DijkstraPlutusPurpose (..)) +import Cardano.Ledger.Dijkstra.TxCert (DijkstraTxCert (..)) import Cardano.Ledger.Hashes ( ADDRHASH , SafeHash diff --git a/cardano-api/src/Cardano/Api/Plutus/Internal/Script.hs b/cardano-api/src/Cardano/Api/Plutus/Internal/Script.hs index 4b044d46ba..ce7944f2ed 100644 --- a/cardano-api/src/Cardano/Api/Plutus/Internal/Script.hs +++ b/cardano-api/src/Cardano/Api/Plutus/Internal/Script.hs @@ -660,6 +660,12 @@ scriptLanguageSupportedInEra era lang = Just PlutusScriptV2InConway (ShelleyBasedEraConway, PlutusScriptLanguage PlutusScriptV3) -> Just PlutusScriptV3InConway + (ShelleyBasedEraDijkstra, PlutusScriptLanguage PlutusScriptV1) -> + Just PlutusScriptV1InDijkstra + (ShelleyBasedEraDijkstra, PlutusScriptLanguage PlutusScriptV2) -> + Just PlutusScriptV2InDijkstra + (ShelleyBasedEraDijkstra, PlutusScriptLanguage PlutusScriptV3) -> + Just PlutusScriptV3InDijkstra _ -> Nothing languageOfScriptLanguageInEra diff --git a/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal.hs b/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal.hs index 8d15a137b1..06e7082fa9 100644 --- a/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal.hs +++ b/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal.hs @@ -181,12 +181,14 @@ legacyComparison (TextEnvelopeType expectedType) (TextEnvelopeType actualType) = ("Tx AlonzoEra", "Witnessed Tx AlonzoEra") -> True ("Tx BabbageEra", "Witnessed Tx BabbageEra") -> True ("Tx ConwayEra", "Witnessed Tx ConwayEra") -> True + ("Tx DijkstraEra", "Witnessed Tx DijkstraEra") -> True ("TxSignedShelley", "Unwitnessed Tx ShelleyEra") -> True ("Tx AllegraEra", "Unwitnessed Tx AllegraEra") -> True ("Tx MaryEra", "Unwitnessed Tx MaryEra") -> True ("Tx AlonzoEra", "Unwitnessed Tx AlonzoEra") -> True ("Tx BabbageEra", "Unwitnessed Tx BabbageEra") -> True ("Tx ConwayEra", "Unwitnessed Tx ConwayEra") -> True + ("Tx DijkstraEra", "Unwitnessed Tx DijkstraEra") -> True ("Certificate", "CertificateConway") -> True ("Certificate", "CertificateShelley") -> True (expectedOther, expectedActual) -> expectedOther == expectedActual @@ -394,22 +396,26 @@ textEnvelopeTypeToEra = "Tx AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "Tx BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "Tx ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "Tx DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra "Witnessed Tx ShelleyEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraShelley "Witnessed Tx AllegraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAllegra "Witnessed Tx MaryEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraMary "Witnessed Tx AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "Witnessed Tx BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "Witnessed Tx ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "Witnessed Tx DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra "Unwitnessed Tx ShelleyEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraShelley "Unwitnessed Tx AllegraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAllegra "Unwitnessed Tx MaryEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraMary "Unwitnessed Tx AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "Unwitnessed Tx BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "Unwitnessed Tx ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "Unwitnessed Tx DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra "TxWitness ShelleyEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraShelley "TxWitness AllegraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAllegra "TxWitness MaryEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraMary "TxWitness AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "TxWitness BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "TxWitness ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "TxWitness DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra unknownCddlType -> Left $ TextEnvelopeUnknownType unknownCddlType diff --git a/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal/Cddl.hs b/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal/Cddl.hs index 412cb082ad..f8a37d4c54 100644 --- a/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal/Cddl.hs +++ b/cardano-api/src/Cardano/Api/Serialise/TextEnvelope/Internal/Cddl.hs @@ -317,24 +317,28 @@ cddlTypeToEra = "Tx AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "Tx BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "Tx ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "Tx DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra "Witnessed Tx ShelleyEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraShelley "Witnessed Tx AllegraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAllegra "Witnessed Tx MaryEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraMary "Witnessed Tx AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "Witnessed Tx BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "Witnessed Tx ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "Witnessed Tx DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra "Unwitnessed Tx ShelleyEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraShelley "Unwitnessed Tx AllegraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAllegra "Unwitnessed Tx MaryEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraMary "Unwitnessed Tx AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "Unwitnessed Tx BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "Unwitnessed Tx ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "Unwitnessed Tx DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra "TxWitness ShelleyEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraShelley "TxWitness AllegraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAllegra "TxWitness MaryEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraMary "TxWitness AlonzoEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "TxWitness BabbageEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraBabbage "TxWitness ConwayEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraConway + "TxWitness DijkstraEra" -> return $ AnyShelleyBasedEra ShelleyBasedEraDijkstra unknownCddlType -> Left $ TextEnvelopeCddlErrUnknownType unknownCddlType {-# DEPRECATED readFileTextEnvelopeCddlAnyOf "Use readFileTextEnvelopeAnyOf instead." #-} diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Certificate.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Certificate.hs index 130e1fc323..c8bef0ad6a 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Certificate.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Certificate.hs @@ -24,8 +24,7 @@ import Cardano.Ledger.BaseTypes qualified as L import Cardano.Ledger.Binary qualified as L (ipv4ToBytes, ipv6ToBytes) import Cardano.Ledger.Coin qualified as L (DeltaCoin (..)) import Cardano.Ledger.Dijkstra.TxCert qualified as L - ( DijkstraTxCert (..) - , dijkstraToConwayDelegCert + ( dijkstraToConwayDelegCert ) import Cardano.Ledger.Hashes qualified as L (ScriptHash (..), VRFVerKeyHash (..)) From e1df987852dd6e9173e38a5809fb70c11a5055d1 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 18 Aug 2026 00:57:03 +0000 Subject: [PATCH 15/62] Expose the Dijkstra era in AnyCardanoEra, AnyShelleyBasedEra and SomeEra Flip maxBound to Dijkstra and extend the Enum instances and the era-name parsers accordingly, un-hiding the era from era enumeration and selection, in the old and the experimental API alike. This also fixes a latent Enum roundtrip crash: fromEnum already mapped the Dijkstra constructors of AnyCardanoEra and AnyShelleyBasedEra to 7, but toEnum errored on that index. Co-Authored-By: Konstantinos Lambrou-Latreille --- ...44719_cardano-api_palas_dijkstra_era_enumerations.yml | 9 +++++++++ cardano-api/src/Cardano/Api/Era/Internal/Core.hs | 4 +++- .../src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs | 4 +++- cardano-api/src/Cardano/Api/Experimental/Era.hs | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 .changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml diff --git a/.changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml b/.changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml new file mode 100644 index 0000000000..151d5e9a93 --- /dev/null +++ b/.changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml @@ -0,0 +1,9 @@ +description: | + The Dijkstra era can now be selected and enumerated like the other eras: `maxBound` and `[minBound .. maxBound]` for `AnyCardanoEra`, `AnyShelleyBasedEra` and the experimental `Some Era` include it, and the era-name parsers (`anyCardanoEraFromStringLike` and the JSON instances) accept "Dijkstra". + + Also fixed an `Enum` roundtrip crash: `fromEnum` already mapped Dijkstra to 7 for `AnyCardanoEra` and `AnyShelleyBasedEra`, but `toEnum 7` errored. +kind: + - feature + - bugfix +pr: 1317 +project: cardano-api diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Core.hs b/cardano-api/src/Cardano/Api/Era/Internal/Core.hs index 62e2d518e9..0594aa9f7b 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Core.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Core.hs @@ -381,7 +381,7 @@ instance Eq AnyCardanoEra where instance Bounded AnyCardanoEra where minBound = AnyCardanoEra ByronEra - maxBound = AnyCardanoEra ConwayEra + maxBound = AnyCardanoEra DijkstraEra instance Enum AnyCardanoEra where -- [e..] = [e..maxBound] @@ -405,6 +405,7 @@ instance Enum AnyCardanoEra where 4 -> AnyCardanoEra AlonzoEra 5 -> AnyCardanoEra BabbageEra 6 -> AnyCardanoEra ConwayEra + 7 -> AnyCardanoEra DijkstraEra n -> error $ "AnyCardanoEra.toEnum: " @@ -445,6 +446,7 @@ anyCardanoEraFromStringLike = \case "Alonzo" -> pure $ AnyCardanoEra AlonzoEra "Babbage" -> pure $ AnyCardanoEra BabbageEra "Conway" -> pure $ AnyCardanoEra ConwayEra + "Dijkstra" -> pure $ AnyCardanoEra DijkstraEra wrong -> Left wrong -- | Like the 'AnyCardanoEra' constructor but does not demand a 'IsCardanoEra' diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs index 53cf718e70..edd58c8d97 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Eon/ShelleyBasedEra.hs @@ -279,7 +279,7 @@ instance Eq AnyShelleyBasedEra where instance Bounded AnyShelleyBasedEra where minBound = AnyShelleyBasedEra ShelleyBasedEraShelley - maxBound = AnyShelleyBasedEra ShelleyBasedEraConway + maxBound = AnyShelleyBasedEra ShelleyBasedEraDijkstra instance Enum AnyShelleyBasedEra where enumFrom e = enumFromTo e maxBound @@ -300,6 +300,7 @@ instance Enum AnyShelleyBasedEra where 4 -> AnyShelleyBasedEra ShelleyBasedEraAlonzo 5 -> AnyShelleyBasedEra ShelleyBasedEraBabbage 6 -> AnyShelleyBasedEra ShelleyBasedEraConway + 7 -> AnyShelleyBasedEra ShelleyBasedEraDijkstra n -> error $ "AnyShelleyBasedEra.toEnum: " @@ -318,6 +319,7 @@ instance FromJSON AnyShelleyBasedEra where "Alonzo" -> pure $ AnyShelleyBasedEra ShelleyBasedEraAlonzo "Babbage" -> pure $ AnyShelleyBasedEra ShelleyBasedEraBabbage "Conway" -> pure $ AnyShelleyBasedEra ShelleyBasedEraConway + "Dijkstra" -> pure $ AnyShelleyBasedEra ShelleyBasedEraDijkstra wrong -> fail $ "Failed to parse unknown shelley-based era: " <> Text.unpack wrong -- | This pairs up some era-dependent type with a 'ShelleyBasedEra' value that diff --git a/cardano-api/src/Cardano/Api/Experimental/Era.hs b/cardano-api/src/Cardano/Api/Experimental/Era.hs index 2bc889d094..3e0b628d5e 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Era.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Era.hs @@ -130,7 +130,7 @@ instance Eq (Some Era) where instance Bounded (Some Era) where minBound = Some ConwayEra - maxBound = Some ConwayEra + maxBound = Some DijkstraEra instance Enum (Some Era) where toEnum 0 = Some ConwayEra From 7fe60822d783af564695f0fadd1b0a0ddaebcb35 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Tue, 18 Aug 2026 22:28:05 +0200 Subject: [PATCH 16/62] Update herald tool to 0.2.0 --- ...260818_cardano-api_bump_herald_tooling.yml | 13 +++++ .github/workflows/check-pr-changelog.yml | 2 +- .github/workflows/release.yml | 3 +- flake.lock | 53 +++++++++---------- 4 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 .changes/20260818_cardano-api_bump_herald_tooling.yml diff --git a/.changes/20260818_cardano-api_bump_herald_tooling.yml b/.changes/20260818_cardano-api_bump_herald_tooling.yml new file mode 100644 index 0000000000..2987baeca4 --- /dev/null +++ b/.changes/20260818_cardano-api_bump_herald_tooling.yml @@ -0,0 +1,13 @@ +project: cardano-api + +pr: 1296 + +kind: + - maintenance + +description: | + Updated the herald changelog tooling to herald 0.2.0.0. + The herald-validate action in check-pr-changelog.yml was bumped to herald-validate-0.0.1.1 and the herald-release action in release.yml to herald-release-0.0.3.0; both now default to herald 0.2.0.0, so no explicit `herald-ref` override is needed. + The cardano-dev flake input was updated so the dev shell also provides herald 0.2.0.0. + Note that herald 0.2.0.0 requires an explicit version choice for `herald batch`: pass `--version` or `--auto-version` (preview with `--dry-run`). + Release PRs now include copy-paste CHaP submission instructions (herald-release's chap-instructions input is enabled). diff --git a/.github/workflows/check-pr-changelog.yml b/.github/workflows/check-pr-changelog.yml index 1c0895f485..b9750fa4f2 100644 --- a/.github/workflows/check-pr-changelog.yml +++ b/.github/workflows/check-pr-changelog.yml @@ -27,4 +27,4 @@ jobs: extra_nix_config: | accept-flake-config = true - - uses: input-output-hk/cardano-dev/actions/herald-validate@herald-validate-0.0.1.0 + - uses: input-output-hk/cardano-dev/actions/herald-validate@herald-validate-0.0.1.1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11df7d1992..10353f402e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,8 +39,9 @@ jobs: extra_nix_config: | accept-flake-config = true - - uses: input-output-hk/cardano-dev/actions/herald-release@herald-release-0.0.1.0 + - uses: input-output-hk/cardano-dev/actions/herald-release@herald-release-0.0.3.0 with: package: ${{ inputs.package }} version: ${{ inputs.version }} base-branch: ${{ inputs.branch || github.ref_name }} + chap-instructions: true diff --git a/flake.lock b/flake.lock index fedabc556a..986aad6f0e 100644 --- a/flake.lock +++ b/flake.lock @@ -164,11 +164,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1775053833, - "narHash": "sha256-CX81JqTsZLdLo5WDrQTGKH/WkCQSXIZqrGVJNkggH7c=", + "lastModified": 1787599162, + "narHash": "sha256-hkHFme3QTTycmi9e3nXbwt12rNCrkwqiWWjerJga01I=", "owner": "input-output-hk", "repo": "cardano-dev", - "rev": "543053382386e840ce60574d7f4321b12c0da378", + "rev": "1acac1188d189a19264a7a41487505a93de41217", "type": "github" }, "original": { @@ -357,11 +357,11 @@ "hackage": { "flake": false, "locked": { - "lastModified": 1785398528, - "narHash": "sha256-dl5vmLjnVynFaniJ60YNZfDT7m/psLU1P/bj+gwlZt8=", + "lastModified": 1778807596, + "narHash": "sha256-3QQWTI6Md7aKhc88vb7dg5jvS+lFXbm0IbYAwHEOLkg=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "cee34cd6eac747364751d1971080bc72c461506d", + "rev": "970dbf08cc174c56fef2522c1d21e04eb969a1bf", "type": "github" }, "original": { @@ -373,11 +373,11 @@ "hackage-for-stackage": { "flake": false, "locked": { - "lastModified": 1774571863, - "narHash": "sha256-iOZRO9gZIRiJ7kdLjZyGVY0ms+xUZvWKMg1gDsx4XY0=", + "lastModified": 1778806225, + "narHash": "sha256-iy3Juc9g68k2aZTgFQX7kJU1wDUdY2G+YsTRkd+YmIw=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "712954158ec8c10c6a8b09cb9de675684df1ebd2", + "rev": "db343e074ad11a1431627a8d3817ec574230cd84", "type": "github" }, "original": { @@ -494,16 +494,15 @@ "stackage": "stackage" }, "locked": { - "lastModified": 1774631528, - "narHash": "sha256-tYufdrpGh76VBfCBuFzo4TMgJPPAkjOfeM94dJGyC+A=", - "owner": "carbolymer", + "lastModified": 1778807965, + "narHash": "sha256-QWNQB1ZmNk7MA6+WSHkeB7278Ykx0TkCzlY1OMwD8ro=", + "owner": "input-output-hk", "repo": "haskell.nix", - "rev": "395a7cf54ef9ceedc1a29e9f5055fc148e48cb6f", + "rev": "3883823f608fa19fad8c94e0203be37e124b4bed", "type": "github" }, "original": { - "owner": "carbolymer", - "ref": "remove-deprecated-pie-hardening", + "owner": "input-output-hk", "repo": "haskell.nix", "type": "github" } @@ -1149,11 +1148,11 @@ "iserv-proxy": { "flake": false, "locked": { - "lastModified": 1770174258, - "narHash": "sha256-x6QYupvHZM7rRpVO4AIC5gUWFprFQ59A95FPC7/Owjg=", + "lastModified": 1775620557, + "narHash": "sha256-10x8/G0x3eR/++XRHPx4MBuqlnc6+N+ajIxXyLkG+nU=", "owner": "stable-haskell", "repo": "iserv-proxy", - "rev": "91ef7ffdeedfb141a4d69dcf9e550abe3e1160c6", + "rev": "3f7b2815307c20a0dfd816bdf4a39ab86af3e0d4", "type": "github" }, "original": { @@ -1373,11 +1372,11 @@ }, "nixpkgs-2511": { "locked": { - "lastModified": 1764572236, - "narHash": "sha256-hLp6T/vKdrBQolpbN3EhJOKTXZYxJZPzpnoZz+fEGlE=", + "lastModified": 1775749320, + "narHash": "sha256-msT6frWJSQ2WR+0cpk+KPcZdLTLagUIsJwQwIX9JNSo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b0924ea1889b366de6bb0018a9db70b2c43a15f8", + "rev": "74b87959b2d16f59f54d8559cf3cf26b9d907949", "type": "github" }, "original": { @@ -1405,11 +1404,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1764587062, - "narHash": "sha256-hdFa0TAVQAQLDF31cEW3enWmBP+b592OvHs6WVe3D8k=", + "lastModified": 1775888245, + "narHash": "sha256-nwASzrRDD1JBEu/o8ekKYEXm/oJW6EMCzCRdrwcLe90=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c1cb7d097cb250f6e1904aacd5f2ba5ffd8a49ce", + "rev": "13043924aaa7375ce482ebe2494338e058282925", "type": "github" }, "original": { @@ -1645,11 +1644,11 @@ "stackage": { "flake": false, "locked": { - "lastModified": 1774570839, - "narHash": "sha256-tyAzxmjnAtwAux2Dbw5yUOTPhNcFrDjpvQlVtFqA8Ak=", + "lastModified": 1778805211, + "narHash": "sha256-Nu/V1NuOsz4iteePdkzcufDOY3vhbl7Wl1MhQjUTJc0=", "owner": "input-output-hk", "repo": "stackage.nix", - "rev": "af474ea91cba204905ee7d2273a0f1782b13ed46", + "rev": "6af1a5ac5c3e2ca2261d56696f2d8f8e9220ffdf", "type": "github" }, "original": { From e225c89279a57570b60d7c529c30d6e05947e24e Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Thu, 20 Aug 2026 14:45:00 +0200 Subject: [PATCH 17/62] cardano-rpc: resolve genesis initial funds from sgExtraConfig. Add timed cache of resolved Shelley Genesis. --- ..._api_ledgerstate_resolve_initial_funds.yml | 9 + ..._rpc_genesis_initial_funds_extraconfig.yml | 10 ++ cardano-api/cardano-api.cabal | 1 + cardano-api/src/Cardano/Api/Consensus.hs | 6 + .../Api/Consensus/Internal/Reexport.hs | 20 ++- cardano-api/src/Cardano/Api/LedgerState.hs | 55 ++++++- cardano-rpc/cardano-rpc.cabal | 3 + .../Cardano/Rpc/Server/Internal/TimedCache.hs | 154 ++++++++++++++++++ .../Rpc/Server/Internal/UtxoRpc/Query.hs | 80 ++++++++- .../Server/Internal/UtxoRpc/Type/Genesis.hs | 27 +-- .../Cardano/Rpc/Server/NodeKernelAccess.hs | 82 +++++++--- .../Rpc/Server/NodeKernelAccess/Type.hs | 59 +++++-- 12 files changed, 441 insertions(+), 65 deletions(-) create mode 100644 .changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml create mode 100644 .changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml create mode 100644 cardano-rpc/src/Cardano/Rpc/Server/Internal/TimedCache.hs diff --git a/.changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml b/.changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml new file mode 100644 index 0000000000..ccb39e29e1 --- /dev/null +++ b/.changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml @@ -0,0 +1,9 @@ +project: cardano-api + +pr: 1305 + +kind: + - compatible + +description: | + Export resolveShelleyInitialFunds from Cardano.Api.LedgerState. It takes a ShelleyGenesis and resolves its initial funds against its sgExtraConfig the way ledger's own genesis state construction does, including streaming InjectionFromFile sources with content-hash verification. diff --git a/.changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml b/.changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml new file mode 100644 index 0000000000..23b8f191f2 --- /dev/null +++ b/.changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml @@ -0,0 +1,10 @@ +project: cardano-rpc + +pr: 1305 + +kind: + - bugfix + - breaking + +description: | + Fixed the UTxO RPC `ReadGenesis` response reporting no initial funds for networks created with `cardano-cli create-testnet-data`, and stopped the node retaining the parsed genesis in memory for its whole lifetime. The Shelley genesis is now read from disk when `ReadGenesis` is served, verified against the genesis hash computed at node startup, and kept for five minutes after the last request; a genesis file that changed since startup fails the request with `FAILED_PRECONDITION`. Breaking change: `mkNodeKernelAccess` no longer takes `ProtocolInfoArgs` and takes the Shelley genesis file path instead. diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index e1ea28870c..f5ed902169 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -167,6 +167,7 @@ library filepath, formatting, fs-api ^>=0.4, + io-classes, iproute, memory, mempack, diff --git a/cardano-api/src/Cardano/Api/Consensus.hs b/cardano-api/src/Cardano/Api/Consensus.hs index b2e709ae50..a710f8ac05 100644 --- a/cardano-api/src/Cardano/Api/Consensus.hs +++ b/cardano-api/src/Cardano/Api/Consensus.hs @@ -53,6 +53,7 @@ module Cardano.Api.Consensus -- * Reexports from @ouroboros-consensus@ , BlockComponent (..) , ByronBlock + , ByronPartialLedgerConfig (..) , CardanoBlock , ChainDB.ChainDB , ChainDB.ChainType (..) @@ -66,6 +67,7 @@ module Cardano.Api.Consensus , ChainDepState , GenTx (..) , EraMismatch (..) + , HardForkLedgerConfig (..) , HasHardForkHistory (..) , HasHeader , Header @@ -73,16 +75,20 @@ module Cardano.Api.Consensus , NodeKernel (..) , OneEraHash (..) , PastHorizonException + , PerEraLedgerConfig (..) , PraosProtocolSupportsNode , PraosProtocolSupportsNodeCrypto , RealPoint (..) , ResourceRegistry , SecurityParam (..) , ShelleyGenesisStaking (..) + , ShelleyPartialLedgerConfig (..) , StandardCrypto , TopLevelConfig + , WrapPartialLedgerConfig (..) , ledgerState , shelleyLedgerGenesis + , shelleyLedgerTranslationContext , blockHash , blockNo , blockSlot diff --git a/cardano-api/src/Cardano/Api/Consensus/Internal/Reexport.hs b/cardano-api/src/Cardano/Api/Consensus/Internal/Reexport.hs index 94521666ae..603dd72e56 100644 --- a/cardano-api/src/Cardano/Api/Consensus/Internal/Reexport.hs +++ b/cardano-api/src/Cardano/Api/Consensus/Internal/Reexport.hs @@ -1,6 +1,7 @@ module Cardano.Api.Consensus.Internal.Reexport ( BlockComponent (..) , ByronBlock + , ByronPartialLedgerConfig (..) , CardanoBlock , ChainUpdate (..) , ConfigSupportsNode @@ -12,18 +13,23 @@ module Cardano.Api.Consensus.Internal.Reexport , EraMismatch (..) , NodeKernel (..) , OneEraHash (..) + , HardForkLedgerConfig (..) , HasHardForkHistory (..) , PastHorizonException + , PerEraLedgerConfig (..) , PraosProtocolSupportsNode , PraosProtocolSupportsNodeCrypto , RealPoint (..) , ResourceRegistry , SecurityParam (..) , ShelleyGenesisStaking (..) + , ShelleyPartialLedgerConfig (..) , StandardCrypto , TopLevelConfig + , WrapPartialLedgerConfig (..) , ledgerState , shelleyLedgerGenesis + , shelleyLedgerTranslationContext , blockHash , blockNo , blockSlot @@ -52,6 +58,7 @@ import Ouroboros.Consensus.Block , blockNo , blockSlot ) +import Ouroboros.Consensus.Byron.ByronHFC (ByronPartialLedgerConfig (..)) import Ouroboros.Consensus.Byron.Ledger (ByronBlock (byronBlockRaw), GenTx (..), byronIdTx) import Ouroboros.Consensus.Cardano.Block (CardanoBlock, EraMismatch (..)) import Ouroboros.Consensus.Config @@ -63,7 +70,12 @@ import Ouroboros.Consensus.Config import Ouroboros.Consensus.Config.SecurityParam (SecurityParam (..)) import Ouroboros.Consensus.Config.SupportsNode (ConfigSupportsNode) import Ouroboros.Consensus.HardFork.Abstract (HasHardForkHistory (..)) -import Ouroboros.Consensus.HardFork.Combinator.AcrossEras (OneEraHash (..)) +import Ouroboros.Consensus.HardFork.Combinator.AcrossEras + ( OneEraHash (..) + , PerEraLedgerConfig (..) + ) +import Ouroboros.Consensus.HardFork.Combinator.Basics (HardForkLedgerConfig (..)) +import Ouroboros.Consensus.HardFork.Combinator.PartialConfig (WrapPartialLedgerConfig (..)) import Ouroboros.Consensus.HardFork.History.EpochInfo (interpreterToEpochInfo) import Ouroboros.Consensus.HardFork.History.Qry ( PastHorizonException @@ -79,7 +91,11 @@ import Ouroboros.Consensus.Protocol.Praos.Common , PraosProtocolSupportsNodeCrypto , getOpCertCounters ) -import Ouroboros.Consensus.Shelley.Ledger.Ledger (shelleyLedgerGenesis) +import Ouroboros.Consensus.Shelley.Ledger.Ledger + ( ShelleyPartialLedgerConfig (..) + , shelleyLedgerGenesis + , shelleyLedgerTranslationContext + ) import Ouroboros.Consensus.Shelley.Node (ShelleyGenesisStaking (..)) import Ouroboros.Consensus.Storage.Common (BlockComponent (..)) import Ouroboros.Consensus.Util.Condense (condense) diff --git a/cardano-api/src/Cardano/Api/LedgerState.hs b/cardano-api/src/Cardano/Api/LedgerState.hs index d3e1af57e5..fb509f6785 100644 --- a/cardano-api/src/Cardano/Api/LedgerState.hs +++ b/cardano-api/src/Cardano/Api/LedgerState.hs @@ -77,6 +77,7 @@ module Cardano.Api.LedgerState , GenesisConfig (..) , readCardanoGenesisConfig , mkProtocolInfoCardano + , resolveShelleyInitialFunds -- *** Byron Genesis Config , readByronGenesisConfig @@ -174,6 +175,7 @@ import Cardano.Ledger.Keys qualified as SL import Cardano.Ledger.Shelley.API qualified as ShelleyAPI import Cardano.Ledger.Shelley.Core qualified as Core import Cardano.Ledger.Shelley.Genesis qualified as Ledger +import Cardano.Ledger.Shelley.Transition qualified as Ledger import Cardano.Ledger.Slot qualified as Ledger import Cardano.Ledger.State qualified as SL import Cardano.Protocol.Crypto qualified as Crypto @@ -221,8 +223,10 @@ import Ouroboros.Network.Protocol.ChainSync.PipelineDecision import Control.Concurrent import Control.DeepSeq import Control.Error.Util (note) -import Control.Exception.Safe +import Control.Exception.Safe hiding (MonadThrow) import Control.Monad +import Control.Monad.Class.MonadST (MonadST) +import Control.Monad.Class.MonadThrow (MonadThrow) import Control.Monad.State.Strict import Control.Tracer qualified as Tracer import Data.Aeson as Aeson @@ -272,7 +276,7 @@ import GHC.Stack (HasCallStack) import Lens.Micro import Network.Mux qualified as Mux import Network.TypedProtocol.Core (Nat (..)) -import System.FS.API (SomeHasFS) +import System.FS.API (SomeHasFS (..)) import System.FilePath data InitialLedgerStateError @@ -1521,6 +1525,53 @@ readCardanoGenesisConfig enc = do let transCfg = Ledger.mkLatestTransitionConfig shelleyGenesis alonzoGenesis conwayGenesis dijkstraGenesis pure $ GenesisCardano enc byronGenesis shelleyGenesisHash transCfg +-- | Resolve a Shelley genesis' 'Ledger.sgInitialFunds' against its +-- 'Ledger.sgExtraConfig', mirroring the resolution ledger's own +-- @registerInitialFunds@ performs when building the initial ledger state +-- from genesis. +-- +-- A 'Ledger.ShelleyGenesis' carries two sources of initial funds: the legacy +-- 'Ledger.sgInitialFunds' field, and 'Ledger.sgExtraConfig', which is where +-- @cardano-cli create-testnet-data@ puts the funded addresses, embedded or in +-- an external hash-verified file. The ledger reconciles the two only while +-- building the initial ledger state and never writes the result back into the +-- 'Ledger.ShelleyGenesis' value, so a parsed genesis read outside that path +-- must repeat the resolution. Once the ledger drops the legacy field, the +-- two-source reconciliation here can go, but turning 'Ledger.secInitialFunds' +-- into actual funds (including reading and hash-checking an injection file) +-- is still needed. +-- +-- Throws 'Ledger.InjectionConflictingSources' if the genesis specifies initial +-- funds through both the legacy field and the extra config, and +-- 'Ledger.InjectionHashMismatch' if an 'Ledger.InjectionFromFile' source does +-- not hash to the value the genesis declares for it. +resolveShelleyInitialFunds + :: (MonadST m, MonadThrow m) + => SomeHasFS m + -- ^ Filesystem capability used to stream an 'Ledger.InjectionFromFile' + -- source, mounted at the Shelley genesis file's directory. + -> Ledger.ShelleyGenesis + -- ^ The Shelley genesis whose initial funds to resolve. + -> m Ledger.ShelleyGenesis +resolveShelleyInitialFunds (SomeHasFS hasFS) genesis = do + initialFundsSource <- + Ledger.resolveInjectionSource + "initialFunds" + (Ledger.sgExtraConfig genesis) + Ledger.secInitialFunds + (Ledger.sgInitialFunds genesis) + resolvedInitialFunds <- + fromList <$> Ledger.foldInjectionData hasFS initialFundsSource (flip (:)) [] + pure $ + genesis + & Ledger.sgInitialFundsL .~ resolvedInitialFunds + -- The source has now been folded into 'sgInitialFunds'; null it out + -- so that re-resolving this (already-resolved) genesis later does + -- not trip 'Ledger.InjectionConflictingSources'. + & Ledger.sgExtraConfigL .~ (clearInitialFundsSource <$> Ledger.sgExtraConfig genesis) + where + clearInitialFundsSource extraConfig = extraConfig{Ledger.secInitialFunds = Ledger.NoInjection} + exampleDijkstraGenesis :: Ledger.DijkstraGenesis exampleDijkstraGenesis = Ledger.DijkstraGenesis diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index 57835e03a6..c954857720 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -58,6 +58,7 @@ library Cardano.Rpc.Server.Internal.Error Cardano.Rpc.Server.Internal.Monad Cardano.Rpc.Server.Internal.Node + Cardano.Rpc.Server.Internal.TimedCache Cardano.Rpc.Server.Internal.Tracing Cardano.Rpc.Server.Internal.UtxoRpc.Eval Cardano.Rpc.Server.Internal.UtxoRpc.Predicate @@ -115,6 +116,7 @@ library errors, filepath, formatting, + fs-api ^>=0.4, generic-data, grapesy, grpc-spec, @@ -125,6 +127,7 @@ library proto-lens-protobuf-types, random, rio, + strict-sop-core, text, time, diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/TimedCache.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/TimedCache.hs new file mode 100644 index 0000000000..b66e894981 --- /dev/null +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/TimedCache.hs @@ -0,0 +1,154 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE NoFieldSelectors #-} + +-- | A cache for a single value. The value is dropped once nothing has read it +-- for a while. Use it for data that is expensive to build but too big or too +-- rarely needed to keep around forever. +module Cardano.Rpc.Server.Internal.TimedCache + ( TimedCache + , newTimedCache + , readThroughCache + ) +where + +import RIO + +import Data.Time.Clock (DiffTime) + +-- | Holds at most one value. The value is dropped once no read has happened +-- for 'expiryTimeout'. +-- +-- Create with 'newTimedCache', read with 'readThroughCache'. +data TimedCache a = TimedCache + { cacheVar :: !(MVar (Maybe (CacheEntry a))) + -- ^ 'Nothing' means the cache is empty. Otherwise this holds everything the + -- cache knows, and it is the only mutable cell there is. Keeping the read + -- time inside the entry rather than beside it is what makes the cache safe: + -- one lock covers the value, its watcher and its deadline together, so a + -- reader can no longer refresh the deadline while the watcher is deciding + -- to drop the value. The 'MVar' is also the lock: when several readers hit + -- an empty cache at once, one of them loads and the others wait for its + -- result. + , expiryTimeout :: !DiffTime + -- ^ How long the value is kept after the last read. + } + +-- | Everything the cache holds while it is full. +data CacheEntry a = CacheEntry + { cachedValue :: !a + -- ^ The cached value. + , watcher :: !(Async ()) + -- ^ The thread that will drop this value once it goes unread. It lives here + -- so that a value can never be in the cache without its watcher, and so + -- that the handle goes away together with the value it watches. + , lastAccess :: !DiffTime + -- ^ When the value was last read, from the monotonic clock. + } + +-- | Create an empty cache. +-- +-- This starts no thread. The watcher thread only exists while the cache +-- holds a value, so an unused cache holds no data and runs nothing. +newTimedCache + :: MonadIO m + => DiffTime + -- ^ How long the cached value is kept after the last read + -> m (TimedCache a) +newTimedCache expiryTimeout = do + cacheVar <- newMVar Nothing + pure TimedCache{cacheVar, expiryTimeout} + +-- | Read the cached value. If the cache is empty, run the load action and +-- cache its result. Every read restarts the expiry timer. +-- +-- If the load throws, the exception goes to the caller and the cache stays +-- empty. The next read simply tries again. +readThroughCache + :: MonadUnliftIO m + => TimedCache a + -- ^ The cache to read + -> m a + -- ^ How to load the value on a cache miss + -> m a +readThroughCache TimedCache{cacheVar, expiryTimeout} doLoad = + modifyMVar cacheVar $ \case + Just entry@CacheEntry{cachedValue} -> do + -- Restart the expiry timer. We hold the lock while doing it, so the + -- watcher cannot be reading the old deadline at the same time. + now <- getMonotonicDiffTime + pure (Just entry{lastAccess = now}, cachedValue) + Nothing -> do + -- The load runs while we hold the lock, on purpose. When several + -- readers hit an empty cache at once, the first one loads and the + -- others block on the lock until the result is stored. This gives one + -- load in total instead of one load per reader. Do not move the load + -- out of the lock. + loaded <- doLoad + -- Start the timer now that the value is ready. Timing it from when this + -- reader arrived would let a slow load eat part of the value's lifetime. + now <- getMonotonicDiffTime + -- Fork the watcher while still holding the lock, so the value and its + -- watcher go into the cache together. 'asyncWithUnmask' because a + -- thread forked inside a 'modifyMVar' callback starts masked, and the + -- watcher should run unmasked. This is hygiene only: nobody throws to + -- the watcher, and 'threadDelay' can be interrupted even when masked. + -- The handle is only stored. Nobody waits on it, links it or cancels + -- it: the watcher outlives this request and stops by itself. + watcher <- liftIO $ asyncWithUnmask (\unmask -> unmask watchForExpiry) + pure (Just CacheEntry{cachedValue = loaded, watcher, lastAccess = now}, loaded) + where + -- How much of the value's life is left, given when it was last read and + -- what the clock says now. Zero or less means it can be dropped. + remainingIdleTime :: DiffTime -> DiffTime -> DiffTime + remainingIdleTime lastAccess now = lastAccess + expiryTimeout - now + + -- Sleep until the value has gone unread for 'expiryTimeout', then drop it + -- and exit. + -- + -- There is exactly one watcher per cached value, because the watcher is + -- stored in the entry next to the value it watches. It drops the value at + -- most once, then exits, taking its own handle with it. Nothing supervises + -- it and nothing has to: once the cache is empty, no thread is left either. + watchForExpiry :: IO () + watchForExpiry = + readMVar cacheVar >>= \case + -- The cache is empty, so there is nothing to watch. Only a watcher + -- empties the cache, and this one has not, so this should not happen. + -- Stopping is the right answer if it ever does. + Nothing -> pure () + Just CacheEntry{lastAccess} -> do + now <- getMonotonicDiffTime + let remaining = remainingIdleTime lastAccess now + if remaining > 0 + then do + -- A read may move the deadline while we sleep, so look at the + -- entry again instead of dropping the value right after waking up. + delayFor remaining + watchForExpiry + else do + isEmptied <- modifyMVar cacheVar $ \case + -- Already empty, so there is nothing left to drop. + Nothing -> pure (Nothing, True) + Just entry@CacheEntry{lastAccess = lastAccessUnderLock} -> do + -- Check again while holding the lock. A read may have + -- restarted the timer between the check above and us getting + -- the lock. + nowUnderLock <- getMonotonicDiffTime + pure $ + if remainingIdleTime lastAccessUnderLock nowUnderLock > 0 + then (Just entry, False) + else (Nothing, True) + unless isEmptied watchForExpiry + +-- | The monotonic clock, in seconds since some fixed point. +-- +-- The wall clock would be wrong here. An NTP time jump could drop a value +-- right after a read, or keep a stale one alive for hours. +getMonotonicDiffTime :: MonadIO m => m DiffTime +getMonotonicDiffTime = realToFrac <$> getMonotonicTime + +-- | Sleep for the given duration, rounded up to whole microseconds. +delayFor :: MonadIO m => DiffTime -> m () +delayFor duration = threadDelay . ceiling $ duration * 1_000_000 diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs index 3baff121bf..dc3cc70598 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs @@ -28,13 +28,13 @@ import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as UtxoRpc import Cardano.Rpc.Server.Internal.Error import Cardano.Rpc.Server.Internal.Monad import Cardano.Rpc.Server.Internal.Orphans () +import Cardano.Rpc.Server.Internal.TimedCache (readThroughCache) import Cardano.Rpc.Server.Internal.UtxoRpc.Predicate import Cardano.Rpc.Server.Internal.UtxoRpc.Type import Cardano.Rpc.Server.NodeKernelAccess import Cardano.Crypto.Hash.Class qualified as Crypto (hashToBytes) -import Cardano.Ledger.Api.Transition qualified as L (tcShelleyGenesisL) -import Cardano.Ledger.Shelley.Genesis qualified as L (sgNetworkMagic) +import Cardano.Ledger.Shelley.Genesis qualified as L (ShelleyGenesis, sgNetworkMagic) import RIO hiding (toList) @@ -42,9 +42,13 @@ import Control.Error.Util (hush) import Data.Default import Data.List (sortBy) import Data.ProtoLens (defMessage) +import Data.Text qualified as Text (pack) import Data.Time.Clock (UTCTime) import GHC.IsList import Network.GRPC.Spec +import System.FS.API (MountPoint (..), SomeHasFS (..)) +import System.FS.IO (ioHasFS) +import System.FilePath (takeDirectory) -- | Handle the @ReadParams@ RPC method. -- Queries the node for current protocol parameters and returns them @@ -170,20 +174,84 @@ searchUtxosMethod req = do -- Returns the chain's identity - the Shelley genesis hash and the CAIP-2 chain -- identifier - together with the @cardano@ config, the Byron, Shelley, Alonzo -- and Conway genesis parameters mapped by 'genesisBundleToProto'. +-- +-- The whole Shelley genesis comes from the bundle's cache, so the file is only +-- read on a cache miss. The @FAILED_PRECONDITION@ that +-- 'readShelleyGenesisWithInitialFunds' raises for a genesis file that has +-- changed since the node started is therefore raised on cache misses only: a +-- file edited while the cache is warm goes unnoticed until the cache next +-- empties, which is at most five idle minutes later. readGenesisMethod :: MonadRpc e m => Proto UtxoRpc.ReadGenesisRequest -> m (Proto UtxoRpc.ReadGenesisResponse) readGenesisMethod _req = do -- TODO: field masks are ignored for now (same as readParamsMethod) - NodeKernelAccess{genesisConfig = genesisBundle@GenesisBundle{shelleyGenesisHash, transitionConfig}} <- + NodeKernelAccess + { genesisConfig = + genesisBundle@GenesisBundle + { shelleyGenesisHash + , shelleyGenesis = (shelleyGenesisFile, shelleyGenesisCache) + } + } <- grabNodeKernelAccess - let networkMagic = L.sgNetworkMagic $ transitionConfig ^. L.tcShelleyGenesisL + shelleyGenesis <- + readThroughCache shelleyGenesisCache $ + readShelleyGenesisWithInitialFunds shelleyGenesisFile shelleyGenesisHash pure $ defMessage & U5c.genesis .~ Crypto.hashToBytes (unGenesisHashShelley shelleyGenesisHash) - & U5c.caip2 .~ networkMagicToCaip2 networkMagic - & U5c.cardano .~ genesisBundleToProto genesisBundle + & U5c.caip2 .~ networkMagicToCaip2 (L.sgNetworkMagic shelleyGenesis) + & U5c.cardano .~ genesisBundleToProto genesisBundle shelleyGenesis + +-- | Re-read the Shelley genesis file to recover the network's initial funds. +-- +-- The genesis consensus keeps in memory is compacted, with the initial funds +-- erased, so the file is the only place they can come from. +readShelleyGenesisWithInitialFunds + :: forall e m + . MonadRpc e m + => ShelleyGenesisFile In + -- ^ Path to the Shelley genesis file, as the node was configured with it + -> GenesisHashShelley + -- ^ Blake2b-256 hash the node computed over that file at startup + -> m L.ShelleyGenesis +readShelleyGenesisWithInitialFunds shelleyGenesisFile@(File path) bootGenesisHash = do + -- 'readShelleyGenesis' is the node's own boot-time path: it reads the bytes, + -- hashes them and checks them against the hash we pass in, then decodes. + -- Running it at IO because its 'MonadIOTransError' needs a 'MonadCatch' that + -- 'MonadRpc' does not provide. + ShelleyConfig bootGenesis _ <- + either rejectGenesisFile pure + =<< liftIO (runExceptT (readShelleyGenesis shelleyGenesisFile (Just bootGenesisHash))) + -- An injection file is named relative to the genesis file's own directory, + -- which is where consensus mounts it when it injects the funds itself. + let genesisDirectory = SomeHasFS . ioHasFS . MountPoint $ takeDirectory path + either (rejectInitialFunds . displayException) pure + =<< tryAny (liftIO $ resolveShelleyInitialFunds genesisDirectory bootGenesis) + where + -- Both helpers carry explicit signatures because their result type is + -- polymorphic, which MonoLocalBinds would otherwise refuse to generalise on + -- GHC 9.6 and 9.10. + rejectGenesisFile :: ShelleyGenesisError -> m a + rejectGenesisFile = \case + -- Deliberately not 'renderShelleyGenesisError' for this one: its wording + -- blames the hash given in the node's configuration file, whereas the hash + -- we compare against is the one the node itself computed at startup. + ShelleyGenesisHashMismatch{} -> + throwGrpcErrorWithMessage GrpcFailedPrecondition $ + "The Shelley genesis file " + <> tshow path + <> " has changed since the node started, so it no longer describes the genesis the node is running on." + err -> throwGrpcErrorWithMessage GrpcInternal $ renderShelleyGenesisError err + + rejectInitialFunds :: String -> m a + rejectInitialFunds reason = + throwGrpcErrorWithMessage GrpcInternal $ + "Cannot resolve the initial funds of the Shelley genesis file " + <> tshow path + <> ": " + <> Text.pack reason -- | The CAIP-2 chain identifier for a Cardano network, keyed on the Shelley -- network magic. diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs index b775547320..cbaa534d92 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs @@ -76,7 +76,6 @@ import Cardano.Crypto qualified as Byron import Cardano.Ledger.Address qualified as L import Cardano.Ledger.Alonzo.Genesis qualified as L import Cardano.Ledger.Api qualified as L -import Cardano.Ledger.Api.Transition qualified as L import Cardano.Ledger.BaseTypes qualified as L import Cardano.Ledger.Conway.PParams qualified as L import Cardano.Ledger.Hashes qualified as L @@ -98,27 +97,19 @@ import Network.GRPC.Spec -- | Convert the network's genesis bundle to the UTxO RPC 'U5c.Genesis' -- message, populating the Byron, Shelley, Alonzo and Conway fields. -genesisBundleToProto :: GenesisBundle -> Proto U5c.Genesis -genesisBundleToProto GenesisBundle{byronConfig, transitionConfig} = - byronGenesisToProto byronGenesis +-- +-- The Shelley genesis is passed in separately rather than taken from the bundle, +-- because the copy the bundle holds is the one consensus compacted: its initial +-- funds have to be recovered from the genesis file first, which is a read and so +-- cannot happen in this pure mapping (see +-- 'Cardano.Rpc.Server.Internal.UtxoRpc.Query.readGenesisMethod'). +genesisBundleToProto :: GenesisBundle -> L.ShelleyGenesis -> Proto U5c.Genesis +genesisBundleToProto GenesisBundle{byronConfig, alonzoGenesis, conwayGenesis} shelleyGenesis = + byronGenesisToProto (Byron.configGenesisData byronConfig) . shelleyGenesisToProto shelleyGenesis . alonzoGenesisToProto alonzoGenesis . conwayGenesisToProto conwayGenesis $ defMessage - where - byronGenesis = Byron.configGenesisData byronConfig - shelleyGenesis = transitionConfig ^. L.tcShelleyGenesisL - -- LatestKnownEra is Dijkstra; its previous era is Conway, whose translation - -- context is the Conway genesis. - conwayGenesis = transitionConfig ^. L.tcPreviousEraConfigL . L.tcTranslationContextL - -- Dijkstra -> Conway -> Babbage -> Alonzo config, whose translation context - -- is the Alonzo genesis. - alonzoGenesis = - transitionConfig - ^. L.tcPreviousEraConfigL - . L.tcPreviousEraConfigL - . L.tcPreviousEraConfigL - . L.tcTranslationContextL -------------------------------------------------------------------------------- -- Byron diff --git a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs index a8e721cf8b..51223ccc39 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} @@ -20,6 +21,7 @@ where import Cardano.Api import Cardano.Api.Consensus qualified as Consensus import Cardano.Rpc.Server.Internal.Monad (MonadRpc, grab) +import Cardano.Rpc.Server.Internal.TimedCache (newTimedCache) import Cardano.Rpc.Server.Internal.Tracing import Cardano.Rpc.Server.NodeKernelAccess.Type @@ -29,27 +31,31 @@ import Control.Tracer (Tracer, traceWith) import Data.ByteString (ByteString) import Data.ByteString.Lazy qualified as BSL import Data.IORef +import Data.SOP.Strict (NP (..)) import Data.Text (pack) -import Network.GRPC.Spec +import Data.Time.Clock (DiffTime) +-- Imported narrowly: grpc-spec exports an unrelated ':*' which would otherwise +-- make the 'NP' pattern match in 'readGenesisBundle' ambiguous. +import Network.GRPC.Spec (GrpcError (..), GrpcException (..)) -- | Construct 'NodeKernelAccess' from a consensus 'Consensus.NodeKernel'. -- Returns 'Nothing' and traces the block type for non-Cardano block types. mkNodeKernelAccess - :: Monad m + :: MonadIO m => Tracer m TraceRpc -- ^ Tracer for RPC events -> GenesisHashShelley -- ^ Boot-time Shelley genesis hash - -> Consensus.ProtocolInfoArgs n blk - -- ^ Protocol info arguments (carrying the parsed genesis and transition - -- config) + -> ShelleyGenesisFile In + -- ^ Path to the Shelley genesis file the node was configured with -> Consensus.BlockType blk -- ^ Block type witness -> Consensus.NodeKernel IO addrNTN addrNTC blk -- ^ Consensus node kernel -> m (Maybe NodeKernelAccess) -mkNodeKernelAccess tracer shelleyGenesisHash protocolInfoArgs blockType kernel = case blockType of - Consensus.CardanoBlockType -> +mkNodeKernelAccess tracer shelleyGenesisHash shelleyGenesisFile blockType kernel = case blockType of + Consensus.CardanoBlockType -> do + genesisConfig <- readGenesisBundle shelleyGenesisHash shelleyGenesisFile topLevelConfig pure $ Just NodeKernelAccess{chainDb, systemStart, readEraHistory, securityParam, genesisConfig} where chainDb = Consensus.getChainDB kernel @@ -57,7 +63,6 @@ mkNodeKernelAccess tracer shelleyGenesisHash protocolInfoArgs blockType kernel = ledgerConfig = Consensus.configLedger topLevelConfig systemStart = Consensus.nodeSystemStart topLevelConfig securityParam = Consensus.configSecurityParam topLevelConfig - genesisConfig = readGenesisBundle shelleyGenesisHash protocolInfoArgs -- Read the current ledger state (cheap STM TVar read) and recompute -- the era summary on every call - O(number_of_eras). -- This is the same approach consensus uses for GetInterpreter queries @@ -73,18 +78,57 @@ mkNodeKernelAccess tracer shelleyGenesisHash protocolInfoArgs blockType kernel = traceWith tracer . inject . TraceRpcUnsupportedBlockType . pack $ show blockType pure Nothing --- | Gather the network's genesis configuration from the node's boot-time --- 'Consensus.ProtocolInfoArgs'. +-- | How long the resolved Shelley genesis is kept after the request that last +-- needed it: five minutes. +-- +-- Long enough that a client walking through several genesis queries pays the +-- re-read once, short enough that an idle node is back to retaining nothing +-- soon after being left alone. +shelleyGenesisExpiryTimeout :: DiffTime +shelleyGenesisExpiryTimeout = 5 * 60 + +-- | Gather the network's genesis configuration out of the node kernel's ledger +-- config, so that the RPC server shares the node's own genesis values instead of +-- holding a second copy alive for the lifetime of the process. +-- +-- The per-era ledger configs are matched positionally and exhaustively, so a new +-- Cardano era is a compile error here rather than a silently misread genesis. +-- The Shelley slot is matched but not read. The node only has a compacted copy +-- with the initial funds erased, so the file is the only useful source and the +-- cache reads it when a caller asks. +-- +-- The only thing allocated here is that empty cache. Nothing is read from disk +-- and no thread is started. readGenesisBundle - :: GenesisHashShelley - -> Consensus.ProtocolInfoArgs n (Consensus.CardanoBlock Consensus.StandardCrypto) - -> GenesisBundle -readGenesisBundle shelleyGenesisHash (Consensus.ProtocolInfoArgsCardano _ cardanoProtocolParams) = - GenesisBundle - { byronConfig = Consensus.byronGenesis $ Consensus.byronProtocolParams cardanoProtocolParams - , shelleyGenesisHash - , transitionConfig = Consensus.cardanoLedgerTransitionConfig cardanoProtocolParams - } + :: MonadIO m + => GenesisHashShelley + -> ShelleyGenesisFile In + -> Consensus.TopLevelConfig (Consensus.CardanoBlock Consensus.StandardCrypto) + -> m GenesisBundle +readGenesisBundle shelleyGenesisHash shelleyGenesisFile topLevelConfig = + case Consensus.getPerEraLedgerConfig perEraLedgerConfig of + Consensus.WrapPartialLedgerConfig byron + :* _shelley + :* _allegra + :* _mary + :* Consensus.WrapPartialLedgerConfig alonzo + :* _babbage + :* Consensus.WrapPartialLedgerConfig conway + :* _dijkstra + :* Nil -> do + shelleyGenesisCache <- newTimedCache shelleyGenesisExpiryTimeout + pure + GenesisBundle + { byronConfig = Consensus.byronLedgerConfig byron + , shelleyGenesisHash + , shelleyGenesis = (shelleyGenesisFile, shelleyGenesisCache) + , alonzoGenesis = + Consensus.shelleyLedgerTranslationContext $ Consensus.shelleyLedgerConfig alonzo + , conwayGenesis = + Consensus.shelleyLedgerTranslationContext $ Consensus.shelleyLedgerConfig conway + } + where + perEraLedgerConfig = Consensus.hardForkLedgerConfigPerEra $ Consensus.configLedger topLevelConfig -- | Grab the current 'NodeKernelAccess' from the environment, or throw -- gRPC UNAVAILABLE if the node kernel has not yet initialised. diff --git a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs index 30a1380b86..1e035a7d95 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE DataKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE NoFieldSelectors #-} @@ -7,12 +8,20 @@ module Cardano.Rpc.Server.NodeKernelAccess.Type ) where -import Cardano.Api (EraHistory, GenesisHashShelley, SystemStart) +import Cardano.Api + ( EraHistory + , FileDirection (In) + , GenesisHashShelley + , ShelleyGenesisFile + , SystemStart + ) import Cardano.Api.Consensus qualified as Consensus +import Cardano.Rpc.Server.Internal.TimedCache (TimedCache) import Cardano.Chain.Genesis qualified as Byron (Config) -import Cardano.Ledger.Api.Era qualified as L (LatestKnownEra) -import Cardano.Ledger.Api.Transition qualified as L (TransitionConfig) +import Cardano.Ledger.Alonzo.Genesis qualified as L (AlonzoGenesis) +import Cardano.Ledger.Conway.Genesis qualified as L (ConwayGenesis) +import Cardano.Ledger.Shelley.Genesis qualified as L (ShelleyGenesis) import Control.Monad.IO.Class (MonadIO) @@ -35,20 +44,27 @@ data NodeKernelAccess = NodeKernelAccess -- than /k/ blocks. , genesisConfig :: GenesisBundle -- ^ The network's genesis configuration. - -- Genesis data never changes after startup, so it is read once and stored - -- as a pure value. + -- Genesis data never changes after startup. Most of it is shared with the + -- running node. The Shelley genesis is read from its file when a caller + -- asks for it, and dropped again afterwards. } -- | The per-era genesis configuration of the network the node is running on. -- --- Gathered once, when the node kernel hook fires. The Byron genesis and the --- Shelley-onwards transition config are both read straight off --- 'Consensus.CardanoProtocolParams', part of cardano-node's boot-time --- 'Consensus.ProtocolInfoArgs'. No hard-fork navigation is needed. +-- Gathered once, when the node kernel hook fires, by walking the per-era ledger +-- configs of the node kernel's 'Consensus.TopLevelConfig'. The Byron, Alonzo and +-- Conway genesis values are the ones the running node holds, shared with it +-- rather than copied. Nothing is kept from cardano-node's boot-time +-- 'Consensus.ProtocolInfoArgs', whose Shelley genesis reaches gigabytes on +-- networks with large initial fund sets. +-- +-- The Shelley genesis is not kept here at all. All the node has is a compacted +-- copy with the initial funds erased, which is no use to a caller, so +-- 'shelleyGenesis' holds the file and a cache instead and the genesis is read +-- from disk when someone asks for it. -- --- The Shelley genesis hash is the exception: 'Consensus.ProtocolInfoArgs' --- does not carry it, so it is threaded in separately from cardano-node's own --- boot-time genesis parsing (see +-- The Shelley genesis hash and file path come from cardano-node's own boot-time +-- genesis parsing, because the ledger config carries neither (see -- 'Cardano.Rpc.Server.NodeKernelAccess.mkNodeKernelAccess'). data GenesisBundle = GenesisBundle { byronConfig :: !Byron.Config @@ -56,10 +72,17 @@ data GenesisBundle = GenesisBundle -- the hash the Byron ledger computed when it parsed the file. , shelleyGenesisHash :: !GenesisHashShelley -- ^ Blake2b-256 hash of the raw Shelley genesis file bytes. - , transitionConfig :: !(L.TransitionConfig L.LatestKnownEra) - -- ^ The Shelley-onwards genesis configuration, in the same representation - -- 'Cardano.Api.LedgerState.GenesisConfig' uses. - -- It retains the full parsed Shelley genesis, including @sgInitialFunds@ - -- and @sgStaking@; consensus keeps only a compacted copy with those fields - -- erased. + , shelleyGenesis :: !(ShelleyGenesisFile In, TimedCache L.ShelleyGenesis) + -- ^ The Shelley genesis file the node booted from, and a cache of that file + -- parsed in full, with the initial funds resolved. The two belong together: + -- the path is what the cache loads from. The cache starts empty, is filled by + -- the first request that needs the genesis, and empties itself once five + -- minutes have passed without another one. A node whose genesis nobody asks + -- about therefore keeps none of it in memory (issue #1314). + , alonzoGenesis :: !L.AlonzoGenesis + -- ^ The Alonzo genesis, which the ledger keeps as the Alonzo translation + -- context. + , conwayGenesis :: !L.ConwayGenesis + -- ^ The Conway genesis, which the ledger keeps as the Conway translation + -- context. } From 3e0aa6d66dddc9486b571c5141c255a983ab3167 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Aug 2026 13:58:33 +0000 Subject: [PATCH 18/62] Release cardano-api-11.6.0.0 --- ...thub-actions[bot]_cardano_api_11_5_0_0.yml | 5 -- ..._palas_skip_drep_query_when_not_needed.yml | 6 --- ...dano-api_palas_dijkstra_eon_completion.yml | 15 ------ ...260818_cardano-api_bump_herald_tooling.yml | 13 ------ ...pablo.lamela_rewrite_readme_onboarding.yml | 5 -- ..._api_ledgerstate_resolve_initial_funds.yml | 9 ---- ...api_palas_dijkstra_protocol_parameters.yml | 6 --- ...dano-api_palas_dijkstra_ledger_queries.yml | 6 --- ...ano-api_palas_dijkstra_tx_construction.yml | 9 ---- ...no-api_palas_dijkstra_tx_serialisation.yml | 6 --- ...no-api_palas_dijkstra_era_enumerations.yml | 9 ---- cardano-api/CHANGELOG.md | 46 +++++++++++++++++++ cardano-api/cardano-api.cabal | 2 +- 13 files changed, 47 insertions(+), 90 deletions(-) delete mode 100644 .changes/20260817_091148_cardano-api_github-actions[bot]_cardano_api_11_5_0_0.yml delete mode 100644 .changes/20260818_120000_cardano-api_palas_skip_drep_query_when_not_needed.yml delete mode 100644 .changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml delete mode 100644 .changes/20260818_cardano-api_bump_herald_tooling.yml delete mode 100644 .changes/20260819_083000_cardano-api_pablo.lamela_rewrite_readme_onboarding.yml delete mode 100644 .changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml delete mode 100644 .changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml delete mode 100644 .changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml delete mode 100644 .changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml delete mode 100644 .changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml delete mode 100644 .changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml diff --git a/.changes/20260817_091148_cardano-api_github-actions[bot]_cardano_api_11_5_0_0.yml b/.changes/20260817_091148_cardano-api_github-actions[bot]_cardano_api_11_5_0_0.yml deleted file mode 100644 index 209666df18..0000000000 --- a/.changes/20260817_091148_cardano-api_github-actions[bot]_cardano_api_11_5_0_0.yml +++ /dev/null @@ -1,5 +0,0 @@ -description: Release cardano-api 11.5.0.0 -kind: -- release -pr: 1293 -project: cardano-api diff --git a/.changes/20260818_120000_cardano-api_palas_skip_drep_query_when_not_needed.yml b/.changes/20260818_120000_cardano-api_palas_skip_drep_query_when_not_needed.yml deleted file mode 100644 index 7b160582fd..0000000000 --- a/.changes/20260818_120000_cardano-api_palas_skip_drep_query_when_not_needed.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: | - Fixed `queryStateForBalancedTx` to skip the DRepState query when transaction contains no DRep unregistration certificates -kind: - - bugfix -pr: 1297 -project: cardano-api diff --git a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml b/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml deleted file mode 100644 index 13dc599996..0000000000 --- a/.changes/20260818_120100_cardano-api_palas_dijkstra_eon_completion.yml +++ /dev/null @@ -1,15 +0,0 @@ -description: | - `DijkstraEra` now works everywhere the API dispatches on eras: the era helpers and instances that used to error out or not exist for Dijkstra are implemented. - - Extra key witnesses keep working in Dijkstra: the era replaces required signer hashes with guards, so `TxExtraKeyWitnesses` becomes key-hash guards. The effect is the same — those keys must sign. - - Simple scripts are still unsupported in Dijkstra. - - Most `LedgerTxBody` wrapper lenses are deprecated: use the same-named ledger lenses from `Cardano.Api.Ledger` (through `txBodyL`). `coinTxOutL` replaces `valueTxOutAdaAssetL`, and `reqSignerHashesTxBodyG` covers era-generic reads. `Cardano.Api.Ledger` now also re-exports the era tx-body classes and these lenses. The validity-interval lenses, `adaAssetL` and `multiAssetL` stay: the ledger has no equivalent for them. `reqSignerHashesTxBodyL` now also carries the ledger's `AtMostEra "Conway"` constraint, so using it in Dijkstra is a compile error. - - Breaking: the era constraint bundles (`AllegraEraOnwardsConstraints`, `MaryEraOnwardsConstraints`, `BabbageEraOnwardsConstraints`, `ConwayEraOnwardsConstraints`) no longer provide `ShelleyEraTxCert` or `TxCert era ~ ConwayTxCert era`, because Dijkstra does not support those certificates. If your code needs them, add the constraint explicitly. -kind: - - feature - - breaking -pr: 1298 -project: cardano-api diff --git a/.changes/20260818_cardano-api_bump_herald_tooling.yml b/.changes/20260818_cardano-api_bump_herald_tooling.yml deleted file mode 100644 index 2987baeca4..0000000000 --- a/.changes/20260818_cardano-api_bump_herald_tooling.yml +++ /dev/null @@ -1,13 +0,0 @@ -project: cardano-api - -pr: 1296 - -kind: - - maintenance - -description: | - Updated the herald changelog tooling to herald 0.2.0.0. - The herald-validate action in check-pr-changelog.yml was bumped to herald-validate-0.0.1.1 and the herald-release action in release.yml to herald-release-0.0.3.0; both now default to herald 0.2.0.0, so no explicit `herald-ref` override is needed. - The cardano-dev flake input was updated so the dev shell also provides herald 0.2.0.0. - Note that herald 0.2.0.0 requires an explicit version choice for `herald batch`: pass `--version` or `--auto-version` (preview with `--dry-run`). - Release PRs now include copy-paste CHaP submission instructions (herald-release's chap-instructions input is enabled). diff --git a/.changes/20260819_083000_cardano-api_pablo.lamela_rewrite_readme_onboarding.yml b/.changes/20260819_083000_cardano-api_pablo.lamela_rewrite_readme_onboarding.yml deleted file mode 100644 index be280b2f62..0000000000 --- a/.changes/20260819_083000_cardano-api_pablo.lamela_rewrite_readme_onboarding.yml +++ /dev/null @@ -1,5 +0,0 @@ -description: Rewrote the README with onboarding sections (overview, project structure, requirements, quick start, consumer setup and a verified usage example) -kind: -- documentation -pr: 1300 -project: cardano-api diff --git a/.changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml b/.changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml deleted file mode 100644 index ccb39e29e1..0000000000 --- a/.changes/20260820_cardano_api_ledgerstate_resolve_initial_funds.yml +++ /dev/null @@ -1,9 +0,0 @@ -project: cardano-api - -pr: 1305 - -kind: - - compatible - -description: | - Export resolveShelleyInitialFunds from Cardano.Api.LedgerState. It takes a ShelleyGenesis and resolves its initial funds against its sgExtraConfig the way ledger's own genesis state construction does, including streaming InjectionFromFile sources with content-hash verification. diff --git a/.changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml b/.changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml deleted file mode 100644 index fdd19d7503..0000000000 --- a/.changes/20260822_025911_cardano-api_palas_dijkstra_protocol_parameters.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: | - Protocol-parameter updates can now be created and inspected for `DijkstraEra`, via the new `DijkstraEraBasedProtocolParametersUpdate`. It adds the four parameters introduced in Dijkstra: the maximum reference-script size per block and per transaction, and the reference-script cost stride and multiplier. -kind: - - feature -pr: 1309 -project: cardano-api diff --git a/.changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml b/.changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml deleted file mode 100644 index 0d11bb70e0..0000000000 --- a/.changes/20260822_030407_cardano-api_palas_dijkstra_ledger_queries.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: | - All Conway-onwards ledger queries can now be run in the Dijkstra era: constitution, governance state, DRep and SPO state and stake distributions, committee state, vote delegatees, proposals, ratification state and future protocol parameters, default votes, and DRep delegations. Previously they errored for Dijkstra. -kind: - - feature -pr: 1310 -project: cardano-api diff --git a/.changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml b/.changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml deleted file mode 100644 index c5ff7f3a49..0000000000 --- a/.changes/20260822_035732_cardano-api_palas_dijkstra_tx_construction.yml +++ /dev/null @@ -1,9 +0,0 @@ -description: | - Dijkstra transactions can now be built, fee-estimated and auto-balanced with the experimental API (`makeUnsignedTx`, `estimateBalancedTxBody`, `makeTransactionBodyAutoBalance`). Extra key witnesses become key-hash guards, the era's replacement for required signer hashes — the same keys must sign. - - Breaking: `BalanceIsNegative` now carries the era's `UnsignedTx` instead of a Conway-specific one; code matching on it needs the more general type. -kind: - - feature - - breaking -pr: 1312 -project: cardano-api diff --git a/.changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml b/.changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml deleted file mode 100644 index c28f22e25f..0000000000 --- a/.changes/20260824_092254_cardano-api_palas_dijkstra_tx_serialisation.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: | - Dijkstra transactions can now be serialised and witnessed: the `Tx DijkstraEra` text-envelope types work (witnessed and unwitnessed), Plutus V1-V3 scripts are supported in the era (the ledger's maximum for Dijkstra is V3 for now), and `createCompatibleTx` handles Dijkstra. By the era's design, transactions cannot be marked script-invalid in Dijkstra. -kind: - - feature -pr: 1313 -project: cardano-api diff --git a/.changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml b/.changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml deleted file mode 100644 index 151d5e9a93..0000000000 --- a/.changes/20260824_144719_cardano-api_palas_dijkstra_era_enumerations.yml +++ /dev/null @@ -1,9 +0,0 @@ -description: | - The Dijkstra era can now be selected and enumerated like the other eras: `maxBound` and `[minBound .. maxBound]` for `AnyCardanoEra`, `AnyShelleyBasedEra` and the experimental `Some Era` include it, and the era-name parsers (`anyCardanoEraFromStringLike` and the JSON instances) accept "Dijkstra". - - Also fixed an `Enum` roundtrip crash: `fromEnum` already mapped Dijkstra to 7 for `AnyCardanoEra` and `AnyShelleyBasedEra`, but `toEnum 7` errored. -kind: - - feature - - bugfix -pr: 1317 -project: cardano-api diff --git a/cardano-api/CHANGELOG.md b/cardano-api/CHANGELOG.md index 09272ea42f..acf7e03b71 100644 --- a/cardano-api/CHANGELOG.md +++ b/cardano-api/CHANGELOG.md @@ -1,5 +1,51 @@ # Changelog for cardano-api +## 11.6.0.0 -- 2026-08-25 + +- The Dijkstra era can now be selected and enumerated like the other eras: `maxBound` and `[minBound .. maxBound]` for `AnyCardanoEra`, `AnyShelleyBasedEra` and the experimental `Some Era` include it, and the era-name parsers (`anyCardanoEraFromStringLike` and the JSON instances) accept "Dijkstra". + + Also fixed an `Enum` roundtrip crash: `fromEnum` already mapped Dijkstra to 7 for `AnyCardanoEra` and `AnyShelleyBasedEra`, but `toEnum 7` errored. + (feature, bugfix) + [PR 1317](https://github.com/intersectmbo/cardano-api/pull/1317) + +- Dijkstra transactions can now be serialised and witnessed: the `Tx DijkstraEra` text-envelope types work (witnessed and unwitnessed), Plutus V1-V3 scripts are supported in the era (the ledger's maximum for Dijkstra is V3 for now), and `createCompatibleTx` handles Dijkstra. By the era's design, transactions cannot be marked script-invalid in Dijkstra. + (feature) + [PR 1313](https://github.com/intersectmbo/cardano-api/pull/1313) + +- Dijkstra transactions can now be built, fee-estimated and auto-balanced with the experimental API (`makeUnsignedTx`, `estimateBalancedTxBody`, `makeTransactionBodyAutoBalance`). Extra key witnesses become key-hash guards, the era's replacement for required signer hashes — the same keys must sign. + + Breaking: `BalanceIsNegative` now carries the era's `UnsignedTx` instead of a Conway-specific one; code matching on it needs the more general type. + (feature, breaking) + [PR 1312](https://github.com/intersectmbo/cardano-api/pull/1312) + +- All Conway-onwards ledger queries can now be run in the Dijkstra era: constitution, governance state, DRep and SPO state and stake distributions, committee state, vote delegatees, proposals, ratification state and future protocol parameters, default votes, and DRep delegations. Previously they errored for Dijkstra. + (feature) + [PR 1310](https://github.com/intersectmbo/cardano-api/pull/1310) + +- Protocol-parameter updates can now be created and inspected for `DijkstraEra`, via the new `DijkstraEraBasedProtocolParametersUpdate`. It adds the four parameters introduced in Dijkstra: the maximum reference-script size per block and per transaction, and the reference-script cost stride and multiplier. + (feature) + [PR 1309](https://github.com/intersectmbo/cardano-api/pull/1309) + +- Export resolveShelleyInitialFunds from Cardano.Api.LedgerState. It takes a ShelleyGenesis and resolves its initial funds against its sgExtraConfig the way ledger's own genesis state construction does, including streaming InjectionFromFile sources with content-hash verification. + (compatible) + [PR 1305](https://github.com/intersectmbo/cardano-api/pull/1305) + +- `DijkstraEra` now works everywhere the API dispatches on eras: the era helpers and instances that used to error out or not exist for Dijkstra are implemented. + + Extra key witnesses keep working in Dijkstra: the era replaces required signer hashes with guards, so `TxExtraKeyWitnesses` becomes key-hash guards. The effect is the same — those keys must sign. + + Simple scripts are still unsupported in Dijkstra. + + Most `LedgerTxBody` wrapper lenses are deprecated: use the same-named ledger lenses from `Cardano.Api.Ledger` (through `txBodyL`). `coinTxOutL` replaces `valueTxOutAdaAssetL`, and `reqSignerHashesTxBodyG` covers era-generic reads. `Cardano.Api.Ledger` now also re-exports the era tx-body classes and these lenses. The validity-interval lenses, `adaAssetL` and `multiAssetL` stay: the ledger has no equivalent for them. `reqSignerHashesTxBodyL` now also carries the ledger's `AtMostEra "Conway"` constraint, so using it in Dijkstra is a compile error. + + Breaking: the era constraint bundles (`AllegraEraOnwardsConstraints`, `MaryEraOnwardsConstraints`, `BabbageEraOnwardsConstraints`, `ConwayEraOnwardsConstraints`) no longer provide `ShelleyEraTxCert` or `TxCert era ~ ConwayTxCert era`, because Dijkstra does not support those certificates. If your code needs them, add the constraint explicitly. + (feature, breaking) + [PR 1298](https://github.com/intersectmbo/cardano-api/pull/1298) + +- Fixed `queryStateForBalancedTx` to skip the DRepState query when transaction contains no DRep unregistration certificates + (bugfix) + [PR 1297](https://github.com/intersectmbo/cardano-api/pull/1297) + ## 11.5.0.0 -- 2026-08-17 - On POSIX, the `WithOwnerPermissions` family of functions (`writeFileTextEnvelopeWithOwnerPermissions`, `writeByteStringFileWithOwnerPermissions`, `writeLazyByteStringFileWithOwnerPermissions`, `writeTextFileWithOwnerPermissions`) and `writeSecrets` now write atomically: the contents go to a temporary file, are synced to disk, and the temporary file is renamed over the target, as was already the case on Windows. diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index f5ed902169..f266da3722 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -1,6 +1,6 @@ cabal-version: 3.8 name: cardano-api -version: 11.5.0.0 +version: 11.6.0.0 synopsis: The cardano API description: The cardano API. category: From bb4c0344207ad3f7872f95c94d6410d395b2f435 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Aug 2026 13:58:37 +0000 Subject: [PATCH 19/62] Add release changelog fragment for cardano-api 11.6.0.0 --- ..._cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml diff --git a/.changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml b/.changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml new file mode 100644 index 0000000000..49ed5b4866 --- /dev/null +++ b/.changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml @@ -0,0 +1,5 @@ +description: Release cardano-api 11.6.0.0 +kind: +- release +pr: 1319 +project: cardano-api From dcd3f1a20079893fa488b41c074fc97d40db386b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Aug 2026 14:24:32 +0000 Subject: [PATCH 20/62] Release cardano-rpc-11.2.0.0 --- ...no-rpc_github-actions[bot]_cardano_rpc_11_1_0_0.yml | 5 ----- ...0_cardano_rpc_genesis_initial_funds_extraconfig.yml | 10 ---------- ...123958_cardano-rpc_palas_dijkstra_txcert_import.yml | 6 ------ cardano-rpc/CHANGELOG.md | 6 ++++++ cardano-rpc/cardano-rpc.cabal | 2 +- 5 files changed, 7 insertions(+), 22 deletions(-) delete mode 100644 .changes/20260817_091158_cardano-rpc_github-actions[bot]_cardano_rpc_11_1_0_0.yml delete mode 100644 .changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml delete mode 100644 .changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml diff --git a/.changes/20260817_091158_cardano-rpc_github-actions[bot]_cardano_rpc_11_1_0_0.yml b/.changes/20260817_091158_cardano-rpc_github-actions[bot]_cardano_rpc_11_1_0_0.yml deleted file mode 100644 index 938044b64a..0000000000 --- a/.changes/20260817_091158_cardano-rpc_github-actions[bot]_cardano_rpc_11_1_0_0.yml +++ /dev/null @@ -1,5 +0,0 @@ -description: Release cardano-rpc 11.1.0.0 -kind: -- release -pr: 1294 -project: cardano-rpc diff --git a/.changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml b/.changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml deleted file mode 100644 index 23b8f191f2..0000000000 --- a/.changes/20260820_cardano_rpc_genesis_initial_funds_extraconfig.yml +++ /dev/null @@ -1,10 +0,0 @@ -project: cardano-rpc - -pr: 1305 - -kind: - - bugfix - - breaking - -description: | - Fixed the UTxO RPC `ReadGenesis` response reporting no initial funds for networks created with `cardano-cli create-testnet-data`, and stopped the node retaining the parsed genesis in memory for its whole lifetime. The Shelley genesis is now read from disk when `ReadGenesis` is served, verified against the genesis hash computed at node startup, and kept for five minutes after the last request; a genesis file that changed since startup fails the request with `FAILED_PRECONDITION`. Breaking change: `mkNodeKernelAccess` no longer takes `ProtocolInfoArgs` and takes the Shelley genesis file path instead. diff --git a/.changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml b/.changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml deleted file mode 100644 index 3724d61b8f..0000000000 --- a/.changes/20260824_123958_cardano-rpc_palas_dijkstra_txcert_import.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: | - cardano-rpc now gets `DijkstraTxCert` through `cardano-api`'s reexport instead of importing it directly from the ledger; no user-facing changes. -kind: - - refactoring -pr: 1313 -project: cardano-rpc diff --git a/cardano-rpc/CHANGELOG.md b/cardano-rpc/CHANGELOG.md index 172c0fc85f..e097de98f0 100644 --- a/cardano-rpc/CHANGELOG.md +++ b/cardano-rpc/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog for cardano-rpc +## 11.2.0.0 -- 2026-08-25 + +- Fixed the UTxO RPC `ReadGenesis` response reporting no initial funds for networks created with `cardano-cli create-testnet-data`, and stopped the node retaining the parsed genesis in memory for its whole lifetime. The Shelley genesis is now read from disk when `ReadGenesis` is served, verified against the genesis hash computed at node startup, and kept for five minutes after the last request; a genesis file that changed since startup fails the request with `FAILED_PRECONDITION`. Breaking change: `mkNodeKernelAccess` no longer takes `ProtocolInfoArgs` and takes the Shelley genesis file path instead. + (bugfix, breaking) + [PR 1305](https://github.com/intersectmbo/cardano-api/pull/1305) + ## 11.1.0.0 -- 2026-08-17 - Add the `QueryService.ReadGenesis` UTxO RPC method, returning the full per-era genesis configuration. diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index c954857720..354c8864d9 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -1,6 +1,6 @@ cabal-version: 3.8 name: cardano-rpc -version: 11.1.0.0 +version: 11.2.0.0 synopsis: A gRPC server and client for interacting with the Cardano node description: A Haskell library providing a gRPC-based RPC interface for the Cardano node, From ddffc4c3dd615e98cfb7a21ff0efe985cf188e58 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Aug 2026 14:24:37 +0000 Subject: [PATCH 21/62] Add release changelog fragment for cardano-rpc 11.2.0.0 --- ..._cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml diff --git a/.changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml b/.changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml new file mode 100644 index 0000000000..03c3831aee --- /dev/null +++ b/.changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml @@ -0,0 +1,5 @@ +description: Release cardano-rpc 11.2.0.0 +kind: +- release +pr: 1320 +project: cardano-rpc From e0b35828d779c9ec214bc100e378fe4866353b51 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 25 Aug 2026 14:16:08 +0000 Subject: [PATCH 22/62] Honour TestDijkstraHardForkAtEpoch when parsing the node configuration parseHardForkTriggers filled the Dijkstra slot with CardanoTriggerHardForkAtDefaultVersion unconditionally, so foldBlocks and everything built on the ledger-state machinery could not follow a chain whose Dijkstra fork is configured by epoch and failed at the first Dijkstra block; parse the trigger like every other era's, and add a NodeConfig parsing test pinning both the epoch and the default behaviour. --- ...o-api_palas_dijkstra_hard_fork_trigger.yml | 6 ++ cardano-api/cardano-api.cabal | 3 +- cardano-api/src/Cardano/Api/LedgerState.hs | 9 ++- .../Test/Cardano/Api/NodeConfig.hs | 69 +++++++++++++++++++ .../test/cardano-api-test/cardano-api-test.hs | 2 + 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 .changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml create mode 100644 cardano-api/test/cardano-api-test/Test/Cardano/Api/NodeConfig.hs diff --git a/.changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml b/.changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml new file mode 100644 index 0000000000..d617debb85 --- /dev/null +++ b/.changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml @@ -0,0 +1,6 @@ +description: | + `foldBlocks` and the rest of the ledger-state machinery now honour `TestDijkstraHardForkAtEpoch` in the node configuration file, so they can follow a chain into the Dijkstra era. +kind: + - bugfix +pr: 1321 +project: cardano-api diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index f266da3722..196dbc83fa 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -398,7 +398,7 @@ test-suite cardano-api-test hedgehog-quickcheck, microlens, mtl, - ouroboros-consensus:{ouroboros-consensus, protocol}, + ouroboros-consensus:{cardano, ouroboros-consensus, protocol}, raw-strings-qq, tasty, tasty-hedgehog, @@ -427,6 +427,7 @@ test-suite cardano-api-test Test.Cardano.Api.Ledger Test.Cardano.Api.Leios Test.Cardano.Api.Metadata + Test.Cardano.Api.NodeConfig Test.Cardano.Api.Ord Test.Cardano.Api.Orphans Test.Cardano.Api.RawBytes diff --git a/cardano-api/src/Cardano/Api/LedgerState.hs b/cardano-api/src/Cardano/Api/LedgerState.hs index fb509f6785..6e3c3b6c1b 100644 --- a/cardano-api/src/Cardano/Api/LedgerState.hs +++ b/cardano-api/src/Cardano/Api/LedgerState.hs @@ -1173,7 +1173,7 @@ instance FromJSON NodeConfig where <*> parseAlonzoHardForkEpoch o <*> parseBabbageHardForkEpoch o <*> parseConwayHardForkEpoch o - <*> pure Consensus.CardanoTriggerHardForkAtDefaultVersion -- TODO Dijkstra + <*> parseDijkstraHardForkEpoch o parseShelleyHardForkEpoch :: Object -> Parser (Consensus.CardanoHardForkTrigger blk) parseShelleyHardForkEpoch o = asum @@ -1215,6 +1215,13 @@ instance FromJSON NodeConfig where , pure Consensus.CardanoTriggerHardForkAtDefaultVersion ] + parseDijkstraHardForkEpoch :: Object -> Parser (Consensus.CardanoHardForkTrigger blk) + parseDijkstraHardForkEpoch o = + asum + [ Consensus.CardanoTriggerHardForkAtEpoch <$> o .: "TestDijkstraHardForkAtEpoch" + , pure Consensus.CardanoTriggerHardForkAtDefaultVersion + ] + ---------------------------------------------------------------------- -- WARNING When adding new entries above, be aware that if there is an -- intra-era fork, then the numbering is not consecutive. diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/NodeConfig.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/NodeConfig.hs new file mode 100644 index 0000000000..3f63a1adac --- /dev/null +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/NodeConfig.hs @@ -0,0 +1,69 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Test.Cardano.Api.NodeConfig + ( tests + ) +where + +import Cardano.Api (EpochNo (..)) +import Cardano.Api.LedgerState (NodeConfig (..)) + +import Ouroboros.Consensus.Cardano.Node qualified as Consensus + +import Data.Aeson qualified as Aeson +import GHC.Stack + +import Hedgehog as H +import Hedgehog.Extras (propertyOnce) +import Test.Tasty (TestTree, testGroup) +import Test.Tasty.Hedgehog (testProperty) + +-- | A minimal node configuration with the given extra keys. +nodeConfigWith :: [(Aeson.Key, Aeson.Value)] -> Aeson.Value +nodeConfigWith extras = + Aeson.object $ + [ "ByronGenesisFile" Aeson..= ("byron-genesis.json" :: String) + , "ShelleyGenesisFile" Aeson..= ("shelley-genesis.json" :: String) + , "AlonzoGenesisFile" Aeson..= ("alonzo-genesis.json" :: String) + , "ConwayGenesisFile" Aeson..= ("conway-genesis.json" :: String) + , "RequiresNetworkMagic" Aeson..= ("RequiresNoMagic" :: String) + , "LastKnownBlockVersion-Major" Aeson..= (3 :: Int) + , "LastKnownBlockVersion-Minor" Aeson..= (0 :: Int) + , "LastKnownBlockVersion-Alt" Aeson..= (0 :: Int) + ] + <> map (uncurry (Aeson..=)) extras + +parseTriggers + :: (HasCallStack, MonadTest m) + => [(Aeson.Key, Aeson.Value)] + -> m Consensus.CardanoHardForkTriggers +parseTriggers extras = + case Aeson.fromJSON $ nodeConfigWith extras of + Aeson.Error e -> withFrozenCallStack $ H.annotate e >> H.failure + Aeson.Success nc -> pure $ ncHardForkTriggers nc + +prop_parse_dijkstra_hard_fork_at_epoch :: Property +prop_parse_dijkstra_hard_fork_at_epoch = propertyOnce $ do + triggers <- parseTriggers [("TestDijkstraHardForkAtEpoch", Aeson.toJSON (5 :: Int))] + case triggers of + Consensus.CardanoHardForkTriggers'{Consensus.triggerHardForkDijkstra = trigger} -> + case trigger of + Consensus.CardanoTriggerHardForkAtEpoch (EpochNo 5) -> H.success + other -> H.annotateShow other >> H.failure + +prop_parse_dijkstra_hard_fork_default :: Property +prop_parse_dijkstra_hard_fork_default = propertyOnce $ do + triggers <- parseTriggers [] + case triggers of + Consensus.CardanoHardForkTriggers'{Consensus.triggerHardForkDijkstra = trigger} -> + case trigger of + Consensus.CardanoTriggerHardForkAtDefaultVersion -> H.success + other -> H.annotateShow other >> H.failure + +tests :: TestTree +tests = + testGroup + "Test.Cardano.Api.NodeConfig" + [ testProperty "parse TestDijkstraHardForkAtEpoch" prop_parse_dijkstra_hard_fork_at_epoch + , testProperty "parse Dijkstra hard fork default" prop_parse_dijkstra_hard_fork_default + ] diff --git a/cardano-api/test/cardano-api-test/cardano-api-test.hs b/cardano-api/test/cardano-api-test/cardano-api-test.hs index adb0a82bf1..dd9d1e4796 100644 --- a/cardano-api/test/cardano-api-test/cardano-api-test.hs +++ b/cardano-api/test/cardano-api-test/cardano-api-test.hs @@ -25,6 +25,7 @@ import Test.Cardano.Api.KeysByron qualified import Test.Cardano.Api.Ledger qualified import Test.Cardano.Api.Leios qualified import Test.Cardano.Api.Metadata qualified +import Test.Cardano.Api.NodeConfig qualified import Test.Cardano.Api.Ord qualified import Test.Cardano.Api.RawBytes qualified import Test.Cardano.Api.Transaction.Autobalance qualified @@ -67,6 +68,7 @@ tests = , Test.Cardano.Api.Ledger.tests , Test.Cardano.Api.Leios.tests , Test.Cardano.Api.Metadata.tests + , Test.Cardano.Api.NodeConfig.tests , Test.Cardano.Api.Ord.tests , Test.Cardano.Api.RawBytes.tests , Test.Cardano.Api.Transaction.Body.Plutus.Scripts.tests From f7664caa6667442e350362fae3af8b8496063b43 Mon Sep 17 00:00:00 2001 From: Sasha Bogicevic Date: Thu, 25 Jun 2026 14:29:04 +0200 Subject: [PATCH 23/62] JSON round-trip fails for TxOut with non-canonical inline datum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FromJSON (TxOut CtxUTxO era) ignores inlineDatumRaw and reconstructs HashableScriptData via scriptDataFromJson, which re-serialises to canonical CBOR bytes. For datums whose original CBOR uses definite-length arrays (non-canonical), H(canonical) ≠ H(original), causing "Inline datum not equivalent to inline datum hash" on parse. Signed-off-by: Sasha Bogicevic --- ..._canonical_inline_datum_json_roundtrip.yml | 6 + cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs | 23 ++- .../src/Cardano/Api/Tx/Internal/Output.hs | 135 +++++------------- .../cardano-api-test/Test/Cardano/Api/Json.hs | 19 +++ 4 files changed, 85 insertions(+), 98 deletions(-) create mode 100644 .changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml diff --git a/.changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml b/.changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml new file mode 100644 index 0000000000..56ce8bc2e4 --- /dev/null +++ b/.changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml @@ -0,0 +1,6 @@ +project: cardano-api +pr: 1238 +kind: + - bugfix +description: | + FromJSON (TxOut) no longer crashes when parsing a TxOut whose inline datum was encoded with non-canonical CBOR bytes (e.g. definite-length arrays instead of the indefinite-length form Plutus normally emits). diff --git a/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs b/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs index ef3ab6d609..63130f4b53 100644 --- a/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs +++ b/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs @@ -44,6 +44,7 @@ module Test.Gen.Cardano.Api.Typed -- * Scripts , genHashableScriptData + , genNonCanonicalHashableScriptData , genReferenceScript , genScript , genValidScript @@ -189,7 +190,7 @@ import Data.Int (Int64) import Data.Maybe import Data.Ratio (Ratio, (%)) import Data.String -import Data.Word (Word32, Word64) +import Data.Word (Word32, Word64, Word8) import GHC.Exts (IsList (..)) import GHC.Stack import Numeric.Natural (Natural) @@ -392,6 +393,26 @@ genHashableScriptData = do Left e -> error $ "genHashableScriptData: " <> show e Right r -> return r +-- | Generate 'HashableScriptData' whose CBOR uses a definite-length array +-- instead of the canonical indefinite-length form that Plutus normally emits. +-- This means 'hashScriptDataBytes' of the result differs from +-- 'hashScriptDataBytes' of its canonical re-encoding, exposing any JSON +-- round-trip that reconstructs CBOR rather than preserving original bytes. +genNonCanonicalHashableScriptData :: HasCallStack => Gen HashableScriptData +genNonCanonicalHashableScriptData = do + constrIdx <- Gen.integral (Range.linear 0 6 :: Range.Range Int) + args <- Gen.list (Range.linear 1 5) (Gen.integral (Range.linear 0 23 :: Range.Range Int)) + -- Plutus constructor n uses CBOR tag 121+n. + -- Canonical encoding wraps fields in an indefinite-length array (0x9f..0xff). + -- We use a definite-length array (0x80+len) to produce non-canonical bytes. + let tagBytes = [0xd8, fromIntegral (0x79 + constrIdx)] :: [Word8] + arrayHdr = [fromIntegral (0x80 + length args)] :: [Word8] + argBytes = map fromIntegral args :: [Word8] + bytes = BS.pack (tagBytes <> arrayHdr <> argBytes) + case deserialiseFromCBOR AsHashableScriptData bytes of + Left e -> error $ "genNonCanonicalHashableScriptData: " <> show e -- impossible case: we should always be able to deserialize cbor + Right r -> pure r + {-# DEPRECATED genScriptData "Use genHashableScriptData" #-} genScriptData :: Gen ScriptData genScriptData = diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs index a3a872a7ee..160ca317f4 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Output.hs @@ -90,6 +90,7 @@ import Cardano.Ledger.Plutus.Data qualified as Plutus import Data.Aeson (object, withObject, (.:), (.:?), (.=)) import Data.Aeson qualified as Aeson import Data.Aeson.Key qualified as Aeson +import Data.Aeson.Text qualified as Aeson import Data.Aeson.Types qualified as Aeson import Data.Bifunctor (Bifunctor (..)) import Data.ByteString.Base16 qualified as Base16 @@ -98,6 +99,7 @@ import Data.Map.Strict qualified as Map import Data.Scientific (toBoundedInteger) import Data.Sequence.Strict qualified as Seq import Data.Text.Encoding qualified as Text +import Data.Text.Lazy (unpack) import Data.Type.Equality import Data.Typeable (Typeable) import Data.Word @@ -431,6 +433,36 @@ txOutToJsonValue era (TxOut addr val dat refScript) = ReferenceScript _ s -> toJSON s ReferenceScriptNone -> Aeson.Null +-- | Parse 'HashableScriptData' from a JSON object, preferring the raw CBOR +-- bytes in @inlineDatumRaw@ when present to preserve non-canonical encodings, +-- falling back to the detailed-schema JSON for objects that lack the field. +parseInlineDatum + :: Aeson.Object + -> Aeson.Parser (Maybe HashableScriptData) +parseInlineDatum o = do + -- We check for the existence of inline datums + inlineDatumHash <- o .:? "inlineDatumhash" + inlineDatum <- o .:? "inlineDatum" + mRaw <- o .:? "inlineDatumRaw" + case (inlineDatum, inlineDatumHash) of + (Just dVal, Just h) -> do + hashableData <- case mRaw of + Just rawHex -> do + rawBytes <- either fail pure $ Base16.decode (Text.encodeUtf8 rawHex) -- 'inlineDatum' is ignored in this case + either (fail . show) pure $ deserialiseFromCBOR AsHashableScriptData rawBytes + Nothing -> + case scriptDataFromJson ScriptDataJsonDetailedSchema dVal of + Left err -> fail $ "Error parsing TxOut JSON: " <> displayError err + Right sData -> pure sData + if hashScriptDataBytes hashableData /= h + then + fail $ "Inline datum not equivalent to inline datum hash. " <> unpack (Aeson.encodeToLazyText o) + else return $ Just hashableData + (Nothing, Nothing) -> return Nothing + (_, _) -> + fail + "Should not be possible to create a tx output with either an inline datum hash or an inline datum" + instance IsShelleyBasedEra era => FromJSON (TxOut CtxTx era) where parseJSON = withObject "TxOut" $ \o -> do case shelleyBasedEra :: ShelleyBasedEra era of @@ -456,47 +488,16 @@ instance IsShelleyBasedEra era => FromJSON (TxOut CtxTx era) where ShelleyBasedEraBabbage -> do alonzoTxOutInBabbage <- alonzoTxOutParser AlonzoEraOnwardsBabbage o - -- We check for the existence of inline datums - inlineDatumHash <- o .:? "inlineDatumhash" - inlineDatum <- o .:? "inlineDatum" mInlineDatum <- - case (inlineDatum, inlineDatumHash) of - (Just dVal, Just h) -> do - case scriptDataJsonToHashable ScriptDataJsonDetailedSchema dVal of - Left err -> - fail $ "Error parsing TxOut JSON: " <> displayError err - Right hashableData -> do - if hashScriptDataBytes hashableData /= h - then fail "Inline datum not equivalent to inline datum hash" - else return $ TxOutDatumInline BabbageEraOnwardsBabbage hashableData - (Nothing, Nothing) -> return TxOutDatumNone - (_, _) -> - fail - "Should not be possible to create a tx output with either an inline datum hash or an inline datum" - + maybe TxOutDatumNone (TxOutDatumInline BabbageEraOnwardsBabbage) <$> parseInlineDatum o mReferenceScript <- o .:? "referenceScript" reconcileBabbage alonzoTxOutInBabbage mInlineDatum mReferenceScript ShelleyBasedEraConway -> do alonzoTxOutInConway <- alonzoTxOutParser AlonzoEraOnwardsConway o - -- We check for the existence of inline datums - inlineDatumHash <- o .:? "inlineDatumhash" - inlineDatum <- o .:? "inlineDatum" mInlineDatum <- - case (inlineDatum, inlineDatumHash) of - (Just dVal, Just h) -> - case scriptDataFromJson ScriptDataJsonDetailedSchema dVal of - Left err -> - fail $ "Error parsing TxOut JSON: " <> displayError err - Right sData -> - if hashScriptDataBytes sData /= h - then fail "Inline datum not equivalent to inline datum hash" - else return $ TxOutDatumInline BabbageEraOnwardsConway sData - (Nothing, Nothing) -> return TxOutDatumNone - (_, _) -> - fail - "Should not be possible to create a tx output with either an inline datum hash or an inline datum" + maybe TxOutDatumNone (TxOutDatumInline BabbageEraOnwardsConway) <$> parseInlineDatum o mReferenceScript <- o .:? "referenceScript" @@ -504,23 +505,8 @@ instance IsShelleyBasedEra era => FromJSON (TxOut CtxTx era) where ShelleyBasedEraDijkstra -> do alonzoTxOutInConway <- alonzoTxOutParser AlonzoEraOnwardsDijkstra o - -- We check for the existence of inline datums - inlineDatumHash <- o .:? "inlineDatumhash" - inlineDatum <- o .:? "inlineDatum" mInlineDatum <- - case (inlineDatum, inlineDatumHash) of - (Just dVal, Just h) -> - case scriptDataFromJson ScriptDataJsonDetailedSchema dVal of - Left err -> - fail $ "Error parsing TxOut JSON: " <> displayError err - Right sData -> - if hashScriptDataBytes sData /= h - then fail "Inline datum not equivalent to inline datum hash" - else return $ TxOutDatumInline BabbageEraOnwardsDijkstra sData - (Nothing, Nothing) -> return TxOutDatumNone - (_, _) -> - fail - "Should not be possible to create a tx output with either an inline datum hash or an inline datum" + maybe TxOutDatumNone (TxOutDatumInline BabbageEraOnwardsDijkstra) <$> parseInlineDatum o mReferenceScript <- o .:? "referenceScript" @@ -639,23 +625,8 @@ instance IsShelleyBasedEra era => FromJSON (TxOut CtxUTxO era) where ShelleyBasedEraBabbage -> do alonzoTxOutInBabbage <- alonzoTxOutParser AlonzoEraOnwardsBabbage o - -- We check for the existence of inline datums - inlineDatumHash <- o .:? "inlineDatumhash" - inlineDatum <- o .:? "inlineDatum" mInlineDatum <- - case (inlineDatum, inlineDatumHash) of - (Just dVal, Just h) -> do - case scriptDataJsonToHashable ScriptDataJsonDetailedSchema dVal of - Left err -> - fail $ "Error parsing TxOut JSON: " <> displayError err - Right hashableData -> do - if hashScriptDataBytes hashableData /= h - then fail "Inline datum not equivalent to inline datum hash" - else return $ TxOutDatumInline BabbageEraOnwardsBabbage hashableData - (Nothing, Nothing) -> return TxOutDatumNone - (_, _) -> - fail - "Should not be possible to create a tx output with either an inline datum hash or an inline datum" + maybe TxOutDatumNone (TxOutDatumInline BabbageEraOnwardsBabbage) <$> parseInlineDatum o -- We check for a reference script mReferenceScript <- o .:? "referenceScript" @@ -664,23 +635,8 @@ instance IsShelleyBasedEra era => FromJSON (TxOut CtxUTxO era) where ShelleyBasedEraConway -> do alonzoTxOutInConway <- alonzoTxOutParser AlonzoEraOnwardsConway o - -- We check for the existence of inline datums - inlineDatumHash <- o .:? "inlineDatumhash" - inlineDatum <- o .:? "inlineDatum" mInlineDatum <- - case (inlineDatum, inlineDatumHash) of - (Just dVal, Just h) -> - case scriptDataFromJson ScriptDataJsonDetailedSchema dVal of - Left err -> - fail $ "Error parsing TxOut JSON: " <> displayError err - Right sData -> - if hashScriptDataBytes sData /= h - then fail "Inline datum not equivalent to inline datum hash" - else return $ TxOutDatumInline BabbageEraOnwardsConway sData - (Nothing, Nothing) -> return TxOutDatumNone - (_, _) -> - fail - "Should not be possible to create a tx output with either an inline datum hash or an inline datum" + maybe TxOutDatumNone (TxOutDatumInline BabbageEraOnwardsConway) <$> parseInlineDatum o -- We check for a reference script mReferenceScript <- o .:? "referenceScript" @@ -689,23 +645,8 @@ instance IsShelleyBasedEra era => FromJSON (TxOut CtxUTxO era) where ShelleyBasedEraDijkstra -> do alonzoTxOutInConway <- alonzoTxOutParser AlonzoEraOnwardsDijkstra o - -- We check for the existence of inline datums - inlineDatumHash <- o .:? "inlineDatumhash" - inlineDatum <- o .:? "inlineDatum" mInlineDatum <- - case (inlineDatum, inlineDatumHash) of - (Just dVal, Just h) -> - case scriptDataFromJson ScriptDataJsonDetailedSchema dVal of - Left err -> - fail $ "Error parsing TxOut JSON: " <> displayError err - Right sData -> - if hashScriptDataBytes sData /= h - then fail "Inline datum not equivalent to inline datum hash" - else return $ TxOutDatumInline BabbageEraOnwardsDijkstra sData - (Nothing, Nothing) -> return TxOutDatumNone - (_, _) -> - fail - "Should not be possible to create a tx output with either an inline datum hash or an inline datum" + maybe TxOutDatumNone (TxOutDatumInline BabbageEraOnwardsDijkstra) <$> parseInlineDatum o -- We check for a reference script mReferenceScript <- o .:? "referenceScript" diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Json.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Json.hs index b8b9667345..484175e002 100644 --- a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Json.hs +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Json.hs @@ -54,6 +54,22 @@ prop_json_roundtrip_txout_utxo_context = H.property $ do txOut <- forAll $ genTxOutUTxOContext ShelleyBasedEraBabbage tripping txOut encode eitherDecode +-- | Round-trips a 'TxOut' whose inline datum uses non-canonical CBOR bytes +-- (definite-length array instead of the canonical indefinite-length form). +prop_json_roundtrip_txout_noncanonical_inline_datum :: Property +prop_json_roundtrip_txout_noncanonical_inline_datum = H.property $ do + hsd <- forAll genNonCanonicalHashableScriptData + addr <- forAll $ genAddressInEra ShelleyBasedEraConway + val <- forAll $ genTxOutValue ShelleyBasedEraConway + let txOutUTxO = + TxOut addr val (TxOutDatumInline BabbageEraOnwardsConway hsd) ReferenceScriptNone + :: TxOut CtxUTxO ConwayEra + txOutTx = + TxOut addr val (TxOutDatumInline BabbageEraOnwardsConway hsd) ReferenceScriptNone + :: TxOut CtxTx ConwayEra + tripping txOutUTxO encode eitherDecode + tripping txOutTx encode eitherDecode + prop_json_roundtrip_scriptdata_detailed_json :: Property prop_json_roundtrip_scriptdata_detailed_json = H.property $ do sData <- forAll genHashableScriptData @@ -131,6 +147,9 @@ tests = , testProperty "json roundtrip txoutvalue" prop_json_roundtrip_txoutvalue , testProperty "json roundtrip txout tx context" prop_json_roundtrip_txout_tx_context , testProperty "json roundtrip txout utxo context" prop_json_roundtrip_txout_utxo_context + , testProperty + "json roundtrip txout noncanonical inline datum" + prop_json_roundtrip_txout_noncanonical_inline_datum , testProperty "json roundtrip scriptdata detailed json" prop_json_roundtrip_scriptdata_detailed_json , testProperty "json roundtrip praos nonce" prop_roundtrip_praos_nonce_JSON , testProperty "new TxOut ToJSON matches legacy" prop_new_txout_json_matches_legacy From 29d06f59cc92a50c68f115768f37510a1dd66108 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Wed, 22 Jul 2026 11:14:33 -0400 Subject: [PATCH 24/62] Re-export ledger accessors auxDataTxL and metadataTxAuxDataL Widen the EraTx re-export to include auxDataTxL, and re-export EraTxAuxData(metadataTxAuxDataL) from Cardano.Api.Ledger. Together these let downstream code read a transaction's auxiliary data (metadata) through the ledger lenses without depending on cardano-ledger directly. --- cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs index bc10ce4fae..6d99276818 100644 --- a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs +++ b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs @@ -181,7 +181,8 @@ module Cardano.Api.Ledger.Internal.Reexport , pattern AlonzoGenesis , AsIxItem (..) , EraGov - , EraTx (witsTxL, bodyTxL) + , EraTx (witsTxL, bodyTxL, auxDataTxL) + , EraTxAuxData (metadataTxAuxDataL) , EraTxBody (..) , TopTx , Tx @@ -246,7 +247,7 @@ import Cardano.Ledger.Alonzo.Core , AsIxItem (AsIxItem) , CoinPerWord (..) , EraGov - , EraTx (bodyTxL, witsTxL) + , EraTx (bodyTxL, witsTxL, auxDataTxL) , EraTxWits (..) , PParamsUpdate (..) , Tx @@ -381,6 +382,7 @@ import Cardano.Ledger.Conway.TxCert import Cardano.Ledger.Core ( Era (..) , EraPParams (..) + , EraTxAuxData (metadataTxAuxDataL) , EraTxBody (..) , EraTxOut , PParams (..) From a1f9cb4669c385ec9b39955086eca6be80176e7b Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Wed, 22 Jul 2026 11:15:58 -0400 Subject: [PATCH 25/62] Add changelog fragment for auxDataTxL/metadataTxAuxDataL re-export --- .changes/reexport-txauxdata-accessors.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/reexport-txauxdata-accessors.yml diff --git a/.changes/reexport-txauxdata-accessors.yml b/.changes/reexport-txauxdata-accessors.yml new file mode 100644 index 0000000000..bcfb2426ee --- /dev/null +++ b/.changes/reexport-txauxdata-accessors.yml @@ -0,0 +1,6 @@ +project: cardano-api +pr: 1262 +kind: + - compatible +description: | + Re-export the ledger accessors `auxDataTxL` (via `EraTx`) and `metadataTxAuxDataL` (via `EraTxAuxData`) from `Cardano.Api.Ledger`, so downstream code can read a transaction's auxiliary data (metadata) through the ledger lenses without depending on `cardano-ledger` directly. From 504ec9c0d533720ce4a9ab81f2821f0a0f992cb2 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Wed, 22 Jul 2026 12:18:32 -0400 Subject: [PATCH 26/62] Re-export ledger TxOut accessors for reading outputs Add addrTxOutL / valueTxOutL (EraTx0ut), datumTxOutF (AlonzoEraTxOut), Datum(..), hashBinaryData, and hashScript to Cardano.Api.Ledger, so downstream code can read a transaction output's address, value, datum and reference script through the ledger lenses. --- .changes/reexport-txauxdata-accessors.yml | 2 +- .../src/Cardano/Api/Ledger/Internal/Reexport.hs | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.changes/reexport-txauxdata-accessors.yml b/.changes/reexport-txauxdata-accessors.yml index bcfb2426ee..ed504331ac 100644 --- a/.changes/reexport-txauxdata-accessors.yml +++ b/.changes/reexport-txauxdata-accessors.yml @@ -3,4 +3,4 @@ pr: 1262 kind: - compatible description: | - Re-export the ledger accessors `auxDataTxL` (via `EraTx`) and `metadataTxAuxDataL` (via `EraTxAuxData`) from `Cardano.Api.Ledger`, so downstream code can read a transaction's auxiliary data (metadata) through the ledger lenses without depending on `cardano-ledger` directly. + Re-export additional ledger accessors from `Cardano.Api.Ledger` so downstream code can read a transaction and its outputs through the ledger lenses without depending on `cardano-ledger` directly: `auxDataTxL` (via `EraTx`), `metadataTxAuxDataL` (via `EraTxAuxData`), `addrTxOutL` / `valueTxOutL` (via `EraTxOut`), `datumTxOutF` (via `AlonzoEraTxOut`), plus `Datum (..)`, `hashBinaryData`, and `hashScript`. diff --git a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs index 6d99276818..22a719096f 100644 --- a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs +++ b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs @@ -51,7 +51,7 @@ module Cardano.Api.Ledger.Internal.Reexport , toCompactPartial , EraPParams (..) , Era (..) - , EraTxOut + , EraTxOut (addrTxOutL, valueTxOutL) , Inject (..) , Network (..) , PoolCert (..) @@ -169,6 +169,10 @@ module Cardano.Api.Ledger.Internal.Reexport , AsIx (..) , CoinPerWord (..) , Data (..) + , Datum (..) + , AlonzoEraTxOut (datumTxOutF) + , hashBinaryData + , hashScript , EraTxWits (..) , ExUnits (..) , Redeemers (..) @@ -241,6 +245,7 @@ import Cardano.Ledger.Address (AccountAddress (..), Addr (..)) import Cardano.Ledger.Allegra.Scripts (AllegraEraScript (..), Timelock (..), showTimelock) import Cardano.Ledger.Alonzo.Core ( AlonzoEraScript (..) + , AlonzoEraTxOut (datumTxOutF) , AlonzoEraTxBody (..) , AlonzoEraTxWits (..) , AsIx (..) @@ -384,13 +389,14 @@ import Cardano.Ledger.Core , EraPParams (..) , EraTxAuxData (metadataTxAuxDataL) , EraTxBody (..) - , EraTxOut + , EraTxOut (addrTxOutL, valueTxOutL) , PParams (..) , PoolCert (..) , TopTx , TxOut , Value , fromEraCBOR + , hashScript , mkBasicTxOut , ppMinFeeAL , ppMinUTxOValueL @@ -418,7 +424,7 @@ import Cardano.Ledger.Keys , toVRFVerKeyHash ) import Cardano.Ledger.Mary.Value (MaryValue (..), MultiAsset (..), PolicyID (..), valueFromList) -import Cardano.Ledger.Plutus.Data (Data (..), unData) +import Cardano.Ledger.Plutus.Data (Data (..), Datum (..), hashBinaryData, unData) import Cardano.Ledger.Plutus.Language ( Language , Plutus From 198afc03d2aa6174d853579d1faab42749ca4a6b Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 30 Jul 2026 11:36:11 -0400 Subject: [PATCH 27/62] Fix fourmolu import ordering and drop redundant test imports Sort the Cardano.Ledger.Alonzo.Core import list: AlonzoEraTxOut after AlonzoEraTxBody, and auxDataTxL first in the EraTx bundle. Re-exporting these accessors from Cardano.Api.Ledger makes two same-alias ledger imports in the test suite fully redundant, which fails the build under -Werror=unused-imports. --- cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs | 6 ++---- .../test/cardano-api-test/Test/Cardano/Api/Experimental.hs | 1 - .../Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs index 22a719096f..7c7741f806 100644 --- a/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs +++ b/cardano-api/src/Cardano/Api/Ledger/Internal/Reexport.hs @@ -74,7 +74,6 @@ module Cardano.Api.Ledger.Internal.Reexport , getScriptsNeeded , mkBasicTxOut , coinTxOutL - , valueTxOutL , toDeltaCoin , toEraCBOR , toSLanguage @@ -245,14 +244,14 @@ import Cardano.Ledger.Address (AccountAddress (..), Addr (..)) import Cardano.Ledger.Allegra.Scripts (AllegraEraScript (..), Timelock (..), showTimelock) import Cardano.Ledger.Alonzo.Core ( AlonzoEraScript (..) - , AlonzoEraTxOut (datumTxOutF) , AlonzoEraTxBody (..) + , AlonzoEraTxOut (datumTxOutF) , AlonzoEraTxWits (..) , AsIx (..) , AsIxItem (AsIxItem) , CoinPerWord (..) , EraGov - , EraTx (bodyTxL, witsTxL, auxDataTxL) + , EraTx (auxDataTxL, bodyTxL, witsTxL) , EraTxWits (..) , PParamsUpdate (..) , Tx @@ -292,7 +291,6 @@ import Cardano.Ledger.Api , treasuryDonationTxBodyL , unRedeemers , updateTxBodyL - , valueTxOutL , votingProceduresTxBodyL ) import Cardano.Ledger.Api.Tx.Cert diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs index 0c4720fbd9..c23461d13b 100644 --- a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs @@ -36,7 +36,6 @@ import Cardano.Ledger.Conway qualified as L import Cardano.Ledger.Core qualified as L import Cardano.Ledger.Dijkstra.Genesis (DijkstraGenesis (..)) import Cardano.Ledger.Mary.Value qualified as Mary -import Cardano.Ledger.Plutus.Data qualified as L import Cardano.Ledger.Plutus.Language qualified as Plutus import Cardano.Slotting.EpochInfo qualified as Slotting import Cardano.Slotting.Slot qualified as Slotting diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs index 031a51d254..d6e0aa4f49 100644 --- a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/Scripts.hs @@ -21,7 +21,6 @@ import Cardano.Api.Serialise.Cbor (SerialiseAsCBOR (..)) import Cardano.Ledger.Conway qualified as L import Cardano.Ledger.Conway.Scripts qualified as L -import Cardano.Ledger.Core qualified as L import Cardano.Ledger.Dijkstra.Scripts qualified as L import Cardano.Ledger.Plutus.Language qualified as L From 1d0f02c0c6bfae88bf02e7af952719045c2afce1 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Tue, 11 Aug 2026 14:47:04 +0200 Subject: [PATCH 28/62] Fix redeemer pointer indexing in the experimental witness machinery Proposal redeemer pointers were computed against Ord-sorted order instead of the ledger's OSet insertion order, and certifying pointers did not count unwitnessed certificates' index slots. Both now follow the ledger's positional resolution, with regression tests pinning the behaviour and property tests checking every witnessable category's pointer against the ledger's own Indexable resolution. The same fix is applied to the deprecated legacy transaction builder (createTransactionBody); end-to-end and legacy-bridge regression properties now cover the deprecated path too. Also harden getVotes against voter-map gaps, remove the unused StakeCredential field from the Witnessable WitTxCert constructor, and correct the redeemer-index ordering documentation. --- ..._cardano_api_redeemer_pointer_indexing.yml | 8 + cardano-api/cardano-api.cabal | 2 + cardano-api/src/Cardano/Api/Compatible/Tx.hs | 9 +- .../Internal/IndexedPlutusScriptWitness.hs | 10 +- .../Tx/Internal/BodyContent/New.hs | 44 +- .../Tx/Internal/Certificate/Compatible.hs | 30 +- .../Api/Experimental/Tx/Internal/Fee.hs | 20 +- cardano-api/src/Cardano/Api/Tx.hs | 4 +- .../src/Cardano/Api/Tx/Internal/Body.hs | 23 +- .../Test/Cardano/Api/Experimental.hs | 145 +++- .../Transaction/Body/Plutus/RedeemerIndex.hs | 801 ++++++++++++++++++ .../test/cardano-api-test/cardano-api-test.hs | 2 + 12 files changed, 1050 insertions(+), 48 deletions(-) create mode 100644 .changes/20260811_cardano_api_redeemer_pointer_indexing.yml create mode 100644 cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/RedeemerIndex.hs diff --git a/.changes/20260811_cardano_api_redeemer_pointer_indexing.yml b/.changes/20260811_cardano_api_redeemer_pointer_indexing.yml new file mode 100644 index 0000000000..89427890e9 --- /dev/null +++ b/.changes/20260811_cardano_api_redeemer_pointer_indexing.yml @@ -0,0 +1,8 @@ +project: cardano-api +pr: 1288 +kind: + - bugfix + - breaking + - test +description: | + Fix plutus redeemer pointer indexing: proposal pointers now follow the transaction's insertion order and certificate pointers count unwitnessed certificates, in both the experimental and the deprecated transaction builders. Remove the unused StakeCredential field from the WitTxCert constructor. Add property tests checking every redeemer pointer against the ledger's own resolution. diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 196dbc83fa..54b27bff3c 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -376,6 +376,7 @@ test-suite cardano-api-test cardano-crypto, cardano-crypto-class:{cardano-crypto-class, testlib} ^>=2.5, cardano-crypto-wrapper:testlib, + cardano-data >=1.0, cardano-ledger-alonzo, cardano-ledger-api ^>=1.14, cardano-ledger-babbage, @@ -432,6 +433,7 @@ test-suite cardano-api-test Test.Cardano.Api.Orphans Test.Cardano.Api.RawBytes Test.Cardano.Api.Transaction.Autobalance + Test.Cardano.Api.Transaction.Body.Plutus.RedeemerIndex Test.Cardano.Api.Transaction.Body.Plutus.Scripts Test.Cardano.Api.Transaction.Collateral Test.Cardano.Api.Transaction.Fixtures diff --git a/cardano-api/src/Cardano/Api/Compatible/Tx.hs b/cardano-api/src/Cardano/Api/Compatible/Tx.hs index 6ec4714250..8d5541e30c 100644 --- a/cardano-api/src/Cardano/Api/Compatible/Tx.hs +++ b/cardano-api/src/Cardano/Api/Compatible/Tx.hs @@ -15,7 +15,6 @@ module Cardano.Api.Compatible.Tx ) where -import Cardano.Api.Address (StakeCredential) import Cardano.Api.Era import Cardano.Api.Experimental.AnyScriptWitness import Cardano.Api.Experimental.Era (obtainCommonConstraints) @@ -134,7 +133,7 @@ createCompatibleTx sbe ins outs extraDatums txFee' anyProtocolUpdate anyVote txC apiScriptWitnesses = [ (ix, witness) - | (ix, _, Just (_, witness)) <- indexedTxCerts + | (ix, _, Just witness) <- indexedTxCerts ] pure @@ -157,7 +156,7 @@ createCompatibleTx sbe ins outs extraDatums txFee' anyProtocolUpdate anyVote txC setRefInputs = do let refInputs = [ toShelleyTxIn refInput - | (_, _, Just (_, wit)) <- indexedTxCerts + | (_, _, Just wit) <- indexedTxCerts , refInput <- maybeToList $ getAnyWitnessReferenceInput wit ] @@ -178,7 +177,7 @@ createCompatibleTx sbe ins outs extraDatums txFee' anyProtocolUpdate anyVote txC indexedTxCerts :: [ ( ScriptWitnessIndex , Exp.Certificate (ShelleyLedgerEra era) - , Maybe (StakeCredential, Exp.AnyWitness (ShelleyLedgerEra era)) + , Maybe (Exp.AnyWitness (ShelleyLedgerEra era)) ) ] indexedTxCerts = indexTxCertificates txCertificates' @@ -334,7 +333,7 @@ indexTxCertificates :: Exp.TxCertificates (ShelleyLedgerEra era) -> [ ( ScriptWitnessIndex , Exp.Certificate (ShelleyLedgerEra era) - , Maybe (StakeCredential, AnyWitness (ShelleyLedgerEra era)) + , Maybe (AnyWitness (ShelleyLedgerEra era)) ) ] indexTxCertificates (Exp.TxCertificates certsWits) = diff --git a/cardano-api/src/Cardano/Api/Experimental/Plutus/Internal/IndexedPlutusScriptWitness.hs b/cardano-api/src/Cardano/Api/Experimental/Plutus/Internal/IndexedPlutusScriptWitness.hs index 0925b19f17..177d2589de 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Plutus/Internal/IndexedPlutusScriptWitness.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Plutus/Internal/IndexedPlutusScriptWitness.hs @@ -79,7 +79,6 @@ data Witnessable (thing :: WitnessableItem) era where WitTxCert :: (L.EraTxCert era, L.AlonzoEraScript era) => L.TxCert era - -> StakeCredential -> Witnessable CertItem era WitMint :: L.AlonzoEraScript era @@ -111,11 +110,16 @@ compareWitnesses :: Witnessable thing era -> Witnessable thing era -> Ordering compareWitnesses a b = case (a, b) of (WitTxIn txinA, WitTxIn txinB) -> compare txinA txinB - (WitTxCert{}, WitTxCert{}) -> LT -- Certificates in the ledger are in an `OSet` therefore we preserve the order. + -- Certificates are stored in an `OSet` but resolved positionally, via + -- `certsTxBodyL`'s `findIndexL`. `EQ` lets the stable sort in + -- `createIndexedPlutusScriptWitnesses` preserve insertion order. + (WitTxCert{}, WitTxCert{}) -> EQ (WitMint polIdA _, WitMint polIdB _) -> compare polIdA polIdB (WitWithdrawal stakeAddrA _, WitWithdrawal stakeAddrB _) -> compare stakeAddrA stakeAddrB (WitVote voterA, WitVote voterB) -> compare voterA voterB - (WitProposal propA, WitProposal propB) -> compare propA propB + -- Proposals are also stored in an `OSet` and resolved positionally + -- (`StrictSeq.findIndexL`), same as `WitTxCert` above. + (WitProposal{}, WitProposal{}) -> EQ data WitnessableItem = TxInItem diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs index 7d27525a79..bc198dda3d 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs @@ -6,7 +6,6 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} -{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} @@ -666,11 +665,12 @@ newtype TxWithdrawals era = TxWithdrawals {unTxWithdrawals :: [(StakeAddress, L. newtype TxCertificates era = TxCertificates - {unTxCertificates :: OMap (Exp.Certificate era) (Maybe (StakeCredential, AnyWitness era))} + {unTxCertificates :: OMap (Exp.Certificate era) (Maybe (AnyWitness era))} deriving (Show, Eq) --- | Create 'TxCertificates'. Note that 'Certificate era' will be deduplicated. Only Certificates with a --- stake credential will be in the result. +-- | Create 'TxCertificates'. Note that 'Certificate era' will be deduplicated. Certificates that +-- require a witness will be stored with 'Just' the caller-supplied witness; those that do not (e.g. +-- deposit-less stake registration in Conway) will be stored with 'Nothing'. -- -- Note that, when building a transaction in Conway era, a witness is not required for staking credential -- registration, but this is only the case during the transitional period of Conway era and only for staking @@ -686,10 +686,10 @@ mkTxCertificates era certs = TxCertificates . OMap.fromList $ map getStakeCred c getStakeCred :: (Exp.Certificate (LedgerEra era), AnyWitness (LedgerEra era)) -> ( Exp.Certificate (LedgerEra era) - , Maybe (StakeCredential, AnyWitness (LedgerEra era)) + , Maybe (AnyWitness (LedgerEra era)) ) getStakeCred (c@(Exp.Certificate cert), wit) = - (c, (,wit) <$> getTxCertWitness (convert era) (obtainCommonConstraints era cert)) + (c, wit <$ getTxCertWitness (convert era) (obtainCommonConstraints era cert)) newtype TxMintValue era = TxMintValue @@ -866,21 +866,30 @@ extractWitnessableTxIns tIns = obtainCommonConstraints (useEra @era) $ List.nub [(WitTxIn txin, wit) | (txin, wit) <- tIns] +-- | Wrap every certificate as a 'Witnessable', paired with its witness. +-- +-- An unwitnessed certificate still occupies a redeemer index slot: the +-- ledger indexes the 'Certifying' purpose by position in the full +-- certificate sequence, not just the witnessed subset, so the result below +-- keeps one entry per certificate in insertion order. +-- +-- In the Conway era only, a certificate may legitimately have no witness +-- (deposit-less stake registration), so a missing witness defaults to +-- 'AnyKeyWitnessPlaceholder'. From Dijkstra onwards 'mkTxCertificates' +-- guarantees every entry has a 'Just' witness, so the placeholder is dead +-- code for those eras. extractWitnessableCertificates :: forall era . IsEra era => TxCertificates (LedgerEra era) -> [(Witnessable CertItem (LedgerEra era), AnyWitness (LedgerEra era))] -extractWitnessableCertificates txCerts = +extractWitnessableCertificates (TxCertificates certs) = obtainCommonConstraints (useEra @era) $ List.nub - [ ( WitTxCert cert stakeCred - , wit - ) - | (Exp.Certificate cert, Just (stakeCred, wit)) <- getCertificates txCerts + [ (WitTxCert cert, wit) + | (Exp.Certificate cert, mWit) <- toList certs + , let wit = fromMaybe AnyKeyWitnessPlaceholder mWit ] - where - getCertificates (TxCertificates txcs) = toList txcs extractWitnessableMints :: forall era @@ -923,13 +932,20 @@ extractWitnessableVotes (Just txVoteProc) = | (vote, wit) <- getVotes txVoteProc ] where + -- Uses a total 'Map.findWithDefault' (placeholder witness on a miss), + -- not a lookup that skips missing voters. A skipped voter would shrink + -- this list and shift every later voter's redeemer index. + -- + -- 'mkTxVotingProcedures' builds 'scriptWitnessedVotes' in lockstep with + -- 'allVotingProcedures', assuming exactly one voter per merged + -- 'L.VotingProcedures' value, so a miss should not normally happen. getVotes :: TxVotingProcedures (LedgerEra era) -> [(L.Voter, AnyWitness (LedgerEra era))] getVotes (TxVotingProcedures allVotingProcedures scriptWitnessedVotes) = [ (voter, wit) | (voter, _) <- toList $ L.unVotingProcedures allVotingProcedures - , wit <- maybe [] return (Map.lookup voter scriptWitnessedVotes) + , let wit = Map.findWithDefault AnyKeyWitnessPlaceholder voter scriptWitnessedVotes ] extractWitnessableProposals diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs index a51335964c..99800f1432 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Certificate/Compatible.hs @@ -46,6 +46,8 @@ import Cardano.Api.Plutus.Internal.Script import Cardano.Ledger.Keys qualified as Ledger +import Control.Applicative + type family Delegatee era where Delegatee DijkstraEra = Ledger.Delegatee Delegatee ConwayEra = Ledger.Delegatee @@ -201,9 +203,25 @@ getTxCertWitness :: ShelleyBasedEra era -> Ledger.TxCert (ShelleyLedgerEra era) -> Maybe StakeCredential -getTxCertWitness sbe ledgerCert = shelleyBasedEraConstraints sbe $ - case Ledger.getVKeyWitnessTxCert ledgerCert of - Just keyHash -> Just $ StakeCredentialByKey $ Api.StakeKeyHash $ Ledger.coerceKeyRole keyHash - Nothing -> - StakeCredentialByScript . fromShelleyScriptHash - <$> Ledger.getScriptWitnessTxCert ledgerCert +getTxCertWitness sbe ledgerCert = mStakeCredByKey <|> mStakeCredByScript <|> witnessOptionalUpToConway + where + mStakeCredByKey = + shelleyBasedEraConstraints sbe $ + StakeCredentialByKey . Api.StakeKeyHash . Ledger.coerceKeyRole + <$> Ledger.getVKeyWitnessTxCert ledgerCert + mStakeCredByScript = + shelleyBasedEraConstraints sbe $ + StakeCredentialByScript . fromShelleyScriptHash <$> Ledger.getScriptWitnessTxCert ledgerCert + witnessOptionalUpToConway = + case sbe of + ShelleyBasedEraShelley -> Nothing + ShelleyBasedEraAllegra -> Nothing + ShelleyBasedEraMary -> Nothing + ShelleyBasedEraAlonzo -> Nothing + ShelleyBasedEraBabbage -> Nothing + ShelleyBasedEraConway -> Nothing + ShelleyBasedEraDijkstra -> + error + "getTxCertWitness: certificate has no witness in the Dijkstra era. \ + \From Dijkstra onwards every certificate requires a witness. \ + \This indicates a bug in the ledger's EraTxCert instance for this certificate type." diff --git a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs index 692113827b..f392f03785 100644 --- a/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs +++ b/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs @@ -1149,18 +1149,14 @@ substituteExecutionUnits :: [ ( Exp.Certificate (LedgerEra era) , Either (TxBodyErrorAutoBalance (LedgerEra era)) - ( Maybe - ( StakeCredential - , AnyWitness (LedgerEra era) - ) - ) + (Maybe (AnyWitness (LedgerEra era))) ) ] mappedScriptWitnesses = [ case mWit of Nothing -> (cert, Right Nothing) - Just (stakeCred, wit) -> - (cert, Just . (stakeCred,) <$> substituteExecUnits ix wit) + Just wit -> + (cert, Just <$> substituteExecUnits ix wit) | (ix, cert, mWit) <- indexTxCertificates txCerts ] TxCertificates . fromList <$> traverseScriptWitnesses mappedScriptWitnesses @@ -1272,14 +1268,16 @@ collectTxBodyScriptWitnesses [ (ix, wit) | (ix, _, _, Just wit@AnyScriptWitnessPlutus{}) <- fmap toAnyScriptWitness <$> indexTxWithdrawals txw ] - -- TODO: If this works you need to change the rest! + -- Unlike the other categories, this intentionally collects simple script + -- witnesses as well as Plutus ones, so that a script-witnessed certificate + -- is never reported as unwitnessed. scriptWitnessesCertificates :: TxCertificates (LedgerEra era) -> [(ScriptWitnessIndex, Exp.AnyScriptWitness (LedgerEra era))] scriptWitnessesCertificates txc = List.nub [ (ix, wit) - | (ix, _, Just (_, anyWit)) <- indexTxCertificates txc + | (ix, _, Just anyWit) <- indexTxCertificates txc , Just wit <- [toAnyScriptWitness anyWit] ] @@ -1366,7 +1364,7 @@ indexTxCertificates :: TxCertificates (LedgerEra era) -> [ ( ScriptWitnessIndex , Exp.Certificate (LedgerEra era) - , Maybe (StakeCredential, AnyWitness (LedgerEra era)) + , Maybe (AnyWitness (LedgerEra era)) ) ] indexTxCertificates (TxCertificates certsWits) = @@ -1782,7 +1780,7 @@ estimateTransactionKeyWitnessCount + case txCertificates of TxCertificates credWits -> length - [() | (_, Just (_, AnyKeyWitnessPlaceholder)) <- toList credWits] + [() | (_, Just AnyKeyWitnessPlaceholder) <- toList credWits] + case txProposalProcedures of Just (TxProposalProcedures m) -> OMap.size m diff --git a/cardano-api/src/Cardano/Api/Tx.hs b/cardano-api/src/Cardano/Api/Tx.hs index 297f56946e..afcc797a65 100644 --- a/cardano-api/src/Cardano/Api/Tx.hs +++ b/cardano-api/src/Cardano/Api/Tx.hs @@ -846,13 +846,13 @@ module Cardano.Api.Tx , fromShelleyMetadata , toShelleyMetadatum , fromShelleyMetadatum - -- Exported for testing - , extractWitnessableCertificates + -- Exported for testing and advanced use , extractWitnessableMints , extractWitnessableProposals , extractWitnessableTxIns , extractWitnessableVotes , extractWitnessableWithdrawals + , extractWitnessableCertificates -- Exporting for testing. Deprecate in the future. , legacyKeyWitnessEncode diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index adad880507..829c376f85 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -830,8 +830,8 @@ mkTxProposalProcedures proposals = do fromList $ map (second pure) proposals --- | Index proposal procedures by their order ('Ord'). --- | and filter out the ones that do not have a witness. +-- | Index proposal procedures by the order they appear in the transaction, +-- and filter out the ones that do not have a witness. indexTxProposalProcedures :: TxProposalProcedures BuildTx era -> [(ScriptWitnessIndex, L.ProposalProcedure (ShelleyLedgerEra era), ScriptWitness WitCtxStake era)] @@ -840,7 +840,7 @@ indexTxProposalProcedures proposals = | (proposal, Just (ix, scriptWitness)) <- indexWitnessedTxProposalProcedures proposals ] --- | Index proposal procedures by their order ('Ord'). +-- | Index proposal procedures by the order they appear in the transaction. indexWitnessedTxProposalProcedures :: TxProposalProcedures BuildTx era -> [ ( L.ProposalProcedure (ShelleyLedgerEra era) @@ -2465,6 +2465,17 @@ extractWitnessableWithdrawals aeon txWithdrawals = getWithdrawals TxWithdrawalsNone = [] getWithdrawals (TxWithdrawals _ txws) = txws +-- | Convert every certificate to a 'Witnessable', paired with its witness. +-- +-- Every certificate must stay in the result, witnessed or not: an +-- unwitnessed certificate still occupies a redeemer index slot, since the +-- ledger indexes the 'Certifying' purpose by position in the full +-- certificate sequence, not just the witnessed subset. See +-- 'indexCertificatesWith' for the same rule applied to the deprecated +-- indexing path. An unwitnessed certificate is paired with the old API's +-- inert stake witness, 'KeyWitness' 'KeyWitnessForStakeAddr' (the same +-- default 'mkTxCertificates' uses), from which +-- 'legacyWitnessToScriptRequirements' extracts no script requirement. extractWitnessableCertificates :: AlonzoEraOnwards era -> TxCertificates BuildTx era @@ -2472,10 +2483,10 @@ extractWitnessableCertificates extractWitnessableCertificates aeon txCertificates = alonzoEraOnwardsConstraints aeon $ List.nub - [ ( WitTxCert cert stakeCred - , BuildTxWith wit + [ ( WitTxCert cert + , BuildTxWith $ maybe (KeyWitness KeyWitnessForStakeAddr) snd mCredAndWit ) - | (Exp.Certificate cert, BuildTxWith (Just (stakeCred, wit))) <- getCertificates txCertificates + | (Exp.Certificate cert, BuildTxWith mCredAndWit) <- getCertificates txCertificates ] where getCertificates TxCertificatesNone = [] diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs index c23461d13b..b16d4682cd 100644 --- a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental.hs @@ -17,7 +17,11 @@ where import Cardano.Api qualified as Api import Cardano.Api.Experimental qualified as Exp import Cardano.Api.Experimental.AnyScriptWitness - ( AnyPlutusScriptWitness (AnyPlutusSpendingScriptWitness) + ( AnyPlutusScriptWitness + ( AnyPlutusCertifyingScriptWitness + , AnyPlutusProposingScriptWitness + , AnyPlutusSpendingScriptWitness + ) , PlutusSpendingScriptWitness (PlutusSpendingScriptWitnessV3) ) import Cardano.Api.Experimental.Era (convert) @@ -30,6 +34,7 @@ import Cardano.Api.Plutus qualified as Script import Cardano.Api.Tx (Tx (ShelleyTx)) import Cardano.Ledger.Address qualified as L +import Cardano.Ledger.Alonzo.TxWits qualified as Alonzo import Cardano.Ledger.Api qualified as UnexportedLedger import Cardano.Ledger.Babbage.TxBody qualified as L import Cardano.Ledger.Conway qualified as L @@ -58,7 +63,9 @@ import Test.Gen.Cardano.Api.Experimental (genAnyScript) import Test.Gen.Cardano.Api.Typed ( genAddressInEra , genPlutusScriptInEra + , genProposal , genSimpleScript + , genStakeCredential , genTx , genTxIn ) @@ -121,6 +128,12 @@ tests = [ testProperty "Plutus scripts without protocol params returns MakeUnsignedTxMissingProtocolParams" prop_makeUnsignedTx_plutus_without_pparams + , testProperty + "Proposal-procedure redeemer pointers follow OMap insertion order, not Ord order" + prop_makeUnsignedTx_proposal_redeemer_indices_follow_insertion_order + , testProperty + "Certifying redeemer indices count unwitnessed certs preceding a plutus-witnessed one" + prop_makeUnsignedTx_cert_redeemer_indices_count_unwitnessed_certs ] , testGroup "calcMinFeeRecursive" @@ -672,6 +685,136 @@ prop_makeUnsignedTx_plutus_without_pparams = H.propertyOnce $ do Exp.makeUnsignedTx Exp.ConwayEra txBodyContent H.=== Left Exp.MakeUnsignedTxMissingProtocolParams +-- | 'makeUnsignedTx' must index plutus-witnessed governance proposals' +-- redeemer pointers ('L.ConwayProposing') by insertion order, never by +-- 'Ord' order. Insertion order is what the ledger's 'OSet'-backed +-- 'proposalProceduresTxBodyL' stores them in. +-- +-- 'propA' and 'propB' only differ in 'pProcDeposit' (the first field +-- 'Ord' compares), chosen so 'propB' sorts before 'propA' by 'Ord' but is +-- inserted after it. A regression to 'Ord'-sorted indexing would swap +-- which redeemer lands at which index. +prop_makeUnsignedTx_proposal_redeemer_indices_follow_insertion_order :: Property +prop_makeUnsignedTx_proposal_redeemer_indices_follow_insertion_order = H.property $ do + scriptTxIn <- H.forAll genTxIn + baseA <- H.forAll (genProposal Api.ConwayEraOnwardsConway) + baseB <- H.forAll (genProposal Api.ConwayEraOnwardsConway) + let propA = baseA{L.pProcDeposit = 2_000_000} + propB = baseB{L.pProcDeposit = 1_000_000} + + mkRedeemer :: Integer -> Script.HashableScriptData + mkRedeemer n = Script.unsafeHashableScriptData $ Script.ScriptDataConstructor n [] + + mkProposingWitness redeemer = + Exp.AnyPlutusScriptWitness $ + AnyPlutusProposingScriptWitness $ + Exp.PlutusScriptWitness + Plutus.SPlutusV3 + (Exp.PReferenceScript scriptTxIn) + Exp.NoScriptDatum + redeemer + (Script.ExecutionUnits 0 0) + + txBodyContent = + Exp.defaultTxBodyContent + & Exp.setTxProtocolParams exampleProtocolParams + & Exp.setTxProposalProcedures + ( Exp.mkTxProposalProcedures + [ (propA, mkProposingWitness (mkRedeemer 1)) + , (propB, mkProposingWitness (mkRedeemer 2)) + ] + ) + & Exp.setTxFee 0 + + Exp.UnsignedTx ledgerTx <- H.evalEither $ Exp.makeUnsignedTx Exp.ConwayEra txBodyContent + + -- Sanity check: the body itself is in insertion order regardless of the + -- bug under test (the bug only affects redeemer indexing, not the body). + let bodyProposals = toList $ ledgerTx ^. L.bodyTxL . UnexportedLedger.proposalProceduresTxBodyL + bodyProposals H.=== [propA, propB] + + -- The redeemer map must key 'propA''s witness to index 0 and 'propB''s + -- to index 1 (insertion order). 'Ord'-sorted indexing would give the + -- opposite, since 'propB' has the smaller deposit and sorts first. + let redeemers = ledgerTx ^. L.witsTxL . Alonzo.rdmrsTxWitsL + expectedRedeemers = + L.Redeemers $ + Map.fromList + [ + ( L.ConwayProposing (L.AsIx 0) + , (Api.toAlonzoData (mkRedeemer 1), Api.toAlonzoExUnits (Script.ExecutionUnits 0 0)) + ) + , + ( L.ConwayProposing (L.AsIx 1) + , (Api.toAlonzoData (mkRedeemer 2), Api.toAlonzoExUnits (Script.ExecutionUnits 0 0)) + ) + ] + redeemers H.=== expectedRedeemers + +-- | 'makeUnsignedTx' must index a plutus-witnessed certificate's +-- 'L.ConwayCertifying' redeemer pointer by its position among all +-- certificates, witnessed and unwitnessed alike, never just among the +-- witnessed subset. +-- +-- 'unwitnessedCert' (a plain stake registration, which the ledger never +-- requires a witness for) is placed before 'witnessedCert'. If unwitnessed +-- certs were skipped when assigning indices, 'witnessedCert' would land +-- at index 0 instead of the correct index 1. +prop_makeUnsignedTx_cert_redeemer_indices_count_unwitnessed_certs :: Property +prop_makeUnsignedTx_cert_redeemer_indices_count_unwitnessed_certs = H.property $ do + stakeCred1 <- H.forAll genStakeCredential + stakeCred2 <- H.forAll genStakeCredential + scriptTxIn <- H.forAll genTxIn + let shelleyCred1 = Api.toShelleyStakeCredential stakeCred1 + shelleyCred2 = Api.toShelleyStakeCredential stakeCred2 + + -- Unwitnessed: a plain stake registration cert needs no witness. + unwitnessedCert = + Exp.Certificate $ L.ConwayTxCertDeleg (L.ConwayRegCert shelleyCred1 L.SNothing) + + -- Plutus-witnessed: a stake delegation cert witnessed by a plutus script. + witnessedCert = + Exp.Certificate $ + L.ConwayTxCertDeleg (L.ConwayDelegCert shelleyCred2 (L.DelegVote L.DRepAlwaysAbstain)) + + redeemer = Script.unsafeHashableScriptData $ Script.ScriptDataConstructor 0 [] + + certWitness = + Exp.AnyPlutusScriptWitness $ + AnyPlutusCertifyingScriptWitness $ + Exp.PlutusScriptWitness + Plutus.SPlutusV3 + (Exp.PReferenceScript scriptTxIn) + Exp.NoScriptDatum + redeemer + (Script.ExecutionUnits 0 0) + + certs = + Exp.mkTxCertificates + Exp.ConwayEra + [ (unwitnessedCert, Exp.AnyKeyWitnessPlaceholder) + , (witnessedCert, certWitness) + ] + + txBodyContent = + Exp.defaultTxBodyContent + & Exp.setTxCertificates certs + & Exp.setTxProtocolParams exampleProtocolParams + & Exp.setTxFee 0 + + Exp.UnsignedTx ledgerTx <- H.evalEither $ Exp.makeUnsignedTx Exp.ConwayEra txBodyContent + + let redeemers = ledgerTx ^. L.witsTxL . Alonzo.rdmrsTxWitsL + expectedRedeemers = + L.Redeemers $ + Map.fromList + [ + ( L.ConwayCertifying (L.AsIx 1) + , (Api.toAlonzoData redeemer, Api.toAlonzoExUnits (Script.ExecutionUnits 0 0)) + ) + ] + redeemers H.=== expectedRedeemers + -- --------------------------------------------------------------------------- -- Property tests for calcMinFeeRecursive -- --------------------------------------------------------------------------- diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/RedeemerIndex.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/RedeemerIndex.hs new file mode 100644 index 0000000000..ee96d9473a --- /dev/null +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Body/Plutus/RedeemerIndex.hs @@ -0,0 +1,801 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# OPTIONS_GHC -Wno-deprecations #-} + +-- | Checks that the redeemer pointer index the API assigns to a +-- plutus-witnessed item agrees with the ledger's own resolution of that +-- index. +-- +-- Each property builds the real ledger container for its category (a +-- 'Set', 'StrictSeq', 'OSet' or 'Map', via +-- 'Cardano.Ledger.Alonzo.TxBody.Indexable') and compares against it +-- directly. +-- +-- Unlike 'prop_extractAllIndexedPlutusScriptWitnesses' in +-- "Test.Cardano.Api.Transaction.Body.Plutus.Scripts", which just counts +-- extracted witnesses, these go through the real +-- 'Cardano.Api.Experimental.Tx.mkTxCertificates' / +-- 'mkTxProposalProcedures' / 'mkTxVotingProcedures' and matching +-- @extractWitnessable*@ / @extractWitnessableCertificates@ functions. +-- +-- 'prop_oldApiCertRedeemerIndexMatchesLedgerIndexable', +-- 'prop_oldApiProposalRedeemerIndexMatchesLedgerIndexable' and +-- 'prop_oldApiVoteRedeemerIndexMatchesLedgerIndexable' instead drive the +-- deprecated old API path, via 'Cardano.Api.Tx.mkTxCertificates' / +-- 'mkTxProposalProcedures' / 'mkTxVotingProcedures' and matching +-- @extractWitnessable*@ / @extractWitnessableCertificates@ functions from +-- "Cardano.Api.Tx.Internal.Body". +-- +-- 'prop_createTransactionBody_redeemer_pointers_match_ledger' checks the +-- same fix end-to-end: it builds a real 'Cardano.Api.TxBody' via the +-- deprecated 'Cardano.Api.createTransactionBody' and asks the ledger's +-- own 'Cardano.Ledger.Alonzo.TxBody.redeemerPointer' where each +-- plutus-witnessed certificate landed, rather than comparing against a +-- hand-built oracle. +module Test.Cardano.Api.Transaction.Body.Plutus.RedeemerIndex + ( tests + ) +where + +import Cardano.Api (TxIn) +import Cardano.Api qualified as Api +import Cardano.Api.Experimental +import Cardano.Api.Experimental.AnyScriptWitness +import Cardano.Api.Experimental.Plutus hiding (AnyPlutusScript (..)) +import Cardano.Api.Experimental.Tx qualified as Exp +import Cardano.Api.Ledger qualified as L +import Cardano.Api.Plutus qualified as Script + +import Cardano.Ledger.Alonzo.Scripts (AsItem (..)) +import Cardano.Ledger.Alonzo.TxBody (Indexable (..)) +import Cardano.Ledger.Keys (coerceKeyRole) +import Cardano.Ledger.Plutus.Language qualified as L + +import Prelude + +import Data.Foldable (for_) +import Data.Function ((&)) +import Data.List qualified as List +import Data.Map.Strict qualified as Map +import Data.Maybe.Strict (StrictMaybe (SJust, SNothing)) +import Data.OSet.Strict qualified as OSet +import Data.Sequence.Strict qualified as StrictSeq +import Data.Set qualified as Set +import Data.Word (Word32) + +import Test.Gen.Cardano.Api.Typed + ( genAddressInEra + , genPolicyAssets + , genPolicyId + , genProposal + , genStakeAddress + , genStakeCredential + , genTxIn + ) + +import Test.Cardano.Api.Orphans () + +import Hedgehog +import Hedgehog.Extras qualified as H +import Hedgehog.Gen qualified as Gen +import Hedgehog.Range qualified as Range +import Test.Tasty (TestTree, testGroup) +import Test.Tasty.Hedgehog (testProperty) + +tests :: TestTree +tests = + testGroup + "Test.Cardano.Api.Transaction.Body.Plutus.RedeemerIndex" + [ testProperty + "Input redeemer index matches ledger Indexable oracle" + prop_txInRedeemerIndexMatchesLedgerIndexable + , testProperty + "Certificate redeemer index matches ledger Indexable oracle" + prop_certRedeemerIndexMatchesLedgerIndexable + , testProperty + "Old API certificate redeemer index matches ledger Indexable oracle" + prop_oldApiCertRedeemerIndexMatchesLedgerIndexable + , testProperty + "createTransactionBody redeemer pointers match the ledger's own resolution" + prop_createTransactionBody_redeemer_pointers_match_ledger + , testProperty + "Proposal redeemer index matches ledger Indexable oracle" + prop_proposalRedeemerIndexMatchesLedgerIndexable + , testProperty + "Old API proposal redeemer index matches ledger Indexable oracle" + prop_oldApiProposalRedeemerIndexMatchesLedgerIndexable + , testProperty + "Withdrawal redeemer index matches ledger Indexable oracle" + prop_withdrawalRedeemerIndexMatchesLedgerIndexable + , testProperty + "Vote redeemer index matches ledger Indexable oracle" + prop_voteRedeemerIndexMatchesLedgerIndexable + , testProperty + "Old API vote redeemer index matches ledger Indexable oracle" + prop_oldApiVoteRedeemerIndexMatchesLedgerIndexable + , testProperty + "Mint redeemer index matches ledger Indexable oracle" + prop_mintRedeemerIndexMatchesLedgerIndexable + ] + +-- --------------------------------------------------------------------------- +-- Inputs: oracle container is a 'Set' of ledger 'L.TxIn', Ord-ranked. +-- --------------------------------------------------------------------------- + +prop_txInRedeemerIndexMatchesLedgerIndexable :: Property +prop_txInRedeemerIndexMatchesLedgerIndexable = property $ do + n <- forAll $ Gen.int (Range.linear 2 6) + txIns <- + take n + <$> forAll (Gen.filter ((>= n) . length) $ List.nub <$> Gen.list (Range.singleton (n + 3)) genTxIn) + referenceTxIn <- forAll genTxIn + flags <- forAll $ Gen.list (Range.singleton n) Gen.bool + pairs <- forAll $ Gen.shuffle (zip txIns flags) + + cover 20 "at least one witnessed input" $ any snd pairs + cover 20 "at least one unwitnessed input" $ not (all snd pairs) + + let toWit witnessed = if witnessed then sharedSpendingWitness referenceTxIn else Exp.AnyKeyWitnessPlaceholder + apiInputs = [(txIn, toWit witnessed) | (txIn, witnessed) <- pairs] + oracle = Set.fromList $ map (Api.toShelleyTxIn . fst) pairs + extracted = Exp.extractWitnessableTxIns @ConwayEra apiInputs + indexed = createIndexedPlutusScriptWitnesses extracted + + length indexed === length (filter snd pairs) + assertRedeemerMapSize extracted (length indexed) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitTxIn txIn -> do + idx <- H.nothingFail $ asSpendingIndex purpose + indexOf (AsItem (Api.toShelleyTxIn txIn)) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitTxIn always produces a ConwaySpending purpose" + failure :: PropertyT IO () + +-- --------------------------------------------------------------------------- +-- Certificates: oracle container is a 'StrictSeq' of ledger 'L.TxCert', positional +-- (insertion order), matching 'certsTxBodyL'. +-- --------------------------------------------------------------------------- + +-- | Certs are laid out as an unwitnessed prefix followed by a witnessed +-- suffix. Dropping unwitnessed certs in 'extractWitnessableCertificates' +-- would then deterministically shift the witnessed certs' indices, not +-- just occasionally. +prop_certRedeemerIndexMatchesLedgerIndexable :: Property +prop_certRedeemerIndexMatchesLedgerIndexable = property $ do + unwitnessedCount <- forAll $ Gen.int (Range.constant 0 4) + witnessedCount <- forAll $ Gen.int (Range.constant 1 4) + let total = unwitnessedCount + witnessedCount + creds <- + take total + <$> forAll + ( Gen.filter ((>= total) . length) $ + List.nub <$> Gen.list (Range.singleton (total + 3)) genStakeCredential + ) + shuffledCreds <- forAll $ Gen.shuffle creds + referenceTxIn <- forAll genTxIn + + let (unwitnessedCreds, witnessedCreds) = List.splitAt unwitnessedCount shuffledCreds + -- A plain stake registration without a deposit never carries a + -- witness ('getTxCertWitness' returns 'Nothing' for it): the + -- "unwitnessed" half. + mkUnwitnessedCert cred = L.ConwayTxCertDeleg $ L.ConwayRegCert (Api.toShelleyStakeCredential cred) SNothing + -- A stake delegation always carries a (possibly placeholder) + -- witness: the "witnessed" half. + mkWitnessedCert cred = + L.ConwayTxCertDeleg $ + L.ConwayDelegCert (Api.toShelleyStakeCredential cred) (L.DelegVote L.DRepAlwaysAbstain) + unwitnessedCerts = map mkUnwitnessedCert unwitnessedCreds + witnessedCerts = map mkWitnessedCert witnessedCreds + orderedCerts = unwitnessedCerts ++ witnessedCerts + + cover 20 "at least two witnessed certs" $ length witnessedCerts >= 2 + cover 20 "at least two unwitnessed certs" $ length unwitnessedCerts >= 2 + + let apiCerts = + [(Certificate cert, Exp.AnyKeyWitnessPlaceholder) | cert <- unwitnessedCerts] + ++ [(Certificate cert, sharedCertifyingWitness referenceTxIn) | cert <- witnessedCerts] + txCertificates = Exp.mkTxCertificates ConwayEra apiCerts + extracted = Exp.extractWitnessableCertificates @ConwayEra txCertificates + indexed = createIndexedPlutusScriptWitnesses extracted + oracle = StrictSeq.fromList orderedCerts + + length indexed === length witnessedCerts + assertRedeemerMapSize extracted (length indexed) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitTxCert cert -> do + idx <- H.nothingFail $ asCertifyingIndex purpose + indexOf (AsItem cert) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitTxCert always produces a ConwayCertifying purpose" + failure :: PropertyT IO () + +-- | Regression test for the deprecated old API path. Drives +-- 'Cardano.Api.Tx.mkTxCertificates' and 'extractWitnessableCertificates' +-- directly, rather than their experimental counterparts used by +-- 'prop_certRedeemerIndexMatchesLedgerIndexable' above. Certs are laid out +-- the same way, an unwitnessed prefix followed by a witnessed suffix, so +-- dropping the unwitnessed prefix shifts every witnessed cert's index. +prop_oldApiCertRedeemerIndexMatchesLedgerIndexable :: Property +prop_oldApiCertRedeemerIndexMatchesLedgerIndexable = property $ do + unwitnessedCount <- forAll $ Gen.int (Range.constant 0 4) + witnessedCount <- forAll $ Gen.int (Range.constant 1 4) + let total = unwitnessedCount + witnessedCount + creds <- + take total + <$> forAll + ( Gen.filter ((>= total) . length) $ + List.nub <$> Gen.list (Range.singleton (total + 3)) genStakeCredential + ) + shuffledCreds <- forAll $ Gen.shuffle creds + referenceTxIn <- forAll genTxIn + + let (unwitnessedCreds, witnessedCreds) = List.splitAt unwitnessedCount shuffledCreds + -- Same rule as 'prop_certRedeemerIndexMatchesLedgerIndexable': a plain + -- stake registration without a deposit never carries a witness. + mkUnwitnessedCert cred = L.ConwayTxCertDeleg $ L.ConwayRegCert (Api.toShelleyStakeCredential cred) SNothing + mkWitnessedCert cred = + L.ConwayTxCertDeleg $ + L.ConwayDelegCert (Api.toShelleyStakeCredential cred) (L.DelegVote L.DRepAlwaysAbstain) + unwitnessedCerts = map mkUnwitnessedCert unwitnessedCreds + witnessedCerts = map mkWitnessedCert witnessedCreds + orderedCerts = unwitnessedCerts ++ witnessedCerts + + cover 20 "at least two witnessed certs" $ length witnessedCerts >= 2 + cover 20 "at least two unwitnessed certs" $ length unwitnessedCerts >= 2 + + let apiCerts = + [(Certificate cert, Nothing) | cert <- unwitnessedCerts] + ++ [(Certificate cert, Just (oldApiStakeWitness referenceTxIn)) | cert <- witnessedCerts] + txCertificates = Api.mkTxCertificates Api.ShelleyBasedEraConway apiCerts + extracted = Api.extractWitnessableCertificates Api.AlonzoEraOnwardsConway txCertificates + oracle = StrictSeq.fromList orderedCerts + + indexed <- indexOldApiWitnessed Api.AlonzoEraOnwardsConway extracted + + length indexed === length witnessedCerts + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitTxCert cert -> do + idx <- H.nothingFail $ asCertifyingIndex purpose + indexOf (AsItem cert) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitTxCert always produces a ConwayCertifying purpose" + failure :: PropertyT IO () + +-- | End-to-end regression test for the deprecated old API path, one level +-- up from 'prop_oldApiCertRedeemerIndexMatchesLedgerIndexable': instead of +-- calling 'Api.extractWitnessableCertificates' directly, this drives it through +-- the real 'Cardano.Api.createTransactionBody' and asks the resulting +-- ledger 'L.TxBody' where each plutus-witnessed certificate's redeemer +-- landed via 'L.redeemerPointer', the ledger's own inverse of the indexing +-- this module tests. This catches a mismatch between the extractor and the +-- rest of body construction, not just a bug in the extractor itself. +prop_createTransactionBody_redeemer_pointers_match_ledger :: Property +prop_createTransactionBody_redeemer_pointers_match_ledger = property $ do + unwitnessedCount <- forAll $ Gen.int (Range.constant 0 4) + witnessedCount <- forAll $ Gen.int (Range.constant 1 4) + let total = unwitnessedCount + witnessedCount + creds <- + take total + <$> forAll + ( Gen.filter ((>= total) . length) $ + List.nub <$> Gen.list (Range.singleton (total + 3)) genStakeCredential + ) + shuffledCreds <- forAll $ Gen.shuffle creds + referenceTxIn <- forAll genTxIn + srcTxIn <- forAll genTxIn + destAddress <- forAll $ genAddressInEra Api.ShelleyBasedEraConway + + let (unwitnessedCreds, witnessedCreds) = List.splitAt unwitnessedCount shuffledCreds + -- Same rule as 'prop_certRedeemerIndexMatchesLedgerIndexable': a plain + -- stake registration without a deposit never carries a witness. + mkUnwitnessedCert cred = L.ConwayTxCertDeleg $ L.ConwayRegCert (Api.toShelleyStakeCredential cred) SNothing + mkWitnessedCert cred = + L.ConwayTxCertDeleg $ + L.ConwayDelegCert (Api.toShelleyStakeCredential cred) (L.DelegVote L.DRepAlwaysAbstain) + unwitnessedCerts = map mkUnwitnessedCert unwitnessedCreds + witnessedCerts = map mkWitnessedCert witnessedCreds + + cover 20 "at least two witnessed certs" $ length witnessedCerts >= 2 + cover 20 "at least two unwitnessed certs" $ length unwitnessedCerts >= 2 + + let + -- Every witnessed cert gets its own redeemer, tagged by its position + -- in 'witnessedCerts'. Unlike the shared 'oldApiStakeWitness' used + -- elsewhere in this module (whose content never matters, since those + -- properties only check index arithmetic), distinct redeemers here + -- let the assertion below pin each cert to *its own* map entry, not + -- merely to some entry: a hypothetical pointer swap between two + -- certs would go undetected with a shared redeemer, since both + -- entries would be identical. + mkRedeemer :: Integer -> Script.HashableScriptData + mkRedeemer tag = Script.unsafeHashableScriptData $ Script.ScriptDataConstructor tag [] + executionUnits = Script.ExecutionUnits 0 0 + mkWitness tag = + Script.PlutusScriptWitness + Script.PlutusScriptV3InConway + Script.PlutusScriptV3 + (Script.PReferenceScript referenceTxIn) + Script.NoScriptDatumForStake + (mkRedeemer tag) + executionUnits + witnessedCertsWithTags = zip witnessedCerts [0 ..] + + let apiCerts = + [(Certificate cert, Nothing) | cert <- unwitnessedCerts] + ++ [(Certificate cert, Just (mkWitness tag)) | (cert, tag) <- witnessedCertsWithTags] + txBodyContent = + Api.defaultTxBodyContent Api.ShelleyBasedEraConway + & Api.setTxIns [(srcTxIn, Api.BuildTxWith (Api.KeyWitness Api.KeyWitnessForSpending))] + & Api.setTxOuts + [ Api.TxOut + destAddress + (Api.lovelaceToTxOutValue Api.ShelleyBasedEraConway 10_000_000) + Api.TxOutDatumNone + Script.ReferenceScriptNone + ] + & Api.setTxFee (Api.TxFeeExplicit Api.ShelleyBasedEraConway 2_000_000) + & Api.setTxCertificates (Api.mkTxCertificates Api.ShelleyBasedEraConway apiCerts) + + Api.ShelleyTxBody _ builtLedgerBody _ builtScriptData _ _ <- + evalEither $ Api.createTransactionBody Api.ShelleyBasedEraConway txBodyContent + + case builtScriptData of + Api.TxBodyScriptData _ _ (L.Redeemers redeemerMap) -> do + Map.size redeemerMap === length witnessedCerts + + for_ witnessedCertsWithTags $ \(cert, tag) -> do + let expectedRedeemerPair = (Api.toAlonzoData (mkRedeemer tag), Api.toAlonzoExUnits executionUnits) + case L.redeemerPointer builtLedgerBody (L.mkCertifyingPurpose (AsItem cert)) of + SJust purposeIx -> Map.lookup purposeIx redeemerMap === Just expectedRedeemerPair + SNothing -> annotate "redeemerPointer returned Nothing for a plutus-witnessed cert" >> failure + Api.TxBodyNoScriptData -> + annotate + "impossible: Conway is Alonzo-onwards, createTransactionBody always attaches TxBodyScriptData" + >> failure + +-- --------------------------------------------------------------------------- +-- Proposals: oracle container is an 'OSet' of ledger 'L.ProposalProcedure', positional +-- (insertion order), matching 'proposalProceduresTxBodyL'. +-- --------------------------------------------------------------------------- + +-- | Insertion order is forced to be the exact reverse of 'Ord' order. +-- 'pProcDeposit' is the first field 'Ord' compares; making it strictly +-- decrease as each proposal is inserted guarantees every generated case +-- disagrees with Ord-based indexing, not just some of them. +prop_proposalRedeemerIndexMatchesLedgerIndexable :: Property +prop_proposalRedeemerIndexMatchesLedgerIndexable = property $ do + n <- forAll $ Gen.int (Range.linear 2 6) + baseProposals <- forAll $ Gen.list (Range.singleton n) (genProposal Api.ConwayEraOnwardsConway) + referenceTxIn <- forAll genTxIn + flags <- forAll $ Gen.list (Range.singleton n) Gen.bool + + let orderedProposals = + [ proposal{L.pProcDeposit = L.Coin (fromIntegral (n - i) * 1_000_000)} + | (i, proposal) <- zip [0 :: Int ..] baseProposals + ] + + cover 20 "at least one witnessed proposal" $ or flags + cover 20 "at least one unwitnessed proposal" $ not (and flags) + + let toWit witnessed = if witnessed then sharedProposingWitness referenceTxIn else Exp.AnyKeyWitnessPlaceholder + apiProposals = zipWith (\proposal witnessed -> (proposal, toWit witnessed)) orderedProposals flags + txProposals = Exp.mkTxProposalProcedures @ConwayEra apiProposals + extracted = Exp.extractWitnessableProposals @ConwayEra (Just txProposals) + indexed = createIndexedPlutusScriptWitnesses extracted + oracle = OSet.fromList orderedProposals + + length indexed === length (filter id flags) + assertRedeemerMapSize extracted (length indexed) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitProposal proposal -> do + idx <- H.nothingFail $ asProposingIndex purpose + indexOf (AsItem proposal) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitProposal always produces a ConwayProposing purpose" + failure :: PropertyT IO () + +-- | Regression test for the deprecated old API path. Drives +-- 'Cardano.Api.Tx.mkTxProposalProcedures' and +-- 'Cardano.Api.Tx.Internal.Body.extractWitnessableProposals' directly, +-- rather than their experimental counterparts used by +-- 'prop_proposalRedeemerIndexMatchesLedgerIndexable' above. Same insertion +-- order trick, with a mix of witnessed and unwitnessed proposals. +prop_oldApiProposalRedeemerIndexMatchesLedgerIndexable :: Property +prop_oldApiProposalRedeemerIndexMatchesLedgerIndexable = property $ do + n <- forAll $ Gen.int (Range.linear 2 6) + baseProposals <- forAll $ Gen.list (Range.singleton n) (genProposal Api.ConwayEraOnwardsConway) + referenceTxIn <- forAll genTxIn + flags <- forAll $ Gen.list (Range.singleton n) Gen.bool + + let orderedProposals = + [ proposal{L.pProcDeposit = L.Coin (fromIntegral (n - i) * 1_000_000)} + | (i, proposal) <- zip [0 :: Int ..] baseProposals + ] + + cover 20 "at least one witnessed proposal" $ or flags + cover 20 "at least one unwitnessed proposal" $ not (and flags) + + let toWit witnessed = if witnessed then Just (oldApiStakeWitness referenceTxIn) else Nothing + apiProposals = zipWith (\proposal witnessed -> (proposal, toWit witnessed)) orderedProposals flags + txProposals = Api.mkTxProposalProcedures @ConwayEra apiProposals + extracted = + Api.extractWitnessableProposals + Api.ConwayEraOnwardsConway + (Just (Api.Featured Api.ConwayEraOnwardsConway txProposals)) + oracle = OSet.fromList orderedProposals + + indexed <- indexOldApiWitnessed Api.AlonzoEraOnwardsConway extracted + + length indexed === length (filter id flags) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitProposal proposal -> do + idx <- H.nothingFail $ asProposingIndex purpose + indexOf (AsItem proposal) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitProposal always produces a ConwayProposing purpose" + failure :: PropertyT IO () + +-- --------------------------------------------------------------------------- +-- Withdrawals: oracle container is a 'Map' of ledger reward accounts, Ord-ranked, +-- matching 'unWithdrawals' of 'withdrawalsTxBodyL'. +-- --------------------------------------------------------------------------- + +prop_withdrawalRedeemerIndexMatchesLedgerIndexable :: Property +prop_withdrawalRedeemerIndexMatchesLedgerIndexable = property $ do + n <- forAll $ Gen.int (Range.linear 2 6) + addrs <- + take n + <$> forAll + (Gen.filter ((>= n) . length) $ List.nub <$> Gen.list (Range.singleton (n + 3)) genStakeAddress) + coins <- forAll $ Gen.list (Range.singleton n) (L.Coin <$> Gen.integral (Range.linear 1 10_000_000)) + referenceTxIn <- forAll genTxIn + flags <- forAll $ Gen.list (Range.singleton n) Gen.bool + shuffled <- forAll $ Gen.shuffle (zip3 addrs coins flags) + + cover 20 "at least one witnessed withdrawal" $ any (\(_, _, w) -> w) shuffled + cover 20 "at least one unwitnessed withdrawal" $ any (\(_, _, w) -> not w) shuffled + + let toWit witnessed = if witnessed then sharedWithdrawingWitness referenceTxIn else Exp.AnyKeyWitnessPlaceholder + apiWithdrawals = Exp.TxWithdrawals [(addr, coin, toWit w) | (addr, coin, w) <- shuffled] + extracted = Exp.extractWitnessableWithdrawals @ConwayEra apiWithdrawals + indexed = createIndexedPlutusScriptWitnesses extracted + oracle = Map.fromList [(Api.toShelleyStakeAddr addr, coin) | (addr, coin, _) <- shuffled] + + length indexed === length (filter (\(_, _, w) -> w) shuffled) + assertRedeemerMapSize extracted (length indexed) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitWithdrawal addr _coin -> do + idx <- H.nothingFail $ asRewardingIndex purpose + indexOf (AsItem (Api.toShelleyStakeAddr addr)) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitWithdrawal always produces a ConwayRewarding purpose" + failure :: PropertyT IO () + +-- --------------------------------------------------------------------------- +-- Votes: oracle container is a ledger 'L.VotingProcedures' (Map-derived), Ord-ranked on +-- the voter, matching the 'Indexable Voter (VotingProcedures era)' instance. +-- --------------------------------------------------------------------------- + +prop_voteRedeemerIndexMatchesLedgerIndexable :: Property +prop_voteRedeemerIndexMatchesLedgerIndexable = property $ do + n <- forAll $ Gen.int (Range.linear 2 6) + voters <- + take n + <$> forAll (Gen.filter ((>= n) . length) $ List.nub <$> Gen.list (Range.singleton (n + 3)) genVoter) + referenceTxIn <- forAll genTxIn + govActionId <- forAll genGovActionId + flags <- forAll $ Gen.list (Range.singleton n) Gen.bool + shuffled <- forAll $ Gen.shuffle (zip voters flags) + + cover 20 "at least one witnessed vote" $ any snd shuffled + cover 20 "at least one unwitnessed vote" $ not (all snd shuffled) + + let toWit witnessed = if witnessed then sharedVotingWitness referenceTxIn else Exp.AnyKeyWitnessPlaceholder + votingProcedure = L.VotingProcedure L.VoteYes SNothing + votingProcedurePairs = + [ (L.VotingProcedures (Map.singleton voter (Map.singleton govActionId votingProcedure)), toWit w) + | (voter, w) <- shuffled + ] + + txVotingProcedures <- + H.leftFail $ Exp.mkTxVotingProcedures @(LedgerEra ConwayEra) votingProcedurePairs + + let extracted = Exp.extractWitnessableVotes @ConwayEra (Just txVotingProcedures) + indexed = createIndexedPlutusScriptWitnesses extracted + oracle = + L.VotingProcedures $ + Map.fromList [(voter, Map.singleton govActionId votingProcedure) | (voter, _) <- shuffled] + + length indexed === length (filter snd shuffled) + assertRedeemerMapSize extracted (length indexed) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitVote voter -> do + idx <- H.nothingFail $ asVotingIndex purpose + indexOf (AsItem voter) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitVote always produces a ConwayVoting purpose" + failure :: PropertyT IO () + +-- | Regression test for the deprecated old API path. Drives +-- 'Cardano.Api.Tx.mkTxVotingProcedures' and +-- 'Cardano.Api.Tx.Internal.Body.extractWitnessableVotes' directly, rather +-- than their experimental counterparts used by +-- 'prop_voteRedeemerIndexMatchesLedgerIndexable' above. Same witness map +-- with some voters missing. +prop_oldApiVoteRedeemerIndexMatchesLedgerIndexable :: Property +prop_oldApiVoteRedeemerIndexMatchesLedgerIndexable = property $ do + n <- forAll $ Gen.int (Range.linear 2 6) + voters <- + take n + <$> forAll (Gen.filter ((>= n) . length) $ List.nub <$> Gen.list (Range.singleton (n + 3)) genVoter) + referenceTxIn <- forAll genTxIn + govActionId <- forAll genGovActionId + flags <- forAll $ Gen.list (Range.singleton n) Gen.bool + shuffled <- forAll $ Gen.shuffle (zip voters flags) + + cover 20 "at least one witnessed vote" $ any snd shuffled + cover 20 "at least one unwitnessed vote" $ not (all snd shuffled) + + let votingProcedure = L.VotingProcedure L.VoteYes SNothing + toWit witnessed = if witnessed then Just (oldApiStakeWitness referenceTxIn) else Nothing + votingProcedurePairs = + [ ( Api.VotingProcedures + (L.VotingProcedures (Map.singleton voter (Map.singleton govActionId votingProcedure))) + , toWit w + ) + | (voter, w) <- shuffled + ] + + txVotingProcedures <- + H.leftFail $ Api.mkTxVotingProcedures @Api.BuildTx @ConwayEra votingProcedurePairs + + let extracted = + Api.extractWitnessableVotes + Api.ConwayEraOnwardsConway + (Just (Api.Featured Api.ConwayEraOnwardsConway txVotingProcedures)) + oracle = + L.VotingProcedures $ + Map.fromList [(voter, Map.singleton govActionId votingProcedure) | (voter, _) <- shuffled] + + indexed <- indexOldApiWitnessed Api.AlonzoEraOnwardsConway extracted + + length indexed === length (filter snd shuffled) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitVote voter -> do + idx <- H.nothingFail $ asVotingIndex purpose + indexOf (AsItem voter) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitVote always produces a ConwayVoting purpose" + failure :: PropertyT IO () + +-- --------------------------------------------------------------------------- +-- Mint: oracle container is a 'Set' of ledger 'L.PolicyID', Ord-ranked, +-- matching 'mintedTxBodyF'. Minting has no key-witness placeholder: every +-- policy is witnessed by some script, so "unwitnessed" here means +-- simple-script-witnessed, not plutus-witnessed. +-- --------------------------------------------------------------------------- + +prop_mintRedeemerIndexMatchesLedgerIndexable :: Property +prop_mintRedeemerIndexMatchesLedgerIndexable = property $ do + n <- forAll $ Gen.int (Range.linear 2 6) + policyIds <- + take n + <$> forAll (Gen.filter ((>= n) . length) $ List.nub <$> Gen.list (Range.singleton (n + 3)) genPolicyId) + assetsList <- forAll $ Gen.list (Range.singleton n) genPolicyAssets + referenceTxIn <- forAll genTxIn + flags <- forAll $ Gen.list (Range.singleton n) Gen.bool + shuffled <- forAll $ Gen.shuffle (zip3 policyIds assetsList flags) + + cover 20 "at least one plutus-witnessed policy" $ any (\(_, _, w) -> w) shuffled + cover 20 "at least one simple-script-witnessed policy" $ any (\(_, _, w) -> not w) shuffled + + let toWit witnessed = + if witnessed + then sharedMintingWitness referenceTxIn + else AnyScriptWitnessSimple (SReferenceScript referenceTxIn) + mintValue = Exp.TxMintValue $ Map.fromList [(pid, (assets, toWit w)) | (pid, assets, w) <- shuffled] + extractedRaw = Exp.extractWitnessableMints @ConwayEra mintValue + extracted = [(wit, anyScriptWitnessToAnyWitness sw) | (wit, sw) <- extractedRaw] + indexed = createIndexedPlutusScriptWitnesses extracted + oracle = Set.fromList [toLedgerPolicyID pid | (pid, _, _) <- shuffled] + + length indexed === length (filter (\(_, _, w) -> w) shuffled) + assertRedeemerMapSize extracted (length indexed) + + for_ indexed $ \(AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness witnessable purpose _)) -> + case witnessable of + WitMint policyId _assets -> do + idx <- H.nothingFail $ asMintingIndex purpose + indexOf (AsItem (toLedgerPolicyID policyId)) oracle === SJust (L.AsIx idx) + _ -> do + annotate "impossible: WitMint always produces a ConwayMinting purpose" + failure :: PropertyT IO () + +-- --------------------------------------------------------------------------- +-- Purpose index extraction (pure, one per category) +-- --------------------------------------------------------------------------- + +-- TODO: replace these projections with toPlutusScriptPurposeIndex (added on master in +-- 284d0bd5dd, after this branch's fork point) when the branch is rebased. + +-- | Each function matches one expected 'L.ConwayPlutusPurpose' constructor +-- and falls back to 'Nothing' for the rest (statically unreachable, but +-- not provably so to GHC). Same defensive-wildcard pattern as elsewhere +-- in the ledger/api integration; see AGENTS.md's GADT gotchas. +asSpendingIndex + , asCertifyingIndex + , asProposingIndex + , asRewardingIndex + , asVotingIndex + , asMintingIndex + :: L.PlutusPurpose L.AsIx (LedgerEra ConwayEra) -> Maybe Word32 +asSpendingIndex (L.ConwaySpending (L.AsIx idx)) = Just idx +asSpendingIndex _ = Nothing +asCertifyingIndex (L.ConwayCertifying (L.AsIx idx)) = Just idx +asCertifyingIndex _ = Nothing +asProposingIndex (L.ConwayProposing (L.AsIx idx)) = Just idx +asProposingIndex _ = Nothing +asRewardingIndex (L.ConwayRewarding (L.AsIx idx)) = Just idx +asRewardingIndex _ = Nothing +asVotingIndex (L.ConwayVoting (L.AsIx idx)) = Just idx +asVotingIndex _ = Nothing +asMintingIndex (L.ConwayMinting (L.AsIx idx)) = Just idx +asMintingIndex _ = Nothing + +-- | Run the shared old-API legacy-witness pipeline: convert extracted +-- witnessable/witness pairs into indexed plutus script witnesses, and +-- check the redeemer map has exactly one entry per indexed witness. +-- +-- Shared by every old-API regression property above +-- ('prop_oldApiCertRedeemerIndexMatchesLedgerIndexable', +-- 'prop_oldApiProposalRedeemerIndexMatchesLedgerIndexable', +-- 'prop_oldApiVoteRedeemerIndexMatchesLedgerIndexable') to avoid a +-- three-way copy of the "convert, index, assert-size" glue between the +-- cert, proposal and vote twins. +indexOldApiWitnessed + :: (MonadTest m, L.AlonzoEraScript (Api.ShelleyLedgerEra era)) + => Api.AlonzoEraOnwards era + -> [ ( Witnessable witnessable (Api.ShelleyLedgerEra era) + , Api.BuildTxWith Api.BuildTx (Script.Witness ctx era) + ) + ] + -> m [AnyIndexedPlutusScriptWitness (Api.ShelleyLedgerEra era)] +indexOldApiWitnessed aeon extracted = do + converted <- H.leftFail $ legacyWitnessConversion aeon extracted + let indexed = createIndexedPlutusScriptWitnesses converted + assertRedeemerMapSize converted (length indexed) + pure indexed + +-- | Sanity check: the redeemer map's size must equal exactly the count of +-- plutus-witnessed items extracted (nothing extra, nothing missing). +assertRedeemerMapSize + :: (MonadTest m, L.AlonzoEraScript era) + => [(Witnessable witnessable era, Exp.AnyWitness era)] + -> Int + -> m () +assertRedeemerMapSize extracted expectedCount = do + let L.Redeemers redeemerMap = getAnyWitnessRedeemerPointerMap extracted + Map.size redeemerMap === expectedCount + +-- --------------------------------------------------------------------------- +-- Shared witness/redeemer fixtures +-- --------------------------------------------------------------------------- + +-- | The single Plutus witness reused for every plutus-witnessed item in +-- this module. +-- +-- Witness content (redeemer, execution units, reference script) has no +-- bearing on redeemer indexing. Only the witnessed item's identity and +-- whether it is witnessed at all matter, so one shared witness suffices. +sharedPlutusScriptWitness + :: TxIn -> PlutusScriptWitness L.PlutusV3 purpose (LedgerEra ConwayEra) +sharedPlutusScriptWitness referenceTxIn = + PlutusScriptWitness + L.SPlutusV3 + (PReferenceScript referenceTxIn) + NoScriptDatum + sharedRedeemer + sharedExecutionUnits + where + sharedRedeemer = Script.unsafeHashableScriptData $ Script.ScriptDataConstructor 0 [] + sharedExecutionUnits = Script.ExecutionUnits 0 0 + +sharedSpendingWitness :: TxIn -> Exp.AnyWitness (LedgerEra ConwayEra) +sharedSpendingWitness referenceTxIn = + Exp.AnyPlutusScriptWitness $ + AnyPlutusSpendingScriptWitness $ + PlutusSpendingScriptWitnessV3 (sharedPlutusScriptWitness referenceTxIn) + +sharedCertifyingWitness :: TxIn -> Exp.AnyWitness (LedgerEra ConwayEra) +sharedCertifyingWitness referenceTxIn = + Exp.AnyPlutusScriptWitness $ + AnyPlutusCertifyingScriptWitness (sharedPlutusScriptWitness referenceTxIn) + +sharedProposingWitness :: TxIn -> Exp.AnyWitness (LedgerEra ConwayEra) +sharedProposingWitness referenceTxIn = + Exp.AnyPlutusScriptWitness $ + AnyPlutusProposingScriptWitness (sharedPlutusScriptWitness referenceTxIn) + +sharedWithdrawingWitness :: TxIn -> Exp.AnyWitness (LedgerEra ConwayEra) +sharedWithdrawingWitness referenceTxIn = + Exp.AnyPlutusScriptWitness $ + AnyPlutusWithdrawingScriptWitness (sharedPlutusScriptWitness referenceTxIn) + +sharedVotingWitness :: TxIn -> Exp.AnyWitness (LedgerEra ConwayEra) +sharedVotingWitness referenceTxIn = + Exp.AnyPlutusScriptWitness $ AnyPlutusVotingScriptWitness (sharedPlutusScriptWitness referenceTxIn) + +sharedMintingWitness :: TxIn -> AnyScriptWitness (LedgerEra ConwayEra) +sharedMintingWitness referenceTxIn = + AnyScriptWitnessPlutus $ AnyPlutusMintingScriptWitness (sharedPlutusScriptWitness referenceTxIn) + +-- | The old API's counterpart to 'sharedCertifyingWitness' / +-- 'sharedProposingWitness' / 'sharedVotingWitness'. Unlike the experimental +-- API, the old API has no separate witness type per purpose: certificates, +-- proposals and votes are all witnessed under 'Script.WitCtxStake', so one +-- shared witness value covers all three old-API regression properties +-- ('prop_oldApiCertRedeemerIndexMatchesLedgerIndexable', +-- 'prop_oldApiProposalRedeemerIndexMatchesLedgerIndexable', +-- 'prop_oldApiVoteRedeemerIndexMatchesLedgerIndexable'). Witness content has +-- no bearing on redeemer indexing (see 'sharedPlutusScriptWitness'), so this +-- is built directly rather than shared with the experimental fixtures above. +oldApiStakeWitness :: TxIn -> Script.ScriptWitness Script.WitCtxStake ConwayEra +oldApiStakeWitness referenceTxIn = + Script.PlutusScriptWitness + Script.PlutusScriptV3InConway + Script.PlutusScriptV3 + (Script.PReferenceScript referenceTxIn) + Script.NoScriptDatumForStake + sharedRedeemer + sharedExecutionUnits + where + sharedRedeemer = Script.unsafeHashableScriptData $ Script.ScriptDataConstructor 0 [] + sharedExecutionUnits = Script.ExecutionUnits 0 0 + +-- --------------------------------------------------------------------------- +-- Small generators not already provided by Test.Gen.Cardano.Api.Typed +-- --------------------------------------------------------------------------- + +-- | 'genStakeCredential' only ever produces 'StakeCredentialByKey', so converting to +-- ledger and coercing the key role never actually fails the pattern match below. +genVoter :: Gen L.Voter +genVoter = do + cred <- Api.toShelleyStakeCredential <$> genStakeCredential + case cred of + L.KeyHashObj keyHash -> + Gen.element + [ L.CommitteeVoter (L.KeyHashObj (coerceKeyRole keyHash)) + , L.DRepVoter (L.KeyHashObj (coerceKeyRole keyHash)) + , L.StakePoolVoter (coerceKeyRole keyHash) + ] + L.ScriptHashObj{} -> Gen.discard + +-- | The governance action a vote targets has no bearing on redeemer indexing (only the +-- voter's identity does), so one fixed action id shared by every generated vote is fine. +genGovActionId :: Gen L.GovActionId +genGovActionId = do + L.TxIn txId _ <- Api.toShelleyTxIn <$> genTxIn + pure $ L.GovActionId txId (L.GovActionIx 0) + +toLedgerPolicyID :: Api.PolicyId -> L.PolicyID +toLedgerPolicyID (Api.PolicyId scriptHash) = L.PolicyID (Script.toShelleyScriptHash scriptHash) diff --git a/cardano-api/test/cardano-api-test/cardano-api-test.hs b/cardano-api/test/cardano-api-test/cardano-api-test.hs index dd9d1e4796..be1678907f 100644 --- a/cardano-api/test/cardano-api-test/cardano-api-test.hs +++ b/cardano-api/test/cardano-api-test/cardano-api-test.hs @@ -29,6 +29,7 @@ import Test.Cardano.Api.NodeConfig qualified import Test.Cardano.Api.Ord qualified import Test.Cardano.Api.RawBytes qualified import Test.Cardano.Api.Transaction.Autobalance qualified +import Test.Cardano.Api.Transaction.Body.Plutus.RedeemerIndex qualified import Test.Cardano.Api.Transaction.Body.Plutus.Scripts qualified import Test.Cardano.Api.Transaction.Collateral qualified import Test.Cardano.Api.TxBody qualified @@ -71,6 +72,7 @@ tests = , Test.Cardano.Api.NodeConfig.tests , Test.Cardano.Api.Ord.tests , Test.Cardano.Api.RawBytes.tests + , Test.Cardano.Api.Transaction.Body.Plutus.RedeemerIndex.tests , Test.Cardano.Api.Transaction.Body.Plutus.Scripts.tests , Test.Cardano.Api.Transaction.Autobalance.tests , Test.Cardano.Api.Transaction.Collateral.tests From fe07f65fa11c7ea9ed5493583bc685a79488c2f9 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Wed, 19 Aug 2026 18:42:47 +0200 Subject: [PATCH 29/62] cardano-rpc: Update UTxO RPC v1beta protos to latest upstream spec Sync the vendored proto definitions with utxorpc/spec main (v0.19.2 plus unreleased EvalReport tweaks): governance vote messages and Tx.votes, TxOutput.original_cbor, the ReadState ledger-state query machinery, and all upstream service methods restored in the service blocks. Regenerate the proto-lens code with buf. --- .../Proto/Utxorpc/V1beta/Cardano/Cardano.hs | 5722 +++++++++++------ .../Utxorpc/V1beta/Cardano/Cardano_Fields.hs | 109 + .../gen/Proto/Utxorpc/V1beta/Query/Query.hs | 1496 ++++- .../Utxorpc/V1beta/Query/Query_Fields.hs | 22 + .../gen/Proto/Utxorpc/V1beta/Submit/Submit.hs | 106 +- .../utxorpc/v1beta/cardano/cardano.proto | 71 +- .../proto/utxorpc/v1beta/query/query.proto | 32 +- .../proto/utxorpc/v1beta/submit/submit.proto | 5 +- 8 files changed, 5279 insertions(+), 2284 deletions(-) diff --git a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano.hs b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano.hs index 51c1c52e12..8a4c546f89 100644 --- a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano.hs +++ b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano.hs @@ -37,8 +37,8 @@ module Proto.Utxorpc.V1beta.Cardano.Cardano ( Genesis'BootStakeholdersEntry(), Genesis'GenDelegsEntry(), Genesis'HeavyDelegationEntry(), Genesis'InitialFundsEntry(), Genesis'NonAvvmBalancesEntry(), Genesis'VssCertsEntry(), - GenesisKeyDelegationCert(), GovernanceAction(), - GovernanceAction'GovernanceAction(..), + GenesisKeyDelegationCert(), GetStakePoolDistribution(), + GovernanceAction(), GovernanceAction'GovernanceAction(..), _GovernanceAction'ParameterChangeAction, _GovernanceAction'HardForkInitiationAction, _GovernanceAction'TreasuryWithdrawalsAction, @@ -64,8 +64,8 @@ module Proto.Utxorpc.V1beta.Cardano.Cardano ( _PlutusData'Array, PlutusDataArray(), PlutusDataMap(), PlutusDataPair(), PoolMetadata(), PoolRegistrationCert(), PoolRegistrationPattern(), PoolRetirementCert(), - PoolRetirementPattern(), PoolVotingThresholds(), ProtocolConsts(), - ProtocolVersion(), RationalNumber(), Redeemer(), + PoolRetirementPattern(), PoolStakeShare(), PoolVotingThresholds(), + ProtocolConsts(), ProtocolVersion(), RationalNumber(), Redeemer(), RedeemerPurpose(..), RedeemerPurpose(), RedeemerPurpose'UnrecognizedValue, RegCert(), RegDRepCert(), Relay(), ResignCommitteeColdCert(), Script(), Script'Script(..), @@ -74,12 +74,18 @@ module Proto.Utxorpc.V1beta.Cardano.Cardano ( StakeCredential(), StakeCredential'StakeCredential(..), _StakeCredential'AddrKeyHash, _StakeCredential'ScriptHash, StakeDelegationCert(), StakeDelegationPattern(), - StakeRegDelegCert(), StakeVoteDelegCert(), StakeVoteRegDelegCert(), + StakePoolDistribution(), StakeRegDelegCert(), StakeVoteDelegCert(), + StakeVoteRegDelegCert(), StateData(), StateData'Result(..), + _StateData'StakePoolDistribution, StateQuery(), + StateQuery'Query(..), _StateQuery'StakePoolDistribution, TreasuryWithdrawalsAction(), Tx(), TxEval(), TxFeePolicy(), TxInput(), TxOutput(), TxOutputPattern(), TxPattern(), TxValidity(), UnRegCert(), UnRegDRepCert(), - UpdateCommitteeAction(), UpdateDRepCert(), VKeyWitness(), - VoteDelegCert(), VoteRegDelegCert(), VotingThresholds(), VssCert(), + UpdateCommitteeAction(), UpdateDRepCert(), VKeyWitness(), Vote(..), + Vote(), Vote'UnrecognizedValue, VoteDelegCert(), + VoteRegDelegCert(), VoterVotes(), VoterVotes'Voter(..), + _VoterVotes'ConstitutionalCommittee, _VoterVotes'Drep, + _VoterVotes'Spo, VotingProcedure(), VotingThresholds(), VssCert(), Withdrawal(), WithdrawalAmount(), WitnessSet() ) where import qualified Data.ProtoLens.Runtime.Control.DeepSeq as Control.DeepSeq @@ -13246,6 +13252,143 @@ instance Control.DeepSeq.NFData GenesisKeyDelegationCert where (_GenesisKeyDelegationCert'vrfKeyhash x__) ()))) {- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.poolKeyhashes' @:: Lens' GetStakePoolDistribution [Data.ByteString.ByteString]@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'poolKeyhashes' @:: Lens' GetStakePoolDistribution (Data.Vector.Vector Data.ByteString.ByteString)@ -} +data GetStakePoolDistribution + = GetStakePoolDistribution'_constructor {_GetStakePoolDistribution'poolKeyhashes :: !(Data.Vector.Vector Data.ByteString.ByteString), + _GetStakePoolDistribution'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show GetStakePoolDistribution where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +instance Data.ProtoLens.Field.HasField GetStakePoolDistribution "poolKeyhashes" [Data.ByteString.ByteString] where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _GetStakePoolDistribution'poolKeyhashes + (\ x__ y__ -> x__ {_GetStakePoolDistribution'poolKeyhashes = y__})) + (Lens.Family2.Unchecked.lens + Data.Vector.Generic.toList + (\ _ y__ -> Data.Vector.Generic.fromList y__)) +instance Data.ProtoLens.Field.HasField GetStakePoolDistribution "vec'poolKeyhashes" (Data.Vector.Vector Data.ByteString.ByteString) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _GetStakePoolDistribution'poolKeyhashes + (\ x__ y__ -> x__ {_GetStakePoolDistribution'poolKeyhashes = y__})) + Prelude.id +instance Data.ProtoLens.Message GetStakePoolDistribution where + messageName _ + = Data.Text.pack "utxorpc.v1beta.cardano.GetStakePoolDistribution" + packedMessageDescriptor _ + = "\n\ + \\CANGetStakePoolDistribution\DC2%\n\ + \\SOpool_keyhashes\CAN\SOH \ETX(\fR\rpoolKeyhashes" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + poolKeyhashes__field_descriptor + = Data.ProtoLens.FieldDescriptor + "pool_keyhashes" + (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField :: + Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString) + (Data.ProtoLens.RepeatedField + Data.ProtoLens.Unpacked + (Data.ProtoLens.Field.field @"poolKeyhashes")) :: + Data.ProtoLens.FieldDescriptor GetStakePoolDistribution + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, poolKeyhashes__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _GetStakePoolDistribution'_unknownFields + (\ x__ y__ -> x__ {_GetStakePoolDistribution'_unknownFields = y__}) + defMessage + = GetStakePoolDistribution'_constructor + {_GetStakePoolDistribution'poolKeyhashes = Data.Vector.Generic.empty, + _GetStakePoolDistribution'_unknownFields = []} + parseMessage + = let + loop :: + GetStakePoolDistribution + -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld Data.ByteString.ByteString + -> Data.ProtoLens.Encoding.Bytes.Parser GetStakePoolDistribution + loop x mutable'poolKeyhashes + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do frozen'poolKeyhashes <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.unsafeFreeze + mutable'poolKeyhashes) + (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) + (Lens.Family2.set + (Data.ProtoLens.Field.field @"vec'poolKeyhashes") + frozen'poolKeyhashes x)) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do !y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.getBytes + (Prelude.fromIntegral len)) + "pool_keyhashes" + v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.append + mutable'poolKeyhashes y) + loop x v + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + mutable'poolKeyhashes + in + (Data.ProtoLens.Encoding.Bytes.) + (do mutable'poolKeyhashes <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + Data.ProtoLens.Encoding.Growing.new + loop Data.ProtoLens.defMessage mutable'poolKeyhashes) + "GetStakePoolDistribution" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.foldMapBuilder + (\ _v + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + _v)) + (Lens.Family2.view + (Data.ProtoLens.Field.field @"vec'poolKeyhashes") _x)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)) +instance Control.DeepSeq.NFData GetStakePoolDistribution where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_GetStakePoolDistribution'_unknownFields x__) + (Control.DeepSeq.deepseq + (_GetStakePoolDistribution'poolKeyhashes x__) ()) +{- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'governanceAction' @:: Lens' GovernanceAction (Prelude.Maybe GovernanceAction'GovernanceAction)@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'parameterChangeAction' @:: Lens' GovernanceAction (Prelude.Maybe ParameterChangeAction)@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.parameterChangeAction' @:: Lens' GovernanceAction ParameterChangeAction@ @@ -21562,6 +21705,225 @@ instance Control.DeepSeq.NFData PoolRetirementPattern where (Control.DeepSeq.deepseq (_PoolRetirementPattern'epoch x__) ())) {- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.poolKeyhash' @:: Lens' PoolStakeShare Data.ByteString.ByteString@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.stakeFraction' @:: Lens' PoolStakeShare RationalNumber@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'stakeFraction' @:: Lens' PoolStakeShare (Prelude.Maybe RationalNumber)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vrfKeyhash' @:: Lens' PoolStakeShare Data.ByteString.ByteString@ -} +data PoolStakeShare + = PoolStakeShare'_constructor {_PoolStakeShare'poolKeyhash :: !Data.ByteString.ByteString, + _PoolStakeShare'stakeFraction :: !(Prelude.Maybe RationalNumber), + _PoolStakeShare'vrfKeyhash :: !Data.ByteString.ByteString, + _PoolStakeShare'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show PoolStakeShare where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +instance Data.ProtoLens.Field.HasField PoolStakeShare "poolKeyhash" Data.ByteString.ByteString where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _PoolStakeShare'poolKeyhash + (\ x__ y__ -> x__ {_PoolStakeShare'poolKeyhash = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField PoolStakeShare "stakeFraction" RationalNumber where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _PoolStakeShare'stakeFraction + (\ x__ y__ -> x__ {_PoolStakeShare'stakeFraction = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) +instance Data.ProtoLens.Field.HasField PoolStakeShare "maybe'stakeFraction" (Prelude.Maybe RationalNumber) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _PoolStakeShare'stakeFraction + (\ x__ y__ -> x__ {_PoolStakeShare'stakeFraction = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField PoolStakeShare "vrfKeyhash" Data.ByteString.ByteString where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _PoolStakeShare'vrfKeyhash + (\ x__ y__ -> x__ {_PoolStakeShare'vrfKeyhash = y__})) + Prelude.id +instance Data.ProtoLens.Message PoolStakeShare where + messageName _ + = Data.Text.pack "utxorpc.v1beta.cardano.PoolStakeShare" + packedMessageDescriptor _ + = "\n\ + \\SOPoolStakeShare\DC2!\n\ + \\fpool_keyhash\CAN\SOH \SOH(\fR\vpoolKeyhash\DC2M\n\ + \\SOstake_fraction\CAN\STX \SOH(\v2&.utxorpc.v1beta.cardano.RationalNumberR\rstakeFraction\DC2\US\n\ + \\vvrf_keyhash\CAN\ETX \SOH(\fR\n\ + \vrfKeyhash" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + poolKeyhash__field_descriptor + = Data.ProtoLens.FieldDescriptor + "pool_keyhash" + (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField :: + Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString) + (Data.ProtoLens.PlainField + Data.ProtoLens.Optional + (Data.ProtoLens.Field.field @"poolKeyhash")) :: + Data.ProtoLens.FieldDescriptor PoolStakeShare + stakeFraction__field_descriptor + = Data.ProtoLens.FieldDescriptor + "stake_fraction" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor RationalNumber) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'stakeFraction")) :: + Data.ProtoLens.FieldDescriptor PoolStakeShare + vrfKeyhash__field_descriptor + = Data.ProtoLens.FieldDescriptor + "vrf_keyhash" + (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField :: + Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString) + (Data.ProtoLens.PlainField + Data.ProtoLens.Optional + (Data.ProtoLens.Field.field @"vrfKeyhash")) :: + Data.ProtoLens.FieldDescriptor PoolStakeShare + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, poolKeyhash__field_descriptor), + (Data.ProtoLens.Tag 2, stakeFraction__field_descriptor), + (Data.ProtoLens.Tag 3, vrfKeyhash__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _PoolStakeShare'_unknownFields + (\ x__ y__ -> x__ {_PoolStakeShare'_unknownFields = y__}) + defMessage + = PoolStakeShare'_constructor + {_PoolStakeShare'poolKeyhash = Data.ProtoLens.fieldDefault, + _PoolStakeShare'stakeFraction = Prelude.Nothing, + _PoolStakeShare'vrfKeyhash = Data.ProtoLens.fieldDefault, + _PoolStakeShare'_unknownFields = []} + parseMessage + = let + loop :: + PoolStakeShare + -> Data.ProtoLens.Encoding.Bytes.Parser PoolStakeShare + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.getBytes + (Prelude.fromIntegral len)) + "pool_keyhash" + loop + (Lens.Family2.set (Data.ProtoLens.Field.field @"poolKeyhash") y x) + 18 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "stake_fraction" + loop + (Lens.Family2.set + (Data.ProtoLens.Field.field @"stakeFraction") y x) + 26 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.getBytes + (Prelude.fromIntegral len)) + "vrf_keyhash" + loop + (Lens.Family2.set (Data.ProtoLens.Field.field @"vrfKeyhash") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "PoolStakeShare" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (let + _v + = Lens.Family2.view (Data.ProtoLens.Field.field @"poolKeyhash") _x + in + if (Prelude.==) _v Data.ProtoLens.fieldDefault then + Data.Monoid.mempty + else + (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + _v)) + ((Data.Monoid.<>) + (case + Lens.Family2.view + (Data.ProtoLens.Field.field @"maybe'stakeFraction") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 18) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + ((Data.Monoid.<>) + (let + _v + = Lens.Family2.view (Data.ProtoLens.Field.field @"vrfKeyhash") _x + in + if (Prelude.==) _v Data.ProtoLens.fieldDefault then + Data.Monoid.mempty + else + (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 26) + ((\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + _v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)))) +instance Control.DeepSeq.NFData PoolStakeShare where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_PoolStakeShare'_unknownFields x__) + (Control.DeepSeq.deepseq + (_PoolStakeShare'poolKeyhash x__) + (Control.DeepSeq.deepseq + (_PoolStakeShare'stakeFraction x__) + (Control.DeepSeq.deepseq (_PoolStakeShare'vrfKeyhash x__) ()))) +{- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.motionNoConfidence' @:: Lens' PoolVotingThresholds RationalNumber@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'motionNoConfidence' @:: Lens' PoolVotingThresholds (Prelude.Maybe RationalNumber)@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.committeeNormal' @:: Lens' PoolVotingThresholds RationalNumber@ @@ -25007,6 +25369,138 @@ instance Control.DeepSeq.NFData StakeDelegationPattern where (_StakeDelegationPattern'poolKeyhash x__) ())) {- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.pools' @:: Lens' StakePoolDistribution [PoolStakeShare]@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'pools' @:: Lens' StakePoolDistribution (Data.Vector.Vector PoolStakeShare)@ -} +data StakePoolDistribution + = StakePoolDistribution'_constructor {_StakePoolDistribution'pools :: !(Data.Vector.Vector PoolStakeShare), + _StakePoolDistribution'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show StakePoolDistribution where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +instance Data.ProtoLens.Field.HasField StakePoolDistribution "pools" [PoolStakeShare] where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StakePoolDistribution'pools + (\ x__ y__ -> x__ {_StakePoolDistribution'pools = y__})) + (Lens.Family2.Unchecked.lens + Data.Vector.Generic.toList + (\ _ y__ -> Data.Vector.Generic.fromList y__)) +instance Data.ProtoLens.Field.HasField StakePoolDistribution "vec'pools" (Data.Vector.Vector PoolStakeShare) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StakePoolDistribution'pools + (\ x__ y__ -> x__ {_StakePoolDistribution'pools = y__})) + Prelude.id +instance Data.ProtoLens.Message StakePoolDistribution where + messageName _ + = Data.Text.pack "utxorpc.v1beta.cardano.StakePoolDistribution" + packedMessageDescriptor _ + = "\n\ + \\NAKStakePoolDistribution\DC2<\n\ + \\ENQpools\CAN\SOH \ETX(\v2&.utxorpc.v1beta.cardano.PoolStakeShareR\ENQpools" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + pools__field_descriptor + = Data.ProtoLens.FieldDescriptor + "pools" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor PoolStakeShare) + (Data.ProtoLens.RepeatedField + Data.ProtoLens.Unpacked (Data.ProtoLens.Field.field @"pools")) :: + Data.ProtoLens.FieldDescriptor StakePoolDistribution + in + Data.Map.fromList [(Data.ProtoLens.Tag 1, pools__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _StakePoolDistribution'_unknownFields + (\ x__ y__ -> x__ {_StakePoolDistribution'_unknownFields = y__}) + defMessage + = StakePoolDistribution'_constructor + {_StakePoolDistribution'pools = Data.Vector.Generic.empty, + _StakePoolDistribution'_unknownFields = []} + parseMessage + = let + loop :: + StakePoolDistribution + -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld PoolStakeShare + -> Data.ProtoLens.Encoding.Bytes.Parser StakePoolDistribution + loop x mutable'pools + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do frozen'pools <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.unsafeFreeze mutable'pools) + (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) + (Lens.Family2.set + (Data.ProtoLens.Field.field @"vec'pools") frozen'pools x)) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do !y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) + Data.ProtoLens.parseMessage) + "pools" + v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.append mutable'pools y) + loop x v + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + mutable'pools + in + (Data.ProtoLens.Encoding.Bytes.) + (do mutable'pools <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + Data.ProtoLens.Encoding.Growing.new + loop Data.ProtoLens.defMessage mutable'pools) + "StakePoolDistribution" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.foldMapBuilder + (\ _v + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Lens.Family2.view (Data.ProtoLens.Field.field @"vec'pools") _x)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)) +instance Control.DeepSeq.NFData StakePoolDistribution where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_StakePoolDistribution'_unknownFields x__) + (Control.DeepSeq.deepseq (_StakePoolDistribution'pools x__) ()) +{- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.stakeCredential' @:: Lens' StakeRegDelegCert StakeCredential@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'stakeCredential' @:: Lens' StakeRegDelegCert (Prelude.Maybe StakeCredential)@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.poolKeyhash' @:: Lens' StakeRegDelegCert Data.ByteString.ByteString@ @@ -25728,6 +26222,315 @@ instance Control.DeepSeq.NFData StakeVoteRegDelegCert where (Control.DeepSeq.deepseq (_StakeVoteRegDelegCert'coin x__) ())))) {- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'result' @:: Lens' StateData (Prelude.Maybe StateData'Result)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'stakePoolDistribution' @:: Lens' StateData (Prelude.Maybe StakePoolDistribution)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.stakePoolDistribution' @:: Lens' StateData StakePoolDistribution@ -} +data StateData + = StateData'_constructor {_StateData'result :: !(Prelude.Maybe StateData'Result), + _StateData'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show StateData where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +data StateData'Result + = StateData'StakePoolDistribution !StakePoolDistribution + deriving stock (Prelude.Show, Prelude.Eq, Prelude.Ord) +instance Data.ProtoLens.Field.HasField StateData "maybe'result" (Prelude.Maybe StateData'Result) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StateData'result (\ x__ y__ -> x__ {_StateData'result = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField StateData "maybe'stakePoolDistribution" (Prelude.Maybe StakePoolDistribution) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StateData'result (\ x__ y__ -> x__ {_StateData'result = y__})) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (StateData'StakePoolDistribution x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap StateData'StakePoolDistribution y__)) +instance Data.ProtoLens.Field.HasField StateData "stakePoolDistribution" StakePoolDistribution where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StateData'result (\ x__ y__ -> x__ {_StateData'result = y__})) + ((Prelude..) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (StateData'StakePoolDistribution x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap StateData'StakePoolDistribution y__)) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage)) +instance Data.ProtoLens.Message StateData where + messageName _ = Data.Text.pack "utxorpc.v1beta.cardano.StateData" + packedMessageDescriptor _ + = "\n\ + \\tStateData\DC2g\n\ + \\ETBstake_pool_distribution\CAN\SOH \SOH(\v2-.utxorpc.v1beta.cardano.StakePoolDistributionH\NULR\NAKstakePoolDistributionB\b\n\ + \\ACKresult" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + stakePoolDistribution__field_descriptor + = Data.ProtoLens.FieldDescriptor + "stake_pool_distribution" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor StakePoolDistribution) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'stakePoolDistribution")) :: + Data.ProtoLens.FieldDescriptor StateData + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, stakePoolDistribution__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _StateData'_unknownFields + (\ x__ y__ -> x__ {_StateData'_unknownFields = y__}) + defMessage + = StateData'_constructor + {_StateData'result = Prelude.Nothing, + _StateData'_unknownFields = []} + parseMessage + = let + loop :: StateData -> Data.ProtoLens.Encoding.Bytes.Parser StateData + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "stake_pool_distribution" + loop + (Lens.Family2.set + (Data.ProtoLens.Field.field @"stakePoolDistribution") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "StateData" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (case + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'result") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just (StateData'StakePoolDistribution v)) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)) +instance Control.DeepSeq.NFData StateData where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_StateData'_unknownFields x__) + (Control.DeepSeq.deepseq (_StateData'result x__) ()) +instance Control.DeepSeq.NFData StateData'Result where + rnf (StateData'StakePoolDistribution x__) = Control.DeepSeq.rnf x__ +_StateData'StakePoolDistribution :: + Data.ProtoLens.Prism.Prism' StateData'Result StakePoolDistribution +_StateData'StakePoolDistribution + = Data.ProtoLens.Prism.prism' + StateData'StakePoolDistribution + (\ p__ + -> case p__ of + (StateData'StakePoolDistribution p__val) -> Prelude.Just p__val) +{- | Fields : + + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'query' @:: Lens' StateQuery (Prelude.Maybe StateQuery'Query)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'stakePoolDistribution' @:: Lens' StateQuery (Prelude.Maybe GetStakePoolDistribution)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.stakePoolDistribution' @:: Lens' StateQuery GetStakePoolDistribution@ -} +data StateQuery + = StateQuery'_constructor {_StateQuery'query :: !(Prelude.Maybe StateQuery'Query), + _StateQuery'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show StateQuery where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +data StateQuery'Query + = StateQuery'StakePoolDistribution !GetStakePoolDistribution + deriving stock (Prelude.Show, Prelude.Eq, Prelude.Ord) +instance Data.ProtoLens.Field.HasField StateQuery "maybe'query" (Prelude.Maybe StateQuery'Query) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StateQuery'query (\ x__ y__ -> x__ {_StateQuery'query = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField StateQuery "maybe'stakePoolDistribution" (Prelude.Maybe GetStakePoolDistribution) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StateQuery'query (\ x__ y__ -> x__ {_StateQuery'query = y__})) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (StateQuery'StakePoolDistribution x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap StateQuery'StakePoolDistribution y__)) +instance Data.ProtoLens.Field.HasField StateQuery "stakePoolDistribution" GetStakePoolDistribution where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _StateQuery'query (\ x__ y__ -> x__ {_StateQuery'query = y__})) + ((Prelude..) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (StateQuery'StakePoolDistribution x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap StateQuery'StakePoolDistribution y__)) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage)) +instance Data.ProtoLens.Message StateQuery where + messageName _ = Data.Text.pack "utxorpc.v1beta.cardano.StateQuery" + packedMessageDescriptor _ + = "\n\ + \\n\ + \StateQuery\DC2j\n\ + \\ETBstake_pool_distribution\CAN\SOH \SOH(\v20.utxorpc.v1beta.cardano.GetStakePoolDistributionH\NULR\NAKstakePoolDistributionB\a\n\ + \\ENQquery" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + stakePoolDistribution__field_descriptor + = Data.ProtoLens.FieldDescriptor + "stake_pool_distribution" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor GetStakePoolDistribution) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'stakePoolDistribution")) :: + Data.ProtoLens.FieldDescriptor StateQuery + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, stakePoolDistribution__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _StateQuery'_unknownFields + (\ x__ y__ -> x__ {_StateQuery'_unknownFields = y__}) + defMessage + = StateQuery'_constructor + {_StateQuery'query = Prelude.Nothing, + _StateQuery'_unknownFields = []} + parseMessage + = let + loop :: + StateQuery -> Data.ProtoLens.Encoding.Bytes.Parser StateQuery + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "stake_pool_distribution" + loop + (Lens.Family2.set + (Data.ProtoLens.Field.field @"stakePoolDistribution") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "StateQuery" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (case + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'query") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just (StateQuery'StakePoolDistribution v)) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)) +instance Control.DeepSeq.NFData StateQuery where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_StateQuery'_unknownFields x__) + (Control.DeepSeq.deepseq (_StateQuery'query x__) ()) +instance Control.DeepSeq.NFData StateQuery'Query where + rnf (StateQuery'StakePoolDistribution x__) + = Control.DeepSeq.rnf x__ +_StateQuery'StakePoolDistribution :: + Data.ProtoLens.Prism.Prism' StateQuery'Query GetStakePoolDistribution +_StateQuery'StakePoolDistribution + = Data.ProtoLens.Prism.prism' + StateQuery'StakePoolDistribution + (\ p__ + -> case p__ of + (StateQuery'StakePoolDistribution p__val) -> Prelude.Just p__val) +{- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.withdrawals' @:: Lens' TreasuryWithdrawalsAction [WithdrawalAmount]@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'withdrawals' @:: Lens' TreasuryWithdrawalsAction (Data.Vector.Vector WithdrawalAmount)@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.policyHash' @:: Lens' TreasuryWithdrawalsAction Data.ByteString.ByteString@ -} @@ -25942,7 +26745,9 @@ instance Control.DeepSeq.NFData TreasuryWithdrawalsAction where * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'auxiliary' @:: Lens' Tx (Prelude.Maybe AuxData)@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.hash' @:: Lens' Tx Data.ByteString.ByteString@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.proposals' @:: Lens' Tx [GovernanceActionProposal]@ - * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'proposals' @:: Lens' Tx (Data.Vector.Vector GovernanceActionProposal)@ -} + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'proposals' @:: Lens' Tx (Data.Vector.Vector GovernanceActionProposal)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.votes' @:: Lens' Tx [VoterVotes]@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'votes' @:: Lens' Tx (Data.Vector.Vector VoterVotes)@ -} data Tx = Tx'_constructor {_Tx'inputs :: !(Data.Vector.Vector TxInput), _Tx'outputs :: !(Data.Vector.Vector TxOutput), @@ -25958,6 +26763,7 @@ data Tx _Tx'auxiliary :: !(Prelude.Maybe AuxData), _Tx'hash :: !Data.ByteString.ByteString, _Tx'proposals :: !(Data.Vector.Vector GovernanceActionProposal), + _Tx'votes :: !(Data.Vector.Vector VoterVotes), _Tx'_unknownFields :: !Data.ProtoLens.FieldSet} deriving stock (Prelude.Eq, Prelude.Ord) instance Prelude.Show Tx where @@ -26136,6 +26942,20 @@ instance Data.ProtoLens.Field.HasField Tx "vec'proposals" (Data.Vector.Vector Go (Lens.Family2.Unchecked.lens _Tx'proposals (\ x__ y__ -> x__ {_Tx'proposals = y__})) Prelude.id +instance Data.ProtoLens.Field.HasField Tx "votes" [VoterVotes] where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _Tx'votes (\ x__ y__ -> x__ {_Tx'votes = y__})) + (Lens.Family2.Unchecked.lens + Data.Vector.Generic.toList + (\ _ y__ -> Data.Vector.Generic.fromList y__)) +instance Data.ProtoLens.Field.HasField Tx "vec'votes" (Data.Vector.Vector VoterVotes) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _Tx'votes (\ x__ y__ -> x__ {_Tx'votes = y__})) + Prelude.id instance Data.ProtoLens.Message Tx where messageName _ = Data.Text.pack "utxorpc.v1beta.cardano.Tx" packedMessageDescriptor _ @@ -26159,7 +26979,8 @@ instance Data.ProtoLens.Message Tx where \successful\DC2=\n\ \\tauxiliary\CAN\f \SOH(\v2\US.utxorpc.v1beta.cardano.AuxDataR\tauxiliary\DC2\DC2\n\ \\EOThash\CAN\r \SOH(\fR\EOThash\DC2N\n\ - \\tproposals\CAN\SO \ETX(\v20.utxorpc.v1beta.cardano.GovernanceActionProposalR\tproposals" + \\tproposals\CAN\SO \ETX(\v20.utxorpc.v1beta.cardano.GovernanceActionProposalR\tproposals\DC28\n\ + \\ENQvotes\CAN\SI \ETX(\v2\".utxorpc.v1beta.cardano.VoterVotesR\ENQvotes" packedFileDescriptor _ = packedFileDescriptor fieldsByTag = let @@ -26280,6 +27101,14 @@ instance Data.ProtoLens.Message Tx where Data.ProtoLens.Unpacked (Data.ProtoLens.Field.field @"proposals")) :: Data.ProtoLens.FieldDescriptor Tx + votes__field_descriptor + = Data.ProtoLens.FieldDescriptor + "votes" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor VoterVotes) + (Data.ProtoLens.RepeatedField + Data.ProtoLens.Unpacked (Data.ProtoLens.Field.field @"votes")) :: + Data.ProtoLens.FieldDescriptor Tx in Data.Map.fromList [(Data.ProtoLens.Tag 1, inputs__field_descriptor), @@ -26295,7 +27124,8 @@ instance Data.ProtoLens.Message Tx where (Data.ProtoLens.Tag 11, successful__field_descriptor), (Data.ProtoLens.Tag 12, auxiliary__field_descriptor), (Data.ProtoLens.Tag 13, hash__field_descriptor), - (Data.ProtoLens.Tag 14, proposals__field_descriptor)] + (Data.ProtoLens.Tag 14, proposals__field_descriptor), + (Data.ProtoLens.Tag 15, votes__field_descriptor)] unknownFields = Lens.Family2.Unchecked.lens _Tx'_unknownFields (\ x__ y__ -> x__ {_Tx'_unknownFields = y__}) @@ -26312,7 +27142,8 @@ instance Data.ProtoLens.Message Tx where _Tx'successful = Data.ProtoLens.fieldDefault, _Tx'auxiliary = Prelude.Nothing, _Tx'hash = Data.ProtoLens.fieldDefault, - _Tx'proposals = Data.Vector.Generic.empty, _Tx'_unknownFields = []} + _Tx'proposals = Data.Vector.Generic.empty, + _Tx'votes = Data.Vector.Generic.empty, _Tx'_unknownFields = []} parseMessage = let loop :: @@ -26323,8 +27154,9 @@ instance Data.ProtoLens.Message Tx where -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld TxOutput -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld GovernanceActionProposal -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld TxInput - -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld Withdrawal - -> Data.ProtoLens.Encoding.Bytes.Parser Tx + -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld VoterVotes + -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld Withdrawal + -> Data.ProtoLens.Encoding.Bytes.Parser Tx loop x mutable'certificates @@ -26333,6 +27165,7 @@ instance Data.ProtoLens.Message Tx where mutable'outputs mutable'proposals mutable'referenceInputs + mutable'votes mutable'withdrawals = do end <- Data.ProtoLens.Encoding.Bytes.atEnd if end then @@ -26353,6 +27186,8 @@ instance Data.ProtoLens.Message Tx where frozen'referenceInputs <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO (Data.ProtoLens.Encoding.Growing.unsafeFreeze mutable'referenceInputs) + frozen'votes <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.unsafeFreeze mutable'votes) frozen'withdrawals <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO (Data.ProtoLens.Encoding.Growing.unsafeFreeze mutable'withdrawals) @@ -26384,8 +27219,11 @@ instance Data.ProtoLens.Message Tx where (Data.ProtoLens.Field.field @"vec'referenceInputs") frozen'referenceInputs (Lens.Family2.set - (Data.ProtoLens.Field.field @"vec'withdrawals") - frozen'withdrawals x)))))))) + (Data.ProtoLens.Field.field @"vec'votes") + frozen'votes + (Lens.Family2.set + (Data.ProtoLens.Field.field @"vec'withdrawals") + frozen'withdrawals x))))))))) else do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt case tag of @@ -26400,7 +27238,8 @@ instance Data.ProtoLens.Message Tx where (Data.ProtoLens.Encoding.Growing.append mutable'inputs y) loop x mutable'certificates v mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 18 -> do !y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26412,7 +27251,8 @@ instance Data.ProtoLens.Message Tx where (Data.ProtoLens.Encoding.Growing.append mutable'outputs y) loop x mutable'certificates mutable'inputs mutable'mint v - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 26 -> do !y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26425,7 +27265,7 @@ instance Data.ProtoLens.Message Tx where mutable'certificates y) loop x v mutable'inputs mutable'mint mutable'outputs mutable'proposals - mutable'referenceInputs mutable'withdrawals + mutable'referenceInputs mutable'votes mutable'withdrawals 34 -> do !y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26438,7 +27278,7 @@ instance Data.ProtoLens.Message Tx where mutable'withdrawals y) loop x mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs v + mutable'proposals mutable'referenceInputs mutable'votes v 42 -> do !y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26450,7 +27290,8 @@ instance Data.ProtoLens.Message Tx where (Data.ProtoLens.Encoding.Growing.append mutable'mint y) loop x mutable'certificates mutable'inputs v mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 50 -> do !y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26463,7 +27304,7 @@ instance Data.ProtoLens.Message Tx where mutable'referenceInputs y) loop x mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals v mutable'withdrawals + mutable'proposals v mutable'votes mutable'withdrawals 58 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26473,7 +27314,8 @@ instance Data.ProtoLens.Message Tx where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"witnesses") y x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 66 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26483,7 +27325,8 @@ instance Data.ProtoLens.Message Tx where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"collateral") y x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 74 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26493,7 +27336,8 @@ instance Data.ProtoLens.Message Tx where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"fee") y x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 82 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26503,7 +27347,8 @@ instance Data.ProtoLens.Message Tx where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"validity") y x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 88 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (Prelude.fmap @@ -26512,7 +27357,8 @@ instance Data.ProtoLens.Message Tx where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"successful") y x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 98 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26522,7 +27368,8 @@ instance Data.ProtoLens.Message Tx where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"auxiliary") y x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 106 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26532,7 +27379,8 @@ instance Data.ProtoLens.Message Tx where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"hash") y x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals 114 -> do !y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -26544,7 +27392,19 @@ instance Data.ProtoLens.Message Tx where (Data.ProtoLens.Encoding.Growing.append mutable'proposals y) loop x mutable'certificates mutable'inputs mutable'mint mutable'outputs - v mutable'referenceInputs mutable'withdrawals + v mutable'referenceInputs mutable'votes mutable'withdrawals + 122 + -> do !y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) + Data.ProtoLens.parseMessage) + "votes" + v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.append mutable'votes y) + loop + x mutable'certificates mutable'inputs mutable'mint mutable'outputs + mutable'proposals mutable'referenceInputs v mutable'withdrawals wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire wire @@ -26552,7 +27412,8 @@ instance Data.ProtoLens.Message Tx where (Lens.Family2.over Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) mutable'certificates mutable'inputs mutable'mint mutable'outputs - mutable'proposals mutable'referenceInputs mutable'withdrawals + mutable'proposals mutable'referenceInputs mutable'votes + mutable'withdrawals in (Data.ProtoLens.Encoding.Bytes.) (do mutable'certificates <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO @@ -26567,12 +27428,14 @@ instance Data.ProtoLens.Message Tx where Data.ProtoLens.Encoding.Growing.new mutable'referenceInputs <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO Data.ProtoLens.Encoding.Growing.new + mutable'votes <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + Data.ProtoLens.Encoding.Growing.new mutable'withdrawals <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO Data.ProtoLens.Encoding.Growing.new loop Data.ProtoLens.defMessage mutable'certificates mutable'inputs mutable'mint mutable'outputs mutable'proposals - mutable'referenceInputs mutable'withdrawals) + mutable'referenceInputs mutable'votes mutable'withdrawals) "Tx" buildMessage = \ _x @@ -26805,10 +27668,31 @@ instance Data.ProtoLens.Message Tx where (Data.ProtoLens.Field.field @"vec'proposals") _x)) - (Data.ProtoLens.Encoding.Wire.buildFieldSet - (Lens.Family2.view - Data.ProtoLens.unknownFields - _x))))))))))))))) + ((Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.foldMapBuilder + (\ _v + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + 122) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral + (Data.ByteString.length + bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes + bs)) + Data.ProtoLens.encodeMessage + _v)) + (Lens.Family2.view + (Data.ProtoLens.Field.field + @"vec'votes") + _x)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view + Data.ProtoLens.unknownFields + _x)))))))))))))))) instance Control.DeepSeq.NFData Tx where rnf = \ x__ @@ -26841,7 +27725,9 @@ instance Control.DeepSeq.NFData Tx where (Control.DeepSeq.deepseq (_Tx'hash x__) (Control.DeepSeq.deepseq - (_Tx'proposals x__) ())))))))))))))) + (_Tx'proposals x__) + (Control.DeepSeq.deepseq + (_Tx'votes x__) ()))))))))))))))) {- | Fields : * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.fee' @:: Lens' TxEval BigInt@ @@ -27629,13 +28515,16 @@ instance Control.DeepSeq.NFData TxInput where * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.datum' @:: Lens' TxOutput Datum@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'datum' @:: Lens' TxOutput (Prelude.Maybe Datum)@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.script' @:: Lens' TxOutput Script@ - * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'script' @:: Lens' TxOutput (Prelude.Maybe Script)@ -} + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'script' @:: Lens' TxOutput (Prelude.Maybe Script)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.originalCbor' @:: Lens' TxOutput Data.ByteString.ByteString@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'originalCbor' @:: Lens' TxOutput (Prelude.Maybe Data.ByteString.ByteString)@ -} data TxOutput = TxOutput'_constructor {_TxOutput'address :: !Data.ByteString.ByteString, _TxOutput'coin :: !(Prelude.Maybe BigInt), _TxOutput'assets :: !(Data.Vector.Vector Multiasset), _TxOutput'datum :: !(Prelude.Maybe Datum), _TxOutput'script :: !(Prelude.Maybe Script), + _TxOutput'originalCbor :: !(Prelude.Maybe Data.ByteString.ByteString), _TxOutput'_unknownFields :: !Data.ProtoLens.FieldSet} deriving stock (Prelude.Eq, Prelude.Ord) instance Prelude.Show TxOutput where @@ -27700,6 +28589,20 @@ instance Data.ProtoLens.Field.HasField TxOutput "maybe'script" (Prelude.Maybe Sc (Lens.Family2.Unchecked.lens _TxOutput'script (\ x__ y__ -> x__ {_TxOutput'script = y__})) Prelude.id +instance Data.ProtoLens.Field.HasField TxOutput "originalCbor" Data.ByteString.ByteString where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _TxOutput'originalCbor + (\ x__ y__ -> x__ {_TxOutput'originalCbor = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.fieldDefault) +instance Data.ProtoLens.Field.HasField TxOutput "maybe'originalCbor" (Prelude.Maybe Data.ByteString.ByteString) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _TxOutput'originalCbor + (\ x__ y__ -> x__ {_TxOutput'originalCbor = y__})) + Prelude.id instance Data.ProtoLens.Message TxOutput where messageName _ = Data.Text.pack "utxorpc.v1beta.cardano.TxOutput" packedMessageDescriptor _ @@ -27709,9 +28612,11 @@ instance Data.ProtoLens.Message TxOutput where \\EOTcoin\CAN\STX \SOH(\v2\RS.utxorpc.v1beta.cardano.BigIntR\EOTcoin\DC2:\n\ \\ACKassets\CAN\ETX \ETX(\v2\".utxorpc.v1beta.cardano.MultiassetR\ACKassets\DC28\n\ \\ENQdatum\CAN\EOT \SOH(\v2\GS.utxorpc.v1beta.cardano.DatumH\NULR\ENQdatum\136\SOH\SOH\DC2;\n\ - \\ACKscript\CAN\ENQ \SOH(\v2\RS.utxorpc.v1beta.cardano.ScriptH\SOHR\ACKscript\136\SOH\SOHB\b\n\ + \\ACKscript\CAN\ENQ \SOH(\v2\RS.utxorpc.v1beta.cardano.ScriptH\SOHR\ACKscript\136\SOH\SOH\DC2(\n\ + \\roriginal_cbor\CAN\ACK \SOH(\fH\STXR\foriginalCbor\136\SOH\SOHB\b\n\ \\ACK_datumB\t\n\ - \\a_script" + \\a_scriptB\DLE\n\ + \\SO_original_cbor" packedFileDescriptor _ = packedFileDescriptor fieldsByTag = let @@ -27755,13 +28660,22 @@ instance Data.ProtoLens.Message TxOutput where (Data.ProtoLens.OptionalField (Data.ProtoLens.Field.field @"maybe'script")) :: Data.ProtoLens.FieldDescriptor TxOutput + originalCbor__field_descriptor + = Data.ProtoLens.FieldDescriptor + "original_cbor" + (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField :: + Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'originalCbor")) :: + Data.ProtoLens.FieldDescriptor TxOutput in Data.Map.fromList [(Data.ProtoLens.Tag 1, address__field_descriptor), (Data.ProtoLens.Tag 2, coin__field_descriptor), (Data.ProtoLens.Tag 3, assets__field_descriptor), (Data.ProtoLens.Tag 4, datum__field_descriptor), - (Data.ProtoLens.Tag 5, script__field_descriptor)] + (Data.ProtoLens.Tag 5, script__field_descriptor), + (Data.ProtoLens.Tag 6, originalCbor__field_descriptor)] unknownFields = Lens.Family2.Unchecked.lens _TxOutput'_unknownFields @@ -27772,7 +28686,9 @@ instance Data.ProtoLens.Message TxOutput where _TxOutput'coin = Prelude.Nothing, _TxOutput'assets = Data.Vector.Generic.empty, _TxOutput'datum = Prelude.Nothing, - _TxOutput'script = Prelude.Nothing, _TxOutput'_unknownFields = []} + _TxOutput'script = Prelude.Nothing, + _TxOutput'originalCbor = Prelude.Nothing, + _TxOutput'_unknownFields = []} parseMessage = let loop :: @@ -27848,6 +28764,16 @@ instance Data.ProtoLens.Message TxOutput where loop (Lens.Family2.set (Data.ProtoLens.Field.field @"script") y x) mutable'assets + 50 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.getBytes + (Prelude.fromIntegral len)) + "original_cbor" + loop + (Lens.Family2.set + (Data.ProtoLens.Field.field @"originalCbor") y x) + mutable'assets wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire wire @@ -27936,8 +28862,24 @@ instance Data.ProtoLens.Message TxOutput where (Prelude.fromIntegral (Data.ByteString.length bs))) (Data.ProtoLens.Encoding.Bytes.putBytes bs)) Data.ProtoLens.encodeMessage _v)) - (Data.ProtoLens.Encoding.Wire.buildFieldSet - (Lens.Family2.view Data.ProtoLens.unknownFields _x)))))) + ((Data.Monoid.<>) + (case + Lens.Family2.view + (Data.ProtoLens.Field.field @"maybe'originalCbor") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 50) + ((\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral + (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + _v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x))))))) instance Control.DeepSeq.NFData TxOutput where rnf = \ x__ @@ -27951,7 +28893,9 @@ instance Control.DeepSeq.NFData TxOutput where (_TxOutput'assets x__) (Control.DeepSeq.deepseq (_TxOutput'datum x__) - (Control.DeepSeq.deepseq (_TxOutput'script x__) ()))))) + (Control.DeepSeq.deepseq + (_TxOutput'script x__) + (Control.DeepSeq.deepseq (_TxOutput'originalCbor x__) ())))))) {- | Fields : * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.address' @:: Lens' TxOutputPattern AddressPattern@ @@ -29656,6 +30600,78 @@ instance Control.DeepSeq.NFData VKeyWitness where (Control.DeepSeq.deepseq (_VKeyWitness'vkey x__) (Control.DeepSeq.deepseq (_VKeyWitness'signature x__) ())) +newtype Vote'UnrecognizedValue + = Vote'UnrecognizedValue Data.Int.Int32 + deriving stock (Prelude.Eq, Prelude.Ord, Prelude.Show) +data Vote + = VOTE_UNSPECIFIED | + VOTE_NO | + VOTE_YES | + VOTE_ABSTAIN | + Vote'Unrecognized !Vote'UnrecognizedValue + deriving stock (Prelude.Show, Prelude.Eq, Prelude.Ord) +instance Data.ProtoLens.MessageEnum Vote where + maybeToEnum 0 = Prelude.Just VOTE_UNSPECIFIED + maybeToEnum 1 = Prelude.Just VOTE_NO + maybeToEnum 2 = Prelude.Just VOTE_YES + maybeToEnum 3 = Prelude.Just VOTE_ABSTAIN + maybeToEnum k + = Prelude.Just + (Vote'Unrecognized + (Vote'UnrecognizedValue (Prelude.fromIntegral k))) + showEnum VOTE_UNSPECIFIED = "VOTE_UNSPECIFIED" + showEnum VOTE_NO = "VOTE_NO" + showEnum VOTE_YES = "VOTE_YES" + showEnum VOTE_ABSTAIN = "VOTE_ABSTAIN" + showEnum (Vote'Unrecognized (Vote'UnrecognizedValue k)) + = Prelude.show k + readEnum k + | (Prelude.==) k "VOTE_UNSPECIFIED" = Prelude.Just VOTE_UNSPECIFIED + | (Prelude.==) k "VOTE_NO" = Prelude.Just VOTE_NO + | (Prelude.==) k "VOTE_YES" = Prelude.Just VOTE_YES + | (Prelude.==) k "VOTE_ABSTAIN" = Prelude.Just VOTE_ABSTAIN + | Prelude.otherwise + = (Prelude.>>=) (Text.Read.readMaybe k) Data.ProtoLens.maybeToEnum +instance Prelude.Bounded Vote where + minBound = VOTE_UNSPECIFIED + maxBound = VOTE_ABSTAIN +instance Prelude.Enum Vote where + toEnum k__ + = Prelude.maybe + (Prelude.error + ((Prelude.++) + "toEnum: unknown value for enum Vote: " (Prelude.show k__))) + Prelude.id (Data.ProtoLens.maybeToEnum k__) + fromEnum VOTE_UNSPECIFIED = 0 + fromEnum VOTE_NO = 1 + fromEnum VOTE_YES = 2 + fromEnum VOTE_ABSTAIN = 3 + fromEnum (Vote'Unrecognized (Vote'UnrecognizedValue k)) + = Prelude.fromIntegral k + succ VOTE_ABSTAIN + = Prelude.error + "Vote.succ: bad argument VOTE_ABSTAIN. This value would be out of bounds." + succ VOTE_UNSPECIFIED = VOTE_NO + succ VOTE_NO = VOTE_YES + succ VOTE_YES = VOTE_ABSTAIN + succ (Vote'Unrecognized _) + = Prelude.error "Vote.succ: bad argument: unrecognized value" + pred VOTE_UNSPECIFIED + = Prelude.error + "Vote.pred: bad argument VOTE_UNSPECIFIED. This value would be out of bounds." + pred VOTE_NO = VOTE_UNSPECIFIED + pred VOTE_YES = VOTE_NO + pred VOTE_ABSTAIN = VOTE_YES + pred (Vote'Unrecognized _) + = Prelude.error "Vote.pred: bad argument: unrecognized value" + enumFrom = Data.ProtoLens.Message.Enum.messageEnumFrom + enumFromTo = Data.ProtoLens.Message.Enum.messageEnumFromTo + enumFromThen = Data.ProtoLens.Message.Enum.messageEnumFromThen + enumFromThenTo = Data.ProtoLens.Message.Enum.messageEnumFromThenTo +instance Data.ProtoLens.FieldDefault Vote where + fieldDefault = VOTE_UNSPECIFIED +instance Control.DeepSeq.NFData Vote where + rnf x__ = Prelude.seq x__ () {- | Fields : * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.stakeCredential' @:: Lens' VoteDelegCert StakeCredential@ @@ -30059,6 +31075,577 @@ instance Control.DeepSeq.NFData VoteRegDelegCert where (Control.DeepSeq.deepseq (_VoteRegDelegCert'coin x__) ()))) {- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.votes' @:: Lens' VoterVotes [VotingProcedure]@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'votes' @:: Lens' VoterVotes (Data.Vector.Vector VotingProcedure)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'voter' @:: Lens' VoterVotes (Prelude.Maybe VoterVotes'Voter)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'constitutionalCommittee' @:: Lens' VoterVotes (Prelude.Maybe StakeCredential)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.constitutionalCommittee' @:: Lens' VoterVotes StakeCredential@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'drep' @:: Lens' VoterVotes (Prelude.Maybe StakeCredential)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.drep' @:: Lens' VoterVotes StakeCredential@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'spo' @:: Lens' VoterVotes (Prelude.Maybe Data.ByteString.ByteString)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.spo' @:: Lens' VoterVotes Data.ByteString.ByteString@ -} +data VoterVotes + = VoterVotes'_constructor {_VoterVotes'votes :: !(Data.Vector.Vector VotingProcedure), + _VoterVotes'voter :: !(Prelude.Maybe VoterVotes'Voter), + _VoterVotes'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show VoterVotes where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +data VoterVotes'Voter + = VoterVotes'ConstitutionalCommittee !StakeCredential | + VoterVotes'Drep !StakeCredential | + VoterVotes'Spo !Data.ByteString.ByteString + deriving stock (Prelude.Show, Prelude.Eq, Prelude.Ord) +instance Data.ProtoLens.Field.HasField VoterVotes "votes" [VotingProcedure] where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'votes (\ x__ y__ -> x__ {_VoterVotes'votes = y__})) + (Lens.Family2.Unchecked.lens + Data.Vector.Generic.toList + (\ _ y__ -> Data.Vector.Generic.fromList y__)) +instance Data.ProtoLens.Field.HasField VoterVotes "vec'votes" (Data.Vector.Vector VotingProcedure) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'votes (\ x__ y__ -> x__ {_VoterVotes'votes = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField VoterVotes "maybe'voter" (Prelude.Maybe VoterVotes'Voter) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'voter (\ x__ y__ -> x__ {_VoterVotes'voter = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField VoterVotes "maybe'constitutionalCommittee" (Prelude.Maybe StakeCredential) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'voter (\ x__ y__ -> x__ {_VoterVotes'voter = y__})) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (VoterVotes'ConstitutionalCommittee x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap VoterVotes'ConstitutionalCommittee y__)) +instance Data.ProtoLens.Field.HasField VoterVotes "constitutionalCommittee" StakeCredential where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'voter (\ x__ y__ -> x__ {_VoterVotes'voter = y__})) + ((Prelude..) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (VoterVotes'ConstitutionalCommittee x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap VoterVotes'ConstitutionalCommittee y__)) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage)) +instance Data.ProtoLens.Field.HasField VoterVotes "maybe'drep" (Prelude.Maybe StakeCredential) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'voter (\ x__ y__ -> x__ {_VoterVotes'voter = y__})) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (VoterVotes'Drep x__val)) -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap VoterVotes'Drep y__)) +instance Data.ProtoLens.Field.HasField VoterVotes "drep" StakeCredential where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'voter (\ x__ y__ -> x__ {_VoterVotes'voter = y__})) + ((Prelude..) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (VoterVotes'Drep x__val)) -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap VoterVotes'Drep y__)) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage)) +instance Data.ProtoLens.Field.HasField VoterVotes "maybe'spo" (Prelude.Maybe Data.ByteString.ByteString) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'voter (\ x__ y__ -> x__ {_VoterVotes'voter = y__})) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (VoterVotes'Spo x__val)) -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap VoterVotes'Spo y__)) +instance Data.ProtoLens.Field.HasField VoterVotes "spo" Data.ByteString.ByteString where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VoterVotes'voter (\ x__ y__ -> x__ {_VoterVotes'voter = y__})) + ((Prelude..) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (VoterVotes'Spo x__val)) -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap VoterVotes'Spo y__)) + (Data.ProtoLens.maybeLens Data.ProtoLens.fieldDefault)) +instance Data.ProtoLens.Message VoterVotes where + messageName _ = Data.Text.pack "utxorpc.v1beta.cardano.VoterVotes" + packedMessageDescriptor _ + = "\n\ + \\n\ + \VoterVotes\DC2d\n\ + \\CANconstitutional_committee\CAN\SOH \SOH(\v2'.utxorpc.v1beta.cardano.StakeCredentialH\NULR\ETBconstitutionalCommittee\DC2=\n\ + \\EOTdrep\CAN\STX \SOH(\v2'.utxorpc.v1beta.cardano.StakeCredentialH\NULR\EOTdrep\DC2\DC2\n\ + \\ETXspo\CAN\ETX \SOH(\fH\NULR\ETXspo\DC2=\n\ + \\ENQvotes\CAN\EOT \ETX(\v2'.utxorpc.v1beta.cardano.VotingProcedureR\ENQvotesB\a\n\ + \\ENQvoter" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + votes__field_descriptor + = Data.ProtoLens.FieldDescriptor + "votes" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor VotingProcedure) + (Data.ProtoLens.RepeatedField + Data.ProtoLens.Unpacked (Data.ProtoLens.Field.field @"votes")) :: + Data.ProtoLens.FieldDescriptor VoterVotes + constitutionalCommittee__field_descriptor + = Data.ProtoLens.FieldDescriptor + "constitutional_committee" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor StakeCredential) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'constitutionalCommittee")) :: + Data.ProtoLens.FieldDescriptor VoterVotes + drep__field_descriptor + = Data.ProtoLens.FieldDescriptor + "drep" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor StakeCredential) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'drep")) :: + Data.ProtoLens.FieldDescriptor VoterVotes + spo__field_descriptor + = Data.ProtoLens.FieldDescriptor + "spo" + (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField :: + Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'spo")) :: + Data.ProtoLens.FieldDescriptor VoterVotes + in + Data.Map.fromList + [(Data.ProtoLens.Tag 4, votes__field_descriptor), + (Data.ProtoLens.Tag 1, constitutionalCommittee__field_descriptor), + (Data.ProtoLens.Tag 2, drep__field_descriptor), + (Data.ProtoLens.Tag 3, spo__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _VoterVotes'_unknownFields + (\ x__ y__ -> x__ {_VoterVotes'_unknownFields = y__}) + defMessage + = VoterVotes'_constructor + {_VoterVotes'votes = Data.Vector.Generic.empty, + _VoterVotes'voter = Prelude.Nothing, + _VoterVotes'_unknownFields = []} + parseMessage + = let + loop :: + VoterVotes + -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld VotingProcedure + -> Data.ProtoLens.Encoding.Bytes.Parser VoterVotes + loop x mutable'votes + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do frozen'votes <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.unsafeFreeze mutable'votes) + (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) + (Lens.Family2.set + (Data.ProtoLens.Field.field @"vec'votes") frozen'votes x)) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 34 + -> do !y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) + Data.ProtoLens.parseMessage) + "votes" + v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.append mutable'votes y) + loop x v + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "constitutional_committee" + loop + (Lens.Family2.set + (Data.ProtoLens.Field.field @"constitutionalCommittee") y x) + mutable'votes + 18 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "drep" + loop + (Lens.Family2.set (Data.ProtoLens.Field.field @"drep") y x) + mutable'votes + 26 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.getBytes + (Prelude.fromIntegral len)) + "spo" + loop + (Lens.Family2.set (Data.ProtoLens.Field.field @"spo") y x) + mutable'votes + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + mutable'votes + in + (Data.ProtoLens.Encoding.Bytes.) + (do mutable'votes <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + Data.ProtoLens.Encoding.Growing.new + loop Data.ProtoLens.defMessage mutable'votes) + "VoterVotes" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.foldMapBuilder + (\ _v + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 34) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Lens.Family2.view (Data.ProtoLens.Field.field @"vec'votes") _x)) + ((Data.Monoid.<>) + (case + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'voter") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just (VoterVotes'ConstitutionalCommittee v)) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage v) + (Prelude.Just (VoterVotes'Drep v)) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 18) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage v) + (Prelude.Just (VoterVotes'Spo v)) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 26) + ((\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x))) +instance Control.DeepSeq.NFData VoterVotes where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_VoterVotes'_unknownFields x__) + (Control.DeepSeq.deepseq + (_VoterVotes'votes x__) + (Control.DeepSeq.deepseq (_VoterVotes'voter x__) ())) +instance Control.DeepSeq.NFData VoterVotes'Voter where + rnf (VoterVotes'ConstitutionalCommittee x__) + = Control.DeepSeq.rnf x__ + rnf (VoterVotes'Drep x__) = Control.DeepSeq.rnf x__ + rnf (VoterVotes'Spo x__) = Control.DeepSeq.rnf x__ +_VoterVotes'ConstitutionalCommittee :: + Data.ProtoLens.Prism.Prism' VoterVotes'Voter StakeCredential +_VoterVotes'ConstitutionalCommittee + = Data.ProtoLens.Prism.prism' + VoterVotes'ConstitutionalCommittee + (\ p__ + -> case p__ of + (VoterVotes'ConstitutionalCommittee p__val) -> Prelude.Just p__val + _otherwise -> Prelude.Nothing) +_VoterVotes'Drep :: + Data.ProtoLens.Prism.Prism' VoterVotes'Voter StakeCredential +_VoterVotes'Drep + = Data.ProtoLens.Prism.prism' + VoterVotes'Drep + (\ p__ + -> case p__ of + (VoterVotes'Drep p__val) -> Prelude.Just p__val + _otherwise -> Prelude.Nothing) +_VoterVotes'Spo :: + Data.ProtoLens.Prism.Prism' VoterVotes'Voter Data.ByteString.ByteString +_VoterVotes'Spo + = Data.ProtoLens.Prism.prism' + VoterVotes'Spo + (\ p__ + -> case p__ of + (VoterVotes'Spo p__val) -> Prelude.Just p__val + _otherwise -> Prelude.Nothing) +{- | Fields : + + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.govActionId' @:: Lens' VotingProcedure GovernanceActionId@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'govActionId' @:: Lens' VotingProcedure (Prelude.Maybe GovernanceActionId)@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vote' @:: Lens' VotingProcedure Vote@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.anchor' @:: Lens' VotingProcedure Anchor@ + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.maybe'anchor' @:: Lens' VotingProcedure (Prelude.Maybe Anchor)@ -} +data VotingProcedure + = VotingProcedure'_constructor {_VotingProcedure'govActionId :: !(Prelude.Maybe GovernanceActionId), + _VotingProcedure'vote :: !Vote, + _VotingProcedure'anchor :: !(Prelude.Maybe Anchor), + _VotingProcedure'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show VotingProcedure where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +instance Data.ProtoLens.Field.HasField VotingProcedure "govActionId" GovernanceActionId where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VotingProcedure'govActionId + (\ x__ y__ -> x__ {_VotingProcedure'govActionId = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) +instance Data.ProtoLens.Field.HasField VotingProcedure "maybe'govActionId" (Prelude.Maybe GovernanceActionId) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VotingProcedure'govActionId + (\ x__ y__ -> x__ {_VotingProcedure'govActionId = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField VotingProcedure "vote" Vote where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VotingProcedure'vote + (\ x__ y__ -> x__ {_VotingProcedure'vote = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField VotingProcedure "anchor" Anchor where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VotingProcedure'anchor + (\ x__ y__ -> x__ {_VotingProcedure'anchor = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) +instance Data.ProtoLens.Field.HasField VotingProcedure "maybe'anchor" (Prelude.Maybe Anchor) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _VotingProcedure'anchor + (\ x__ y__ -> x__ {_VotingProcedure'anchor = y__})) + Prelude.id +instance Data.ProtoLens.Message VotingProcedure where + messageName _ + = Data.Text.pack "utxorpc.v1beta.cardano.VotingProcedure" + packedMessageDescriptor _ + = "\n\ + \\SIVotingProcedure\DC2N\n\ + \\rgov_action_id\CAN\SOH \SOH(\v2*.utxorpc.v1beta.cardano.GovernanceActionIdR\vgovActionId\DC20\n\ + \\EOTvote\CAN\STX \SOH(\SO2\FS.utxorpc.v1beta.cardano.VoteR\EOTvote\DC2;\n\ + \\ACKanchor\CAN\ETX \SOH(\v2\RS.utxorpc.v1beta.cardano.AnchorH\NULR\ACKanchor\136\SOH\SOHB\t\n\ + \\a_anchor" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + govActionId__field_descriptor + = Data.ProtoLens.FieldDescriptor + "gov_action_id" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor GovernanceActionId) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'govActionId")) :: + Data.ProtoLens.FieldDescriptor VotingProcedure + vote__field_descriptor + = Data.ProtoLens.FieldDescriptor + "vote" + (Data.ProtoLens.ScalarField Data.ProtoLens.EnumField :: + Data.ProtoLens.FieldTypeDescriptor Vote) + (Data.ProtoLens.PlainField + Data.ProtoLens.Optional (Data.ProtoLens.Field.field @"vote")) :: + Data.ProtoLens.FieldDescriptor VotingProcedure + anchor__field_descriptor + = Data.ProtoLens.FieldDescriptor + "anchor" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor Anchor) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'anchor")) :: + Data.ProtoLens.FieldDescriptor VotingProcedure + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, govActionId__field_descriptor), + (Data.ProtoLens.Tag 2, vote__field_descriptor), + (Data.ProtoLens.Tag 3, anchor__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _VotingProcedure'_unknownFields + (\ x__ y__ -> x__ {_VotingProcedure'_unknownFields = y__}) + defMessage + = VotingProcedure'_constructor + {_VotingProcedure'govActionId = Prelude.Nothing, + _VotingProcedure'vote = Data.ProtoLens.fieldDefault, + _VotingProcedure'anchor = Prelude.Nothing, + _VotingProcedure'_unknownFields = []} + parseMessage + = let + loop :: + VotingProcedure + -> Data.ProtoLens.Encoding.Bytes.Parser VotingProcedure + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "gov_action_id" + loop + (Lens.Family2.set (Data.ProtoLens.Field.field @"govActionId") y x) + 16 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (Prelude.fmap + Prelude.toEnum + (Prelude.fmap + Prelude.fromIntegral + Data.ProtoLens.Encoding.Bytes.getVarInt)) + "vote" + loop (Lens.Family2.set (Data.ProtoLens.Field.field @"vote") y x) + 26 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "anchor" + loop (Lens.Family2.set (Data.ProtoLens.Field.field @"anchor") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "VotingProcedure" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (case + Lens.Family2.view + (Data.ProtoLens.Field.field @"maybe'govActionId") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + ((Data.Monoid.<>) + (let _v = Lens.Family2.view (Data.ProtoLens.Field.field @"vote") _x + in + if (Prelude.==) _v Data.ProtoLens.fieldDefault then + Data.Monoid.mempty + else + (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 16) + ((Prelude..) + ((Prelude..) + Data.ProtoLens.Encoding.Bytes.putVarInt Prelude.fromIntegral) + Prelude.fromEnum _v)) + ((Data.Monoid.<>) + (case + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'anchor") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 26) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)))) +instance Control.DeepSeq.NFData VotingProcedure where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_VotingProcedure'_unknownFields x__) + (Control.DeepSeq.deepseq + (_VotingProcedure'govActionId x__) + (Control.DeepSeq.deepseq + (_VotingProcedure'vote x__) + (Control.DeepSeq.deepseq (_VotingProcedure'anchor x__) ()))) +{- | Fields : + * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.thresholds' @:: Lens' VotingThresholds [RationalNumber]@ * 'Proto.Utxorpc.V1beta.Cardano.Cardano_Fields.vec'thresholds' @:: Lens' VotingThresholds (Data.Vector.Vector RationalNumber)@ -} data VotingThresholds @@ -31267,15 +32854,17 @@ packedFileDescriptor \\foutput_index\CAN\STX \SOH(\rR\voutputIndex\DC2=\n\ \\tas_output\CAN\ETX \SOH(\v2 .utxorpc.v1beta.cardano.TxOutputR\basOutput\DC2A\n\ \\bredeemer\CAN\EOT \SOH(\v2 .utxorpc.v1beta.cardano.RedeemerH\NULR\bredeemer\136\SOH\SOHB\v\n\ - \\t_redeemer\"\160\STX\n\ + \\t_redeemer\"\220\STX\n\ \\bTxOutput\DC2\CAN\n\ \\aaddress\CAN\SOH \SOH(\fR\aaddress\DC22\n\ \\EOTcoin\CAN\STX \SOH(\v2\RS.utxorpc.v1beta.cardano.BigIntR\EOTcoin\DC2:\n\ \\ACKassets\CAN\ETX \ETX(\v2\".utxorpc.v1beta.cardano.MultiassetR\ACKassets\DC28\n\ \\ENQdatum\CAN\EOT \SOH(\v2\GS.utxorpc.v1beta.cardano.DatumH\NULR\ENQdatum\136\SOH\SOH\DC2;\n\ - \\ACKscript\CAN\ENQ \SOH(\v2\RS.utxorpc.v1beta.cardano.ScriptH\SOHR\ACKscript\136\SOH\SOHB\b\n\ + \\ACKscript\CAN\ENQ \SOH(\v2\RS.utxorpc.v1beta.cardano.ScriptH\SOHR\ACKscript\136\SOH\SOH\DC2(\n\ + \\roriginal_cbor\CAN\ACK \SOH(\fH\STXR\foriginalCbor\136\SOH\SOHB\b\n\ \\ACK_datumB\t\n\ - \\a_script\"\166\SOH\n\ + \\a_scriptB\DLE\n\ + \\SO_original_cbor\"\166\SOH\n\ \\ENQDatum\DC2\DC2\n\ \\EOThash\CAN\SOH \SOH(\fR\EOThash\DC2A\n\ \\apayload\CAN\STX \SOH(\v2\".utxorpc.v1beta.cardano.PlutusDataH\NULR\apayload\136\SOH\SOH\DC2(\n\ @@ -31315,7 +32904,7 @@ packedFileDescriptor \\DC2bootstrapWitnesses\CAN\ENQ \ETX(\v2(.utxorpc.v1beta.cardano.BootstrapWitnessR\DC2bootstrapWitnesses\"\129\SOH\n\ \\aAuxData\DC2<\n\ \\bmetadata\CAN\SOH \ETX(\v2 .utxorpc.v1beta.cardano.MetadataR\bmetadata\DC28\n\ - \\ascripts\CAN\STX \ETX(\v2\RS.utxorpc.v1beta.cardano.ScriptR\ascripts\"\199\ACK\n\ + \\ascripts\CAN\STX \ETX(\v2\RS.utxorpc.v1beta.cardano.ScriptR\ascripts\"\129\a\n\ \\STXTx\DC27\n\ \\ACKinputs\CAN\SOH \ETX(\v2\US.utxorpc.v1beta.cardano.TxInputR\ACKinputs\DC2:\n\ \\aoutputs\CAN\STX \ETX(\v2 .utxorpc.v1beta.cardano.TxOutputR\aoutputs\DC2G\n\ @@ -31335,7 +32924,8 @@ packedFileDescriptor \successful\DC2=\n\ \\tauxiliary\CAN\f \SOH(\v2\US.utxorpc.v1beta.cardano.AuxDataR\tauxiliary\DC2\DC2\n\ \\EOThash\CAN\r \SOH(\fR\EOThash\DC2N\n\ - \\tproposals\CAN\SO \ETX(\v20.utxorpc.v1beta.cardano.GovernanceActionProposalR\tproposals\"\252\SOH\n\ + \\tproposals\CAN\SO \ETX(\v20.utxorpc.v1beta.cardano.GovernanceActionProposalR\tproposals\DC28\n\ + \\ENQvotes\CAN\SI \ETX(\v2\".utxorpc.v1beta.cardano.VoterVotesR\ENQvotes\"\252\SOH\n\ \\CANGovernanceActionProposal\DC28\n\ \\adeposit\CAN\SOH \SOH(\v2\RS.utxorpc.v1beta.cardano.BigIntR\adeposit\DC2%\n\ \\SOreward_account\CAN\STX \SOH(\fR\rrewardAccount\DC2G\n\ @@ -31354,7 +32944,19 @@ packedFileDescriptor \\DC1governance_action\"s\n\ \\DC2GovernanceActionId\DC2%\n\ \\SOtransaction_id\CAN\SOH \SOH(\fR\rtransactionId\DC26\n\ - \\ETBgovernance_action_index\CAN\STX \SOH(\rR\NAKgovernanceActionIndex\"\221\SOH\n\ + \\ETBgovernance_action_index\CAN\STX \SOH(\rR\NAKgovernanceActionIndex\"\219\SOH\n\ + \\SIVotingProcedure\DC2N\n\ + \\rgov_action_id\CAN\SOH \SOH(\v2*.utxorpc.v1beta.cardano.GovernanceActionIdR\vgovActionId\DC20\n\ + \\EOTvote\CAN\STX \SOH(\SO2\FS.utxorpc.v1beta.cardano.VoteR\EOTvote\DC2;\n\ + \\ACKanchor\CAN\ETX \SOH(\v2\RS.utxorpc.v1beta.cardano.AnchorH\NULR\ACKanchor\136\SOH\SOHB\t\n\ + \\a_anchor\"\141\STX\n\ + \\n\ + \VoterVotes\DC2d\n\ + \\CANconstitutional_committee\CAN\SOH \SOH(\v2'.utxorpc.v1beta.cardano.StakeCredentialH\NULR\ETBconstitutionalCommittee\DC2=\n\ + \\EOTdrep\CAN\STX \SOH(\v2'.utxorpc.v1beta.cardano.StakeCredentialH\NULR\EOTdrep\DC2\DC2\n\ + \\ETXspo\CAN\ETX \SOH(\fH\NULR\ETXspo\DC2=\n\ + \\ENQvotes\CAN\EOT \ETX(\v2'.utxorpc.v1beta.cardano.VotingProcedureR\ENQvotesB\a\n\ + \\ENQvoter\"\221\SOH\n\ \\NAKParameterChangeAction\DC2N\n\ \\rgov_action_id\CAN\SOH \SOH(\v2*.utxorpc.v1beta.cardano.GovernanceActionIdR\vgovActionId\DC2S\n\ \\NAKprotocol_param_update\CAN\STX \SOH(\v2\US.utxorpc.v1beta.cardano.PParamsR\DC3protocolParamUpdate\DC2\US\n\ @@ -31596,7 +33198,23 @@ packedFileDescriptor \\EOTcoin\CAN\STX \SOH(\v2\RS.utxorpc.v1beta.cardano.BigIntR\EOTcoin\"\154\SOH\n\ \\SOUpdateDRepCert\DC2P\n\ \\SIdrep_credential\CAN\SOH \SOH(\v2'.utxorpc.v1beta.cardano.StakeCredentialR\SOdrepCredential\DC26\n\ - \\ACKanchor\CAN\STX \SOH(\v2\RS.utxorpc.v1beta.cardano.AnchorR\ACKanchor\"\199\SOH\n\ + \\ACKanchor\CAN\STX \SOH(\v2\RS.utxorpc.v1beta.cardano.AnchorR\ACKanchor\"\129\SOH\n\ + \\n\ + \StateQuery\DC2j\n\ + \\ETBstake_pool_distribution\CAN\SOH \SOH(\v20.utxorpc.v1beta.cardano.GetStakePoolDistributionH\NULR\NAKstakePoolDistributionB\a\n\ + \\ENQquery\"~\n\ + \\tStateData\DC2g\n\ + \\ETBstake_pool_distribution\CAN\SOH \SOH(\v2-.utxorpc.v1beta.cardano.StakePoolDistributionH\NULR\NAKstakePoolDistributionB\b\n\ + \\ACKresult\"A\n\ + \\CANGetStakePoolDistribution\DC2%\n\ + \\SOpool_keyhashes\CAN\SOH \ETX(\fR\rpoolKeyhashes\"\163\SOH\n\ + \\SOPoolStakeShare\DC2!\n\ + \\fpool_keyhash\CAN\SOH \SOH(\fR\vpoolKeyhash\DC2M\n\ + \\SOstake_fraction\CAN\STX \SOH(\v2&.utxorpc.v1beta.cardano.RationalNumberR\rstakeFraction\DC2\US\n\ + \\vvrf_keyhash\CAN\ETX \SOH(\fR\n\ + \vrfKeyhash\"U\n\ + \\NAKStakePoolDistribution\DC2<\n\ + \\ENQpools\CAN\SOH \ETX(\v2&.utxorpc.v1beta.cardano.PoolStakeShareR\ENQpools\"\199\SOH\n\ \\SOAddressPattern\DC2(\n\ \\rexact_address\CAN\SOH \SOH(\fH\NULR\fexactAddress\136\SOH\SOH\DC2&\n\ \\fpayment_part\CAN\STX \SOH(\fH\SOHR\vpaymentPart\136\SOH\SOH\DC2,\n\ @@ -31882,13 +33500,18 @@ packedFileDescriptor \\NAKREDEEMER_PURPOSE_CERT\DLE\ETX\DC2\ESC\n\ \\ETBREDEEMER_PURPOSE_REWARD\DLE\EOT\DC2\EM\n\ \\NAKREDEEMER_PURPOSE_VOTE\DLE\ENQ\DC2\FS\n\ - \\CANREDEEMER_PURPOSE_PROPOSE\DLE\ACK*Y\n\ + \\CANREDEEMER_PURPOSE_PROPOSE\DLE\ACK*I\n\ + \\EOTVote\DC2\DC4\n\ + \\DLEVOTE_UNSPECIFIED\DLE\NUL\DC2\v\n\ + \\aVOTE_NO\DLE\SOH\DC2\f\n\ + \\bVOTE_YES\DLE\STX\DC2\DLE\n\ + \\fVOTE_ABSTAIN\DLE\ETX*Y\n\ \\tMirSource\DC2\SUB\n\ \\SYNMIR_SOURCE_UNSPECIFIED\DLE\NUL\DC2\ETB\n\ \\DC3MIR_SOURCE_RESERVES\DLE\SOH\DC2\ETB\n\ \\DC3MIR_SOURCE_TREASURY\DLE\STXB\164\SOH\n\ - \\SUBcom.utxorpc.v1beta.cardanoB\fCardanoProtoP\SOH\162\STX\ETXUVC\170\STX\SYNUtxorpc.V1beta.Cardano\202\STX\SYNUtxorpc\\V1beta\\Cardano\226\STX\"Utxorpc\\V1beta\\Cardano\\GPBMetadata\234\STX\CANUtxorpc::V1beta::CardanoJ\177\180\STX\n\ - \\a\DC2\ENQ\NUL\NUL\188\ACK\SOH\n\ + \\SUBcom.utxorpc.v1beta.cardanoB\fCardanoProtoP\SOH\162\STX\ETXUVC\170\STX\SYNUtxorpc.V1beta.Cardano\202\STX\SYNUtxorpc\\V1beta\\Cardano\226\STX\"Utxorpc\\V1beta\\Cardano\\GPBMetadata\234\STX\CANUtxorpc::V1beta::CardanoJ\246\204\STX\n\ + \\a\DC2\ENQ\NUL\NUL\129\a\SOH\n\ \\b\n\ \\SOH\f\DC2\ETX\NUL\NUL\DC2\n\ \\b\n\ @@ -32043,7 +33666,7 @@ packedFileDescriptor \\f\n\ \\ENQ\EOT\SOH\STX\ETX\ETX\DC2\ETX\GS\US \n\ \H\n\ - \\STX\EOT\STX\DC2\EOT!\NUL'\SOH\SUB< Represents a transaction output in the Cardano blockchain.\n\ + \\STX\EOT\STX\DC2\EOT!\NUL(\SOH\SUB< Represents a transaction output in the Cardano blockchain.\n\ \\n\ \\n\ \\n\ @@ -32102,3154 +33725,3403 @@ packedFileDescriptor \\ENQ\EOT\STX\STX\EOT\SOH\DC2\ETX&\DC2\CAN\n\ \\f\n\ \\ENQ\EOT\STX\STX\EOT\ETX\DC2\ETX&\ESC\FS\n\ + \=\n\ + \\EOT\EOT\STX\STX\ENQ\DC2\ETX'\STX#\"0 Original cbor-encoded output as seen on-chain.\n\ \\n\ + \\f\n\ + \\ENQ\EOT\STX\STX\ENQ\EOT\DC2\ETX'\STX\n\ + \\n\ + \\f\n\ + \\ENQ\EOT\STX\STX\ENQ\ENQ\DC2\ETX'\v\DLE\n\ + \\f\n\ + \\ENQ\EOT\STX\STX\ENQ\SOH\DC2\ETX'\DC1\RS\n\ + \\f\n\ + \\ENQ\EOT\STX\STX\ENQ\ETX\DC2\ETX'!\"\n\ \\n\ - \\STX\EOT\ETX\DC2\EOT)\NUL-\SOH\n\ \\n\ + \\STX\EOT\ETX\DC2\EOT*\NUL.\SOH\n\ \\n\ - \\ETX\EOT\ETX\SOH\DC2\ETX)\b\r\n\ + \\n\ + \\ETX\EOT\ETX\SOH\DC2\ETX*\b\r\n\ \2\n\ - \\EOT\EOT\ETX\STX\NUL\DC2\ETX*\STX\DC1\"% Hash of this datum as seen on-chain\n\ + \\EOT\EOT\ETX\STX\NUL\DC2\ETX+\STX\DC1\"% Hash of this datum as seen on-chain\n\ \\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\NUL\ENQ\DC2\ETX*\STX\a\n\ + \\ENQ\EOT\ETX\STX\NUL\ENQ\DC2\ETX+\STX\a\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\NUL\SOH\DC2\ETX*\b\f\n\ + \\ENQ\EOT\ETX\STX\NUL\SOH\DC2\ETX+\b\f\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\NUL\ETX\DC2\ETX*\SI\DLE\n\ + \\ENQ\EOT\ETX\STX\NUL\ETX\DC2\ETX+\SI\DLE\n\ \)\n\ - \\EOT\EOT\ETX\STX\SOH\DC2\ETX+\STX\"\"\FS Parsed Plutus data payload\n\ + \\EOT\EOT\ETX\STX\SOH\DC2\ETX,\STX\"\"\FS Parsed Plutus data payload\n\ \\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\SOH\EOT\DC2\ETX+\STX\n\ + \\ENQ\EOT\ETX\STX\SOH\EOT\DC2\ETX,\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\SOH\ACK\DC2\ETX+\v\NAK\n\ + \\ENQ\EOT\ETX\STX\SOH\ACK\DC2\ETX,\v\NAK\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\SOH\SOH\DC2\ETX+\SYN\GS\n\ + \\ENQ\EOT\ETX\STX\SOH\SOH\DC2\ETX,\SYN\GS\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\SOH\ETX\DC2\ETX+ !\n\ + \\ENQ\EOT\ETX\STX\SOH\ETX\DC2\ETX, !\n\ \:\n\ - \\EOT\EOT\ETX\STX\STX\DC2\ETX,\STX#\"- Original cbor-encoded data as seen on-chain\n\ + \\EOT\EOT\ETX\STX\STX\DC2\ETX-\STX#\"- Original cbor-encoded data as seen on-chain\n\ \\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\STX\EOT\DC2\ETX,\STX\n\ + \\ENQ\EOT\ETX\STX\STX\EOT\DC2\ETX-\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\STX\ENQ\DC2\ETX,\v\DLE\n\ + \\ENQ\EOT\ETX\STX\STX\ENQ\DC2\ETX-\v\DLE\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\STX\SOH\DC2\ETX,\DC1\RS\n\ + \\ENQ\EOT\ETX\STX\STX\SOH\DC2\ETX-\DC1\RS\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\STX\ETX\DC2\ETX,!\"\n\ + \\ENQ\EOT\ETX\STX\STX\ETX\DC2\ETX-!\"\n\ \B\n\ - \\STX\EOT\EOT\DC2\EOT0\NUL3\SOH\SUB6 Represents a custom asset in the Cardano blockchain.\n\ + \\STX\EOT\EOT\DC2\EOT1\NUL4\SOH\SUB6 Represents a custom asset in the Cardano blockchain.\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\EOT\SOH\DC2\ETX0\b\r\n\ + \\ETX\EOT\EOT\SOH\DC2\ETX1\b\r\n\ \(\n\ - \\EOT\EOT\EOT\STX\NUL\DC2\ETX1\STX\DC1\"\ESC Name of the custom asset.\n\ + \\EOT\EOT\EOT\STX\NUL\DC2\ETX2\STX\DC1\"\ESC Name of the custom asset.\n\ \\n\ \\f\n\ - \\ENQ\EOT\EOT\STX\NUL\ENQ\DC2\ETX1\STX\a\n\ + \\ENQ\EOT\EOT\STX\NUL\ENQ\DC2\ETX2\STX\a\n\ \\f\n\ - \\ENQ\EOT\EOT\STX\NUL\SOH\DC2\ETX1\b\f\n\ + \\ENQ\EOT\EOT\STX\NUL\SOH\DC2\ETX2\b\f\n\ \\f\n\ - \\ENQ\EOT\EOT\STX\NUL\ETX\DC2\ETX1\SI\DLE\n\ + \\ENQ\EOT\EOT\STX\NUL\ETX\DC2\ETX2\SI\DLE\n\ \\139\SOH\n\ - \\EOT\EOT\EOT\STX\SOH\DC2\ETX2\STX\SYN\"~ Quantity of the custom asset. This can be negative only if it is in a `Tx.mint` field and the transaction is burning tokens.\n\ + \\EOT\EOT\EOT\STX\SOH\DC2\ETX3\STX\SYN\"~ Quantity of the custom asset. This can be negative only if it is in a `Tx.mint` field and the transaction is burning tokens.\n\ \\n\ \\f\n\ - \\ENQ\EOT\EOT\STX\SOH\ACK\DC2\ETX2\STX\b\n\ + \\ENQ\EOT\EOT\STX\SOH\ACK\DC2\ETX3\STX\b\n\ \\f\n\ - \\ENQ\EOT\EOT\STX\SOH\SOH\DC2\ETX2\t\DC1\n\ + \\ENQ\EOT\EOT\STX\SOH\SOH\DC2\ETX3\t\DC1\n\ \\f\n\ - \\ENQ\EOT\EOT\STX\SOH\ETX\DC2\ETX2\DC4\NAK\n\ + \\ENQ\EOT\EOT\STX\SOH\ETX\DC2\ETX3\DC4\NAK\n\ \G\n\ - \\STX\EOT\ENQ\DC2\EOT6\NUL9\SOH\SUB; Represents a multi-asset group in the Cardano blockchain.\n\ + \\STX\EOT\ENQ\DC2\EOT7\NUL:\SOH\SUB; Represents a multi-asset group in the Cardano blockchain.\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\ENQ\SOH\DC2\ETX6\b\DC2\n\ + \\ETX\EOT\ENQ\SOH\DC2\ETX7\b\DC2\n\ \5\n\ - \\EOT\EOT\ENQ\STX\NUL\DC2\ETX7\STX\SYN\"( Policy ID governing the custom assets.\n\ + \\EOT\EOT\ENQ\STX\NUL\DC2\ETX8\STX\SYN\"( Policy ID governing the custom assets.\n\ \\n\ \\f\n\ - \\ENQ\EOT\ENQ\STX\NUL\ENQ\DC2\ETX7\STX\a\n\ + \\ENQ\EOT\ENQ\STX\NUL\ENQ\DC2\ETX8\STX\a\n\ \\f\n\ - \\ENQ\EOT\ENQ\STX\NUL\SOH\DC2\ETX7\b\DC1\n\ + \\ENQ\EOT\ENQ\STX\NUL\SOH\DC2\ETX8\b\DC1\n\ \\f\n\ - \\ENQ\EOT\ENQ\STX\NUL\ETX\DC2\ETX7\DC4\NAK\n\ + \\ENQ\EOT\ENQ\STX\NUL\ETX\DC2\ETX8\DC4\NAK\n\ \%\n\ - \\EOT\EOT\ENQ\STX\SOH\DC2\ETX8\STX\FS\"\CAN List of custom assets.\n\ + \\EOT\EOT\ENQ\STX\SOH\DC2\ETX9\STX\FS\"\CAN List of custom assets.\n\ \\n\ \\f\n\ - \\ENQ\EOT\ENQ\STX\SOH\EOT\DC2\ETX8\STX\n\ + \\ENQ\EOT\ENQ\STX\SOH\EOT\DC2\ETX9\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\ENQ\STX\SOH\ACK\DC2\ETX8\v\DLE\n\ + \\ENQ\EOT\ENQ\STX\SOH\ACK\DC2\ETX9\v\DLE\n\ \\f\n\ - \\ENQ\EOT\ENQ\STX\SOH\SOH\DC2\ETX8\DC1\ETB\n\ + \\ENQ\EOT\ENQ\STX\SOH\SOH\DC2\ETX9\DC1\ETB\n\ \\f\n\ - \\ENQ\EOT\ENQ\STX\SOH\ETX\DC2\ETX8\SUB\ESC\n\ + \\ENQ\EOT\ENQ\STX\SOH\ETX\DC2\ETX9\SUB\ESC\n\ \@\n\ - \\STX\EOT\ACK\DC2\EOT<\NUL?\SOH\SUB4 Represents the validity interval of a transaction.\n\ + \\STX\EOT\ACK\DC2\EOT=\NUL@\SOH\SUB4 Represents the validity interval of a transaction.\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\ACK\SOH\DC2\ETX<\b\DC2\n\ + \\ETX\EOT\ACK\SOH\DC2\ETX=\b\DC2\n\ \.\n\ - \\EOT\EOT\ACK\STX\NUL\DC2\ETX=\STX\DC3\"! Start of the validity interval.\n\ + \\EOT\EOT\ACK\STX\NUL\DC2\ETX>\STX\DC3\"! Start of the validity interval.\n\ \\n\ \\f\n\ - \\ENQ\EOT\ACK\STX\NUL\ENQ\DC2\ETX=\STX\b\n\ + \\ENQ\EOT\ACK\STX\NUL\ENQ\DC2\ETX>\STX\b\n\ \\f\n\ - \\ENQ\EOT\ACK\STX\NUL\SOH\DC2\ETX=\t\SO\n\ + \\ENQ\EOT\ACK\STX\NUL\SOH\DC2\ETX>\t\SO\n\ \\f\n\ - \\ENQ\EOT\ACK\STX\NUL\ETX\DC2\ETX=\DC1\DC2\n\ + \\ENQ\EOT\ACK\STX\NUL\ETX\DC2\ETX>\DC1\DC2\n\ \@\n\ - \\EOT\EOT\ACK\STX\SOH\DC2\ETX>\STX\DC1\"3 End of the validity interval (TTL: Time to Live).\n\ + \\EOT\EOT\ACK\STX\SOH\DC2\ETX?\STX\DC1\"3 End of the validity interval (TTL: Time to Live).\n\ \\n\ \\f\n\ - \\ENQ\EOT\ACK\STX\SOH\ENQ\DC2\ETX>\STX\b\n\ + \\ENQ\EOT\ACK\STX\SOH\ENQ\DC2\ETX?\STX\b\n\ \\f\n\ - \\ENQ\EOT\ACK\STX\SOH\SOH\DC2\ETX>\t\f\n\ + \\ENQ\EOT\ACK\STX\SOH\SOH\DC2\ETX?\t\f\n\ \\f\n\ - \\ENQ\EOT\ACK\STX\SOH\ETX\DC2\ETX>\SI\DLE\n\ + \\ENQ\EOT\ACK\STX\SOH\ETX\DC2\ETX?\SI\DLE\n\ \F\n\ - \\STX\EOT\a\DC2\EOTB\NULF\SOH\SUB: Represents the collateral information for a transaction.\n\ + \\STX\EOT\a\DC2\EOTC\NULG\SOH\SUB: Represents the collateral information for a transaction.\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\a\SOH\DC2\ETXB\b\DC2\n\ + \\ETX\EOT\a\SOH\DC2\ETXC\b\DC2\n\ \5\n\ - \\EOT\EOT\a\STX\NUL\DC2\ETXC\STX\"\"( Collateral inputs for the transaction.\n\ + \\EOT\EOT\a\STX\NUL\DC2\ETXD\STX\"\"( Collateral inputs for the transaction.\n\ \\n\ \\f\n\ - \\ENQ\EOT\a\STX\NUL\EOT\DC2\ETXC\STX\n\ + \\ENQ\EOT\a\STX\NUL\EOT\DC2\ETXD\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\a\STX\NUL\ACK\DC2\ETXC\v\DC2\n\ + \\ENQ\EOT\a\STX\NUL\ACK\DC2\ETXD\v\DC2\n\ \\f\n\ - \\ENQ\EOT\a\STX\NUL\SOH\DC2\ETXC\DC3\GS\n\ + \\ENQ\EOT\a\STX\NUL\SOH\DC2\ETXD\DC3\GS\n\ \\f\n\ - \\ENQ\EOT\a\STX\NUL\ETX\DC2\ETXC !\n\ + \\ENQ\EOT\a\STX\NUL\ETX\DC2\ETXD !\n\ \;\n\ - \\EOT\EOT\a\STX\SOH\DC2\ETXD\STX!\". Collateral return in case of script failure.\n\ + \\EOT\EOT\a\STX\SOH\DC2\ETXE\STX!\". Collateral return in case of script failure.\n\ \\n\ \\f\n\ - \\ENQ\EOT\a\STX\SOH\ACK\DC2\ETXD\STX\n\ + \\ENQ\EOT\a\STX\SOH\ACK\DC2\ETXE\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\a\STX\SOH\SOH\DC2\ETXD\v\FS\n\ + \\ENQ\EOT\a\STX\SOH\SOH\DC2\ETXE\v\FS\n\ \\f\n\ - \\ENQ\EOT\a\STX\SOH\ETX\DC2\ETXD\US \n\ + \\ENQ\EOT\a\STX\SOH\ETX\DC2\ETXE\US \n\ \*\n\ - \\EOT\EOT\a\STX\STX\DC2\ETXE\STX\RS\"\GS Total amount of collateral.\n\ + \\EOT\EOT\a\STX\STX\DC2\ETXF\STX\RS\"\GS Total amount of collateral.\n\ \\n\ \\f\n\ - \\ENQ\EOT\a\STX\STX\ACK\DC2\ETXE\STX\b\n\ + \\ENQ\EOT\a\STX\STX\ACK\DC2\ETXF\STX\b\n\ \\f\n\ - \\ENQ\EOT\a\STX\STX\SOH\DC2\ETXE\t\EM\n\ + \\ENQ\EOT\a\STX\STX\SOH\DC2\ETXF\t\EM\n\ \\f\n\ - \\ENQ\EOT\a\STX\STX\ETX\DC2\ETXE\FS\GS\n\ + \\ENQ\EOT\a\STX\STX\ETX\DC2\ETXF\FS\GS\n\ \<\n\ - \\STX\EOT\b\DC2\EOTI\NULM\SOH\SUB0 Represents a withdrawal from a reward account.\n\ + \\STX\EOT\b\DC2\EOTJ\NULN\SOH\SUB0 Represents a withdrawal from a reward account.\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\b\SOH\DC2\ETXI\b\DC2\n\ + \\ETX\EOT\b\SOH\DC2\ETXJ\b\DC2\n\ \-\n\ - \\EOT\EOT\b\STX\NUL\DC2\ETXJ\STX\ESC\" Address of the reward account.\n\ + \\EOT\EOT\b\STX\NUL\DC2\ETXK\STX\ESC\" Address of the reward account.\n\ \\n\ \\f\n\ - \\ENQ\EOT\b\STX\NUL\ENQ\DC2\ETXJ\STX\a\n\ + \\ENQ\EOT\b\STX\NUL\ENQ\DC2\ETXK\STX\a\n\ \\f\n\ - \\ENQ\EOT\b\STX\NUL\SOH\DC2\ETXJ\b\SYN\n\ + \\ENQ\EOT\b\STX\NUL\SOH\DC2\ETXK\b\SYN\n\ \\f\n\ - \\ENQ\EOT\b\STX\NUL\ETX\DC2\ETXJ\EM\SUB\n\ + \\ENQ\EOT\b\STX\NUL\ETX\DC2\ETXK\EM\SUB\n\ \'\n\ - \\EOT\EOT\b\STX\SOH\DC2\ETXK\STX\DC2\"\SUB Amount of ADA withdrawn.\n\ + \\EOT\EOT\b\STX\SOH\DC2\ETXL\STX\DC2\"\SUB Amount of ADA withdrawn.\n\ \\n\ \\f\n\ - \\ENQ\EOT\b\STX\SOH\ACK\DC2\ETXK\STX\b\n\ + \\ENQ\EOT\b\STX\SOH\ACK\DC2\ETXL\STX\b\n\ \\f\n\ - \\ENQ\EOT\b\STX\SOH\SOH\DC2\ETXK\t\r\n\ + \\ENQ\EOT\b\STX\SOH\SOH\DC2\ETXL\t\r\n\ \\f\n\ - \\ENQ\EOT\b\STX\SOH\ETX\DC2\ETXK\DLE\DC1\n\ + \\ENQ\EOT\b\STX\SOH\ETX\DC2\ETXL\DLE\DC1\n\ \.\n\ - \\EOT\EOT\b\STX\STX\DC2\ETXL\STX\CAN\"! Redeemer for the Plutus script.\n\ + \\EOT\EOT\b\STX\STX\DC2\ETXM\STX\CAN\"! Redeemer for the Plutus script.\n\ \\n\ \\f\n\ - \\ENQ\EOT\b\STX\STX\ACK\DC2\ETXL\STX\n\ + \\ENQ\EOT\b\STX\STX\ACK\DC2\ETXM\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\b\STX\STX\SOH\DC2\ETXL\v\DC3\n\ + \\ENQ\EOT\b\STX\STX\SOH\DC2\ETXM\v\DC3\n\ \\f\n\ - \\ENQ\EOT\b\STX\STX\ETX\DC2\ETXL\SYN\ETB\n\ + \\ENQ\EOT\b\STX\STX\ETX\DC2\ETXM\SYN\ETB\n\ \G\n\ - \\STX\EOT\t\DC2\EOTP\NULV\SOH\SUB; Represents a set of witnesses that validate a transaction\n\ + \\STX\EOT\t\DC2\EOTQ\NULW\SOH\SUB; Represents a set of witnesses that validate a transaction\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\t\SOH\DC2\ETXP\b\DC2\n\ + \\ETX\EOT\t\SOH\DC2\ETXQ\b\DC2\n\ \&\n\ - \\EOT\EOT\t\STX\NUL\DC2\ETXQ\STX'\"\EM List of VKey witnesses.\n\ + \\EOT\EOT\t\STX\NUL\DC2\ETXR\STX'\"\EM List of VKey witnesses.\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\NUL\EOT\DC2\ETXQ\STX\n\ + \\ENQ\EOT\t\STX\NUL\EOT\DC2\ETXR\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\NUL\ACK\DC2\ETXQ\v\SYN\n\ + \\ENQ\EOT\t\STX\NUL\ACK\DC2\ETXR\v\SYN\n\ \\f\n\ - \\ENQ\EOT\t\STX\NUL\SOH\DC2\ETXQ\ETB\"\n\ + \\ENQ\EOT\t\STX\NUL\SOH\DC2\ETXR\ETB\"\n\ \\f\n\ - \\ENQ\EOT\t\STX\NUL\ETX\DC2\ETXQ%&\n\ + \\ENQ\EOT\t\STX\NUL\ETX\DC2\ETXR%&\n\ \\US\n\ - \\EOT\EOT\t\STX\SOH\DC2\ETXR\STX\GS\"\DC2 List of scripts.\n\ + \\EOT\EOT\t\STX\SOH\DC2\ETXS\STX\GS\"\DC2 List of scripts.\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\SOH\EOT\DC2\ETXR\STX\n\ + \\ENQ\EOT\t\STX\SOH\EOT\DC2\ETXS\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\SOH\ACK\DC2\ETXR\v\DC1\n\ + \\ENQ\EOT\t\STX\SOH\ACK\DC2\ETXS\v\DC1\n\ \\f\n\ - \\ENQ\EOT\t\STX\SOH\SOH\DC2\ETXR\DC2\CAN\n\ + \\ENQ\EOT\t\STX\SOH\SOH\DC2\ETXS\DC2\CAN\n\ \\f\n\ - \\ENQ\EOT\t\STX\SOH\ETX\DC2\ETXR\ESC\FS\n\ + \\ENQ\EOT\t\STX\SOH\ETX\DC2\ETXS\ESC\FS\n\ \L\n\ - \\EOT\EOT\t\STX\STX\DC2\ETXS\STX(\"? List of Plutus data elements associated with the transaction.\n\ + \\EOT\EOT\t\STX\STX\DC2\ETXT\STX(\"? List of Plutus data elements associated with the transaction.\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\STX\EOT\DC2\ETXS\STX\n\ + \\ENQ\EOT\t\STX\STX\EOT\DC2\ETXT\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\STX\ACK\DC2\ETXS\v\NAK\n\ + \\ENQ\EOT\t\STX\STX\ACK\DC2\ETXT\v\NAK\n\ \\f\n\ - \\ENQ\EOT\t\STX\STX\SOH\DC2\ETXS\SYN#\n\ + \\ENQ\EOT\t\STX\STX\SOH\DC2\ETXT\SYN#\n\ \\f\n\ - \\ENQ\EOT\t\STX\STX\ETX\DC2\ETXS&'\n\ + \\ENQ\EOT\t\STX\STX\ETX\DC2\ETXT&'\n\ \ \n\ - \\EOT\EOT\t\STX\ETX\DC2\ETXT\STX\"\"\DC3 List of redeemers\n\ + \\EOT\EOT\t\STX\ETX\DC2\ETXU\STX\"\"\DC3 List of redeemers\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\ETX\EOT\DC2\ETXT\STX\n\ + \\ENQ\EOT\t\STX\ETX\EOT\DC2\ETXU\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\ETX\ACK\DC2\ETXT\v\DC3\n\ + \\ENQ\EOT\t\STX\ETX\ACK\DC2\ETXU\v\DC3\n\ \\f\n\ - \\ENQ\EOT\t\STX\ETX\SOH\DC2\ETXT\DC4\GS\n\ + \\ENQ\EOT\t\STX\ETX\SOH\DC2\ETXU\DC4\GS\n\ \\f\n\ - \\ENQ\EOT\t\STX\ETX\ETX\DC2\ETXT !\n\ + \\ENQ\EOT\t\STX\ETX\ETX\DC2\ETXU !\n\ \*\n\ - \\EOT\EOT\t\STX\EOT\DC2\ETXU\STX3\"\GS List of bootstrap witnesses\n\ + \\EOT\EOT\t\STX\EOT\DC2\ETXV\STX3\"\GS List of bootstrap witnesses\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\EOT\EOT\DC2\ETXU\STX\n\ + \\ENQ\EOT\t\STX\EOT\EOT\DC2\ETXV\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\t\STX\EOT\ACK\DC2\ETXU\v\ESC\n\ + \\ENQ\EOT\t\STX\EOT\ACK\DC2\ETXV\v\ESC\n\ \\f\n\ - \\ENQ\EOT\t\STX\EOT\SOH\DC2\ETXU\FS.\n\ + \\ENQ\EOT\t\STX\EOT\SOH\DC2\ETXV\FS.\n\ \\f\n\ - \\ENQ\EOT\t\STX\EOT\ETX\DC2\ETXU12\n\ + \\ENQ\EOT\t\STX\EOT\ETX\DC2\ETXV12\n\ \H\n\ \\STX\EOT\n\ - \\DC2\EOTY\NUL\\\SOH\SUB< Auxiliary data not directly tied to the validation process\n\ + \\DC2\EOTZ\NUL]\SOH\SUB< Auxiliary data not directly tied to the validation process\n\ \\n\ \\n\ \\n\ \\ETX\EOT\n\ - \\SOH\DC2\ETXY\b\SI\n\ + \\SOH\DC2\ETXZ\b\SI\n\ \3\n\ \\EOT\EOT\n\ - \\STX\NUL\DC2\ETXZ\STX!\"& List of auxiliary metadata elements.\n\ + \\STX\NUL\DC2\ETX[\STX!\"& List of auxiliary metadata elements.\n\ \\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\NUL\EOT\DC2\ETXZ\STX\n\ + \\STX\NUL\EOT\DC2\ETX[\STX\n\ \\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\NUL\ACK\DC2\ETXZ\v\DC3\n\ + \\STX\NUL\ACK\DC2\ETX[\v\DC3\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\NUL\SOH\DC2\ETXZ\DC4\FS\n\ + \\STX\NUL\SOH\DC2\ETX[\DC4\FS\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\NUL\ETX\DC2\ETXZ\US \n\ + \\STX\NUL\ETX\DC2\ETX[\US \n\ \)\n\ \\EOT\EOT\n\ - \\STX\SOH\DC2\ETX[\STX\RS\"\FS List of auxiliary scripts.\n\ + \\STX\SOH\DC2\ETX\\\STX\RS\"\FS List of auxiliary scripts.\n\ \\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\SOH\EOT\DC2\ETX[\STX\n\ + \\STX\SOH\EOT\DC2\ETX\\\STX\n\ \\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\SOH\ACK\DC2\ETX[\v\DC1\n\ + \\STX\SOH\ACK\DC2\ETX\\\v\DC1\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\SOH\SOH\DC2\ETX[\DC2\EM\n\ + \\STX\SOH\SOH\DC2\ETX\\\DC2\EM\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\SOH\ETX\DC2\ETX[\FS\GS\n\ + \\STX\SOH\ETX\DC2\ETX\\\FS\GS\n\ \A\n\ - \\STX\EOT\v\DC2\EOT_\NULn\SOH\SUB5 Represents a transaction in the Cardano blockchain.\n\ + \\STX\EOT\v\DC2\EOT`\NULp\SOH\SUB5 Represents a transaction in the Cardano blockchain.\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\v\SOH\DC2\ETX_\b\n\ + \\ETX\EOT\v\SOH\DC2\ETX`\b\n\ \\n\ \)\n\ - \\EOT\EOT\v\STX\NUL\DC2\ETX`\STX\RS\"\FS List of transaction inputs\n\ + \\EOT\EOT\v\STX\NUL\DC2\ETXa\STX\RS\"\FS List of transaction inputs\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\EOT\DC2\ETX`\STX\n\ + \\ENQ\EOT\v\STX\NUL\EOT\DC2\ETXa\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\ACK\DC2\ETX`\v\DC2\n\ + \\ENQ\EOT\v\STX\NUL\ACK\DC2\ETXa\v\DC2\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\SOH\DC2\ETX`\DC3\EM\n\ + \\ENQ\EOT\v\STX\NUL\SOH\DC2\ETXa\DC3\EM\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\ETX\DC2\ETX`\FS\GS\n\ + \\ENQ\EOT\v\STX\NUL\ETX\DC2\ETXa\FS\GS\n\ \*\n\ - \\EOT\EOT\v\STX\SOH\DC2\ETXa\STX \"\GS List of transaction outputs\n\ + \\EOT\EOT\v\STX\SOH\DC2\ETXb\STX \"\GS List of transaction outputs\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\SOH\EOT\DC2\ETXa\STX\n\ + \\ENQ\EOT\v\STX\SOH\EOT\DC2\ETXb\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\SOH\ACK\DC2\ETXa\v\DC3\n\ + \\ENQ\EOT\v\STX\SOH\ACK\DC2\ETXb\v\DC3\n\ \\f\n\ - \\ENQ\EOT\v\STX\SOH\SOH\DC2\ETXa\DC4\ESC\n\ + \\ENQ\EOT\v\STX\SOH\SOH\DC2\ETXb\DC4\ESC\n\ \\f\n\ - \\ENQ\EOT\v\STX\SOH\ETX\DC2\ETXa\RS\US\n\ + \\ENQ\EOT\v\STX\SOH\ETX\DC2\ETXb\RS\US\n\ \#\n\ - \\EOT\EOT\v\STX\STX\DC2\ETXb\STX(\"\SYN List of certificates\n\ + \\EOT\EOT\v\STX\STX\DC2\ETXc\STX(\"\SYN List of certificates\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\STX\EOT\DC2\ETXb\STX\n\ + \\ENQ\EOT\v\STX\STX\EOT\DC2\ETXc\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\STX\ACK\DC2\ETXb\v\SYN\n\ + \\ENQ\EOT\v\STX\STX\ACK\DC2\ETXc\v\SYN\n\ \\f\n\ - \\ENQ\EOT\v\STX\STX\SOH\DC2\ETXb\ETB#\n\ + \\ENQ\EOT\v\STX\STX\SOH\DC2\ETXc\ETB#\n\ \\f\n\ - \\ENQ\EOT\v\STX\STX\ETX\DC2\ETXb&'\n\ + \\ENQ\EOT\v\STX\STX\ETX\DC2\ETXc&'\n\ \\"\n\ - \\EOT\EOT\v\STX\ETX\DC2\ETXc\STX&\"\NAK List of withdrawals\n\ + \\EOT\EOT\v\STX\ETX\DC2\ETXd\STX&\"\NAK List of withdrawals\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\EOT\DC2\ETXc\STX\n\ + \\ENQ\EOT\v\STX\ETX\EOT\DC2\ETXd\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\ACK\DC2\ETXc\v\NAK\n\ + \\ENQ\EOT\v\STX\ETX\ACK\DC2\ETXd\v\NAK\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\SOH\DC2\ETXc\SYN!\n\ + \\ENQ\EOT\v\STX\ETX\SOH\DC2\ETXd\SYN!\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\ETX\DC2\ETXc$%\n\ + \\ENQ\EOT\v\STX\ETX\ETX\DC2\ETXd$%\n\ \+\n\ - \\EOT\EOT\v\STX\EOT\DC2\ETXd\STX\US\"\RS List of minted custom assets\n\ + \\EOT\EOT\v\STX\EOT\DC2\ETXe\STX\US\"\RS List of minted custom assets\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\EOT\EOT\DC2\ETXd\STX\n\ + \\ENQ\EOT\v\STX\EOT\EOT\DC2\ETXe\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\EOT\ACK\DC2\ETXd\v\NAK\n\ + \\ENQ\EOT\v\STX\EOT\ACK\DC2\ETXe\v\NAK\n\ \\f\n\ - \\ENQ\EOT\v\STX\EOT\SOH\DC2\ETXd\SYN\SUB\n\ + \\ENQ\EOT\v\STX\EOT\SOH\DC2\ETXe\SYN\SUB\n\ \\f\n\ - \\ENQ\EOT\v\STX\EOT\ETX\DC2\ETXd\GS\RS\n\ + \\ENQ\EOT\v\STX\EOT\ETX\DC2\ETXe\GS\RS\n\ \'\n\ - \\EOT\EOT\v\STX\ENQ\DC2\ETXe\STX(\"\SUB List of reference inputs\n\ + \\EOT\EOT\v\STX\ENQ\DC2\ETXf\STX(\"\SUB List of reference inputs\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\ENQ\EOT\DC2\ETXe\STX\n\ + \\ENQ\EOT\v\STX\ENQ\EOT\DC2\ETXf\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\ENQ\ACK\DC2\ETXe\v\DC2\n\ + \\ENQ\EOT\v\STX\ENQ\ACK\DC2\ETXf\v\DC2\n\ \\f\n\ - \\ENQ\EOT\v\STX\ENQ\SOH\DC2\ETXe\DC3#\n\ + \\ENQ\EOT\v\STX\ENQ\SOH\DC2\ETXf\DC3#\n\ \\f\n\ - \\ENQ\EOT\v\STX\ENQ\ETX\DC2\ETXe&'\n\ + \\ENQ\EOT\v\STX\ENQ\ETX\DC2\ETXf&'\n\ \5\n\ - \\EOT\EOT\v\STX\ACK\DC2\ETXf\STX\ESC\"( Witnesses that validte the transaction\n\ + \\EOT\EOT\v\STX\ACK\DC2\ETXg\STX\ESC\"( Witnesses that validte the transaction\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\ACK\ACK\DC2\ETXf\STX\f\n\ + \\ENQ\EOT\v\STX\ACK\ACK\DC2\ETXg\STX\f\n\ \\f\n\ - \\ENQ\EOT\v\STX\ACK\SOH\DC2\ETXf\r\SYN\n\ + \\ENQ\EOT\v\STX\ACK\SOH\DC2\ETXg\r\SYN\n\ \\f\n\ - \\ENQ\EOT\v\STX\ACK\ETX\DC2\ETXf\EM\SUB\n\ + \\ENQ\EOT\v\STX\ACK\ETX\DC2\ETXg\EM\SUB\n\ \?\n\ - \\EOT\EOT\v\STX\a\DC2\ETXg\STX\FS\"2 Collateral details in case of failed transaction\n\ + \\EOT\EOT\v\STX\a\DC2\ETXh\STX\FS\"2 Collateral details in case of failed transaction\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\a\ACK\DC2\ETXg\STX\f\n\ + \\ENQ\EOT\v\STX\a\ACK\DC2\ETXh\STX\f\n\ \\f\n\ - \\ENQ\EOT\v\STX\a\SOH\DC2\ETXg\r\ETB\n\ + \\ENQ\EOT\v\STX\a\SOH\DC2\ETXh\r\ETB\n\ \\f\n\ - \\ENQ\EOT\v\STX\a\ETX\DC2\ETXg\SUB\ESC\n\ + \\ENQ\EOT\v\STX\a\ETX\DC2\ETXh\SUB\ESC\n\ \%\n\ - \\EOT\EOT\v\STX\b\DC2\ETXh\STX\DC1\"\CAN Transaction fee in ADA\n\ + \\EOT\EOT\v\STX\b\DC2\ETXi\STX\DC1\"\CAN Transaction fee in ADA\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\b\ACK\DC2\ETXh\STX\b\n\ + \\ENQ\EOT\v\STX\b\ACK\DC2\ETXi\STX\b\n\ \\f\n\ - \\ENQ\EOT\v\STX\b\SOH\DC2\ETXh\t\f\n\ + \\ENQ\EOT\v\STX\b\SOH\DC2\ETXi\t\f\n\ \\f\n\ - \\ENQ\EOT\v\STX\b\ETX\DC2\ETXh\SI\DLE\n\ + \\ENQ\EOT\v\STX\b\ETX\DC2\ETXi\SI\DLE\n\ \3\n\ - \\EOT\EOT\v\STX\t\DC2\ETXi\STX\ESC\"& Validity interval of the transaction\n\ + \\EOT\EOT\v\STX\t\DC2\ETXj\STX\ESC\"& Validity interval of the transaction\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\t\ACK\DC2\ETXi\STX\f\n\ + \\ENQ\EOT\v\STX\t\ACK\DC2\ETXj\STX\f\n\ \\f\n\ - \\ENQ\EOT\v\STX\t\SOH\DC2\ETXi\r\NAK\n\ + \\ENQ\EOT\v\STX\t\SOH\DC2\ETXj\r\NAK\n\ \\f\n\ - \\ENQ\EOT\v\STX\t\ETX\DC2\ETXi\CAN\SUB\n\ + \\ENQ\EOT\v\STX\t\ETX\DC2\ETXj\CAN\SUB\n\ \E\n\ \\EOT\EOT\v\STX\n\ - \\DC2\ETXj\STX\ETB\"8 Flag indicating whether the transaction was successful\n\ + \\DC2\ETXk\STX\ETB\"8 Flag indicating whether the transaction was successful\n\ \\n\ \\f\n\ \\ENQ\EOT\v\STX\n\ - \\ENQ\DC2\ETXj\STX\ACK\n\ + \\ENQ\DC2\ETXk\STX\ACK\n\ \\f\n\ \\ENQ\EOT\v\STX\n\ - \\SOH\DC2\ETXj\a\DC1\n\ + \\SOH\DC2\ETXk\a\DC1\n\ \\f\n\ \\ENQ\EOT\v\STX\n\ - \\ETX\DC2\ETXj\DC4\SYN\n\ + \\ETX\DC2\ETXk\DC4\SYN\n\ \I\n\ - \\EOT\EOT\v\STX\v\DC2\ETXk\STX\EM\"< Auxiliary data not directly tied to the validation process\n\ + \\EOT\EOT\v\STX\v\DC2\ETXl\STX\EM\"< Auxiliary data not directly tied to the validation process\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\v\ACK\DC2\ETXk\STX\t\n\ + \\ENQ\EOT\v\STX\v\ACK\DC2\ETXl\STX\t\n\ \\f\n\ - \\ENQ\EOT\v\STX\v\SOH\DC2\ETXk\n\ + \\ENQ\EOT\v\STX\v\SOH\DC2\ETXl\n\ \\DC3\n\ \\f\n\ - \\ENQ\EOT\v\STX\v\ETX\DC2\ETXk\SYN\CAN\n\ + \\ENQ\EOT\v\STX\v\ETX\DC2\ETXl\SYN\CAN\n\ \E\n\ - \\EOT\EOT\v\STX\f\DC2\ETXl\STX\DC2\"8 Hash of the transaction that serves as main identifier\n\ + \\EOT\EOT\v\STX\f\DC2\ETXm\STX\DC2\"8 Hash of the transaction that serves as main identifier\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\f\ENQ\DC2\ETXl\STX\a\n\ + \\ENQ\EOT\v\STX\f\ENQ\DC2\ETXm\STX\a\n\ \\f\n\ - \\ENQ\EOT\v\STX\f\SOH\DC2\ETXl\b\f\n\ + \\ENQ\EOT\v\STX\f\SOH\DC2\ETXm\b\f\n\ \\f\n\ - \\ENQ\EOT\v\STX\f\ETX\DC2\ETXl\SI\DC1\n\ + \\ENQ\EOT\v\STX\f\ETX\DC2\ETXm\SI\DC1\n\ \2\n\ - \\EOT\EOT\v\STX\r\DC2\ETXm\STX3\"% List of governance actions proposed\n\ + \\EOT\EOT\v\STX\r\DC2\ETXn\STX3\"% List of governance actions proposed\n\ + \\n\ + \\f\n\ + \\ENQ\EOT\v\STX\r\EOT\DC2\ETXn\STX\n\ + \\n\ + \\f\n\ + \\ENQ\EOT\v\STX\r\ACK\DC2\ETXn\v#\n\ + \\f\n\ + \\ENQ\EOT\v\STX\r\SOH\DC2\ETXn$-\n\ + \\f\n\ + \\ENQ\EOT\v\STX\r\ETX\DC2\ETXn02\n\ + \T\n\ + \\EOT\EOT\v\STX\SO\DC2\ETXo\STX!\"G List of voters and their corresponding votes cast in this transaction\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\r\EOT\DC2\ETXm\STX\n\ + \\ENQ\EOT\v\STX\SO\EOT\DC2\ETXo\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\r\ACK\DC2\ETXm\v#\n\ + \\ENQ\EOT\v\STX\SO\ACK\DC2\ETXo\v\NAK\n\ \\f\n\ - \\ENQ\EOT\v\STX\r\SOH\DC2\ETXm$-\n\ + \\ENQ\EOT\v\STX\SO\SOH\DC2\ETXo\SYN\ESC\n\ \\f\n\ - \\ENQ\EOT\v\STX\r\ETX\DC2\ETXm02\n\ + \\ENQ\EOT\v\STX\SO\ETX\DC2\ETXo\RS \n\ \1\n\ - \\STX\EOT\f\DC2\EOTq\NULv\SOH\SUB% Define a governance action proposal\n\ + \\STX\EOT\f\DC2\EOTs\NULx\SOH\SUB% Define a governance action proposal\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\f\SOH\DC2\ETXq\b \n\ + \\ETX\EOT\f\SOH\DC2\ETXs\b \n\ \=\n\ - \\EOT\EOT\f\STX\NUL\DC2\ETXr\STX\NAK\"0 The amount deposited for the governance action\n\ + \\EOT\EOT\f\STX\NUL\DC2\ETXt\STX\NAK\"0 The amount deposited for the governance action\n\ \\n\ \\f\n\ - \\ENQ\EOT\f\STX\NUL\ACK\DC2\ETXr\STX\b\n\ + \\ENQ\EOT\f\STX\NUL\ACK\DC2\ETXt\STX\b\n\ \\f\n\ - \\ENQ\EOT\f\STX\NUL\SOH\DC2\ETXr\t\DLE\n\ + \\ENQ\EOT\f\STX\NUL\SOH\DC2\ETXt\t\DLE\n\ \\f\n\ - \\ENQ\EOT\f\STX\NUL\ETX\DC2\ETXr\DC3\DC4\n\ + \\ENQ\EOT\f\STX\NUL\ETX\DC2\ETXt\DC3\DC4\n\ \C\n\ - \\EOT\EOT\f\STX\SOH\DC2\ETXs\STX\ESC\"6 The reward account the deposit should be returned to\n\ + \\EOT\EOT\f\STX\SOH\DC2\ETXu\STX\ESC\"6 The reward account the deposit should be returned to\n\ \\n\ \\f\n\ - \\ENQ\EOT\f\STX\SOH\ENQ\DC2\ETXs\STX\a\n\ + \\ENQ\EOT\f\STX\SOH\ENQ\DC2\ETXu\STX\a\n\ \\f\n\ - \\ENQ\EOT\f\STX\SOH\SOH\DC2\ETXs\b\SYN\n\ + \\ENQ\EOT\f\STX\SOH\SOH\DC2\ETXu\b\SYN\n\ \\f\n\ - \\ENQ\EOT\f\STX\SOH\ETX\DC2\ETXs\EM\SUB\n\ + \\ENQ\EOT\f\STX\SOH\ETX\DC2\ETXu\EM\SUB\n\ \\v\n\ - \\EOT\EOT\f\STX\STX\DC2\ETXt\STX\"\n\ + \\EOT\EOT\f\STX\STX\DC2\ETXv\STX\"\n\ \\f\n\ - \\ENQ\EOT\f\STX\STX\ACK\DC2\ETXt\STX\DC2\n\ + \\ENQ\EOT\f\STX\STX\ACK\DC2\ETXv\STX\DC2\n\ \\f\n\ - \\ENQ\EOT\f\STX\STX\SOH\DC2\ETXt\DC3\GS\n\ + \\ENQ\EOT\f\STX\STX\SOH\DC2\ETXv\DC3\GS\n\ \\f\n\ - \\ENQ\EOT\f\STX\STX\ETX\DC2\ETXt !\n\ + \\ENQ\EOT\f\STX\STX\ETX\DC2\ETXv !\n\ \\v\n\ - \\EOT\EOT\f\STX\ETX\DC2\ETXu\STX\DC4\n\ + \\EOT\EOT\f\STX\ETX\DC2\ETXw\STX\DC4\n\ \\f\n\ - \\ENQ\EOT\f\STX\ETX\ACK\DC2\ETXu\STX\b\n\ + \\ENQ\EOT\f\STX\ETX\ACK\DC2\ETXw\STX\b\n\ \\f\n\ - \\ENQ\EOT\f\STX\ETX\SOH\DC2\ETXu\t\SI\n\ + \\ENQ\EOT\f\STX\ETX\SOH\DC2\ETXw\t\SI\n\ \\f\n\ - \\ENQ\EOT\f\STX\ETX\ETX\DC2\ETXu\DC2\DC3\n\ + \\ENQ\EOT\f\STX\ETX\ETX\DC2\ETXw\DC2\DC3\n\ \)\n\ - \\STX\EOT\r\DC2\ENQy\NUL\131\SOH\SOH\SUB\FS Define a Governance Action\n\ + \\STX\EOT\r\DC2\ENQ{\NUL\133\SOH\SOH\SUB\FS Define a Governance Action\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\r\SOH\DC2\ETXy\b\CAN\n\ + \\ETX\EOT\r\SOH\DC2\ETX{\b\CAN\n\ \\r\n\ - \\EOT\EOT\r\b\NUL\DC2\ENQz\STX\130\SOH\ETX\n\ + \\EOT\EOT\r\b\NUL\DC2\ENQ|\STX\132\SOH\ETX\n\ \\f\n\ - \\ENQ\EOT\r\b\NUL\SOH\DC2\ETXz\b\EM\n\ + \\ENQ\EOT\r\b\NUL\SOH\DC2\ETX|\b\EM\n\ \)\n\ - \\EOT\EOT\r\STX\NUL\DC2\ETX{\EOT6\"\FS Change on-chain parameters\n\ + \\EOT\EOT\r\STX\NUL\DC2\ETX}\EOT6\"\FS Change on-chain parameters\n\ \\n\ \\f\n\ - \\ENQ\EOT\r\STX\NUL\ACK\DC2\ETX{\EOT\EM\n\ + \\ENQ\EOT\r\STX\NUL\ACK\DC2\ETX}\EOT\EM\n\ \\f\n\ - \\ENQ\EOT\r\STX\NUL\SOH\DC2\ETX{\SUB1\n\ + \\ENQ\EOT\r\STX\NUL\SOH\DC2\ETX}\SUB1\n\ \\f\n\ - \\ENQ\EOT\r\STX\NUL\ETX\DC2\ETX{45\n\ + \\ENQ\EOT\r\STX\NUL\ETX\DC2\ETX}45\n\ \#\n\ - \\EOT\EOT\r\STX\SOH\DC2\ETX|\EOT=\"\SYN Initiate a Hard Fork\n\ + \\EOT\EOT\r\STX\SOH\DC2\ETX~\EOT=\"\SYN Initiate a Hard Fork\n\ \\n\ \\f\n\ - \\ENQ\EOT\r\STX\SOH\ACK\DC2\ETX|\EOT\FS\n\ + \\ENQ\EOT\r\STX\SOH\ACK\DC2\ETX~\EOT\FS\n\ \\f\n\ - \\ENQ\EOT\r\STX\SOH\SOH\DC2\ETX|\GS8\n\ + \\ENQ\EOT\r\STX\SOH\SOH\DC2\ETX~\GS8\n\ \\f\n\ - \\ENQ\EOT\r\STX\SOH\ETX\DC2\ETX|;<\n\ + \\ENQ\EOT\r\STX\SOH\ETX\DC2\ETX~;<\n\ \)\n\ - \\EOT\EOT\r\STX\STX\DC2\ETX}\EOT>\"\FS Withdraw from the Treasury\n\ + \\EOT\EOT\r\STX\STX\DC2\ETX\DEL\EOT>\"\FS Withdraw from the Treasury\n\ \\n\ \\f\n\ - \\ENQ\EOT\r\STX\STX\ACK\DC2\ETX}\EOT\GS\n\ + \\ENQ\EOT\r\STX\STX\ACK\DC2\ETX\DEL\EOT\GS\n\ \\f\n\ - \\ENQ\EOT\r\STX\STX\SOH\DC2\ETX}\RS9\n\ + \\ENQ\EOT\r\STX\STX\SOH\DC2\ETX\DEL\RS9\n\ \\f\n\ - \\ENQ\EOT\r\STX\STX\ETX\DC2\ETX}<=\n\ - \\SO\n\ - \\EOT\EOT\r\STX\ETX\DC2\ETX~\EOT0\"\SOH\n\ + \\ENQ\EOT\r\STX\STX\ETX\DC2\ETX\DEL<=\n\ + \\SI\n\ + \\EOT\EOT\r\STX\ETX\DC2\EOT\128\SOH\EOT0\"\SOH\n\ \\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ETX\ACK\DC2\EOT\128\SOH\EOT\SYN\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ETX\SOH\DC2\EOT\128\SOH\ETB+\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ETX\ETX\DC2\EOT\128\SOH./\n\ + \1\n\ + \\EOT\EOT\r\STX\EOT\DC2\EOT\129\SOH\EOT6\"# Update the Constitution Committee\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\r\STX\EOT\ACK\DC2\EOT\129\SOH\EOT\EM\n\ + \\r\n\ + \\ENQ\EOT\r\STX\EOT\SOH\DC2\EOT\129\SOH\SUB1\n\ + \\r\n\ + \\ENQ\EOT\r\STX\EOT\ETX\DC2\EOT\129\SOH45\n\ + \(\n\ + \\EOT\EOT\r\STX\ENQ\DC2\EOT\130\SOH\EOT6\"\SUB Replace the Constitution\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ENQ\ACK\DC2\EOT\130\SOH\EOT\EM\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ENQ\SOH\DC2\EOT\130\SOH\SUB1\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ENQ\ETX\DC2\EOT\130\SOH45\n\ + \\ESC\n\ + \\EOT\EOT\r\STX\ACK\DC2\EOT\131\SOH\EOT\US\"\r Info action\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ACK\ACK\DC2\EOT\131\SOH\EOT\SO\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ACK\SOH\DC2\EOT\131\SOH\SI\SUB\n\ + \\r\n\ + \\ENQ\EOT\r\STX\ACK\ETX\DC2\EOT\131\SOH\GS\RS\n\ \\f\n\ - \\ENQ\EOT\r\STX\ETX\ACK\DC2\ETX~\EOT\SYN\n\ + \\STX\EOT\SO\DC2\ACK\135\SOH\NUL\138\SOH\SOH\n\ + \\v\n\ + \\ETX\EOT\SO\SOH\DC2\EOT\135\SOH\b\SUB\n\ \\f\n\ - \\ENQ\EOT\r\STX\ETX\SOH\DC2\ETX~\ETB+\n\ + \\EOT\EOT\SO\STX\NUL\DC2\EOT\136\SOH\STX\ESC\n\ + \\r\n\ + \\ENQ\EOT\SO\STX\NUL\ENQ\DC2\EOT\136\SOH\STX\a\n\ + \\r\n\ + \\ENQ\EOT\SO\STX\NUL\SOH\DC2\EOT\136\SOH\b\SYN\n\ + \\r\n\ + \\ENQ\EOT\SO\STX\NUL\ETX\DC2\EOT\136\SOH\EM\SUB\n\ \\f\n\ - \\ENQ\EOT\r\STX\ETX\ETX\DC2\ETX~./\n\ - \0\n\ - \\EOT\EOT\r\STX\EOT\DC2\ETX\DEL\EOT6\"# Update the Constitution Committee\n\ + \\EOT\EOT\SO\STX\SOH\DC2\EOT\137\SOH\STX%\n\ + \\r\n\ + \\ENQ\EOT\SO\STX\SOH\ENQ\DC2\EOT\137\SOH\STX\b\n\ + \\r\n\ + \\ENQ\EOT\SO\STX\SOH\SOH\DC2\EOT\137\SOH\t \n\ + \\r\n\ + \\ENQ\EOT\SO\STX\SOH\ETX\DC2\EOT\137\SOH#$\n\ + \v\n\ + \\STX\ENQ\SOH\DC2\ACK\142\SOH\NUL\147\SOH\SOH\SUBh Valid vote choices for a governance action (CIP-1694).\n\ + \ On-chain CBOR mapping: No=0, Yes=1, Abstain=2.\n\ \\n\ + \\v\n\ + \\ETX\ENQ\SOH\SOH\DC2\EOT\142\SOH\ENQ\t\n\ + \\f\n\ + \\EOT\ENQ\SOH\STX\NUL\DC2\EOT\143\SOH\STX\ETB\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\NUL\SOH\DC2\EOT\143\SOH\STX\DC2\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\NUL\STX\DC2\EOT\143\SOH\NAK\SYN\n\ \\f\n\ - \\ENQ\EOT\r\STX\EOT\ACK\DC2\ETX\DEL\EOT\EM\n\ + \\EOT\ENQ\SOH\STX\SOH\DC2\EOT\144\SOH\STX\SO\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\SOH\SOH\DC2\EOT\144\SOH\STX\t\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\SOH\STX\DC2\EOT\144\SOH\f\r\n\ \\f\n\ - \\ENQ\EOT\r\STX\EOT\SOH\DC2\ETX\DEL\SUB1\n\ + \\EOT\ENQ\SOH\STX\STX\DC2\EOT\145\SOH\STX\SI\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\STX\SOH\DC2\EOT\145\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\STX\STX\DC2\EOT\145\SOH\r\SO\n\ \\f\n\ - \\ENQ\EOT\r\STX\EOT\ETX\DC2\ETX\DEL45\n\ - \(\n\ - \\EOT\EOT\r\STX\ENQ\DC2\EOT\128\SOH\EOT6\"\SUB Replace the Constitution\n\ + \\EOT\ENQ\SOH\STX\ETX\DC2\EOT\146\SOH\STX\DC3\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\ETX\SOH\DC2\EOT\146\SOH\STX\SO\n\ + \\r\n\ + \\ENQ\ENQ\SOH\STX\ETX\STX\DC2\EOT\146\SOH\DC1\DC2\n\ + \:\n\ + \\STX\EOT\SI\DC2\ACK\150\SOH\NUL\154\SOH\SOH\SUB, A single cast vote on a governance action.\n\ + \\n\ + \\v\n\ + \\ETX\EOT\SI\SOH\DC2\EOT\150\SOH\b\ETB\n\ + \;\n\ + \\EOT\EOT\SI\STX\NUL\DC2\EOT\151\SOH\STX'\"- ID of the governance action being voted on.\n\ \\n\ \\r\n\ - \\ENQ\EOT\r\STX\ENQ\ACK\DC2\EOT\128\SOH\EOT\EM\n\ + \\ENQ\EOT\SI\STX\NUL\ACK\DC2\EOT\151\SOH\STX\DC4\n\ \\r\n\ - \\ENQ\EOT\r\STX\ENQ\SOH\DC2\EOT\128\SOH\SUB1\n\ + \\ENQ\EOT\SI\STX\NUL\SOH\DC2\EOT\151\SOH\NAK\"\n\ \\r\n\ - \\ENQ\EOT\r\STX\ENQ\ETX\DC2\EOT\128\SOH45\n\ - \\ESC\n\ - \\EOT\EOT\r\STX\ACK\DC2\EOT\129\SOH\EOT\US\"\r Info action\n\ + \\ENQ\EOT\SI\STX\NUL\ETX\DC2\EOT\151\SOH%&\n\ + \\RS\n\ + \\EOT\EOT\SI\STX\SOH\DC2\EOT\152\SOH\STX\DLE\"\DLE The vote cast.\n\ \\n\ \\r\n\ - \\ENQ\EOT\r\STX\ACK\ACK\DC2\EOT\129\SOH\EOT\SO\n\ + \\ENQ\EOT\SI\STX\SOH\ACK\DC2\EOT\152\SOH\STX\ACK\n\ \\r\n\ - \\ENQ\EOT\r\STX\ACK\SOH\DC2\EOT\129\SOH\SI\SUB\n\ + \\ENQ\EOT\SI\STX\SOH\SOH\DC2\EOT\152\SOH\a\v\n\ \\r\n\ - \\ENQ\EOT\r\STX\ACK\ETX\DC2\EOT\129\SOH\GS\RS\n\ - \\f\n\ - \\STX\EOT\SO\DC2\ACK\133\SOH\NUL\136\SOH\SOH\n\ + \\ENQ\EOT\SI\STX\SOH\ETX\DC2\EOT\152\SOH\SO\SI\n\ + \4\n\ + \\EOT\EOT\SI\STX\STX\DC2\EOT\153\SOH\STX\GS\"& Optional anchor for voter rationale.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\SI\STX\STX\EOT\DC2\EOT\153\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\SI\STX\STX\ACK\DC2\EOT\153\SOH\v\DC1\n\ + \\r\n\ + \\ENQ\EOT\SI\STX\STX\SOH\DC2\EOT\153\SOH\DC2\CAN\n\ + \\r\n\ + \\ENQ\EOT\SI\STX\STX\ETX\DC2\EOT\153\SOH\ESC\FS\n\ + \\168\SOH\n\ + \\STX\EOT\DLE\DC2\ACK\158\SOH\NUL\165\SOH\SOH\SUB\153\SOH Groups a voter with all votes they cast in the transaction.\n\ + \ SPOs can only identify via pool key hash; DReps and CC members may use key or script hash.\n\ + \\n\ \\v\n\ - \\ETX\EOT\SO\SOH\DC2\EOT\133\SOH\b\SUB\n\ - \\f\n\ - \\EOT\EOT\SO\STX\NUL\DC2\EOT\134\SOH\STX\ESC\n\ + \\ETX\EOT\DLE\SOH\DC2\EOT\158\SOH\b\DC2\n\ + \\SO\n\ + \\EOT\EOT\DLE\b\NUL\DC2\ACK\159\SOH\STX\163\SOH\ETX\n\ + \\r\n\ + \\ENQ\EOT\DLE\b\NUL\SOH\DC2\EOT\159\SOH\b\r\n\ + \0\n\ + \\EOT\EOT\DLE\STX\NUL\DC2\EOT\160\SOH\EOT1\"\" Constitutional Committee member.\n\ + \\n\ \\r\n\ - \\ENQ\EOT\SO\STX\NUL\ENQ\DC2\EOT\134\SOH\STX\a\n\ + \\ENQ\EOT\DLE\STX\NUL\ACK\DC2\EOT\160\SOH\EOT\DC3\n\ \\r\n\ - \\ENQ\EOT\SO\STX\NUL\SOH\DC2\EOT\134\SOH\b\SYN\n\ + \\ENQ\EOT\DLE\STX\NUL\SOH\DC2\EOT\160\SOH\DC4,\n\ \\r\n\ - \\ENQ\EOT\SO\STX\NUL\ETX\DC2\EOT\134\SOH\EM\SUB\n\ - \\f\n\ - \\EOT\EOT\SO\STX\SOH\DC2\EOT\135\SOH\STX%\n\ + \\ENQ\EOT\DLE\STX\NUL\ETX\DC2\EOT\160\SOH/0\n\ + \)\n\ + \\EOT\EOT\DLE\STX\SOH\DC2\EOT\161\SOH\EOT\GS\"\ESC Delegated Representative.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\SOH\ACK\DC2\EOT\161\SOH\EOT\DC3\n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\SOH\SOH\DC2\EOT\161\SOH\DC4\CAN\n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\SOH\ETX\DC2\EOT\161\SOH\ESC\FS\n\ + \4\n\ + \\EOT\EOT\DLE\STX\STX\DC2\EOT\162\SOH\EOT\DC2\"& Stake Pool Operator (pool key hash).\n\ + \\n\ \\r\n\ - \\ENQ\EOT\SO\STX\SOH\ENQ\DC2\EOT\135\SOH\STX\b\n\ + \\ENQ\EOT\DLE\STX\STX\ENQ\DC2\EOT\162\SOH\EOT\t\n\ \\r\n\ - \\ENQ\EOT\SO\STX\SOH\SOH\DC2\EOT\135\SOH\t \n\ + \\ENQ\EOT\DLE\STX\STX\SOH\DC2\EOT\162\SOH\n\ \\r\n\ - \\ENQ\EOT\SO\STX\SOH\ETX\DC2\EOT\135\SOH#$\n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\STX\ETX\DC2\EOT\162\SOH\DLE\DC1\n\ + \)\n\ + \\EOT\EOT\DLE\STX\ETX\DC2\EOT\164\SOH\STX%\"\ESC Votes cast by this voter.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\ETX\EOT\DC2\EOT\164\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\ETX\ACK\DC2\EOT\164\SOH\v\SUB\n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\ETX\SOH\DC2\EOT\164\SOH\ESC \n\ + \\r\n\ + \\ENQ\EOT\DLE\STX\ETX\ETX\DC2\EOT\164\SOH#$\n\ \\f\n\ - \\STX\EOT\SI\DC2\ACK\138\SOH\NUL\142\SOH\SOH\n\ + \\STX\EOT\DC1\DC2\ACK\167\SOH\NUL\171\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\SI\SOH\DC2\EOT\138\SOH\b\GS\n\ + \\ETX\EOT\DC1\SOH\DC2\EOT\167\SOH\b\GS\n\ \\f\n\ - \\EOT\EOT\SI\STX\NUL\DC2\EOT\139\SOH\STX'\n\ + \\EOT\EOT\DC1\STX\NUL\DC2\EOT\168\SOH\STX'\n\ \\r\n\ - \\ENQ\EOT\SI\STX\NUL\ACK\DC2\EOT\139\SOH\STX\DC4\n\ + \\ENQ\EOT\DC1\STX\NUL\ACK\DC2\EOT\168\SOH\STX\DC4\n\ \\r\n\ - \\ENQ\EOT\SI\STX\NUL\SOH\DC2\EOT\139\SOH\NAK\"\n\ + \\ENQ\EOT\DC1\STX\NUL\SOH\DC2\EOT\168\SOH\NAK\"\n\ \\r\n\ - \\ENQ\EOT\SI\STX\NUL\ETX\DC2\EOT\139\SOH%&\n\ + \\ENQ\EOT\DC1\STX\NUL\ETX\DC2\EOT\168\SOH%&\n\ \$\n\ - \\EOT\EOT\SI\STX\SOH\DC2\EOT\140\SOH\STX$\"\SYN The updates proposed\n\ + \\EOT\EOT\DC1\STX\SOH\DC2\EOT\169\SOH\STX$\"\SYN The updates proposed\n\ \\n\ \\r\n\ - \\ENQ\EOT\SI\STX\SOH\ACK\DC2\EOT\140\SOH\STX\t\n\ + \\ENQ\EOT\DC1\STX\SOH\ACK\DC2\EOT\169\SOH\STX\t\n\ \\r\n\ - \\ENQ\EOT\SI\STX\SOH\SOH\DC2\EOT\140\SOH\n\ + \\ENQ\EOT\DC1\STX\SOH\SOH\DC2\EOT\169\SOH\n\ \\US\n\ \\r\n\ - \\ENQ\EOT\SI\STX\SOH\ETX\DC2\EOT\140\SOH\"#\n\ + \\ENQ\EOT\DC1\STX\SOH\ETX\DC2\EOT\169\SOH\"#\n\ \\f\n\ - \\EOT\EOT\SI\STX\STX\DC2\EOT\141\SOH\STX\CAN\n\ + \\EOT\EOT\DC1\STX\STX\DC2\EOT\170\SOH\STX\CAN\n\ \\r\n\ - \\ENQ\EOT\SI\STX\STX\ENQ\DC2\EOT\141\SOH\STX\a\n\ + \\ENQ\EOT\DC1\STX\STX\ENQ\DC2\EOT\170\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\SI\STX\STX\SOH\DC2\EOT\141\SOH\b\DC3\n\ + \\ENQ\EOT\DC1\STX\STX\SOH\DC2\EOT\170\SOH\b\DC3\n\ \\r\n\ - \\ENQ\EOT\SI\STX\STX\ETX\DC2\EOT\141\SOH\SYN\ETB\n\ + \\ENQ\EOT\DC1\STX\STX\ETX\DC2\EOT\170\SOH\SYN\ETB\n\ \\f\n\ - \\STX\EOT\DLE\DC2\ACK\144\SOH\NUL\147\SOH\SOH\n\ + \\STX\EOT\DC2\DC2\ACK\173\SOH\NUL\176\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\DLE\SOH\DC2\EOT\144\SOH\b \n\ + \\ETX\EOT\DC2\SOH\DC2\EOT\173\SOH\b \n\ \\f\n\ - \\EOT\EOT\DLE\STX\NUL\DC2\EOT\145\SOH\STX'\n\ + \\EOT\EOT\DC2\STX\NUL\DC2\EOT\174\SOH\STX'\n\ \\r\n\ - \\ENQ\EOT\DLE\STX\NUL\ACK\DC2\EOT\145\SOH\STX\DC4\n\ + \\ENQ\EOT\DC2\STX\NUL\ACK\DC2\EOT\174\SOH\STX\DC4\n\ \\r\n\ - \\ENQ\EOT\DLE\STX\NUL\SOH\DC2\EOT\145\SOH\NAK\"\n\ + \\ENQ\EOT\DC2\STX\NUL\SOH\DC2\EOT\174\SOH\NAK\"\n\ \\r\n\ - \\ENQ\EOT\DLE\STX\NUL\ETX\DC2\EOT\145\SOH%&\n\ + \\ENQ\EOT\DC2\STX\NUL\ETX\DC2\EOT\174\SOH%&\n\ \/\n\ - \\EOT\EOT\DLE\STX\SOH\DC2\EOT\146\SOH\STX'\"! The protocol version to fork to\n\ + \\EOT\EOT\DC2\STX\SOH\DC2\EOT\175\SOH\STX'\"! The protocol version to fork to\n\ \\n\ \\r\n\ - \\ENQ\EOT\DLE\STX\SOH\ACK\DC2\EOT\146\SOH\STX\DC1\n\ + \\ENQ\EOT\DC2\STX\SOH\ACK\DC2\EOT\175\SOH\STX\DC1\n\ \\r\n\ - \\ENQ\EOT\DLE\STX\SOH\SOH\DC2\EOT\146\SOH\DC2\"\n\ + \\ENQ\EOT\DC2\STX\SOH\SOH\DC2\EOT\175\SOH\DC2\"\n\ \\r\n\ - \\ENQ\EOT\DLE\STX\SOH\ETX\DC2\EOT\146\SOH%&\n\ + \\ENQ\EOT\DC2\STX\SOH\ETX\DC2\EOT\175\SOH%&\n\ \\f\n\ - \\STX\EOT\DC1\DC2\ACK\149\SOH\NUL\152\SOH\SOH\n\ + \\STX\EOT\DC3\DC2\ACK\178\SOH\NUL\181\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\DC1\SOH\DC2\EOT\149\SOH\b!\n\ + \\ETX\EOT\DC3\SOH\DC2\EOT\178\SOH\b!\n\ \1\n\ - \\EOT\EOT\DC1\STX\NUL\DC2\EOT\150\SOH\STX,\"# A list of the withdrawals to make\n\ + \\EOT\EOT\DC3\STX\NUL\DC2\EOT\179\SOH\STX,\"# A list of the withdrawals to make\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\EOT\DC2\EOT\150\SOH\STX\n\ + \\ENQ\EOT\DC3\STX\NUL\EOT\DC2\EOT\179\SOH\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\ACK\DC2\EOT\150\SOH\v\ESC\n\ + \\ENQ\EOT\DC3\STX\NUL\ACK\DC2\EOT\179\SOH\v\ESC\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\SOH\DC2\EOT\150\SOH\FS'\n\ + \\ENQ\EOT\DC3\STX\NUL\SOH\DC2\EOT\179\SOH\FS'\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\ETX\DC2\EOT\150\SOH*+\n\ + \\ENQ\EOT\DC3\STX\NUL\ETX\DC2\EOT\179\SOH*+\n\ \\f\n\ - \\EOT\EOT\DC1\STX\SOH\DC2\EOT\151\SOH\STX\CAN\n\ + \\EOT\EOT\DC3\STX\SOH\DC2\EOT\180\SOH\STX\CAN\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\SOH\ENQ\DC2\EOT\151\SOH\STX\a\n\ + \\ENQ\EOT\DC3\STX\SOH\ENQ\DC2\EOT\180\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\SOH\SOH\DC2\EOT\151\SOH\b\DC3\n\ + \\ENQ\EOT\DC3\STX\SOH\SOH\DC2\EOT\180\SOH\b\DC3\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\SOH\ETX\DC2\EOT\151\SOH\SYN\ETB\n\ + \\ENQ\EOT\DC3\STX\SOH\ETX\DC2\EOT\180\SOH\SYN\ETB\n\ \\f\n\ - \\STX\EOT\DC2\DC2\ACK\154\SOH\NUL\157\SOH\SOH\n\ + \\STX\EOT\DC4\DC2\ACK\183\SOH\NUL\186\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\DC2\SOH\DC2\EOT\154\SOH\b\CAN\n\ + \\ETX\EOT\DC4\SOH\DC2\EOT\183\SOH\b\CAN\n\ \\f\n\ - \\EOT\EOT\DC2\STX\NUL\DC2\EOT\155\SOH\STX\ESC\n\ + \\EOT\EOT\DC4\STX\NUL\DC2\EOT\184\SOH\STX\ESC\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\NUL\ENQ\DC2\EOT\155\SOH\STX\a\n\ + \\ENQ\EOT\DC4\STX\NUL\ENQ\DC2\EOT\184\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\NUL\SOH\DC2\EOT\155\SOH\b\SYN\n\ + \\ENQ\EOT\DC4\STX\NUL\SOH\DC2\EOT\184\SOH\b\SYN\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\NUL\ETX\DC2\EOT\155\SOH\EM\SUB\n\ + \\ENQ\EOT\DC4\STX\NUL\ETX\DC2\EOT\184\SOH\EM\SUB\n\ \\f\n\ - \\EOT\EOT\DC2\STX\SOH\DC2\EOT\156\SOH\STX\DC2\n\ + \\EOT\EOT\DC4\STX\SOH\DC2\EOT\185\SOH\STX\DC2\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\SOH\ACK\DC2\EOT\156\SOH\STX\b\n\ + \\ENQ\EOT\DC4\STX\SOH\ACK\DC2\EOT\185\SOH\STX\b\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\SOH\SOH\DC2\EOT\156\SOH\t\r\n\ + \\ENQ\EOT\DC4\STX\SOH\SOH\DC2\EOT\185\SOH\t\r\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\SOH\ETX\DC2\EOT\156\SOH\DLE\DC1\n\ + \\ENQ\EOT\DC4\STX\SOH\ETX\DC2\EOT\185\SOH\DLE\DC1\n\ \\f\n\ - \\STX\EOT\DC3\DC2\ACK\159\SOH\NUL\161\SOH\SOH\n\ + \\STX\EOT\NAK\DC2\ACK\188\SOH\NUL\190\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\DC3\SOH\DC2\EOT\159\SOH\b\SUB\n\ + \\ETX\EOT\NAK\SOH\DC2\EOT\188\SOH\b\SUB\n\ \\f\n\ - \\EOT\EOT\DC3\STX\NUL\DC2\EOT\160\SOH\STX'\n\ + \\EOT\EOT\NAK\STX\NUL\DC2\EOT\189\SOH\STX'\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\NUL\ACK\DC2\EOT\160\SOH\STX\DC4\n\ + \\ENQ\EOT\NAK\STX\NUL\ACK\DC2\EOT\189\SOH\STX\DC4\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\NUL\SOH\DC2\EOT\160\SOH\NAK\"\n\ + \\ENQ\EOT\NAK\STX\NUL\SOH\DC2\EOT\189\SOH\NAK\"\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\NUL\ETX\DC2\EOT\160\SOH%&\n\ + \\ENQ\EOT\NAK\STX\NUL\ETX\DC2\EOT\189\SOH%&\n\ \\f\n\ - \\STX\EOT\DC4\DC2\ACK\163\SOH\NUL\168\SOH\SOH\n\ + \\STX\EOT\SYN\DC2\ACK\192\SOH\NUL\197\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\DC4\SOH\DC2\EOT\163\SOH\b\GS\n\ + \\ETX\EOT\SYN\SOH\DC2\EOT\192\SOH\b\GS\n\ \\f\n\ - \\EOT\EOT\DC4\STX\NUL\DC2\EOT\164\SOH\STX'\n\ + \\EOT\EOT\SYN\STX\NUL\DC2\EOT\193\SOH\STX'\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\NUL\ACK\DC2\EOT\164\SOH\STX\DC4\n\ + \\ENQ\EOT\SYN\STX\NUL\ACK\DC2\EOT\193\SOH\STX\DC4\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\NUL\SOH\DC2\EOT\164\SOH\NAK\"\n\ + \\ENQ\EOT\SYN\STX\NUL\SOH\DC2\EOT\193\SOH\NAK\"\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\NUL\ETX\DC2\EOT\164\SOH%&\n\ + \\ENQ\EOT\SYN\STX\NUL\ETX\DC2\EOT\193\SOH%&\n\ \4\n\ - \\EOT\EOT\DC4\STX\SOH\DC2\EOT\165\SOH\STX<\"& Committee members to remove (if any)\n\ + \\EOT\EOT\SYN\STX\SOH\DC2\EOT\194\SOH\STX<\"& Committee members to remove (if any)\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\SOH\EOT\DC2\EOT\165\SOH\STX\n\ + \\ENQ\EOT\SYN\STX\SOH\EOT\DC2\EOT\194\SOH\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\SOH\ACK\DC2\EOT\165\SOH\v\SUB\n\ + \\ENQ\EOT\SYN\STX\SOH\ACK\DC2\EOT\194\SOH\v\SUB\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\SOH\SOH\DC2\EOT\165\SOH\ESC7\n\ + \\ENQ\EOT\SYN\STX\SOH\SOH\DC2\EOT\194\SOH\ESC7\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\SOH\ETX\DC2\EOT\165\SOH:;\n\ + \\ENQ\EOT\SYN\STX\SOH\ETX\DC2\EOT\194\SOH:;\n\ \)\n\ - \\EOT\EOT\DC4\STX\STX\DC2\EOT\166\SOH\STXA\"\ESC The new committee members\n\ + \\EOT\EOT\SYN\STX\STX\DC2\EOT\195\SOH\STXA\"\ESC The new committee members\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\STX\EOT\DC2\EOT\166\SOH\STX\n\ + \\ENQ\EOT\SYN\STX\STX\EOT\DC2\EOT\195\SOH\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\STX\ACK\DC2\EOT\166\SOH\v\"\n\ + \\ENQ\EOT\SYN\STX\STX\ACK\DC2\EOT\195\SOH\v\"\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\STX\SOH\DC2\EOT\166\SOH#<\n\ + \\ENQ\EOT\SYN\STX\STX\SOH\DC2\EOT\195\SOH#<\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\STX\ETX\DC2\EOT\166\SOH?@\n\ + \\ENQ\EOT\SYN\STX\STX\ETX\DC2\EOT\195\SOH?@\n\ \8\n\ - \\EOT\EOT\DC4\STX\ETX\DC2\EOT\167\SOH\STX-\"* The required threshold for the committee\n\ + \\EOT\EOT\SYN\STX\ETX\DC2\EOT\196\SOH\STX-\"* The required threshold for the committee\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\ETX\ACK\DC2\EOT\167\SOH\STX\DLE\n\ + \\ENQ\EOT\SYN\STX\ETX\ACK\DC2\EOT\196\SOH\STX\DLE\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\ETX\SOH\DC2\EOT\167\SOH\DC1(\n\ + \\ENQ\EOT\SYN\STX\ETX\SOH\DC2\EOT\196\SOH\DC1(\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\ETX\ETX\DC2\EOT\167\SOH+,\n\ + \\ENQ\EOT\SYN\STX\ETX\ETX\DC2\EOT\196\SOH+,\n\ \\f\n\ - \\STX\EOT\NAK\DC2\ACK\170\SOH\NUL\173\SOH\SOH\n\ + \\STX\EOT\ETB\DC2\ACK\199\SOH\NUL\202\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\NAK\SOH\DC2\EOT\170\SOH\b\GS\n\ + \\ETX\EOT\ETB\SOH\DC2\EOT\199\SOH\b\GS\n\ \\f\n\ - \\EOT\EOT\NAK\STX\NUL\DC2\EOT\171\SOH\STX'\n\ + \\EOT\EOT\ETB\STX\NUL\DC2\EOT\200\SOH\STX'\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\NUL\ACK\DC2\EOT\171\SOH\STX\DC4\n\ + \\ENQ\EOT\ETB\STX\NUL\ACK\DC2\EOT\200\SOH\STX\DC4\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\NUL\SOH\DC2\EOT\171\SOH\NAK\"\n\ + \\ENQ\EOT\ETB\STX\NUL\SOH\DC2\EOT\200\SOH\NAK\"\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\NUL\ETX\DC2\EOT\171\SOH%&\n\ + \\ENQ\EOT\ETB\STX\NUL\ETX\DC2\EOT\200\SOH%&\n\ \)\n\ - \\EOT\EOT\NAK\STX\SOH\DC2\EOT\172\SOH\STX \"\ESC The Constitution proposed\n\ + \\EOT\EOT\ETB\STX\SOH\DC2\EOT\201\SOH\STX \"\ESC The Constitution proposed\n\ \\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\SOH\ACK\DC2\EOT\172\SOH\STX\SO\n\ + \\ENQ\EOT\ETB\STX\SOH\ACK\DC2\EOT\201\SOH\STX\SO\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\SOH\SOH\DC2\EOT\172\SOH\SI\ESC\n\ + \\ENQ\EOT\ETB\STX\SOH\SOH\DC2\EOT\201\SOH\SI\ESC\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\SOH\ETX\DC2\EOT\172\SOH\RS\US\n\ + \\ENQ\EOT\ETB\STX\SOH\ETX\DC2\EOT\201\SOH\RS\US\n\ \\n\ \\n\ - \\STX\EOT\SYN\DC2\EOT\175\SOH\NUL\NAK\n\ + \\STX\EOT\CAN\DC2\EOT\204\SOH\NUL\NAK\n\ \\v\n\ - \\ETX\EOT\SYN\SOH\DC2\EOT\175\SOH\b\DC2\n\ + \\ETX\EOT\CAN\SOH\DC2\EOT\204\SOH\b\DC2\n\ \\f\n\ - \\STX\EOT\ETB\DC2\ACK\177\SOH\NUL\180\SOH\SOH\n\ + \\STX\EOT\EM\DC2\ACK\206\SOH\NUL\209\SOH\SOH\n\ \\v\n\ - \\ETX\EOT\ETB\SOH\DC2\EOT\177\SOH\b\DC4\n\ + \\ETX\EOT\EM\SOH\DC2\EOT\206\SOH\b\DC4\n\ \*\n\ - \\EOT\EOT\ETB\STX\NUL\DC2\EOT\178\SOH\STX\DC4\"\FS Anchor to the new document\n\ + \\EOT\EOT\EM\STX\NUL\DC2\EOT\207\SOH\STX\DC4\"\FS Anchor to the new document\n\ \\n\ \\r\n\ - \\ENQ\EOT\ETB\STX\NUL\ACK\DC2\EOT\178\SOH\STX\b\n\ + \\ENQ\EOT\EM\STX\NUL\ACK\DC2\EOT\207\SOH\STX\b\n\ \\r\n\ - \\ENQ\EOT\ETB\STX\NUL\SOH\DC2\EOT\178\SOH\t\SI\n\ + \\ENQ\EOT\EM\STX\NUL\SOH\DC2\EOT\207\SOH\t\SI\n\ \\r\n\ - \\ENQ\EOT\ETB\STX\NUL\ETX\DC2\EOT\178\SOH\DC2\DC3\n\ + \\ENQ\EOT\EM\STX\NUL\ETX\DC2\EOT\207\SOH\DC2\DC3\n\ \$\n\ - \\EOT\EOT\ETB\STX\SOH\DC2\EOT\179\SOH\STX\DC1\"\SYN Hash of the document\n\ + \\EOT\EOT\EM\STX\SOH\DC2\EOT\208\SOH\STX\DC1\"\SYN Hash of the document\n\ \\n\ \\r\n\ - \\ENQ\EOT\ETB\STX\SOH\ENQ\DC2\EOT\179\SOH\STX\a\n\ + \\ENQ\EOT\EM\STX\SOH\ENQ\DC2\EOT\208\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\ETB\STX\SOH\SOH\DC2\EOT\179\SOH\b\f\n\ + \\ENQ\EOT\EM\STX\SOH\SOH\DC2\EOT\208\SOH\b\f\n\ \\r\n\ - \\ENQ\EOT\ETB\STX\SOH\ETX\DC2\EOT\179\SOH\SI\DLE\n\ + \\ENQ\EOT\EM\STX\SOH\ETX\DC2\EOT\208\SOH\SI\DLE\n\ \\176\SOH\n\ - \\STX\EOT\CAN\DC2\ACK\184\SOH\NUL\187\SOH\SOH\SUB\161\SOH The new committee credential are passed as a map where the key is the committee cold credential hash\n\ + \\STX\EOT\SUB\DC2\ACK\213\SOH\NUL\216\SOH\SOH\SUB\161\SOH The new committee credential are passed as a map where the key is the committee cold credential hash\n\ \ and the value is the expiration epoch for that credential\n\ \\n\ \\v\n\ - \\ETX\EOT\CAN\SOH\DC2\EOT\184\SOH\b\US\n\ + \\ETX\EOT\SUB\SOH\DC2\EOT\213\SOH\b\US\n\ \\f\n\ - \\EOT\EOT\CAN\STX\NUL\DC2\EOT\185\SOH\STX0\n\ + \\EOT\EOT\SUB\STX\NUL\DC2\EOT\214\SOH\STX0\n\ \\r\n\ - \\ENQ\EOT\CAN\STX\NUL\ACK\DC2\EOT\185\SOH\STX\DC1\n\ + \\ENQ\EOT\SUB\STX\NUL\ACK\DC2\EOT\214\SOH\STX\DC1\n\ \\r\n\ - \\ENQ\EOT\CAN\STX\NUL\SOH\DC2\EOT\185\SOH\DC2+\n\ + \\ENQ\EOT\SUB\STX\NUL\SOH\DC2\EOT\214\SOH\DC2+\n\ \\r\n\ - \\ENQ\EOT\CAN\STX\NUL\ETX\DC2\EOT\185\SOH./\n\ + \\ENQ\EOT\SUB\STX\NUL\ETX\DC2\EOT\214\SOH./\n\ \\f\n\ - \\EOT\EOT\CAN\STX\SOH\DC2\EOT\186\SOH\STX\ESC\n\ + \\EOT\EOT\SUB\STX\SOH\DC2\EOT\215\SOH\STX\ESC\n\ \\r\n\ - \\ENQ\EOT\CAN\STX\SOH\ENQ\DC2\EOT\186\SOH\STX\b\n\ + \\ENQ\EOT\SUB\STX\SOH\ENQ\DC2\EOT\215\SOH\STX\b\n\ \\r\n\ - \\ENQ\EOT\CAN\STX\SOH\SOH\DC2\EOT\186\SOH\t\SYN\n\ + \\ENQ\EOT\SUB\STX\SOH\SOH\DC2\EOT\215\SOH\t\SYN\n\ \\r\n\ - \\ENQ\EOT\CAN\STX\SOH\ETX\DC2\EOT\186\SOH\EM\SUB\n\ + \\ENQ\EOT\SUB\STX\SOH\ETX\DC2\EOT\215\SOH\EM\SUB\n\ \<\n\ - \\STX\EOT\EM\DC2\ACK\190\SOH\NUL\194\SOH\SOH\SUB. Contains the header information for a block.\n\ + \\STX\EOT\ESC\DC2\ACK\219\SOH\NUL\223\SOH\SOH\SUB. Contains the header information for a block.\n\ \\n\ \\v\n\ - \\ETX\EOT\EM\SOH\DC2\EOT\190\SOH\b\DC3\n\ + \\ETX\EOT\ESC\SOH\DC2\EOT\219\SOH\b\DC3\n\ \\FS\n\ - \\EOT\EOT\EM\STX\NUL\DC2\EOT\191\SOH\STX\DC2\"\SO Slot number.\n\ + \\EOT\EOT\ESC\STX\NUL\DC2\EOT\220\SOH\STX\DC2\"\SO Slot number.\n\ \\n\ \\r\n\ - \\ENQ\EOT\EM\STX\NUL\ENQ\DC2\EOT\191\SOH\STX\b\n\ + \\ENQ\EOT\ESC\STX\NUL\ENQ\DC2\EOT\220\SOH\STX\b\n\ \\r\n\ - \\ENQ\EOT\EM\STX\NUL\SOH\DC2\EOT\191\SOH\t\r\n\ + \\ENQ\EOT\ESC\STX\NUL\SOH\DC2\EOT\220\SOH\t\r\n\ \\r\n\ - \\ENQ\EOT\EM\STX\NUL\ETX\DC2\EOT\191\SOH\DLE\DC1\n\ + \\ENQ\EOT\ESC\STX\NUL\ETX\DC2\EOT\220\SOH\DLE\DC1\n\ \\ESC\n\ - \\EOT\EOT\EM\STX\SOH\DC2\EOT\192\SOH\STX\DC1\"\r Block hash.\n\ + \\EOT\EOT\ESC\STX\SOH\DC2\EOT\221\SOH\STX\DC1\"\r Block hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT\EM\STX\SOH\ENQ\DC2\EOT\192\SOH\STX\a\n\ + \\ENQ\EOT\ESC\STX\SOH\ENQ\DC2\EOT\221\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\EM\STX\SOH\SOH\DC2\EOT\192\SOH\b\f\n\ + \\ENQ\EOT\ESC\STX\SOH\SOH\DC2\EOT\221\SOH\b\f\n\ \\r\n\ - \\ENQ\EOT\EM\STX\SOH\ETX\DC2\EOT\192\SOH\SI\DLE\n\ + \\ENQ\EOT\ESC\STX\SOH\ETX\DC2\EOT\221\SOH\SI\DLE\n\ \\GS\n\ - \\EOT\EOT\EM\STX\STX\DC2\EOT\193\SOH\STX\DC4\"\SI Block height.\n\ + \\EOT\EOT\ESC\STX\STX\DC2\EOT\222\SOH\STX\DC4\"\SI Block height.\n\ \\n\ \\r\n\ - \\ENQ\EOT\EM\STX\STX\ENQ\DC2\EOT\193\SOH\STX\b\n\ + \\ENQ\EOT\ESC\STX\STX\ENQ\DC2\EOT\222\SOH\STX\b\n\ \\r\n\ - \\ENQ\EOT\EM\STX\STX\SOH\DC2\EOT\193\SOH\t\SI\n\ + \\ENQ\EOT\ESC\STX\STX\SOH\DC2\EOT\222\SOH\t\SI\n\ \\r\n\ - \\ENQ\EOT\EM\STX\STX\ETX\DC2\EOT\193\SOH\DC2\DC3\n\ + \\ENQ\EOT\ESC\STX\STX\ETX\DC2\EOT\222\SOH\DC2\DC3\n\ \:\n\ - \\STX\EOT\SUB\DC2\ACK\197\SOH\NUL\199\SOH\SOH\SUB, Contains the transaction data for a block.\n\ + \\STX\EOT\FS\DC2\ACK\226\SOH\NUL\228\SOH\SOH\SUB, Contains the transaction data for a block.\n\ \\n\ \\v\n\ - \\ETX\EOT\SUB\SOH\DC2\EOT\197\SOH\b\DC1\n\ + \\ETX\EOT\FS\SOH\DC2\EOT\226\SOH\b\DC1\n\ \%\n\ - \\EOT\EOT\SUB\STX\NUL\DC2\EOT\198\SOH\STX\NAK\"\ETB List of transactions.\n\ + \\EOT\EOT\FS\STX\NUL\DC2\EOT\227\SOH\STX\NAK\"\ETB List of transactions.\n\ \\n\ \\r\n\ - \\ENQ\EOT\SUB\STX\NUL\EOT\DC2\EOT\198\SOH\STX\n\ + \\ENQ\EOT\FS\STX\NUL\EOT\DC2\EOT\227\SOH\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT\SUB\STX\NUL\ACK\DC2\EOT\198\SOH\v\r\n\ + \\ENQ\EOT\FS\STX\NUL\ACK\DC2\EOT\227\SOH\v\r\n\ \\r\n\ - \\ENQ\EOT\SUB\STX\NUL\SOH\DC2\EOT\198\SOH\SO\DLE\n\ + \\ENQ\EOT\FS\STX\NUL\SOH\DC2\EOT\227\SOH\SO\DLE\n\ \\r\n\ - \\ENQ\EOT\SUB\STX\NUL\ETX\DC2\EOT\198\SOH\DC3\DC4\n\ + \\ENQ\EOT\FS\STX\NUL\ETX\DC2\EOT\227\SOH\DC3\DC4\n\ \G\n\ - \\STX\EOT\ESC\DC2\ACK\202\SOH\NUL\206\SOH\SOH\SUB9 Represents a complete block, including header and body.\n\ + \\STX\EOT\GS\DC2\ACK\231\SOH\NUL\235\SOH\SOH\SUB9 Represents a complete block, including header and body.\n\ \\n\ \\v\n\ - \\ETX\EOT\ESC\SOH\DC2\EOT\202\SOH\b\r\n\ + \\ETX\EOT\GS\SOH\DC2\EOT\231\SOH\b\r\n\ \\GS\n\ - \\EOT\EOT\ESC\STX\NUL\DC2\EOT\203\SOH\STX\EM\"\SI Block header.\n\ + \\EOT\EOT\GS\STX\NUL\DC2\EOT\232\SOH\STX\EM\"\SI Block header.\n\ \\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\NUL\ACK\DC2\EOT\203\SOH\STX\r\n\ + \\ENQ\EOT\GS\STX\NUL\ACK\DC2\EOT\232\SOH\STX\r\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\NUL\SOH\DC2\EOT\203\SOH\SO\DC4\n\ + \\ENQ\EOT\GS\STX\NUL\SOH\DC2\EOT\232\SOH\SO\DC4\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\NUL\ETX\DC2\EOT\203\SOH\ETB\CAN\n\ + \\ENQ\EOT\GS\STX\NUL\ETX\DC2\EOT\232\SOH\ETB\CAN\n\ \\ESC\n\ - \\EOT\EOT\ESC\STX\SOH\DC2\EOT\204\SOH\STX\NAK\"\r Block body.\n\ + \\EOT\EOT\GS\STX\SOH\DC2\EOT\233\SOH\STX\NAK\"\r Block body.\n\ \\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\SOH\ACK\DC2\EOT\204\SOH\STX\v\n\ + \\ENQ\EOT\GS\STX\SOH\ACK\DC2\EOT\233\SOH\STX\v\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\SOH\SOH\DC2\EOT\204\SOH\f\DLE\n\ + \\ENQ\EOT\GS\STX\SOH\SOH\DC2\EOT\233\SOH\f\DLE\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\SOH\ETX\DC2\EOT\204\SOH\DC3\DC4\n\ + \\ENQ\EOT\GS\STX\SOH\ETX\DC2\EOT\233\SOH\DC3\DC4\n\ \\"\n\ - \\EOT\EOT\ESC\STX\STX\DC2\EOT\205\SOH\STX\ETB\"\DC4 Block ms timestamp\n\ + \\EOT\EOT\GS\STX\STX\DC2\EOT\234\SOH\STX\ETB\"\DC4 Block ms timestamp\n\ \\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\STX\ENQ\DC2\EOT\205\SOH\STX\b\n\ + \\ENQ\EOT\GS\STX\STX\ENQ\DC2\EOT\234\SOH\STX\b\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\STX\SOH\DC2\EOT\205\SOH\t\DC2\n\ + \\ENQ\EOT\GS\STX\STX\SOH\DC2\EOT\234\SOH\t\DC2\n\ \\r\n\ - \\ENQ\EOT\ESC\STX\STX\ETX\DC2\EOT\205\SOH\NAK\SYN\n\ + \\ENQ\EOT\GS\STX\STX\ETX\DC2\EOT\234\SOH\NAK\SYN\n\ \8\n\ - \\STX\EOT\FS\DC2\ACK\209\SOH\NUL\214\SOH\SOH\SUB* Represents bootstrap keys from Byron era\n\ + \\STX\EOT\RS\DC2\ACK\238\SOH\NUL\243\SOH\SOH\SUB* Represents bootstrap keys from Byron era\n\ \\n\ \\v\n\ - \\ETX\EOT\FS\SOH\DC2\EOT\209\SOH\b\CAN\n\ + \\ETX\EOT\RS\SOH\DC2\EOT\238\SOH\b\CAN\n\ \!\n\ - \\EOT\EOT\FS\STX\NUL\DC2\EOT\210\SOH\STX\DC1\"\DC3 Verification key.\n\ + \\EOT\EOT\RS\STX\NUL\DC2\EOT\239\SOH\STX\DC1\"\DC3 Verification key.\n\ \\n\ \\r\n\ - \\ENQ\EOT\FS\STX\NUL\ENQ\DC2\EOT\210\SOH\STX\a\n\ + \\ENQ\EOT\RS\STX\NUL\ENQ\DC2\EOT\239\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\FS\STX\NUL\SOH\DC2\EOT\210\SOH\b\f\n\ + \\ENQ\EOT\RS\STX\NUL\SOH\DC2\EOT\239\SOH\b\f\n\ \\r\n\ - \\ENQ\EOT\FS\STX\NUL\ETX\DC2\EOT\210\SOH\SI\DLE\n\ + \\ENQ\EOT\RS\STX\NUL\ETX\DC2\EOT\239\SOH\SI\DLE\n\ \E\n\ - \\EOT\EOT\FS\STX\SOH\DC2\EOT\211\SOH\STX\SYN\"7 Signature generated using the associated private key.\n\ + \\EOT\EOT\RS\STX\SOH\DC2\EOT\240\SOH\STX\SYN\"7 Signature generated using the associated private key.\n\ \\n\ \\r\n\ - \\ENQ\EOT\FS\STX\SOH\ENQ\DC2\EOT\211\SOH\STX\a\n\ + \\ENQ\EOT\RS\STX\SOH\ENQ\DC2\EOT\240\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\FS\STX\SOH\SOH\DC2\EOT\211\SOH\b\DC1\n\ + \\ENQ\EOT\RS\STX\SOH\SOH\DC2\EOT\240\SOH\b\DC1\n\ \\r\n\ - \\ENQ\EOT\FS\STX\SOH\ETX\DC2\EOT\211\SOH\DC4\NAK\n\ + \\ENQ\EOT\RS\STX\SOH\ETX\DC2\EOT\240\SOH\DC4\NAK\n\ \&\n\ - \\EOT\EOT\FS\STX\STX\DC2\EOT\212\SOH\STX\ETB\"\CAN 32 bytes of chain code\n\ + \\EOT\EOT\RS\STX\STX\DC2\EOT\241\SOH\STX\ETB\"\CAN 32 bytes of chain code\n\ \\n\ \\r\n\ - \\ENQ\EOT\FS\STX\STX\ENQ\DC2\EOT\212\SOH\STX\a\n\ + \\ENQ\EOT\RS\STX\STX\ENQ\DC2\EOT\241\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\FS\STX\STX\SOH\DC2\EOT\212\SOH\b\DC2\n\ + \\ENQ\EOT\RS\STX\STX\SOH\DC2\EOT\241\SOH\b\DC2\n\ \\r\n\ - \\ENQ\EOT\FS\STX\STX\ETX\DC2\EOT\212\SOH\NAK\SYN\n\ + \\ENQ\EOT\RS\STX\STX\ETX\DC2\EOT\241\SOH\NAK\SYN\n\ \\RS\n\ - \\EOT\EOT\FS\STX\ETX\DC2\EOT\213\SOH\STX\ETB\"\DLE key attributes\n\ + \\EOT\EOT\RS\STX\ETX\DC2\EOT\242\SOH\STX\ETB\"\DLE key attributes\n\ \\n\ \\r\n\ - \\ENQ\EOT\FS\STX\ETX\ENQ\DC2\EOT\213\SOH\STX\a\n\ + \\ENQ\EOT\RS\STX\ETX\ENQ\DC2\EOT\242\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\FS\STX\ETX\SOH\DC2\EOT\213\SOH\b\DC2\n\ + \\ENQ\EOT\RS\STX\ETX\SOH\DC2\EOT\242\SOH\b\DC2\n\ \\r\n\ - \\ENQ\EOT\FS\STX\ETX\ETX\DC2\EOT\213\SOH\NAK\SYN\n\ + \\ENQ\EOT\RS\STX\ETX\ETX\DC2\EOT\242\SOH\NAK\SYN\n\ \E\n\ - \\STX\EOT\GS\DC2\ACK\217\SOH\NUL\220\SOH\SOH\SUB7 Represents a VKey witness used to sign a transaction.\n\ + \\STX\EOT\US\DC2\ACK\246\SOH\NUL\249\SOH\SOH\SUB7 Represents a VKey witness used to sign a transaction.\n\ \\n\ \\v\n\ - \\ETX\EOT\GS\SOH\DC2\EOT\217\SOH\b\DC3\n\ + \\ETX\EOT\US\SOH\DC2\EOT\246\SOH\b\DC3\n\ \!\n\ - \\EOT\EOT\GS\STX\NUL\DC2\EOT\218\SOH\STX\DC1\"\DC3 Verification key.\n\ + \\EOT\EOT\US\STX\NUL\DC2\EOT\247\SOH\STX\DC1\"\DC3 Verification key.\n\ \\n\ \\r\n\ - \\ENQ\EOT\GS\STX\NUL\ENQ\DC2\EOT\218\SOH\STX\a\n\ + \\ENQ\EOT\US\STX\NUL\ENQ\DC2\EOT\247\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\GS\STX\NUL\SOH\DC2\EOT\218\SOH\b\f\n\ + \\ENQ\EOT\US\STX\NUL\SOH\DC2\EOT\247\SOH\b\f\n\ \\r\n\ - \\ENQ\EOT\GS\STX\NUL\ETX\DC2\EOT\218\SOH\SI\DLE\n\ + \\ENQ\EOT\US\STX\NUL\ETX\DC2\EOT\247\SOH\SI\DLE\n\ \E\n\ - \\EOT\EOT\GS\STX\SOH\DC2\EOT\219\SOH\STX\SYN\"7 Signature generated using the associated private key.\n\ + \\EOT\EOT\US\STX\SOH\DC2\EOT\248\SOH\STX\SYN\"7 Signature generated using the associated private key.\n\ \\n\ \\r\n\ - \\ENQ\EOT\GS\STX\SOH\ENQ\DC2\EOT\219\SOH\STX\a\n\ + \\ENQ\EOT\US\STX\SOH\ENQ\DC2\EOT\248\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\GS\STX\SOH\SOH\DC2\EOT\219\SOH\b\DC1\n\ + \\ENQ\EOT\US\STX\SOH\SOH\DC2\EOT\248\SOH\b\DC1\n\ \\r\n\ - \\ENQ\EOT\GS\STX\SOH\ETX\DC2\EOT\219\SOH\DC4\NAK\n\ + \\ENQ\EOT\US\STX\SOH\ETX\DC2\EOT\248\SOH\DC4\NAK\n\ \6\n\ - \\STX\EOT\RS\DC2\ACK\223\SOH\NUL\232\SOH\SOH\SUB( Represents a native script in Cardano.\n\ + \\STX\EOT \DC2\ACK\252\SOH\NUL\133\STX\SOH\SUB( Represents a native script in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT\RS\SOH\DC2\EOT\223\SOH\b\DC4\n\ + \\ETX\EOT \SOH\DC2\EOT\252\SOH\b\DC4\n\ \\SO\n\ - \\EOT\EOT\RS\b\NUL\DC2\ACK\224\SOH\STX\231\SOH\ETX\n\ + \\EOT\EOT \b\NUL\DC2\ACK\253\SOH\STX\132\STX\ETX\n\ \\r\n\ - \\ENQ\EOT\RS\b\NUL\SOH\DC2\EOT\224\SOH\b\NAK\n\ + \\ENQ\EOT \b\NUL\SOH\DC2\EOT\253\SOH\b\NAK\n\ \4\n\ - \\EOT\EOT\RS\STX\NUL\DC2\EOT\225\SOH\EOT!\"& Script based on an address key hash.\n\ + \\EOT\EOT \STX\NUL\DC2\EOT\254\SOH\EOT!\"& Script based on an address key hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\NUL\ENQ\DC2\EOT\225\SOH\EOT\t\n\ + \\ENQ\EOT \STX\NUL\ENQ\DC2\EOT\254\SOH\EOT\t\n\ \\r\n\ - \\ENQ\EOT\RS\STX\NUL\SOH\DC2\EOT\225\SOH\n\ + \\ENQ\EOT \STX\NUL\SOH\DC2\EOT\254\SOH\n\ \\FS\n\ \\r\n\ - \\ENQ\EOT\RS\STX\NUL\ETX\DC2\EOT\225\SOH\US \n\ + \\ENQ\EOT \STX\NUL\ETX\DC2\EOT\254\SOH\US \n\ \H\n\ - \\EOT\EOT\RS\STX\SOH\DC2\EOT\226\SOH\EOT$\": Script that requires all nested scripts to be satisfied.\n\ + \\EOT\EOT \STX\SOH\DC2\EOT\255\SOH\EOT$\": Script that requires all nested scripts to be satisfied.\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\SOH\ACK\DC2\EOT\226\SOH\EOT\DC4\n\ + \\ENQ\EOT \STX\SOH\ACK\DC2\EOT\255\SOH\EOT\DC4\n\ \\r\n\ - \\ENQ\EOT\RS\STX\SOH\SOH\DC2\EOT\226\SOH\NAK\US\n\ + \\ENQ\EOT \STX\SOH\SOH\DC2\EOT\255\SOH\NAK\US\n\ \\r\n\ - \\ENQ\EOT\RS\STX\SOH\ETX\DC2\EOT\226\SOH\"#\n\ + \\ENQ\EOT \STX\SOH\ETX\DC2\EOT\255\SOH\"#\n\ \O\n\ - \\EOT\EOT\RS\STX\STX\DC2\EOT\227\SOH\EOT$\"A Script that requires any of the nested scripts to be satisfied.\n\ + \\EOT\EOT \STX\STX\DC2\EOT\128\STX\EOT$\"A Script that requires any of the nested scripts to be satisfied.\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\STX\ACK\DC2\EOT\227\SOH\EOT\DC4\n\ + \\ENQ\EOT \STX\STX\ACK\DC2\EOT\128\STX\EOT\DC4\n\ \\r\n\ - \\ENQ\EOT\RS\STX\STX\SOH\DC2\EOT\227\SOH\NAK\US\n\ + \\ENQ\EOT \STX\STX\SOH\DC2\EOT\128\STX\NAK\US\n\ \\r\n\ - \\ENQ\EOT\RS\STX\STX\ETX\DC2\EOT\227\SOH\"#\n\ + \\ENQ\EOT \STX\STX\ETX\DC2\EOT\128\STX\"#\n\ \O\n\ - \\EOT\EOT\RS\STX\ETX\DC2\EOT\228\SOH\EOT!\"A Script that requires k out of n nested scripts to be satisfied.\n\ + \\EOT\EOT \STX\ETX\DC2\EOT\129\STX\EOT!\"A Script that requires k out of n nested scripts to be satisfied.\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\ETX\ACK\DC2\EOT\228\SOH\EOT\SO\n\ + \\ENQ\EOT \STX\ETX\ACK\DC2\EOT\129\STX\EOT\SO\n\ \\r\n\ - \\ENQ\EOT\RS\STX\ETX\SOH\DC2\EOT\228\SOH\SI\FS\n\ + \\ENQ\EOT \STX\ETX\SOH\DC2\EOT\129\STX\SI\FS\n\ \\r\n\ - \\ENQ\EOT\RS\STX\ETX\ETX\DC2\EOT\228\SOH\US \n\ + \\ENQ\EOT \STX\ETX\ETX\DC2\EOT\129\STX\US \n\ \?\n\ - \\EOT\EOT\RS\STX\EOT\DC2\EOT\229\SOH\EOT\RS\"1 Slot number before which the script is invalid.\n\ + \\EOT\EOT \STX\EOT\DC2\EOT\130\STX\EOT\RS\"1 Slot number before which the script is invalid.\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\EOT\ENQ\DC2\EOT\229\SOH\EOT\n\ + \\ENQ\EOT \STX\EOT\ENQ\DC2\EOT\130\STX\EOT\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\EOT\SOH\DC2\EOT\229\SOH\v\EM\n\ + \\ENQ\EOT \STX\EOT\SOH\DC2\EOT\130\STX\v\EM\n\ \\r\n\ - \\ENQ\EOT\RS\STX\EOT\ETX\DC2\EOT\229\SOH\FS\GS\n\ + \\ENQ\EOT \STX\EOT\ETX\DC2\EOT\130\STX\FS\GS\n\ \>\n\ - \\EOT\EOT\RS\STX\ENQ\DC2\EOT\230\SOH\EOT!\"0 Slot number after which the script is invalid.\n\ + \\EOT\EOT \STX\ENQ\DC2\EOT\131\STX\EOT!\"0 Slot number after which the script is invalid.\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\ENQ\ENQ\DC2\EOT\230\SOH\EOT\n\ + \\ENQ\EOT \STX\ENQ\ENQ\DC2\EOT\131\STX\EOT\n\ \\n\ \\r\n\ - \\ENQ\EOT\RS\STX\ENQ\SOH\DC2\EOT\230\SOH\v\FS\n\ + \\ENQ\EOT \STX\ENQ\SOH\DC2\EOT\131\STX\v\FS\n\ \\r\n\ - \\ENQ\EOT\RS\STX\ENQ\ETX\DC2\EOT\230\SOH\US \n\ + \\ENQ\EOT \STX\ENQ\ETX\DC2\EOT\131\STX\US \n\ \4\n\ - \\STX\EOT\US\DC2\ACK\235\SOH\NUL\237\SOH\SOH\SUB& Represents a list of native scripts.\n\ + \\STX\EOT!\DC2\ACK\136\STX\NUL\138\STX\SOH\SUB& Represents a list of native scripts.\n\ \\n\ \\v\n\ - \\ETX\EOT\US\SOH\DC2\EOT\235\SOH\b\CAN\n\ + \\ETX\EOT!\SOH\DC2\EOT\136\STX\b\CAN\n\ \'\n\ - \\EOT\EOT\US\STX\NUL\DC2\EOT\236\SOH\STX\"\"\EM List of native scripts.\n\ + \\EOT\EOT!\STX\NUL\DC2\EOT\137\STX\STX\"\"\EM List of native scripts.\n\ \\n\ \\r\n\ - \\ENQ\EOT\US\STX\NUL\EOT\DC2\EOT\236\SOH\STX\n\ + \\ENQ\EOT!\STX\NUL\EOT\DC2\EOT\137\STX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT\US\STX\NUL\ACK\DC2\EOT\236\SOH\v\ETB\n\ + \\ENQ\EOT!\STX\NUL\ACK\DC2\EOT\137\STX\v\ETB\n\ \\r\n\ - \\ENQ\EOT\US\STX\NUL\SOH\DC2\EOT\236\SOH\CAN\GS\n\ + \\ENQ\EOT!\STX\NUL\SOH\DC2\EOT\137\STX\CAN\GS\n\ \\r\n\ - \\ENQ\EOT\US\STX\NUL\ETX\DC2\EOT\236\SOH !\n\ + \\ENQ\EOT!\STX\NUL\ETX\DC2\EOT\137\STX !\n\ \8\n\ - \\STX\EOT \DC2\ACK\240\SOH\NUL\243\SOH\SOH\SUB* Represents a \"k out of n\" native script.\n\ + \\STX\EOT\"\DC2\ACK\141\STX\NUL\144\STX\SOH\SUB* Represents a \"k out of n\" native script.\n\ \\n\ \\v\n\ - \\ETX\EOT \SOH\DC2\EOT\240\SOH\b\DC2\n\ + \\ETX\EOT\"\SOH\DC2\EOT\141\STX\b\DC2\n\ \9\n\ - \\EOT\EOT \STX\NUL\DC2\EOT\241\SOH\STX\SI\"+ The number of required satisfied scripts.\n\ + \\EOT\EOT\"\STX\NUL\DC2\EOT\142\STX\STX\SI\"+ The number of required satisfied scripts.\n\ \\n\ \\r\n\ - \\ENQ\EOT \STX\NUL\ENQ\DC2\EOT\241\SOH\STX\b\n\ + \\ENQ\EOT\"\STX\NUL\ENQ\DC2\EOT\142\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT \STX\NUL\SOH\DC2\EOT\241\SOH\t\n\ + \\ENQ\EOT\"\STX\NUL\SOH\DC2\EOT\142\STX\t\n\ \\n\ \\r\n\ - \\ENQ\EOT \STX\NUL\ETX\DC2\EOT\241\SOH\r\SO\n\ + \\ENQ\EOT\"\STX\NUL\ETX\DC2\EOT\142\STX\r\SO\n\ \'\n\ - \\EOT\EOT \STX\SOH\DC2\EOT\242\SOH\STX$\"\EM List of native scripts.\n\ + \\EOT\EOT\"\STX\SOH\DC2\EOT\143\STX\STX$\"\EM List of native scripts.\n\ \\n\ \\r\n\ - \\ENQ\EOT \STX\SOH\EOT\DC2\EOT\242\SOH\STX\n\ + \\ENQ\EOT\"\STX\SOH\EOT\DC2\EOT\143\STX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT \STX\SOH\ACK\DC2\EOT\242\SOH\v\ETB\n\ + \\ENQ\EOT\"\STX\SOH\ACK\DC2\EOT\143\STX\v\ETB\n\ \\r\n\ - \\ENQ\EOT \STX\SOH\SOH\DC2\EOT\242\SOH\CAN\US\n\ + \\ENQ\EOT\"\STX\SOH\SOH\DC2\EOT\143\STX\CAN\US\n\ \\r\n\ - \\ENQ\EOT \STX\SOH\ETX\DC2\EOT\242\SOH\"#\n\ + \\ENQ\EOT\"\STX\SOH\ETX\DC2\EOT\143\STX\"#\n\ \D\n\ - \\STX\EOT!\DC2\ACK\246\SOH\NUL\250\SOH\SOH\SUB6 Represents a constructor for Plutus data in Cardano.\n\ + \\STX\EOT#\DC2\ACK\147\STX\NUL\151\STX\SOH\SUB6 Represents a constructor for Plutus data in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT!\SOH\DC2\EOT\246\SOH\b\SO\n\ + \\ETX\EOT#\SOH\DC2\EOT\147\STX\b\SO\n\ \\f\n\ - \\EOT\EOT!\STX\NUL\DC2\EOT\247\SOH\STX\DC1\n\ + \\EOT\EOT#\STX\NUL\DC2\EOT\148\STX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT!\STX\NUL\ENQ\DC2\EOT\247\SOH\STX\b\n\ + \\ENQ\EOT#\STX\NUL\ENQ\DC2\EOT\148\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT!\STX\NUL\SOH\DC2\EOT\247\SOH\t\f\n\ + \\ENQ\EOT#\STX\NUL\SOH\DC2\EOT\148\STX\t\f\n\ \\r\n\ - \\ENQ\EOT!\STX\NUL\ETX\DC2\EOT\247\SOH\SI\DLE\n\ + \\ENQ\EOT#\STX\NUL\ETX\DC2\EOT\148\STX\SI\DLE\n\ \\f\n\ - \\EOT\EOT!\STX\SOH\DC2\EOT\248\SOH\STX\GS\n\ + \\EOT\EOT#\STX\SOH\DC2\EOT\149\STX\STX\GS\n\ \\r\n\ - \\ENQ\EOT!\STX\SOH\ENQ\DC2\EOT\248\SOH\STX\b\n\ + \\ENQ\EOT#\STX\SOH\ENQ\DC2\EOT\149\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT!\STX\SOH\SOH\DC2\EOT\248\SOH\t\CAN\n\ + \\ENQ\EOT#\STX\SOH\SOH\DC2\EOT\149\STX\t\CAN\n\ \\r\n\ - \\ENQ\EOT!\STX\SOH\ETX\DC2\EOT\248\SOH\ESC\FS\n\ + \\ENQ\EOT#\STX\SOH\ETX\DC2\EOT\149\STX\ESC\FS\n\ \\f\n\ - \\EOT\EOT!\STX\STX\DC2\EOT\249\SOH\STX!\n\ + \\EOT\EOT#\STX\STX\DC2\EOT\150\STX\STX!\n\ \\r\n\ - \\ENQ\EOT!\STX\STX\EOT\DC2\EOT\249\SOH\STX\n\ + \\ENQ\EOT#\STX\STX\EOT\DC2\EOT\150\STX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT!\STX\STX\ACK\DC2\EOT\249\SOH\v\NAK\n\ + \\ENQ\EOT#\STX\STX\ACK\DC2\EOT\150\STX\v\NAK\n\ \\r\n\ - \\ENQ\EOT!\STX\STX\SOH\DC2\EOT\249\SOH\SYN\FS\n\ + \\ENQ\EOT#\STX\STX\SOH\DC2\EOT\150\STX\SYN\FS\n\ \\r\n\ - \\ENQ\EOT!\STX\STX\ETX\DC2\EOT\249\SOH\US \n\ + \\ENQ\EOT#\STX\STX\ETX\DC2\EOT\150\STX\US \n\ \\207\SOH\n\ - \\STX\EOT\"\DC2\ACK\255\SOH\NUL\133\STX\SOH\SUB\192\SOH Represents a big integer for Plutus data in Cardano.\n\ + \\STX\EOT$\DC2\ACK\156\STX\NUL\162\STX\SOH\SUB\192\SOH Represents a big integer for Plutus data in Cardano.\n\ \ The representation here follows CBOR specification for bignums:\n\ \ https://www.rfc-editor.org/rfc/rfc8949.html#name-bignums section 3.4.3.\n\ \\n\ \\v\n\ - \\ETX\EOT\"\SOH\DC2\EOT\255\SOH\b\SO\n\ + \\ETX\EOT$\SOH\DC2\EOT\156\STX\b\SO\n\ \\SO\n\ - \\EOT\EOT\"\b\NUL\DC2\ACK\128\STX\STX\132\STX\ETX\n\ + \\EOT\EOT$\b\NUL\DC2\ACK\157\STX\STX\161\STX\ETX\n\ \\r\n\ - \\ENQ\EOT\"\b\NUL\SOH\DC2\EOT\128\STX\b\SI\n\ + \\ENQ\EOT$\b\NUL\SOH\DC2\EOT\157\STX\b\SI\n\ \7\n\ - \\EOT\EOT\"\STX\NUL\DC2\EOT\129\STX\EOT\DC2\") Stores value fitting within int64 range\n\ + \\EOT\EOT$\STX\NUL\DC2\EOT\158\STX\EOT\DC2\") Stores value fitting within int64 range\n\ \\n\ \\r\n\ - \\ENQ\EOT\"\STX\NUL\ENQ\DC2\EOT\129\STX\EOT\t\n\ + \\ENQ\EOT$\STX\NUL\ENQ\DC2\EOT\158\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT\"\STX\NUL\SOH\DC2\EOT\129\STX\n\ + \\ENQ\EOT$\STX\NUL\SOH\DC2\EOT\158\STX\n\ \\r\n\ \\r\n\ - \\ENQ\EOT\"\STX\NUL\ETX\DC2\EOT\129\STX\DLE\DC1\n\ + \\ENQ\EOT$\STX\NUL\ETX\DC2\EOT\158\STX\DLE\DC1\n\ \;\n\ - \\EOT\EOT\"\STX\SOH\DC2\EOT\130\STX\EOT\CAN\"- Stores unsigned value exceeding int64 range\n\ + \\EOT\EOT$\STX\SOH\DC2\EOT\159\STX\EOT\CAN\"- Stores unsigned value exceeding int64 range\n\ \\n\ \\r\n\ - \\ENQ\EOT\"\STX\SOH\ENQ\DC2\EOT\130\STX\EOT\t\n\ + \\ENQ\EOT$\STX\SOH\ENQ\DC2\EOT\159\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT\"\STX\SOH\SOH\DC2\EOT\130\STX\n\ + \\ENQ\EOT$\STX\SOH\SOH\DC2\EOT\159\STX\n\ \\DC3\n\ \\r\n\ - \\ENQ\EOT\"\STX\SOH\ETX\DC2\EOT\130\STX\SYN\ETB\n\ + \\ENQ\EOT$\STX\SOH\ETX\DC2\EOT\159\STX\SYN\ETB\n\ \K\n\ - \\EOT\EOT\"\STX\STX\DC2\EOT\131\STX\EOT\CAN\"= Stores negative value `n` exceeding int64 range as `-1 - n`\n\ + \\EOT\EOT$\STX\STX\DC2\EOT\160\STX\EOT\CAN\"= Stores negative value `n` exceeding int64 range as `-1 - n`\n\ \\n\ \\r\n\ - \\ENQ\EOT\"\STX\STX\ENQ\DC2\EOT\131\STX\EOT\t\n\ + \\ENQ\EOT$\STX\STX\ENQ\DC2\EOT\160\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT\"\STX\STX\SOH\DC2\EOT\131\STX\n\ + \\ENQ\EOT$\STX\STX\SOH\DC2\EOT\160\STX\n\ \\DC3\n\ \\r\n\ - \\ENQ\EOT\"\STX\STX\ETX\DC2\EOT\131\STX\SYN\ETB\n\ + \\ENQ\EOT$\STX\STX\ETX\DC2\EOT\160\STX\SYN\ETB\n\ \G\n\ - \\STX\EOT#\DC2\ACK\136\STX\NUL\139\STX\SOH\SUB9 Represents a key-value pair for Plutus data in Cardano.\n\ + \\STX\EOT%\DC2\ACK\165\STX\NUL\168\STX\SOH\SUB9 Represents a key-value pair for Plutus data in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT#\SOH\DC2\EOT\136\STX\b\SYN\n\ + \\ETX\EOT%\SOH\DC2\EOT\165\STX\b\SYN\n\ \ \n\ - \\EOT\EOT#\STX\NUL\DC2\EOT\137\STX\STX\NAK\"\DC2 Key of the pair.\n\ + \\EOT\EOT%\STX\NUL\DC2\EOT\166\STX\STX\NAK\"\DC2 Key of the pair.\n\ \\n\ \\r\n\ - \\ENQ\EOT#\STX\NUL\ACK\DC2\EOT\137\STX\STX\f\n\ + \\ENQ\EOT%\STX\NUL\ACK\DC2\EOT\166\STX\STX\f\n\ \\r\n\ - \\ENQ\EOT#\STX\NUL\SOH\DC2\EOT\137\STX\r\DLE\n\ + \\ENQ\EOT%\STX\NUL\SOH\DC2\EOT\166\STX\r\DLE\n\ \\r\n\ - \\ENQ\EOT#\STX\NUL\ETX\DC2\EOT\137\STX\DC3\DC4\n\ + \\ENQ\EOT%\STX\NUL\ETX\DC2\EOT\166\STX\DC3\DC4\n\ \\"\n\ - \\EOT\EOT#\STX\SOH\DC2\EOT\138\STX\STX\ETB\"\DC4 Value of the pair.\n\ + \\EOT\EOT%\STX\SOH\DC2\EOT\167\STX\STX\ETB\"\DC4 Value of the pair.\n\ \\n\ \\r\n\ - \\ENQ\EOT#\STX\SOH\ACK\DC2\EOT\138\STX\STX\f\n\ + \\ENQ\EOT%\STX\SOH\ACK\DC2\EOT\167\STX\STX\f\n\ \\r\n\ - \\ENQ\EOT#\STX\SOH\SOH\DC2\EOT\138\STX\r\DC2\n\ + \\ENQ\EOT%\STX\SOH\SOH\DC2\EOT\167\STX\r\DC2\n\ \\r\n\ - \\ENQ\EOT#\STX\SOH\ETX\DC2\EOT\138\STX\NAK\SYN\n\ + \\ENQ\EOT%\STX\SOH\ETX\DC2\EOT\167\STX\NAK\SYN\n\ \9\n\ - \\STX\EOT$\DC2\ACK\142\STX\NUL\150\STX\SOH\SUB+ Represents a Plutus data item in Cardano.\n\ + \\STX\EOT&\DC2\ACK\171\STX\NUL\179\STX\SOH\SUB+ Represents a Plutus data item in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT$\SOH\DC2\EOT\142\STX\b\DC2\n\ + \\ETX\EOT&\SOH\DC2\EOT\171\STX\b\DC2\n\ \\SO\n\ - \\EOT\EOT$\b\NUL\DC2\ACK\143\STX\STX\149\STX\ETX\n\ + \\EOT\EOT&\b\NUL\DC2\ACK\172\STX\STX\178\STX\ETX\n\ \\r\n\ - \\ENQ\EOT$\b\NUL\SOH\DC2\EOT\143\STX\b\DC3\n\ + \\ENQ\EOT&\b\NUL\SOH\DC2\EOT\172\STX\b\DC3\n\ \\FS\n\ - \\EOT\EOT$\STX\NUL\DC2\EOT\144\STX\EOT\SYN\"\SO Constructor.\n\ + \\EOT\EOT&\STX\NUL\DC2\EOT\173\STX\EOT\SYN\"\SO Constructor.\n\ \\n\ \\r\n\ - \\ENQ\EOT$\STX\NUL\ACK\DC2\EOT\144\STX\EOT\n\ + \\ENQ\EOT&\STX\NUL\ACK\DC2\EOT\173\STX\EOT\n\ \\n\ \\r\n\ - \\ENQ\EOT$\STX\NUL\SOH\DC2\EOT\144\STX\v\DC1\n\ + \\ENQ\EOT&\STX\NUL\SOH\DC2\EOT\173\STX\v\DC1\n\ \\r\n\ - \\ENQ\EOT$\STX\NUL\ETX\DC2\EOT\144\STX\DC4\NAK\n\ + \\ENQ\EOT&\STX\NUL\ETX\DC2\EOT\173\STX\DC4\NAK\n\ \#\n\ - \\EOT\EOT$\STX\SOH\DC2\EOT\145\STX\EOT\SUB\"\NAK Map of Plutus data.\n\ + \\EOT\EOT&\STX\SOH\DC2\EOT\174\STX\EOT\SUB\"\NAK Map of Plutus data.\n\ \\n\ \\r\n\ - \\ENQ\EOT$\STX\SOH\ACK\DC2\EOT\145\STX\EOT\DC1\n\ + \\ENQ\EOT&\STX\SOH\ACK\DC2\EOT\174\STX\EOT\DC1\n\ \\r\n\ - \\ENQ\EOT$\STX\SOH\SOH\DC2\EOT\145\STX\DC2\NAK\n\ + \\ENQ\EOT&\STX\SOH\SOH\DC2\EOT\174\STX\DC2\NAK\n\ \\r\n\ - \\ENQ\EOT$\STX\SOH\ETX\DC2\EOT\145\STX\CAN\EM\n\ + \\ENQ\EOT&\STX\SOH\ETX\DC2\EOT\174\STX\CAN\EM\n\ \\FS\n\ - \\EOT\EOT$\STX\STX\DC2\EOT\146\STX\EOT\ETB\"\SO Big integer.\n\ + \\EOT\EOT&\STX\STX\DC2\EOT\175\STX\EOT\ETB\"\SO Big integer.\n\ \\n\ \\r\n\ - \\ENQ\EOT$\STX\STX\ACK\DC2\EOT\146\STX\EOT\n\ + \\ENQ\EOT&\STX\STX\ACK\DC2\EOT\175\STX\EOT\n\ \\n\ \\r\n\ - \\ENQ\EOT$\STX\STX\SOH\DC2\EOT\146\STX\v\DC2\n\ + \\ENQ\EOT&\STX\STX\SOH\DC2\EOT\175\STX\v\DC2\n\ \\r\n\ - \\ENQ\EOT$\STX\STX\ETX\DC2\EOT\146\STX\NAK\SYN\n\ + \\ENQ\EOT&\STX\STX\ETX\DC2\EOT\175\STX\NAK\SYN\n\ \\RS\n\ - \\EOT\EOT$\STX\ETX\DC2\EOT\147\STX\EOT\FS\"\DLE Bounded bytes.\n\ + \\EOT\EOT&\STX\ETX\DC2\EOT\176\STX\EOT\FS\"\DLE Bounded bytes.\n\ \\n\ \\r\n\ - \\ENQ\EOT$\STX\ETX\ENQ\DC2\EOT\147\STX\EOT\t\n\ + \\ENQ\EOT&\STX\ETX\ENQ\DC2\EOT\176\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT$\STX\ETX\SOH\DC2\EOT\147\STX\n\ + \\ENQ\EOT&\STX\ETX\SOH\DC2\EOT\176\STX\n\ \\ETB\n\ \\r\n\ - \\ENQ\EOT$\STX\ETX\ETX\DC2\EOT\147\STX\SUB\ESC\n\ + \\ENQ\EOT&\STX\ETX\ETX\DC2\EOT\176\STX\SUB\ESC\n\ \%\n\ - \\EOT\EOT$\STX\EOT\DC2\EOT\148\STX\EOT\RS\"\ETB Array of Plutus data.\n\ + \\EOT\EOT&\STX\EOT\DC2\EOT\177\STX\EOT\RS\"\ETB Array of Plutus data.\n\ \\n\ \\r\n\ - \\ENQ\EOT$\STX\EOT\ACK\DC2\EOT\148\STX\EOT\DC3\n\ + \\ENQ\EOT&\STX\EOT\ACK\DC2\EOT\177\STX\EOT\DC3\n\ \\r\n\ - \\ENQ\EOT$\STX\EOT\SOH\DC2\EOT\148\STX\DC4\EM\n\ + \\ENQ\EOT&\STX\EOT\SOH\DC2\EOT\177\STX\DC4\EM\n\ \\r\n\ - \\ENQ\EOT$\STX\EOT\ETX\DC2\EOT\148\STX\FS\GS\n\ + \\ENQ\EOT&\STX\EOT\ETX\DC2\EOT\177\STX\FS\GS\n\ \;\n\ - \\STX\EOT%\DC2\ACK\153\STX\NUL\155\STX\SOH\SUB- Represents a map of Plutus data in Cardano.\n\ + \\STX\EOT'\DC2\ACK\182\STX\NUL\184\STX\SOH\SUB- Represents a map of Plutus data in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT%\SOH\DC2\EOT\153\STX\b\NAK\n\ + \\ETX\EOT'\SOH\DC2\EOT\182\STX\b\NAK\n\ \(\n\ - \\EOT\EOT%\STX\NUL\DC2\EOT\154\STX\STX$\"\SUB List of key-value pairs.\n\ + \\EOT\EOT'\STX\NUL\DC2\EOT\183\STX\STX$\"\SUB List of key-value pairs.\n\ \\n\ \\r\n\ - \\ENQ\EOT%\STX\NUL\EOT\DC2\EOT\154\STX\STX\n\ + \\ENQ\EOT'\STX\NUL\EOT\DC2\EOT\183\STX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT%\STX\NUL\ACK\DC2\EOT\154\STX\v\EM\n\ + \\ENQ\EOT'\STX\NUL\ACK\DC2\EOT\183\STX\v\EM\n\ \\r\n\ - \\ENQ\EOT%\STX\NUL\SOH\DC2\EOT\154\STX\SUB\US\n\ + \\ENQ\EOT'\STX\NUL\SOH\DC2\EOT\183\STX\SUB\US\n\ \\r\n\ - \\ENQ\EOT%\STX\NUL\ETX\DC2\EOT\154\STX\"#\n\ + \\ENQ\EOT'\STX\NUL\ETX\DC2\EOT\183\STX\"#\n\ \>\n\ - \\STX\EOT&\DC2\ACK\158\STX\NUL\160\STX\SOH\SUB0 Represents an array of Plutus data in Cardano.\n\ + \\STX\EOT(\DC2\ACK\187\STX\NUL\189\STX\SOH\SUB0 Represents an array of Plutus data in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT&\SOH\DC2\EOT\158\STX\b\ETB\n\ + \\ETX\EOT(\SOH\DC2\EOT\187\STX\b\ETB\n\ \*\n\ - \\EOT\EOT&\STX\NUL\DC2\EOT\159\STX\STX \"\FS List of Plutus data items.\n\ + \\EOT\EOT(\STX\NUL\DC2\EOT\188\STX\STX \"\FS List of Plutus data items.\n\ \\n\ \\r\n\ - \\ENQ\EOT&\STX\NUL\EOT\DC2\EOT\159\STX\STX\n\ + \\ENQ\EOT(\STX\NUL\EOT\DC2\EOT\188\STX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT&\STX\NUL\ACK\DC2\EOT\159\STX\v\NAK\n\ + \\ENQ\EOT(\STX\NUL\ACK\DC2\EOT\188\STX\v\NAK\n\ \\r\n\ - \\ENQ\EOT&\STX\NUL\SOH\DC2\EOT\159\STX\SYN\ESC\n\ + \\ENQ\EOT(\STX\NUL\SOH\DC2\EOT\188\STX\SYN\ESC\n\ \\r\n\ - \\ENQ\EOT&\STX\NUL\ETX\DC2\EOT\159\STX\RS\US\n\ + \\ENQ\EOT(\STX\NUL\ETX\DC2\EOT\188\STX\RS\US\n\ \/\n\ - \\STX\EOT'\DC2\ACK\163\STX\NUL\171\STX\SOH\SUB! Represents a script in Cardano.\n\ + \\STX\EOT)\DC2\ACK\192\STX\NUL\200\STX\SOH\SUB! Represents a script in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT'\SOH\DC2\EOT\163\STX\b\SO\n\ + \\ETX\EOT)\SOH\DC2\EOT\192\STX\b\SO\n\ \\SO\n\ - \\EOT\EOT'\b\NUL\DC2\ACK\164\STX\STX\170\STX\ETX\n\ + \\EOT\EOT)\b\NUL\DC2\ACK\193\STX\STX\199\STX\ETX\n\ \\r\n\ - \\ENQ\EOT'\b\NUL\SOH\DC2\EOT\164\STX\b\SO\n\ + \\ENQ\EOT)\b\NUL\SOH\DC2\EOT\193\STX\b\SO\n\ \\RS\n\ - \\EOT\EOT'\STX\NUL\DC2\EOT\165\STX\EOT\FS\"\DLE Native script.\n\ + \\EOT\EOT)\STX\NUL\DC2\EOT\194\STX\EOT\FS\"\DLE Native script.\n\ \\n\ \\r\n\ - \\ENQ\EOT'\STX\NUL\ACK\DC2\EOT\165\STX\EOT\DLE\n\ + \\ENQ\EOT)\STX\NUL\ACK\DC2\EOT\194\STX\EOT\DLE\n\ \\r\n\ - \\ENQ\EOT'\STX\NUL\SOH\DC2\EOT\165\STX\DC1\ETB\n\ + \\ENQ\EOT)\STX\NUL\SOH\DC2\EOT\194\STX\DC1\ETB\n\ \\r\n\ - \\ENQ\EOT'\STX\NUL\ETX\DC2\EOT\165\STX\SUB\ESC\n\ + \\ENQ\EOT)\STX\NUL\ETX\DC2\EOT\194\STX\SUB\ESC\n\ \!\n\ - \\EOT\EOT'\STX\SOH\DC2\EOT\166\STX\EOT\CAN\"\DC3 Plutus V1 script.\n\ + \\EOT\EOT)\STX\SOH\DC2\EOT\195\STX\EOT\CAN\"\DC3 Plutus V1 script.\n\ \\n\ \\r\n\ - \\ENQ\EOT'\STX\SOH\ENQ\DC2\EOT\166\STX\EOT\t\n\ + \\ENQ\EOT)\STX\SOH\ENQ\DC2\EOT\195\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT'\STX\SOH\SOH\DC2\EOT\166\STX\n\ + \\ENQ\EOT)\STX\SOH\SOH\DC2\EOT\195\STX\n\ \\DC3\n\ \\r\n\ - \\ENQ\EOT'\STX\SOH\ETX\DC2\EOT\166\STX\SYN\ETB\n\ + \\ENQ\EOT)\STX\SOH\ETX\DC2\EOT\195\STX\SYN\ETB\n\ \!\n\ - \\EOT\EOT'\STX\STX\DC2\EOT\167\STX\EOT\CAN\"\DC3 Plutus V2 script.\n\ + \\EOT\EOT)\STX\STX\DC2\EOT\196\STX\EOT\CAN\"\DC3 Plutus V2 script.\n\ \\n\ \\r\n\ - \\ENQ\EOT'\STX\STX\ENQ\DC2\EOT\167\STX\EOT\t\n\ + \\ENQ\EOT)\STX\STX\ENQ\DC2\EOT\196\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT'\STX\STX\SOH\DC2\EOT\167\STX\n\ + \\ENQ\EOT)\STX\STX\SOH\DC2\EOT\196\STX\n\ \\DC3\n\ \\r\n\ - \\ENQ\EOT'\STX\STX\ETX\DC2\EOT\167\STX\SYN\ETB\n\ + \\ENQ\EOT)\STX\STX\ETX\DC2\EOT\196\STX\SYN\ETB\n\ \!\n\ - \\EOT\EOT'\STX\ETX\DC2\EOT\168\STX\EOT\CAN\"\DC3 Plutus V3 script.\n\ + \\EOT\EOT)\STX\ETX\DC2\EOT\197\STX\EOT\CAN\"\DC3 Plutus V3 script.\n\ \\n\ \\r\n\ - \\ENQ\EOT'\STX\ETX\ENQ\DC2\EOT\168\STX\EOT\t\n\ + \\ENQ\EOT)\STX\ETX\ENQ\DC2\EOT\197\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT'\STX\ETX\SOH\DC2\EOT\168\STX\n\ + \\ENQ\EOT)\STX\ETX\SOH\DC2\EOT\197\STX\n\ \\DC3\n\ \\r\n\ - \\ENQ\EOT'\STX\ETX\ETX\DC2\EOT\168\STX\SYN\ETB\n\ + \\ENQ\EOT)\STX\ETX\ETX\DC2\EOT\197\STX\SYN\ETB\n\ \!\n\ - \\EOT\EOT'\STX\EOT\DC2\EOT\169\STX\EOT\CAN\"\DC3 Plutus V4 script.\n\ + \\EOT\EOT)\STX\EOT\DC2\EOT\198\STX\EOT\CAN\"\DC3 Plutus V4 script.\n\ \\n\ \\r\n\ - \\ENQ\EOT'\STX\EOT\ENQ\DC2\EOT\169\STX\EOT\t\n\ + \\ENQ\EOT)\STX\EOT\ENQ\DC2\EOT\198\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT'\STX\EOT\SOH\DC2\EOT\169\STX\n\ + \\ENQ\EOT)\STX\EOT\SOH\DC2\EOT\198\STX\n\ \\DC3\n\ \\r\n\ - \\ENQ\EOT'\STX\EOT\ETX\DC2\EOT\169\STX\SYN\ETB\n\ + \\ENQ\EOT)\STX\EOT\ETX\DC2\EOT\198\STX\SYN\ETB\n\ \\f\n\ - \\STX\EOT(\DC2\ACK\173\STX\NUL\181\STX\SOH\n\ + \\STX\EOT*\DC2\ACK\202\STX\NUL\210\STX\SOH\n\ \\v\n\ - \\ETX\EOT(\SOH\DC2\EOT\173\STX\b\DC1\n\ + \\ETX\EOT*\SOH\DC2\EOT\202\STX\b\DC1\n\ \\SO\n\ - \\EOT\EOT(\b\NUL\DC2\ACK\174\STX\STX\180\STX\ETX\n\ + \\EOT\EOT*\b\NUL\DC2\ACK\203\STX\STX\209\STX\ETX\n\ \\r\n\ - \\ENQ\EOT(\b\NUL\SOH\DC2\EOT\174\STX\b\DC1\n\ + \\ENQ\EOT*\b\NUL\SOH\DC2\EOT\203\STX\b\DC1\n\ \\f\n\ - \\EOT\EOT(\STX\NUL\DC2\EOT\175\STX\EOT\DC2\n\ + \\EOT\EOT*\STX\NUL\DC2\EOT\204\STX\EOT\DC2\n\ \\r\n\ - \\ENQ\EOT(\STX\NUL\ENQ\DC2\EOT\175\STX\EOT\t\n\ + \\ENQ\EOT*\STX\NUL\ENQ\DC2\EOT\204\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT(\STX\NUL\SOH\DC2\EOT\175\STX\n\ + \\ENQ\EOT*\STX\NUL\SOH\DC2\EOT\204\STX\n\ \\r\n\ \\r\n\ - \\ENQ\EOT(\STX\NUL\ETX\DC2\EOT\175\STX\DLE\DC1\n\ + \\ENQ\EOT*\STX\NUL\ETX\DC2\EOT\204\STX\DLE\DC1\n\ \\f\n\ - \\EOT\EOT(\STX\SOH\DC2\EOT\176\STX\EOT\DC4\n\ + \\EOT\EOT*\STX\SOH\DC2\EOT\205\STX\EOT\DC4\n\ \\r\n\ - \\ENQ\EOT(\STX\SOH\ENQ\DC2\EOT\176\STX\EOT\t\n\ + \\ENQ\EOT*\STX\SOH\ENQ\DC2\EOT\205\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT(\STX\SOH\SOH\DC2\EOT\176\STX\n\ + \\ENQ\EOT*\STX\SOH\SOH\DC2\EOT\205\STX\n\ \\SI\n\ \\r\n\ - \\ENQ\EOT(\STX\SOH\ETX\DC2\EOT\176\STX\DC2\DC3\n\ + \\ENQ\EOT*\STX\SOH\ETX\DC2\EOT\205\STX\DC2\DC3\n\ \\f\n\ - \\EOT\EOT(\STX\STX\DC2\EOT\177\STX\EOT\DC4\n\ + \\EOT\EOT*\STX\STX\DC2\EOT\206\STX\EOT\DC4\n\ \\r\n\ - \\ENQ\EOT(\STX\STX\ENQ\DC2\EOT\177\STX\EOT\n\ + \\ENQ\EOT*\STX\STX\ENQ\DC2\EOT\206\STX\EOT\n\ \\n\ \\r\n\ - \\ENQ\EOT(\STX\STX\SOH\DC2\EOT\177\STX\v\SI\n\ + \\ENQ\EOT*\STX\STX\SOH\DC2\EOT\206\STX\v\SI\n\ \\r\n\ - \\ENQ\EOT(\STX\STX\ETX\DC2\EOT\177\STX\DC2\DC3\n\ + \\ENQ\EOT*\STX\STX\ETX\DC2\EOT\206\STX\DC2\DC3\n\ \\f\n\ - \\EOT\EOT(\STX\ETX\DC2\EOT\178\STX\EOT\GS\n\ + \\EOT\EOT*\STX\ETX\DC2\EOT\207\STX\EOT\GS\n\ \\r\n\ - \\ENQ\EOT(\STX\ETX\ACK\DC2\EOT\178\STX\EOT\DC2\n\ + \\ENQ\EOT*\STX\ETX\ACK\DC2\EOT\207\STX\EOT\DC2\n\ \\r\n\ - \\ENQ\EOT(\STX\ETX\SOH\DC2\EOT\178\STX\DC3\CAN\n\ + \\ENQ\EOT*\STX\ETX\SOH\DC2\EOT\207\STX\DC3\CAN\n\ \\r\n\ - \\ENQ\EOT(\STX\ETX\ETX\DC2\EOT\178\STX\ESC\FS\n\ + \\ENQ\EOT*\STX\ETX\ETX\DC2\EOT\207\STX\ESC\FS\n\ \\f\n\ - \\EOT\EOT(\STX\EOT\DC2\EOT\179\STX\EOT\EM\n\ + \\EOT\EOT*\STX\EOT\DC2\EOT\208\STX\EOT\EM\n\ \\r\n\ - \\ENQ\EOT(\STX\EOT\ACK\DC2\EOT\179\STX\EOT\DLE\n\ + \\ENQ\EOT*\STX\EOT\ACK\DC2\EOT\208\STX\EOT\DLE\n\ \\r\n\ - \\ENQ\EOT(\STX\EOT\SOH\DC2\EOT\179\STX\DC1\DC4\n\ + \\ENQ\EOT*\STX\EOT\SOH\DC2\EOT\208\STX\DC1\DC4\n\ \\r\n\ - \\ENQ\EOT(\STX\EOT\ETX\DC2\EOT\179\STX\ETB\CAN\n\ + \\ENQ\EOT*\STX\EOT\ETX\DC2\EOT\208\STX\ETB\CAN\n\ \\f\n\ - \\STX\EOT)\DC2\ACK\183\STX\NUL\185\STX\SOH\n\ + \\STX\EOT+\DC2\ACK\212\STX\NUL\214\STX\SOH\n\ \\v\n\ - \\ETX\EOT)\SOH\DC2\EOT\183\STX\b\SYN\n\ + \\ETX\EOT+\SOH\DC2\EOT\212\STX\b\SYN\n\ \\f\n\ - \\EOT\EOT)\STX\NUL\DC2\EOT\184\STX\STX\US\n\ + \\EOT\EOT+\STX\NUL\DC2\EOT\213\STX\STX\US\n\ \\r\n\ - \\ENQ\EOT)\STX\NUL\EOT\DC2\EOT\184\STX\STX\n\ + \\ENQ\EOT+\STX\NUL\EOT\DC2\EOT\213\STX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT)\STX\NUL\ACK\DC2\EOT\184\STX\v\DC4\n\ + \\ENQ\EOT+\STX\NUL\ACK\DC2\EOT\213\STX\v\DC4\n\ \\r\n\ - \\ENQ\EOT)\STX\NUL\SOH\DC2\EOT\184\STX\NAK\SUB\n\ + \\ENQ\EOT+\STX\NUL\SOH\DC2\EOT\213\STX\NAK\SUB\n\ \\r\n\ - \\ENQ\EOT)\STX\NUL\ETX\DC2\EOT\184\STX\GS\RS\n\ + \\ENQ\EOT+\STX\NUL\ETX\DC2\EOT\213\STX\GS\RS\n\ \\f\n\ - \\STX\EOT*\DC2\ACK\187\STX\NUL\189\STX\SOH\n\ + \\STX\EOT,\DC2\ACK\216\STX\NUL\218\STX\SOH\n\ \\v\n\ - \\ETX\EOT*\SOH\DC2\EOT\187\STX\b\DC4\n\ + \\ETX\EOT,\SOH\DC2\EOT\216\STX\b\DC4\n\ \\f\n\ - \\EOT\EOT*\STX\NUL\DC2\EOT\188\STX\STX#\n\ + \\EOT\EOT,\STX\NUL\DC2\EOT\217\STX\STX#\n\ \\r\n\ - \\ENQ\EOT*\STX\NUL\EOT\DC2\EOT\188\STX\STX\n\ + \\ENQ\EOT,\STX\NUL\EOT\DC2\EOT\217\STX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT*\STX\NUL\ACK\DC2\EOT\188\STX\v\CAN\n\ + \\ENQ\EOT,\STX\NUL\ACK\DC2\EOT\217\STX\v\CAN\n\ \\r\n\ - \\ENQ\EOT*\STX\NUL\SOH\DC2\EOT\188\STX\EM\RS\n\ + \\ENQ\EOT,\STX\NUL\SOH\DC2\EOT\217\STX\EM\RS\n\ \\r\n\ - \\ENQ\EOT*\STX\NUL\ETX\DC2\EOT\188\STX!\"\n\ + \\ENQ\EOT,\STX\NUL\ETX\DC2\EOT\217\STX!\"\n\ \\f\n\ - \\STX\EOT+\DC2\ACK\191\STX\NUL\194\STX\SOH\n\ + \\STX\EOT-\DC2\ACK\220\STX\NUL\223\STX\SOH\n\ \\v\n\ - \\ETX\EOT+\SOH\DC2\EOT\191\STX\b\NAK\n\ + \\ETX\EOT-\SOH\DC2\EOT\220\STX\b\NAK\n\ \\f\n\ - \\EOT\EOT+\STX\NUL\DC2\EOT\192\STX\STX\DC4\n\ + \\EOT\EOT-\STX\NUL\DC2\EOT\221\STX\STX\DC4\n\ \\r\n\ - \\ENQ\EOT+\STX\NUL\ACK\DC2\EOT\192\STX\STX\v\n\ + \\ENQ\EOT-\STX\NUL\ACK\DC2\EOT\221\STX\STX\v\n\ \\r\n\ - \\ENQ\EOT+\STX\NUL\SOH\DC2\EOT\192\STX\f\SI\n\ + \\ENQ\EOT-\STX\NUL\SOH\DC2\EOT\221\STX\f\SI\n\ \\r\n\ - \\ENQ\EOT+\STX\NUL\ETX\DC2\EOT\192\STX\DC2\DC3\n\ + \\ENQ\EOT-\STX\NUL\ETX\DC2\EOT\221\STX\DC2\DC3\n\ \\f\n\ - \\EOT\EOT+\STX\SOH\DC2\EOT\193\STX\STX\SYN\n\ + \\EOT\EOT-\STX\SOH\DC2\EOT\222\STX\STX\SYN\n\ \\r\n\ - \\ENQ\EOT+\STX\SOH\ACK\DC2\EOT\193\STX\STX\v\n\ + \\ENQ\EOT-\STX\SOH\ACK\DC2\EOT\222\STX\STX\v\n\ \\r\n\ - \\ENQ\EOT+\STX\SOH\SOH\DC2\EOT\193\STX\f\DC1\n\ + \\ENQ\EOT-\STX\SOH\SOH\DC2\EOT\222\STX\f\DC1\n\ \\r\n\ - \\ENQ\EOT+\STX\SOH\ETX\DC2\EOT\193\STX\DC4\NAK\n\ + \\ENQ\EOT-\STX\SOH\ETX\DC2\EOT\222\STX\DC4\NAK\n\ \\f\n\ - \\STX\EOT,\DC2\ACK\196\STX\NUL\199\STX\SOH\n\ + \\STX\EOT.\DC2\ACK\225\STX\NUL\228\STX\SOH\n\ \\v\n\ - \\ETX\EOT,\SOH\DC2\EOT\196\STX\b\DLE\n\ + \\ETX\EOT.\SOH\DC2\EOT\225\STX\b\DLE\n\ \\f\n\ - \\EOT\EOT,\STX\NUL\DC2\EOT\197\STX\STX\DC3\n\ + \\EOT\EOT.\STX\NUL\DC2\EOT\226\STX\STX\DC3\n\ \\r\n\ - \\ENQ\EOT,\STX\NUL\ENQ\DC2\EOT\197\STX\STX\b\n\ + \\ENQ\EOT.\STX\NUL\ENQ\DC2\EOT\226\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT,\STX\NUL\SOH\DC2\EOT\197\STX\t\SO\n\ + \\ENQ\EOT.\STX\NUL\SOH\DC2\EOT\226\STX\t\SO\n\ \\r\n\ - \\ENQ\EOT,\STX\NUL\ETX\DC2\EOT\197\STX\DC1\DC2\n\ + \\ENQ\EOT.\STX\NUL\ETX\DC2\EOT\226\STX\DC1\DC2\n\ \\f\n\ - \\EOT\EOT,\STX\SOH\DC2\EOT\198\STX\STX\SYN\n\ + \\EOT\EOT.\STX\SOH\DC2\EOT\227\STX\STX\SYN\n\ \\r\n\ - \\ENQ\EOT,\STX\SOH\ACK\DC2\EOT\198\STX\STX\v\n\ + \\ENQ\EOT.\STX\SOH\ACK\DC2\EOT\227\STX\STX\v\n\ \\r\n\ - \\ENQ\EOT,\STX\SOH\SOH\DC2\EOT\198\STX\f\DC1\n\ + \\ENQ\EOT.\STX\SOH\SOH\DC2\EOT\227\STX\f\DC1\n\ \\r\n\ - \\ENQ\EOT,\STX\SOH\ETX\DC2\EOT\198\STX\DC4\NAK\n\ + \\ENQ\EOT.\STX\SOH\ETX\DC2\EOT\227\STX\DC4\NAK\n\ \9\n\ - \\STX\EOT-\DC2\ACK\202\STX\NUL\207\STX\SOH\SUB+ Represents a stake credential in Cardano.\n\ + \\STX\EOT/\DC2\ACK\231\STX\NUL\236\STX\SOH\SUB+ Represents a stake credential in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT-\SOH\DC2\EOT\202\STX\b\ETB\n\ + \\ETX\EOT/\SOH\DC2\EOT\231\STX\b\ETB\n\ \\SO\n\ - \\EOT\EOT-\b\NUL\DC2\ACK\203\STX\STX\206\STX\ETX\n\ + \\EOT\EOT/\b\NUL\DC2\ACK\232\STX\STX\235\STX\ETX\n\ \\r\n\ - \\ENQ\EOT-\b\NUL\SOH\DC2\EOT\203\STX\b\CAN\n\ + \\ENQ\EOT/\b\NUL\SOH\DC2\EOT\232\STX\b\CAN\n\ \!\n\ - \\EOT\EOT-\STX\NUL\DC2\EOT\204\STX\EOT\FS\"\DC3 Address key hash.\n\ + \\EOT\EOT/\STX\NUL\DC2\EOT\233\STX\EOT\FS\"\DC3 Address key hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT-\STX\NUL\ENQ\DC2\EOT\204\STX\EOT\t\n\ + \\ENQ\EOT/\STX\NUL\ENQ\DC2\EOT\233\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT-\STX\NUL\SOH\DC2\EOT\204\STX\n\ + \\ENQ\EOT/\STX\NUL\SOH\DC2\EOT\233\STX\n\ \\ETB\n\ \\r\n\ - \\ENQ\EOT-\STX\NUL\ETX\DC2\EOT\204\STX\SUB\ESC\n\ + \\ENQ\EOT/\STX\NUL\ETX\DC2\EOT\233\STX\SUB\ESC\n\ \\FS\n\ - \\EOT\EOT-\STX\SOH\DC2\EOT\205\STX\EOT\SUB\"\SO Script hash.\n\ + \\EOT\EOT/\STX\SOH\DC2\EOT\234\STX\EOT\SUB\"\SO Script hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT-\STX\SOH\ENQ\DC2\EOT\205\STX\EOT\t\n\ + \\ENQ\EOT/\STX\SOH\ENQ\DC2\EOT\234\STX\EOT\t\n\ \\r\n\ - \\ENQ\EOT-\STX\SOH\SOH\DC2\EOT\205\STX\n\ + \\ENQ\EOT/\STX\SOH\SOH\DC2\EOT\234\STX\n\ \\NAK\n\ \\r\n\ - \\ENQ\EOT-\STX\SOH\ETX\DC2\EOT\205\STX\CAN\EM\n\ + \\ENQ\EOT/\STX\SOH\ETX\DC2\EOT\234\STX\CAN\EM\n\ \;\n\ - \\STX\EOT.\DC2\ACK\210\STX\NUL\213\STX\SOH\SUB- Represents a rational number as a fraction.\n\ + \\STX\EOT0\DC2\ACK\239\STX\NUL\242\STX\SOH\SUB- Represents a rational number as a fraction.\n\ \\n\ \\v\n\ - \\ETX\EOT.\SOH\DC2\EOT\210\STX\b\SYN\n\ + \\ETX\EOT0\SOH\DC2\EOT\239\STX\b\SYN\n\ \\f\n\ - \\EOT\EOT.\STX\NUL\DC2\EOT\211\STX\STX\SYN\n\ + \\EOT\EOT0\STX\NUL\DC2\EOT\240\STX\STX\SYN\n\ \\r\n\ - \\ENQ\EOT.\STX\NUL\ENQ\DC2\EOT\211\STX\STX\a\n\ + \\ENQ\EOT0\STX\NUL\ENQ\DC2\EOT\240\STX\STX\a\n\ \\r\n\ - \\ENQ\EOT.\STX\NUL\SOH\DC2\EOT\211\STX\b\DC1\n\ + \\ENQ\EOT0\STX\NUL\SOH\DC2\EOT\240\STX\b\DC1\n\ \\r\n\ - \\ENQ\EOT.\STX\NUL\ETX\DC2\EOT\211\STX\DC4\NAK\n\ + \\ENQ\EOT0\STX\NUL\ETX\DC2\EOT\240\STX\DC4\NAK\n\ \\f\n\ - \\EOT\EOT.\STX\SOH\DC2\EOT\212\STX\STX\EM\n\ + \\EOT\EOT0\STX\SOH\DC2\EOT\241\STX\STX\EM\n\ \\r\n\ - \\ENQ\EOT.\STX\SOH\ENQ\DC2\EOT\212\STX\STX\b\n\ + \\ENQ\EOT0\STX\SOH\ENQ\DC2\EOT\241\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT.\STX\SOH\SOH\DC2\EOT\212\STX\t\DC4\n\ + \\ENQ\EOT0\STX\SOH\SOH\DC2\EOT\241\STX\t\DC4\n\ \\r\n\ - \\ENQ\EOT.\STX\SOH\ETX\DC2\EOT\212\STX\ETB\CAN\n\ + \\ENQ\EOT0\STX\SOH\ETX\DC2\EOT\241\STX\ETB\CAN\n\ \.\n\ - \\STX\EOT/\DC2\ACK\216\STX\NUL\221\STX\SOH\SUB Represents a relay in Cardano.\n\ + \\STX\EOT1\DC2\ACK\245\STX\NUL\250\STX\SOH\SUB Represents a relay in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT/\SOH\DC2\EOT\216\STX\b\r\n\ + \\ETX\EOT1\SOH\DC2\EOT\245\STX\b\r\n\ \\f\n\ - \\EOT\EOT/\STX\NUL\DC2\EOT\217\STX\STX\DC2\n\ + \\EOT\EOT1\STX\NUL\DC2\EOT\246\STX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT/\STX\NUL\ENQ\DC2\EOT\217\STX\STX\a\n\ + \\ENQ\EOT1\STX\NUL\ENQ\DC2\EOT\246\STX\STX\a\n\ \\r\n\ - \\ENQ\EOT/\STX\NUL\SOH\DC2\EOT\217\STX\b\r\n\ + \\ENQ\EOT1\STX\NUL\SOH\DC2\EOT\246\STX\b\r\n\ \\r\n\ - \\ENQ\EOT/\STX\NUL\ETX\DC2\EOT\217\STX\DLE\DC1\n\ + \\ENQ\EOT1\STX\NUL\ETX\DC2\EOT\246\STX\DLE\DC1\n\ \\f\n\ - \\EOT\EOT/\STX\SOH\DC2\EOT\218\STX\STX\DC2\n\ + \\EOT\EOT1\STX\SOH\DC2\EOT\247\STX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT/\STX\SOH\ENQ\DC2\EOT\218\STX\STX\a\n\ + \\ENQ\EOT1\STX\SOH\ENQ\DC2\EOT\247\STX\STX\a\n\ \\r\n\ - \\ENQ\EOT/\STX\SOH\SOH\DC2\EOT\218\STX\b\r\n\ + \\ENQ\EOT1\STX\SOH\SOH\DC2\EOT\247\STX\b\r\n\ \\r\n\ - \\ENQ\EOT/\STX\SOH\ETX\DC2\EOT\218\STX\DLE\DC1\n\ + \\ENQ\EOT1\STX\SOH\ETX\DC2\EOT\247\STX\DLE\DC1\n\ \\f\n\ - \\EOT\EOT/\STX\STX\DC2\EOT\219\STX\STX\SYN\n\ + \\EOT\EOT1\STX\STX\DC2\EOT\248\STX\STX\SYN\n\ \\r\n\ - \\ENQ\EOT/\STX\STX\ENQ\DC2\EOT\219\STX\STX\b\n\ + \\ENQ\EOT1\STX\STX\ENQ\DC2\EOT\248\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT/\STX\STX\SOH\DC2\EOT\219\STX\t\DC1\n\ + \\ENQ\EOT1\STX\STX\SOH\DC2\EOT\248\STX\t\DC1\n\ \\r\n\ - \\ENQ\EOT/\STX\STX\ETX\DC2\EOT\219\STX\DC4\NAK\n\ + \\ENQ\EOT1\STX\STX\ETX\DC2\EOT\248\STX\DC4\NAK\n\ \\f\n\ - \\EOT\EOT/\STX\ETX\DC2\EOT\220\STX\STX\DC2\n\ + \\EOT\EOT1\STX\ETX\DC2\EOT\249\STX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT/\STX\ETX\ENQ\DC2\EOT\220\STX\STX\b\n\ + \\ENQ\EOT1\STX\ETX\ENQ\DC2\EOT\249\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT/\STX\ETX\SOH\DC2\EOT\220\STX\t\r\n\ + \\ENQ\EOT1\STX\ETX\SOH\DC2\EOT\249\STX\t\r\n\ \\r\n\ - \\ENQ\EOT/\STX\ETX\ETX\DC2\EOT\220\STX\DLE\DC1\n\ + \\ENQ\EOT1\STX\ETX\ETX\DC2\EOT\249\STX\DLE\DC1\n\ \4\n\ - \\STX\EOT0\DC2\ACK\224\STX\NUL\227\STX\SOH\SUB& Represents pool metadata in Cardano.\n\ + \\STX\EOT2\DC2\ACK\253\STX\NUL\128\ETX\SOH\SUB& Represents pool metadata in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT0\SOH\DC2\EOT\224\STX\b\DC4\n\ + \\ETX\EOT2\SOH\DC2\EOT\253\STX\b\DC4\n\ \\f\n\ - \\EOT\EOT0\STX\NUL\DC2\EOT\225\STX\STX\DC1\n\ + \\EOT\EOT2\STX\NUL\DC2\EOT\254\STX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT0\STX\NUL\ENQ\DC2\EOT\225\STX\STX\b\n\ + \\ENQ\EOT2\STX\NUL\ENQ\DC2\EOT\254\STX\STX\b\n\ \\r\n\ - \\ENQ\EOT0\STX\NUL\SOH\DC2\EOT\225\STX\t\f\n\ + \\ENQ\EOT2\STX\NUL\SOH\DC2\EOT\254\STX\t\f\n\ \\r\n\ - \\ENQ\EOT0\STX\NUL\ETX\DC2\EOT\225\STX\SI\DLE\n\ + \\ENQ\EOT2\STX\NUL\ETX\DC2\EOT\254\STX\SI\DLE\n\ \\f\n\ - \\EOT\EOT0\STX\SOH\DC2\EOT\226\STX\STX\DC1\n\ + \\EOT\EOT2\STX\SOH\DC2\EOT\255\STX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT0\STX\SOH\ENQ\DC2\EOT\226\STX\STX\a\n\ + \\ENQ\EOT2\STX\SOH\ENQ\DC2\EOT\255\STX\STX\a\n\ \\r\n\ - \\ENQ\EOT0\STX\SOH\SOH\DC2\EOT\226\STX\b\f\n\ + \\ENQ\EOT2\STX\SOH\SOH\DC2\EOT\255\STX\b\f\n\ \\r\n\ - \\ENQ\EOT0\STX\SOH\ETX\DC2\EOT\226\STX\SI\DLE\n\ + \\ENQ\EOT2\STX\SOH\ETX\DC2\EOT\255\STX\SI\DLE\n\ \4\n\ - \\STX\EOT1\DC2\ACK\230\STX\NUL\253\STX\SOH\SUB& Represents a certificate in Cardano.\n\ + \\STX\EOT3\DC2\ACK\131\ETX\NUL\154\ETX\SOH\SUB& Represents a certificate in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT1\SOH\DC2\EOT\230\STX\b\DC3\n\ + \\ETX\EOT3\SOH\DC2\EOT\131\ETX\b\DC3\n\ \\SO\n\ - \\EOT\EOT1\b\NUL\DC2\ACK\231\STX\STX\251\STX\ETX\n\ + \\EOT\EOT3\b\NUL\DC2\ACK\132\ETX\STX\152\ETX\ETX\n\ \\r\n\ - \\ENQ\EOT1\b\NUL\SOH\DC2\EOT\231\STX\b\DC3\n\ + \\ENQ\EOT3\b\NUL\SOH\DC2\EOT\132\ETX\b\DC3\n\ \/\n\ - \\EOT\EOT1\STX\NUL\DC2\EOT\232\STX\EOT+\"! Stake registration certificate.\n\ + \\EOT\EOT3\STX\NUL\DC2\EOT\133\ETX\EOT+\"! Stake registration certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\NUL\ACK\DC2\EOT\232\STX\EOT\DC3\n\ + \\ENQ\EOT3\STX\NUL\ACK\DC2\EOT\133\ETX\EOT\DC3\n\ \\r\n\ - \\ENQ\EOT1\STX\NUL\SOH\DC2\EOT\232\STX\DC4&\n\ + \\ENQ\EOT3\STX\NUL\SOH\DC2\EOT\133\ETX\DC4&\n\ \\r\n\ - \\ENQ\EOT1\STX\NUL\ETX\DC2\EOT\232\STX)*\n\ + \\ENQ\EOT3\STX\NUL\ETX\DC2\EOT\133\ETX)*\n\ \1\n\ - \\EOT\EOT1\STX\SOH\DC2\EOT\233\STX\EOT-\"# Stake deregistration certificate.\n\ + \\EOT\EOT3\STX\SOH\DC2\EOT\134\ETX\EOT-\"# Stake deregistration certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\SOH\ACK\DC2\EOT\233\STX\EOT\DC3\n\ + \\ENQ\EOT3\STX\SOH\ACK\DC2\EOT\134\ETX\EOT\DC3\n\ \\r\n\ - \\ENQ\EOT1\STX\SOH\SOH\DC2\EOT\233\STX\DC4(\n\ + \\ENQ\EOT3\STX\SOH\SOH\DC2\EOT\134\ETX\DC4(\n\ \\r\n\ - \\ENQ\EOT1\STX\SOH\ETX\DC2\EOT\233\STX+,\n\ + \\ENQ\EOT3\STX\SOH\ETX\DC2\EOT\134\ETX+,\n\ \-\n\ - \\EOT\EOT1\STX\STX\DC2\EOT\234\STX\EOT-\"\US Stake delegation certificate.\n\ + \\EOT\EOT3\STX\STX\DC2\EOT\135\ETX\EOT-\"\US Stake delegation certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\STX\ACK\DC2\EOT\234\STX\EOT\ETB\n\ + \\ENQ\EOT3\STX\STX\ACK\DC2\EOT\135\ETX\EOT\ETB\n\ \\r\n\ - \\ENQ\EOT1\STX\STX\SOH\DC2\EOT\234\STX\CAN(\n\ + \\ENQ\EOT3\STX\STX\SOH\DC2\EOT\135\ETX\CAN(\n\ \\r\n\ - \\ENQ\EOT1\STX\STX\ETX\DC2\EOT\234\STX+,\n\ + \\ENQ\EOT3\STX\STX\ETX\DC2\EOT\135\ETX+,\n\ \.\n\ - \\EOT\EOT1\STX\ETX\DC2\EOT\235\STX\EOT/\" Pool registration certificate.\n\ + \\EOT\EOT3\STX\ETX\DC2\EOT\136\ETX\EOT/\" Pool registration certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\ETX\ACK\DC2\EOT\235\STX\EOT\CAN\n\ + \\ENQ\EOT3\STX\ETX\ACK\DC2\EOT\136\ETX\EOT\CAN\n\ \\r\n\ - \\ENQ\EOT1\STX\ETX\SOH\DC2\EOT\235\STX\EM*\n\ + \\ENQ\EOT3\STX\ETX\SOH\DC2\EOT\136\ETX\EM*\n\ \\r\n\ - \\ENQ\EOT1\STX\ETX\ETX\DC2\EOT\235\STX-.\n\ + \\ENQ\EOT3\STX\ETX\ETX\DC2\EOT\136\ETX-.\n\ \,\n\ - \\EOT\EOT1\STX\EOT\DC2\EOT\236\STX\EOT+\"\RS Pool retirement certificate.\n\ + \\EOT\EOT3\STX\EOT\DC2\EOT\137\ETX\EOT+\"\RS Pool retirement certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\EOT\ACK\DC2\EOT\236\STX\EOT\SYN\n\ + \\ENQ\EOT3\STX\EOT\ACK\DC2\EOT\137\ETX\EOT\SYN\n\ \\r\n\ - \\ENQ\EOT1\STX\EOT\SOH\DC2\EOT\236\STX\ETB&\n\ + \\ENQ\EOT3\STX\EOT\SOH\DC2\EOT\137\ETX\ETB&\n\ \\r\n\ - \\ENQ\EOT1\STX\EOT\ETX\DC2\EOT\236\STX)*\n\ + \\ENQ\EOT3\STX\EOT\ETX\DC2\EOT\137\ETX)*\n\ \3\n\ - \\EOT\EOT1\STX\ENQ\DC2\EOT\237\STX\EOT8\"% Genesis key delegation certificate.\n\ + \\EOT\EOT3\STX\ENQ\DC2\EOT\138\ETX\EOT8\"% Genesis key delegation certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\ENQ\ACK\DC2\EOT\237\STX\EOT\FS\n\ + \\ENQ\EOT3\STX\ENQ\ACK\DC2\EOT\138\ETX\EOT\FS\n\ \\r\n\ - \\ENQ\EOT1\STX\ENQ\SOH\DC2\EOT\237\STX\GS3\n\ + \\ENQ\EOT3\STX\ENQ\SOH\DC2\EOT\138\ETX\GS3\n\ \\r\n\ - \\ENQ\EOT1\STX\ENQ\ETX\DC2\EOT\237\STX67\n\ + \\ENQ\EOT3\STX\ENQ\ETX\DC2\EOT\138\ETX67\n\ \7\n\ - \\EOT\EOT1\STX\ACK\DC2\EOT\238\STX\EOT\EM\") Move instantaneous rewards certificate.\n\ + \\EOT\EOT3\STX\ACK\DC2\EOT\139\ETX\EOT\EM\") Move instantaneous rewards certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\ACK\ACK\DC2\EOT\238\STX\EOT\v\n\ + \\ENQ\EOT3\STX\ACK\ACK\DC2\EOT\139\ETX\EOT\v\n\ \\r\n\ - \\ENQ\EOT1\STX\ACK\SOH\DC2\EOT\238\STX\f\DC4\n\ + \\ENQ\EOT3\STX\ACK\SOH\DC2\EOT\139\ETX\f\DC4\n\ \\r\n\ - \\ENQ\EOT1\STX\ACK\ETX\DC2\EOT\238\STX\ETB\CAN\n\ + \\ENQ\EOT3\STX\ACK\ETX\DC2\EOT\139\ETX\ETB\CAN\n\ \)\n\ - \\EOT\EOT1\STX\a\DC2\EOT\239\STX\EOT\EM\"\ESC Registration certificate.\n\ + \\EOT\EOT3\STX\a\DC2\EOT\140\ETX\EOT\EM\"\ESC Registration certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\a\ACK\DC2\EOT\239\STX\EOT\v\n\ + \\ENQ\EOT3\STX\a\ACK\DC2\EOT\140\ETX\EOT\v\n\ \\r\n\ - \\ENQ\EOT1\STX\a\SOH\DC2\EOT\239\STX\f\DC4\n\ + \\ENQ\EOT3\STX\a\SOH\DC2\EOT\140\ETX\f\DC4\n\ \\r\n\ - \\ENQ\EOT1\STX\a\ETX\DC2\EOT\239\STX\ETB\CAN\n\ + \\ENQ\EOT3\STX\a\ETX\DC2\EOT\140\ETX\ETB\CAN\n\ \+\n\ - \\EOT\EOT1\STX\b\DC2\EOT\240\STX\EOT\GS\"\GS Unregistration certificate.\n\ + \\EOT\EOT3\STX\b\DC2\EOT\141\ETX\EOT\GS\"\GS Unregistration certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\b\ACK\DC2\EOT\240\STX\EOT\r\n\ + \\ENQ\EOT3\STX\b\ACK\DC2\EOT\141\ETX\EOT\r\n\ \\r\n\ - \\ENQ\EOT1\STX\b\SOH\DC2\EOT\240\STX\SO\CAN\n\ + \\ENQ\EOT3\STX\b\SOH\DC2\EOT\141\ETX\SO\CAN\n\ \\r\n\ - \\ENQ\EOT1\STX\b\ETX\DC2\EOT\240\STX\ESC\FS\n\ + \\ENQ\EOT3\STX\b\ETX\DC2\EOT\141\ETX\ESC\FS\n\ \,\n\ - \\EOT\EOT1\STX\t\DC2\EOT\241\STX\EOT'\"\RS Vote delegation certificate.\n\ + \\EOT\EOT3\STX\t\DC2\EOT\142\ETX\EOT'\"\RS Vote delegation certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\t\ACK\DC2\EOT\241\STX\EOT\DC1\n\ + \\ENQ\EOT3\STX\t\ACK\DC2\EOT\142\ETX\EOT\DC1\n\ \\r\n\ - \\ENQ\EOT1\STX\t\SOH\DC2\EOT\241\STX\DC2!\n\ + \\ENQ\EOT3\STX\t\SOH\DC2\EOT\142\ETX\DC2!\n\ \\r\n\ - \\ENQ\EOT1\STX\t\ETX\DC2\EOT\241\STX$&\n\ + \\ENQ\EOT3\STX\t\ETX\DC2\EOT\142\ETX$&\n\ \6\n\ - \\EOT\EOT1\STX\n\ - \\DC2\EOT\242\STX\EOT2\"( Stake and vote delegation certificate.\n\ + \\EOT\EOT3\STX\n\ + \\DC2\EOT\143\ETX\EOT2\"( Stake and vote delegation certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\n\ - \\ACK\DC2\EOT\242\STX\EOT\SYN\n\ + \\ENQ\EOT3\STX\n\ + \\ACK\DC2\EOT\143\ETX\EOT\SYN\n\ \\r\n\ - \\ENQ\EOT1\STX\n\ - \\SOH\DC2\EOT\242\STX\ETB,\n\ + \\ENQ\EOT3\STX\n\ + \\SOH\DC2\EOT\143\ETX\ETB,\n\ \\r\n\ - \\ENQ\EOT1\STX\n\ - \\ETX\DC2\EOT\242\STX/1\n\ + \\ENQ\EOT3\STX\n\ + \\ETX\DC2\EOT\143\ETX/1\n\ \>\n\ - \\EOT\EOT1\STX\v\DC2\EOT\243\STX\EOT0\"0 Stake registration and delegation certificate.\n\ + \\EOT\EOT3\STX\v\DC2\EOT\144\ETX\EOT0\"0 Stake registration and delegation certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\v\ACK\DC2\EOT\243\STX\EOT\NAK\n\ + \\ENQ\EOT3\STX\v\ACK\DC2\EOT\144\ETX\EOT\NAK\n\ \\r\n\ - \\ENQ\EOT1\STX\v\SOH\DC2\EOT\243\STX\SYN*\n\ + \\ENQ\EOT3\STX\v\SOH\DC2\EOT\144\ETX\SYN*\n\ \\r\n\ - \\ENQ\EOT1\STX\v\ETX\DC2\EOT\243\STX-/\n\ + \\ENQ\EOT3\STX\v\ETX\DC2\EOT\144\ETX-/\n\ \=\n\ - \\EOT\EOT1\STX\f\DC2\EOT\244\STX\EOT.\"/ Vote registration and delegation certificate.\n\ + \\EOT\EOT3\STX\f\DC2\EOT\145\ETX\EOT.\"/ Vote registration and delegation certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\f\ACK\DC2\EOT\244\STX\EOT\DC4\n\ + \\ENQ\EOT3\STX\f\ACK\DC2\EOT\145\ETX\EOT\DC4\n\ \\r\n\ - \\ENQ\EOT1\STX\f\SOH\DC2\EOT\244\STX\NAK(\n\ + \\ENQ\EOT3\STX\f\SOH\DC2\EOT\145\ETX\NAK(\n\ \\r\n\ - \\ENQ\EOT1\STX\f\ETX\DC2\EOT\244\STX+-\n\ + \\ENQ\EOT3\STX\f\ETX\DC2\EOT\145\ETX+-\n\ \G\n\ - \\EOT\EOT1\STX\r\DC2\EOT\245\STX\EOT9\"9 Stake and vote registration and delegation certificate.\n\ + \\EOT\EOT3\STX\r\DC2\EOT\146\ETX\EOT9\"9 Stake and vote registration and delegation certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\r\ACK\DC2\EOT\245\STX\EOT\EM\n\ + \\ENQ\EOT3\STX\r\ACK\DC2\EOT\146\ETX\EOT\EM\n\ \\r\n\ - \\ENQ\EOT1\STX\r\SOH\DC2\EOT\245\STX\SUB3\n\ + \\ENQ\EOT3\STX\r\SOH\DC2\EOT\146\ETX\SUB3\n\ \\r\n\ - \\ENQ\EOT1\STX\r\ETX\DC2\EOT\245\STX68\n\ + \\ENQ\EOT3\STX\r\ETX\DC2\EOT\146\ETX68\n\ \8\n\ - \\EOT\EOT1\STX\SO\DC2\EOT\246\STX\EOT6\"* Authorize committee hot key certificate.\n\ + \\EOT\EOT3\STX\SO\DC2\EOT\147\ETX\EOT6\"* Authorize committee hot key certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\SO\ACK\DC2\EOT\246\STX\EOT\CAN\n\ + \\ENQ\EOT3\STX\SO\ACK\DC2\EOT\147\ETX\EOT\CAN\n\ \\r\n\ - \\ENQ\EOT1\STX\SO\SOH\DC2\EOT\246\STX\EM0\n\ + \\ENQ\EOT3\STX\SO\SOH\DC2\EOT\147\ETX\EM0\n\ \\r\n\ - \\ENQ\EOT1\STX\SO\ETX\DC2\EOT\246\STX35\n\ + \\ENQ\EOT3\STX\SO\ETX\DC2\EOT\147\ETX35\n\ \6\n\ - \\EOT\EOT1\STX\SI\DC2\EOT\247\STX\EOT<\"( Resign committee cold key certificate.\n\ + \\EOT\EOT3\STX\SI\DC2\EOT\148\ETX\EOT<\"( Resign committee cold key certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\SI\ACK\DC2\EOT\247\STX\EOT\ESC\n\ + \\ENQ\EOT3\STX\SI\ACK\DC2\EOT\148\ETX\EOT\ESC\n\ \\r\n\ - \\ENQ\EOT1\STX\SI\SOH\DC2\EOT\247\STX\FS6\n\ + \\ENQ\EOT3\STX\SI\SOH\DC2\EOT\148\ETX\FS6\n\ \\r\n\ - \\ENQ\EOT1\STX\SI\ETX\DC2\EOT\247\STX9;\n\ + \\ENQ\EOT3\STX\SI\ETX\DC2\EOT\148\ETX9;\n\ \*\n\ - \\EOT\EOT1\STX\DLE\DC2\EOT\248\STX\EOT#\"\FS Register DRep certificate.\n\ + \\EOT\EOT3\STX\DLE\DC2\EOT\149\ETX\EOT#\"\FS Register DRep certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\DLE\ACK\DC2\EOT\248\STX\EOT\SI\n\ + \\ENQ\EOT3\STX\DLE\ACK\DC2\EOT\149\ETX\EOT\SI\n\ \\r\n\ - \\ENQ\EOT1\STX\DLE\SOH\DC2\EOT\248\STX\DLE\GS\n\ + \\ENQ\EOT3\STX\DLE\SOH\DC2\EOT\149\ETX\DLE\GS\n\ \\r\n\ - \\ENQ\EOT1\STX\DLE\ETX\DC2\EOT\248\STX \"\n\ + \\ENQ\EOT3\STX\DLE\ETX\DC2\EOT\149\ETX \"\n\ \,\n\ - \\EOT\EOT1\STX\DC1\DC2\EOT\249\STX\EOT'\"\RS Unregister DRep certificate.\n\ + \\EOT\EOT3\STX\DC1\DC2\EOT\150\ETX\EOT'\"\RS Unregister DRep certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\DC1\ACK\DC2\EOT\249\STX\EOT\DC1\n\ + \\ENQ\EOT3\STX\DC1\ACK\DC2\EOT\150\ETX\EOT\DC1\n\ \\r\n\ - \\ENQ\EOT1\STX\DC1\SOH\DC2\EOT\249\STX\DC2!\n\ + \\ENQ\EOT3\STX\DC1\SOH\DC2\EOT\150\ETX\DC2!\n\ \\r\n\ - \\ENQ\EOT1\STX\DC1\ETX\DC2\EOT\249\STX$&\n\ + \\ENQ\EOT3\STX\DC1\ETX\DC2\EOT\150\ETX$&\n\ \(\n\ - \\EOT\EOT1\STX\DC2\DC2\EOT\250\STX\EOT)\"\SUB Update DRep certificate.\n\ + \\EOT\EOT3\STX\DC2\DC2\EOT\151\ETX\EOT)\"\SUB Update DRep certificate.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\DC2\ACK\DC2\EOT\250\STX\EOT\DC2\n\ + \\ENQ\EOT3\STX\DC2\ACK\DC2\EOT\151\ETX\EOT\DC2\n\ \\r\n\ - \\ENQ\EOT1\STX\DC2\SOH\DC2\EOT\250\STX\DC3#\n\ + \\ENQ\EOT3\STX\DC2\SOH\DC2\EOT\151\ETX\DC3#\n\ \\r\n\ - \\ENQ\EOT1\STX\DC2\ETX\DC2\EOT\250\STX&(\n\ + \\ENQ\EOT3\STX\DC2\ETX\DC2\EOT\151\ETX&(\n\ \/\n\ - \\EOT\EOT1\STX\DC3\DC2\EOT\252\STX\STX\SUB\"! Redeemer for the Plutus script.\n\ + \\EOT\EOT3\STX\DC3\DC2\EOT\153\ETX\STX\SUB\"! Redeemer for the Plutus script.\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\DC3\ACK\DC2\EOT\252\STX\STX\n\ + \\ENQ\EOT3\STX\DC3\ACK\DC2\EOT\153\ETX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT1\STX\DC3\SOH\DC2\EOT\252\STX\v\DC3\n\ + \\ENQ\EOT3\STX\DC3\SOH\DC2\EOT\153\ETX\v\DC3\n\ \\r\n\ - \\ENQ\EOT1\STX\DC3\ETX\DC2\EOT\252\STX\SYN\EM\n\ + \\ENQ\EOT3\STX\DC3\ETX\DC2\EOT\153\ETX\SYN\EM\n\ \E\n\ - \\STX\EOT2\DC2\ACK\128\ETX\NUL\131\ETX\SOH\SUB7 Represents a stake delegation certificate in Cardano.\n\ + \\STX\EOT4\DC2\ACK\157\ETX\NUL\160\ETX\SOH\SUB7 Represents a stake delegation certificate in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT2\SOH\DC2\EOT\128\ETX\b\ESC\n\ + \\ETX\EOT4\SOH\DC2\EOT\157\ETX\b\ESC\n\ \!\n\ - \\EOT\EOT2\STX\NUL\DC2\EOT\129\ETX\STX'\"\DC3 Stake credential.\n\ + \\EOT\EOT4\STX\NUL\DC2\EOT\158\ETX\STX'\"\DC3 Stake credential.\n\ \\n\ \\r\n\ - \\ENQ\EOT2\STX\NUL\ACK\DC2\EOT\129\ETX\STX\DC1\n\ + \\ENQ\EOT4\STX\NUL\ACK\DC2\EOT\158\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT2\STX\NUL\SOH\DC2\EOT\129\ETX\DC2\"\n\ + \\ENQ\EOT4\STX\NUL\SOH\DC2\EOT\158\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT2\STX\NUL\ETX\DC2\EOT\129\ETX%&\n\ + \\ENQ\EOT4\STX\NUL\ETX\DC2\EOT\158\ETX%&\n\ \\RS\n\ - \\EOT\EOT2\STX\SOH\DC2\EOT\130\ETX\STX\EM\"\DLE Pool key hash.\n\ + \\EOT\EOT4\STX\SOH\DC2\EOT\159\ETX\STX\EM\"\DLE Pool key hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT2\STX\SOH\ENQ\DC2\EOT\130\ETX\STX\a\n\ + \\ENQ\EOT4\STX\SOH\ENQ\DC2\EOT\159\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT2\STX\SOH\SOH\DC2\EOT\130\ETX\b\DC4\n\ + \\ENQ\EOT4\STX\SOH\SOH\DC2\EOT\159\ETX\b\DC4\n\ \\r\n\ - \\ENQ\EOT2\STX\SOH\ETX\DC2\EOT\130\ETX\ETB\CAN\n\ + \\ENQ\EOT4\STX\SOH\ETX\DC2\EOT\159\ETX\ETB\CAN\n\ \F\n\ - \\STX\EOT3\DC2\ACK\134\ETX\NUL\144\ETX\SOH\SUB8 Represents a pool registration certificate in Cardano.\n\ + \\STX\EOT5\DC2\ACK\163\ETX\NUL\173\ETX\SOH\SUB8 Represents a pool registration certificate in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT3\SOH\DC2\EOT\134\ETX\b\FS\n\ + \\ETX\EOT5\SOH\DC2\EOT\163\ETX\b\FS\n\ \\"\n\ - \\EOT\EOT3\STX\NUL\DC2\EOT\135\ETX\STX\NAK\"\DC4 Operator key hash.\n\ + \\EOT\EOT5\STX\NUL\DC2\EOT\164\ETX\STX\NAK\"\DC4 Operator key hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\NUL\ENQ\DC2\EOT\135\ETX\STX\a\n\ + \\ENQ\EOT5\STX\NUL\ENQ\DC2\EOT\164\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT3\STX\NUL\SOH\DC2\EOT\135\ETX\b\DLE\n\ + \\ENQ\EOT5\STX\NUL\SOH\DC2\EOT\164\ETX\b\DLE\n\ \\r\n\ - \\ENQ\EOT3\STX\NUL\ETX\DC2\EOT\135\ETX\DC3\DC4\n\ + \\ENQ\EOT5\STX\NUL\ETX\DC2\EOT\164\ETX\DC3\DC4\n\ \\GS\n\ - \\EOT\EOT3\STX\SOH\DC2\EOT\136\ETX\STX\CAN\"\SI VRF key hash.\n\ + \\EOT\EOT5\STX\SOH\DC2\EOT\165\ETX\STX\CAN\"\SI VRF key hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\SOH\ENQ\DC2\EOT\136\ETX\STX\a\n\ + \\ENQ\EOT5\STX\SOH\ENQ\DC2\EOT\165\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT3\STX\SOH\SOH\DC2\EOT\136\ETX\b\DC3\n\ + \\ENQ\EOT5\STX\SOH\SOH\DC2\EOT\165\ETX\b\DC3\n\ \\r\n\ - \\ENQ\EOT3\STX\SOH\ETX\DC2\EOT\136\ETX\SYN\ETB\n\ + \\ENQ\EOT5\STX\SOH\ETX\DC2\EOT\165\ETX\SYN\ETB\n\ \\RS\n\ - \\EOT\EOT3\STX\STX\DC2\EOT\137\ETX\STX\DC4\"\DLE Pledge amount.\n\ + \\EOT\EOT5\STX\STX\DC2\EOT\166\ETX\STX\DC4\"\DLE Pledge amount.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\STX\ACK\DC2\EOT\137\ETX\STX\b\n\ + \\ENQ\EOT5\STX\STX\ACK\DC2\EOT\166\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT3\STX\STX\SOH\DC2\EOT\137\ETX\t\SI\n\ + \\ENQ\EOT5\STX\STX\SOH\DC2\EOT\166\ETX\t\SI\n\ \\r\n\ - \\ENQ\EOT3\STX\STX\ETX\DC2\EOT\137\ETX\DC2\DC3\n\ + \\ENQ\EOT5\STX\STX\ETX\DC2\EOT\166\ETX\DC2\DC3\n\ \\SUB\n\ - \\EOT\EOT3\STX\ETX\DC2\EOT\138\ETX\STX\DC2\"\f Pool cost.\n\ + \\EOT\EOT5\STX\ETX\DC2\EOT\167\ETX\STX\DC2\"\f Pool cost.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\ETX\ACK\DC2\EOT\138\ETX\STX\b\n\ + \\ENQ\EOT5\STX\ETX\ACK\DC2\EOT\167\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT3\STX\ETX\SOH\DC2\EOT\138\ETX\t\r\n\ + \\ENQ\EOT5\STX\ETX\SOH\DC2\EOT\167\ETX\t\r\n\ \\r\n\ - \\ENQ\EOT3\STX\ETX\ETX\DC2\EOT\138\ETX\DLE\DC1\n\ + \\ENQ\EOT5\STX\ETX\ETX\DC2\EOT\167\ETX\DLE\DC1\n\ \\FS\n\ - \\EOT\EOT3\STX\EOT\DC2\EOT\139\ETX\STX\FS\"\SO Pool margin.\n\ + \\EOT\EOT5\STX\EOT\DC2\EOT\168\ETX\STX\FS\"\SO Pool margin.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\EOT\ACK\DC2\EOT\139\ETX\STX\DLE\n\ + \\ENQ\EOT5\STX\EOT\ACK\DC2\EOT\168\ETX\STX\DLE\n\ \\r\n\ - \\ENQ\EOT3\STX\EOT\SOH\DC2\EOT\139\ETX\DC1\ETB\n\ + \\ENQ\EOT5\STX\EOT\SOH\DC2\EOT\168\ETX\DC1\ETB\n\ \\r\n\ - \\ENQ\EOT3\STX\EOT\ETX\DC2\EOT\139\ETX\SUB\ESC\n\ + \\ENQ\EOT5\STX\EOT\ETX\DC2\EOT\168\ETX\SUB\ESC\n\ \\US\n\ - \\EOT\EOT3\STX\ENQ\DC2\EOT\140\ETX\STX\ESC\"\DC1 Reward account.\n\ + \\EOT\EOT5\STX\ENQ\DC2\EOT\169\ETX\STX\ESC\"\DC1 Reward account.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\ENQ\ENQ\DC2\EOT\140\ETX\STX\a\n\ + \\ENQ\EOT5\STX\ENQ\ENQ\DC2\EOT\169\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT3\STX\ENQ\SOH\DC2\EOT\140\ETX\b\SYN\n\ + \\ENQ\EOT5\STX\ENQ\SOH\DC2\EOT\169\ETX\b\SYN\n\ \\r\n\ - \\ENQ\EOT3\STX\ENQ\ETX\DC2\EOT\140\ETX\EM\SUB\n\ + \\ENQ\EOT5\STX\ENQ\ETX\DC2\EOT\169\ETX\EM\SUB\n\ \.\n\ - \\EOT\EOT3\STX\ACK\DC2\EOT\141\ETX\STX!\" List of pool owner key hashes.\n\ + \\EOT\EOT5\STX\ACK\DC2\EOT\170\ETX\STX!\" List of pool owner key hashes.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\ACK\EOT\DC2\EOT\141\ETX\STX\n\ + \\ENQ\EOT5\STX\ACK\EOT\DC2\EOT\170\ETX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\ACK\ENQ\DC2\EOT\141\ETX\v\DLE\n\ + \\ENQ\EOT5\STX\ACK\ENQ\DC2\EOT\170\ETX\v\DLE\n\ \\r\n\ - \\ENQ\EOT3\STX\ACK\SOH\DC2\EOT\141\ETX\DC1\FS\n\ + \\ENQ\EOT5\STX\ACK\SOH\DC2\EOT\170\ETX\DC1\FS\n\ \\r\n\ - \\ENQ\EOT3\STX\ACK\ETX\DC2\EOT\141\ETX\US \n\ + \\ENQ\EOT5\STX\ACK\ETX\DC2\EOT\170\ETX\US \n\ \\US\n\ - \\EOT\EOT3\STX\a\DC2\EOT\142\ETX\STX\FS\"\DC1 List of relays.\n\ + \\EOT\EOT5\STX\a\DC2\EOT\171\ETX\STX\FS\"\DC1 List of relays.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\a\EOT\DC2\EOT\142\ETX\STX\n\ + \\ENQ\EOT5\STX\a\EOT\DC2\EOT\171\ETX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\a\ACK\DC2\EOT\142\ETX\v\DLE\n\ + \\ENQ\EOT5\STX\a\ACK\DC2\EOT\171\ETX\v\DLE\n\ \\r\n\ - \\ENQ\EOT3\STX\a\SOH\DC2\EOT\142\ETX\DC1\ETB\n\ + \\ENQ\EOT5\STX\a\SOH\DC2\EOT\171\ETX\DC1\ETB\n\ \\r\n\ - \\ENQ\EOT3\STX\a\ETX\DC2\EOT\142\ETX\SUB\ESC\n\ + \\ENQ\EOT5\STX\a\ETX\DC2\EOT\171\ETX\SUB\ESC\n\ \\RS\n\ - \\EOT\EOT3\STX\b\DC2\EOT\143\ETX\STX!\"\DLE Pool metadata.\n\ + \\EOT\EOT5\STX\b\DC2\EOT\172\ETX\STX!\"\DLE Pool metadata.\n\ \\n\ \\r\n\ - \\ENQ\EOT3\STX\b\ACK\DC2\EOT\143\ETX\STX\SO\n\ + \\ENQ\EOT5\STX\b\ACK\DC2\EOT\172\ETX\STX\SO\n\ \\r\n\ - \\ENQ\EOT3\STX\b\SOH\DC2\EOT\143\ETX\SI\FS\n\ + \\ENQ\EOT5\STX\b\SOH\DC2\EOT\172\ETX\SI\FS\n\ \\r\n\ - \\ENQ\EOT3\STX\b\ETX\DC2\EOT\143\ETX\US \n\ + \\ENQ\EOT5\STX\b\ETX\DC2\EOT\172\ETX\US \n\ \D\n\ - \\STX\EOT4\DC2\ACK\147\ETX\NUL\150\ETX\SOH\SUB6 Represents a pool retirement certificate in Cardano.\n\ + \\STX\EOT6\DC2\ACK\176\ETX\NUL\179\ETX\SOH\SUB6 Represents a pool retirement certificate in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT4\SOH\DC2\EOT\147\ETX\b\SUB\n\ + \\ETX\EOT6\SOH\DC2\EOT\176\ETX\b\SUB\n\ \\RS\n\ - \\EOT\EOT4\STX\NUL\DC2\EOT\148\ETX\STX\EM\"\DLE Pool key hash.\n\ + \\EOT\EOT6\STX\NUL\DC2\EOT\177\ETX\STX\EM\"\DLE Pool key hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT4\STX\NUL\ENQ\DC2\EOT\148\ETX\STX\a\n\ + \\ENQ\EOT6\STX\NUL\ENQ\DC2\EOT\177\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT4\STX\NUL\SOH\DC2\EOT\148\ETX\b\DC4\n\ + \\ENQ\EOT6\STX\NUL\SOH\DC2\EOT\177\ETX\b\DC4\n\ \\r\n\ - \\ENQ\EOT4\STX\NUL\ETX\DC2\EOT\148\ETX\ETB\CAN\n\ + \\ENQ\EOT6\STX\NUL\ETX\DC2\EOT\177\ETX\ETB\CAN\n\ \!\n\ - \\EOT\EOT4\STX\SOH\DC2\EOT\149\ETX\STX\DC3\"\DC3 Retirement epoch.\n\ + \\EOT\EOT6\STX\SOH\DC2\EOT\178\ETX\STX\DC3\"\DC3 Retirement epoch.\n\ \\n\ \\r\n\ - \\ENQ\EOT4\STX\SOH\ENQ\DC2\EOT\149\ETX\STX\b\n\ + \\ENQ\EOT6\STX\SOH\ENQ\DC2\EOT\178\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT4\STX\SOH\SOH\DC2\EOT\149\ETX\t\SO\n\ + \\ENQ\EOT6\STX\SOH\SOH\DC2\EOT\178\ETX\t\SO\n\ \\r\n\ - \\ENQ\EOT4\STX\SOH\ETX\DC2\EOT\149\ETX\DC1\DC2\n\ + \\ENQ\EOT6\STX\SOH\ETX\DC2\EOT\178\ETX\DC1\DC2\n\ \K\n\ - \\STX\EOT5\DC2\ACK\153\ETX\NUL\157\ETX\SOH\SUB= Represents a genesis key delegation certificate in Cardano.\n\ + \\STX\EOT7\DC2\ACK\182\ETX\NUL\186\ETX\SOH\SUB= Represents a genesis key delegation certificate in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT5\SOH\DC2\EOT\153\ETX\b \n\ + \\ETX\EOT7\SOH\DC2\EOT\182\ETX\b \n\ \\GS\n\ - \\EOT\EOT5\STX\NUL\DC2\EOT\154\ETX\STX\EM\"\SI Genesis hash.\n\ + \\EOT\EOT7\STX\NUL\DC2\EOT\183\ETX\STX\EM\"\SI Genesis hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT5\STX\NUL\ENQ\DC2\EOT\154\ETX\STX\a\n\ + \\ENQ\EOT7\STX\NUL\ENQ\DC2\EOT\183\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT5\STX\NUL\SOH\DC2\EOT\154\ETX\b\DC4\n\ + \\ENQ\EOT7\STX\NUL\SOH\DC2\EOT\183\ETX\b\DC4\n\ \\r\n\ - \\ENQ\EOT5\STX\NUL\ETX\DC2\EOT\154\ETX\ETB\CAN\n\ + \\ENQ\EOT7\STX\NUL\ETX\DC2\EOT\183\ETX\ETB\CAN\n\ \&\n\ - \\EOT\EOT5\STX\SOH\DC2\EOT\155\ETX\STX\"\"\CAN Genesis delegate hash.\n\ + \\EOT\EOT7\STX\SOH\DC2\EOT\184\ETX\STX\"\"\CAN Genesis delegate hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT5\STX\SOH\ENQ\DC2\EOT\155\ETX\STX\a\n\ + \\ENQ\EOT7\STX\SOH\ENQ\DC2\EOT\184\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT5\STX\SOH\SOH\DC2\EOT\155\ETX\b\GS\n\ + \\ENQ\EOT7\STX\SOH\SOH\DC2\EOT\184\ETX\b\GS\n\ \\r\n\ - \\ENQ\EOT5\STX\SOH\ETX\DC2\EOT\155\ETX !\n\ + \\ENQ\EOT7\STX\SOH\ETX\DC2\EOT\184\ETX !\n\ \\GS\n\ - \\EOT\EOT5\STX\STX\DC2\EOT\156\ETX\STX\CAN\"\SI VRF key hash.\n\ + \\EOT\EOT7\STX\STX\DC2\EOT\185\ETX\STX\CAN\"\SI VRF key hash.\n\ \\n\ \\r\n\ - \\ENQ\EOT5\STX\STX\ENQ\DC2\EOT\156\ETX\STX\a\n\ + \\ENQ\EOT7\STX\STX\ENQ\DC2\EOT\185\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT5\STX\STX\SOH\DC2\EOT\156\ETX\b\DC3\n\ + \\ENQ\EOT7\STX\STX\SOH\DC2\EOT\185\ETX\b\DC3\n\ \\r\n\ - \\ENQ\EOT5\STX\STX\ETX\DC2\EOT\156\ETX\SYN\ETB\n\ + \\ENQ\EOT7\STX\STX\ETX\DC2\EOT\185\ETX\SYN\ETB\n\ \\f\n\ - \\STX\ENQ\SOH\DC2\ACK\159\ETX\NUL\163\ETX\SOH\n\ + \\STX\ENQ\STX\DC2\ACK\188\ETX\NUL\192\ETX\SOH\n\ \\v\n\ - \\ETX\ENQ\SOH\SOH\DC2\EOT\159\ETX\ENQ\SO\n\ + \\ETX\ENQ\STX\SOH\DC2\EOT\188\ETX\ENQ\SO\n\ \\f\n\ - \\EOT\ENQ\SOH\STX\NUL\DC2\EOT\160\ETX\STX\GS\n\ + \\EOT\ENQ\STX\STX\NUL\DC2\EOT\189\ETX\STX\GS\n\ \\r\n\ - \\ENQ\ENQ\SOH\STX\NUL\SOH\DC2\EOT\160\ETX\STX\CAN\n\ + \\ENQ\ENQ\STX\STX\NUL\SOH\DC2\EOT\189\ETX\STX\CAN\n\ \\r\n\ - \\ENQ\ENQ\SOH\STX\NUL\STX\DC2\EOT\160\ETX\ESC\FS\n\ + \\ENQ\ENQ\STX\STX\NUL\STX\DC2\EOT\189\ETX\ESC\FS\n\ \\f\n\ - \\EOT\ENQ\SOH\STX\SOH\DC2\EOT\161\ETX\STX\SUB\n\ + \\EOT\ENQ\STX\STX\SOH\DC2\EOT\190\ETX\STX\SUB\n\ \\r\n\ - \\ENQ\ENQ\SOH\STX\SOH\SOH\DC2\EOT\161\ETX\STX\NAK\n\ + \\ENQ\ENQ\STX\STX\SOH\SOH\DC2\EOT\190\ETX\STX\NAK\n\ \\r\n\ - \\ENQ\ENQ\SOH\STX\SOH\STX\DC2\EOT\161\ETX\CAN\EM\n\ + \\ENQ\ENQ\STX\STX\SOH\STX\DC2\EOT\190\ETX\CAN\EM\n\ \\f\n\ - \\EOT\ENQ\SOH\STX\STX\DC2\EOT\162\ETX\STX\SUB\n\ + \\EOT\ENQ\STX\STX\STX\DC2\EOT\191\ETX\STX\SUB\n\ \\r\n\ - \\ENQ\ENQ\SOH\STX\STX\SOH\DC2\EOT\162\ETX\STX\NAK\n\ + \\ENQ\ENQ\STX\STX\STX\SOH\DC2\EOT\191\ETX\STX\NAK\n\ \\r\n\ - \\ENQ\ENQ\SOH\STX\STX\STX\DC2\EOT\162\ETX\CAN\EM\n\ + \\ENQ\ENQ\STX\STX\STX\STX\DC2\EOT\191\ETX\CAN\EM\n\ \\f\n\ - \\STX\EOT6\DC2\ACK\165\ETX\NUL\168\ETX\SOH\n\ + \\STX\EOT8\DC2\ACK\194\ETX\NUL\197\ETX\SOH\n\ \\v\n\ - \\ETX\EOT6\SOH\DC2\EOT\165\ETX\b\DC1\n\ + \\ETX\EOT8\SOH\DC2\EOT\194\ETX\b\DC1\n\ \\f\n\ - \\EOT\EOT6\STX\NUL\DC2\EOT\166\ETX\STX'\n\ + \\EOT\EOT8\STX\NUL\DC2\EOT\195\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT6\STX\NUL\ACK\DC2\EOT\166\ETX\STX\DC1\n\ + \\ENQ\EOT8\STX\NUL\ACK\DC2\EOT\195\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT6\STX\NUL\SOH\DC2\EOT\166\ETX\DC2\"\n\ + \\ENQ\EOT8\STX\NUL\SOH\DC2\EOT\195\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT6\STX\NUL\ETX\DC2\EOT\166\ETX%&\n\ + \\ENQ\EOT8\STX\NUL\ETX\DC2\EOT\195\ETX%&\n\ \\f\n\ - \\EOT\EOT6\STX\SOH\DC2\EOT\167\ETX\STX\CAN\n\ + \\EOT\EOT8\STX\SOH\DC2\EOT\196\ETX\STX\CAN\n\ \\r\n\ - \\ENQ\EOT6\STX\SOH\ACK\DC2\EOT\167\ETX\STX\b\n\ + \\ENQ\EOT8\STX\SOH\ACK\DC2\EOT\196\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT6\STX\SOH\SOH\DC2\EOT\167\ETX\t\DC3\n\ + \\ENQ\EOT8\STX\SOH\SOH\DC2\EOT\196\ETX\t\DC3\n\ \\r\n\ - \\ENQ\EOT6\STX\SOH\ETX\DC2\EOT\167\ETX\SYN\ETB\n\ + \\ENQ\EOT8\STX\SOH\ETX\DC2\EOT\196\ETX\SYN\ETB\n\ \N\n\ - \\STX\EOT7\DC2\ACK\171\ETX\NUL\175\ETX\SOH\SUB@ Represents a move instantaneous reward certificate in Cardano.\n\ + \\STX\EOT9\DC2\ACK\200\ETX\NUL\204\ETX\SOH\SUB@ Represents a move instantaneous reward certificate in Cardano.\n\ \\n\ \\v\n\ - \\ETX\EOT7\SOH\DC2\EOT\171\ETX\b\SI\n\ + \\ETX\EOT9\SOH\DC2\EOT\200\ETX\b\SI\n\ \\f\n\ - \\EOT\EOT7\STX\NUL\DC2\EOT\172\ETX\STX\NAK\n\ + \\EOT\EOT9\STX\NUL\DC2\EOT\201\ETX\STX\NAK\n\ \\r\n\ - \\ENQ\EOT7\STX\NUL\ACK\DC2\EOT\172\ETX\STX\v\n\ + \\ENQ\EOT9\STX\NUL\ACK\DC2\EOT\201\ETX\STX\v\n\ \\r\n\ - \\ENQ\EOT7\STX\NUL\SOH\DC2\EOT\172\ETX\f\DLE\n\ + \\ENQ\EOT9\STX\NUL\SOH\DC2\EOT\201\ETX\f\DLE\n\ \\r\n\ - \\ENQ\EOT7\STX\NUL\ETX\DC2\EOT\172\ETX\DC3\DC4\n\ + \\ENQ\EOT9\STX\NUL\ETX\DC2\EOT\201\ETX\DC3\DC4\n\ \\f\n\ - \\EOT\EOT7\STX\SOH\DC2\EOT\173\ETX\STX\FS\n\ + \\EOT\EOT9\STX\SOH\DC2\EOT\202\ETX\STX\FS\n\ \\r\n\ - \\ENQ\EOT7\STX\SOH\EOT\DC2\EOT\173\ETX\STX\n\ + \\ENQ\EOT9\STX\SOH\EOT\DC2\EOT\202\ETX\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT7\STX\SOH\ACK\DC2\EOT\173\ETX\v\DC4\n\ + \\ENQ\EOT9\STX\SOH\ACK\DC2\EOT\202\ETX\v\DC4\n\ \\r\n\ - \\ENQ\EOT7\STX\SOH\SOH\DC2\EOT\173\ETX\NAK\ETB\n\ + \\ENQ\EOT9\STX\SOH\SOH\DC2\EOT\202\ETX\NAK\ETB\n\ \\r\n\ - \\ENQ\EOT7\STX\SOH\ETX\DC2\EOT\173\ETX\SUB\ESC\n\ + \\ENQ\EOT9\STX\SOH\ETX\DC2\EOT\202\ETX\SUB\ESC\n\ \\f\n\ - \\EOT\EOT7\STX\STX\DC2\EOT\174\ETX\STX\ETB\n\ + \\EOT\EOT9\STX\STX\DC2\EOT\203\ETX\STX\ETB\n\ \\r\n\ - \\ENQ\EOT7\STX\STX\ENQ\DC2\EOT\174\ETX\STX\b\n\ + \\ENQ\EOT9\STX\STX\ENQ\DC2\EOT\203\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT7\STX\STX\SOH\DC2\EOT\174\ETX\t\DC2\n\ + \\ENQ\EOT9\STX\STX\SOH\DC2\EOT\203\ETX\t\DC2\n\ \\r\n\ - \\ENQ\EOT7\STX\STX\ETX\DC2\EOT\174\ETX\NAK\SYN\n\ + \\ENQ\EOT9\STX\STX\ETX\DC2\EOT\203\ETX\NAK\SYN\n\ \\f\n\ - \\STX\EOT8\DC2\ACK\177\ETX\NUL\180\ETX\SOH\n\ + \\STX\EOT:\DC2\ACK\206\ETX\NUL\209\ETX\SOH\n\ \\v\n\ - \\ETX\EOT8\SOH\DC2\EOT\177\ETX\b\SI\n\ + \\ETX\EOT:\SOH\DC2\EOT\206\ETX\b\SI\n\ \\f\n\ - \\EOT\EOT8\STX\NUL\DC2\EOT\178\ETX\STX'\n\ + \\EOT\EOT:\STX\NUL\DC2\EOT\207\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT8\STX\NUL\ACK\DC2\EOT\178\ETX\STX\DC1\n\ + \\ENQ\EOT:\STX\NUL\ACK\DC2\EOT\207\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT8\STX\NUL\SOH\DC2\EOT\178\ETX\DC2\"\n\ + \\ENQ\EOT:\STX\NUL\SOH\DC2\EOT\207\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT8\STX\NUL\ETX\DC2\EOT\178\ETX%&\n\ + \\ENQ\EOT:\STX\NUL\ETX\DC2\EOT\207\ETX%&\n\ \\f\n\ - \\EOT\EOT8\STX\SOH\DC2\EOT\179\ETX\STX\DC2\n\ + \\EOT\EOT:\STX\SOH\DC2\EOT\208\ETX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT8\STX\SOH\ACK\DC2\EOT\179\ETX\STX\b\n\ + \\ENQ\EOT:\STX\SOH\ACK\DC2\EOT\208\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT8\STX\SOH\SOH\DC2\EOT\179\ETX\t\r\n\ + \\ENQ\EOT:\STX\SOH\SOH\DC2\EOT\208\ETX\t\r\n\ \\r\n\ - \\ENQ\EOT8\STX\SOH\ETX\DC2\EOT\179\ETX\DLE\DC1\n\ + \\ENQ\EOT:\STX\SOH\ETX\DC2\EOT\208\ETX\DLE\DC1\n\ \\f\n\ - \\STX\EOT9\DC2\ACK\182\ETX\NUL\185\ETX\SOH\n\ + \\STX\EOT;\DC2\ACK\211\ETX\NUL\214\ETX\SOH\n\ \\v\n\ - \\ETX\EOT9\SOH\DC2\EOT\182\ETX\b\DC1\n\ + \\ETX\EOT;\SOH\DC2\EOT\211\ETX\b\DC1\n\ \\f\n\ - \\EOT\EOT9\STX\NUL\DC2\EOT\183\ETX\STX'\n\ + \\EOT\EOT;\STX\NUL\DC2\EOT\212\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT9\STX\NUL\ACK\DC2\EOT\183\ETX\STX\DC1\n\ + \\ENQ\EOT;\STX\NUL\ACK\DC2\EOT\212\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT9\STX\NUL\SOH\DC2\EOT\183\ETX\DC2\"\n\ + \\ENQ\EOT;\STX\NUL\SOH\DC2\EOT\212\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT9\STX\NUL\ETX\DC2\EOT\183\ETX%&\n\ + \\ENQ\EOT;\STX\NUL\ETX\DC2\EOT\212\ETX%&\n\ \\f\n\ - \\EOT\EOT9\STX\SOH\DC2\EOT\184\ETX\STX\DC2\n\ + \\EOT\EOT;\STX\SOH\DC2\EOT\213\ETX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT9\STX\SOH\ACK\DC2\EOT\184\ETX\STX\b\n\ + \\ENQ\EOT;\STX\SOH\ACK\DC2\EOT\213\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT9\STX\SOH\SOH\DC2\EOT\184\ETX\t\r\n\ + \\ENQ\EOT;\STX\SOH\SOH\DC2\EOT\213\ETX\t\r\n\ \\r\n\ - \\ENQ\EOT9\STX\SOH\ETX\DC2\EOT\184\ETX\DLE\DC1\n\ + \\ENQ\EOT;\STX\SOH\ETX\DC2\EOT\213\ETX\DLE\DC1\n\ \\f\n\ - \\STX\EOT:\DC2\ACK\187\ETX\NUL\194\ETX\SOH\n\ + \\STX\EOT<\DC2\ACK\216\ETX\NUL\223\ETX\SOH\n\ \\v\n\ - \\ETX\EOT:\SOH\DC2\EOT\187\ETX\b\f\n\ + \\ETX\EOT<\SOH\DC2\EOT\216\ETX\b\f\n\ \\SO\n\ - \\EOT\EOT:\b\NUL\DC2\ACK\188\ETX\STX\193\ETX\ETX\n\ + \\EOT\EOT<\b\NUL\DC2\ACK\217\ETX\STX\222\ETX\ETX\n\ \\r\n\ - \\ENQ\EOT:\b\NUL\SOH\DC2\EOT\188\ETX\b\f\n\ + \\ENQ\EOT<\b\NUL\SOH\DC2\EOT\217\ETX\b\f\n\ \ \n\ - \\EOT\EOT:\STX\NUL\DC2\EOT\189\ETX\EOT\FS\"\DC2 Address key hash\n\ + \\EOT\EOT<\STX\NUL\DC2\EOT\218\ETX\EOT\FS\"\DC2 Address key hash\n\ \\n\ \\r\n\ - \\ENQ\EOT:\STX\NUL\ENQ\DC2\EOT\189\ETX\EOT\t\n\ + \\ENQ\EOT<\STX\NUL\ENQ\DC2\EOT\218\ETX\EOT\t\n\ \\r\n\ - \\ENQ\EOT:\STX\NUL\SOH\DC2\EOT\189\ETX\n\ + \\ENQ\EOT<\STX\NUL\SOH\DC2\EOT\218\ETX\n\ \\ETB\n\ \\r\n\ - \\ENQ\EOT:\STX\NUL\ETX\DC2\EOT\189\ETX\SUB\ESC\n\ + \\ENQ\EOT<\STX\NUL\ETX\DC2\EOT\218\ETX\SUB\ESC\n\ \\ESC\n\ - \\EOT\EOT:\STX\SOH\DC2\EOT\190\ETX\EOT\SUB\"\r Script hash\n\ + \\EOT\EOT<\STX\SOH\DC2\EOT\219\ETX\EOT\SUB\"\r Script hash\n\ \\n\ \\r\n\ - \\ENQ\EOT:\STX\SOH\ENQ\DC2\EOT\190\ETX\EOT\t\n\ + \\ENQ\EOT<\STX\SOH\ENQ\DC2\EOT\219\ETX\EOT\t\n\ \\r\n\ - \\ENQ\EOT:\STX\SOH\SOH\DC2\EOT\190\ETX\n\ + \\ENQ\EOT<\STX\SOH\SOH\DC2\EOT\219\ETX\n\ \\NAK\n\ \\r\n\ - \\ENQ\EOT:\STX\SOH\ETX\DC2\EOT\190\ETX\CAN\EM\n\ + \\ENQ\EOT<\STX\SOH\ETX\DC2\EOT\219\ETX\CAN\EM\n\ \\ETB\n\ - \\EOT\EOT:\STX\STX\DC2\EOT\191\ETX\EOT\NAK\"\t Abstain\n\ + \\EOT\EOT<\STX\STX\DC2\EOT\220\ETX\EOT\NAK\"\t Abstain\n\ \\n\ \\r\n\ - \\ENQ\EOT:\STX\STX\ENQ\DC2\EOT\191\ETX\EOT\b\n\ + \\ENQ\EOT<\STX\STX\ENQ\DC2\EOT\220\ETX\EOT\b\n\ \\r\n\ - \\ENQ\EOT:\STX\STX\SOH\DC2\EOT\191\ETX\t\DLE\n\ + \\ENQ\EOT<\STX\STX\SOH\DC2\EOT\220\ETX\t\DLE\n\ \\r\n\ - \\ENQ\EOT:\STX\STX\ETX\DC2\EOT\191\ETX\DC3\DC4\n\ + \\ENQ\EOT<\STX\STX\ETX\DC2\EOT\220\ETX\DC3\DC4\n\ \\GS\n\ - \\EOT\EOT:\STX\ETX\DC2\EOT\192\ETX\EOT\ESC\"\SI No confidence\n\ + \\EOT\EOT<\STX\ETX\DC2\EOT\221\ETX\EOT\ESC\"\SI No confidence\n\ \\n\ \\r\n\ - \\ENQ\EOT:\STX\ETX\ENQ\DC2\EOT\192\ETX\EOT\b\n\ + \\ENQ\EOT<\STX\ETX\ENQ\DC2\EOT\221\ETX\EOT\b\n\ \\r\n\ - \\ENQ\EOT:\STX\ETX\SOH\DC2\EOT\192\ETX\t\SYN\n\ + \\ENQ\EOT<\STX\ETX\SOH\DC2\EOT\221\ETX\t\SYN\n\ \\r\n\ - \\ENQ\EOT:\STX\ETX\ETX\DC2\EOT\192\ETX\EM\SUB\n\ + \\ENQ\EOT<\STX\ETX\ETX\DC2\EOT\221\ETX\EM\SUB\n\ \\f\n\ - \\STX\EOT;\DC2\ACK\196\ETX\NUL\199\ETX\SOH\n\ + \\STX\EOT=\DC2\ACK\225\ETX\NUL\228\ETX\SOH\n\ \\v\n\ - \\ETX\EOT;\SOH\DC2\EOT\196\ETX\b\NAK\n\ + \\ETX\EOT=\SOH\DC2\EOT\225\ETX\b\NAK\n\ \\f\n\ - \\EOT\EOT;\STX\NUL\DC2\EOT\197\ETX\STX'\n\ + \\EOT\EOT=\STX\NUL\DC2\EOT\226\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT;\STX\NUL\ACK\DC2\EOT\197\ETX\STX\DC1\n\ + \\ENQ\EOT=\STX\NUL\ACK\DC2\EOT\226\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT;\STX\NUL\SOH\DC2\EOT\197\ETX\DC2\"\n\ + \\ENQ\EOT=\STX\NUL\SOH\DC2\EOT\226\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT;\STX\NUL\ETX\DC2\EOT\197\ETX%&\n\ + \\ENQ\EOT=\STX\NUL\ETX\DC2\EOT\226\ETX%&\n\ \\f\n\ - \\EOT\EOT;\STX\SOH\DC2\EOT\198\ETX\STX\DLE\n\ + \\EOT\EOT=\STX\SOH\DC2\EOT\227\ETX\STX\DLE\n\ \\r\n\ - \\ENQ\EOT;\STX\SOH\ACK\DC2\EOT\198\ETX\STX\ACK\n\ + \\ENQ\EOT=\STX\SOH\ACK\DC2\EOT\227\ETX\STX\ACK\n\ \\r\n\ - \\ENQ\EOT;\STX\SOH\SOH\DC2\EOT\198\ETX\a\v\n\ + \\ENQ\EOT=\STX\SOH\SOH\DC2\EOT\227\ETX\a\v\n\ \\r\n\ - \\ENQ\EOT;\STX\SOH\ETX\DC2\EOT\198\ETX\SO\SI\n\ + \\ENQ\EOT=\STX\SOH\ETX\DC2\EOT\227\ETX\SO\SI\n\ \\f\n\ - \\STX\EOT<\DC2\ACK\201\ETX\NUL\205\ETX\SOH\n\ + \\STX\EOT>\DC2\ACK\230\ETX\NUL\234\ETX\SOH\n\ \\v\n\ - \\ETX\EOT<\SOH\DC2\EOT\201\ETX\b\SUB\n\ + \\ETX\EOT>\SOH\DC2\EOT\230\ETX\b\SUB\n\ \\f\n\ - \\EOT\EOT<\STX\NUL\DC2\EOT\202\ETX\STX'\n\ + \\EOT\EOT>\STX\NUL\DC2\EOT\231\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT<\STX\NUL\ACK\DC2\EOT\202\ETX\STX\DC1\n\ + \\ENQ\EOT>\STX\NUL\ACK\DC2\EOT\231\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT<\STX\NUL\SOH\DC2\EOT\202\ETX\DC2\"\n\ + \\ENQ\EOT>\STX\NUL\SOH\DC2\EOT\231\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT<\STX\NUL\ETX\DC2\EOT\202\ETX%&\n\ + \\ENQ\EOT>\STX\NUL\ETX\DC2\EOT\231\ETX%&\n\ \\f\n\ - \\EOT\EOT<\STX\SOH\DC2\EOT\203\ETX\STX\EM\n\ + \\EOT\EOT>\STX\SOH\DC2\EOT\232\ETX\STX\EM\n\ \\r\n\ - \\ENQ\EOT<\STX\SOH\ENQ\DC2\EOT\203\ETX\STX\a\n\ + \\ENQ\EOT>\STX\SOH\ENQ\DC2\EOT\232\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT<\STX\SOH\SOH\DC2\EOT\203\ETX\b\DC4\n\ + \\ENQ\EOT>\STX\SOH\SOH\DC2\EOT\232\ETX\b\DC4\n\ \\r\n\ - \\ENQ\EOT<\STX\SOH\ETX\DC2\EOT\203\ETX\ETB\CAN\n\ + \\ENQ\EOT>\STX\SOH\ETX\DC2\EOT\232\ETX\ETB\CAN\n\ \\f\n\ - \\EOT\EOT<\STX\STX\DC2\EOT\204\ETX\STX\DLE\n\ + \\EOT\EOT>\STX\STX\DC2\EOT\233\ETX\STX\DLE\n\ \\r\n\ - \\ENQ\EOT<\STX\STX\ACK\DC2\EOT\204\ETX\STX\ACK\n\ + \\ENQ\EOT>\STX\STX\ACK\DC2\EOT\233\ETX\STX\ACK\n\ \\r\n\ - \\ENQ\EOT<\STX\STX\SOH\DC2\EOT\204\ETX\a\v\n\ + \\ENQ\EOT>\STX\STX\SOH\DC2\EOT\233\ETX\a\v\n\ \\r\n\ - \\ENQ\EOT<\STX\STX\ETX\DC2\EOT\204\ETX\SO\SI\n\ + \\ENQ\EOT>\STX\STX\ETX\DC2\EOT\233\ETX\SO\SI\n\ \\f\n\ - \\STX\EOT=\DC2\ACK\207\ETX\NUL\211\ETX\SOH\n\ + \\STX\EOT?\DC2\ACK\236\ETX\NUL\240\ETX\SOH\n\ \\v\n\ - \\ETX\EOT=\SOH\DC2\EOT\207\ETX\b\EM\n\ + \\ETX\EOT?\SOH\DC2\EOT\236\ETX\b\EM\n\ \\f\n\ - \\EOT\EOT=\STX\NUL\DC2\EOT\208\ETX\STX'\n\ + \\EOT\EOT?\STX\NUL\DC2\EOT\237\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT=\STX\NUL\ACK\DC2\EOT\208\ETX\STX\DC1\n\ + \\ENQ\EOT?\STX\NUL\ACK\DC2\EOT\237\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT=\STX\NUL\SOH\DC2\EOT\208\ETX\DC2\"\n\ + \\ENQ\EOT?\STX\NUL\SOH\DC2\EOT\237\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT=\STX\NUL\ETX\DC2\EOT\208\ETX%&\n\ + \\ENQ\EOT?\STX\NUL\ETX\DC2\EOT\237\ETX%&\n\ \\f\n\ - \\EOT\EOT=\STX\SOH\DC2\EOT\209\ETX\STX\EM\n\ + \\EOT\EOT?\STX\SOH\DC2\EOT\238\ETX\STX\EM\n\ \\r\n\ - \\ENQ\EOT=\STX\SOH\ENQ\DC2\EOT\209\ETX\STX\a\n\ + \\ENQ\EOT?\STX\SOH\ENQ\DC2\EOT\238\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT=\STX\SOH\SOH\DC2\EOT\209\ETX\b\DC4\n\ + \\ENQ\EOT?\STX\SOH\SOH\DC2\EOT\238\ETX\b\DC4\n\ \\r\n\ - \\ENQ\EOT=\STX\SOH\ETX\DC2\EOT\209\ETX\ETB\CAN\n\ + \\ENQ\EOT?\STX\SOH\ETX\DC2\EOT\238\ETX\ETB\CAN\n\ \\f\n\ - \\EOT\EOT=\STX\STX\DC2\EOT\210\ETX\STX\DC2\n\ + \\EOT\EOT?\STX\STX\DC2\EOT\239\ETX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT=\STX\STX\ACK\DC2\EOT\210\ETX\STX\b\n\ + \\ENQ\EOT?\STX\STX\ACK\DC2\EOT\239\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT=\STX\STX\SOH\DC2\EOT\210\ETX\t\r\n\ + \\ENQ\EOT?\STX\STX\SOH\DC2\EOT\239\ETX\t\r\n\ \\r\n\ - \\ENQ\EOT=\STX\STX\ETX\DC2\EOT\210\ETX\DLE\DC1\n\ + \\ENQ\EOT?\STX\STX\ETX\DC2\EOT\239\ETX\DLE\DC1\n\ \\f\n\ - \\STX\EOT>\DC2\ACK\213\ETX\NUL\217\ETX\SOH\n\ + \\STX\EOT@\DC2\ACK\242\ETX\NUL\246\ETX\SOH\n\ \\v\n\ - \\ETX\EOT>\SOH\DC2\EOT\213\ETX\b\CAN\n\ + \\ETX\EOT@\SOH\DC2\EOT\242\ETX\b\CAN\n\ \\f\n\ - \\EOT\EOT>\STX\NUL\DC2\EOT\214\ETX\STX'\n\ + \\EOT\EOT@\STX\NUL\DC2\EOT\243\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT>\STX\NUL\ACK\DC2\EOT\214\ETX\STX\DC1\n\ + \\ENQ\EOT@\STX\NUL\ACK\DC2\EOT\243\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT>\STX\NUL\SOH\DC2\EOT\214\ETX\DC2\"\n\ + \\ENQ\EOT@\STX\NUL\SOH\DC2\EOT\243\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT>\STX\NUL\ETX\DC2\EOT\214\ETX%&\n\ + \\ENQ\EOT@\STX\NUL\ETX\DC2\EOT\243\ETX%&\n\ \\f\n\ - \\EOT\EOT>\STX\SOH\DC2\EOT\215\ETX\STX\DLE\n\ + \\EOT\EOT@\STX\SOH\DC2\EOT\244\ETX\STX\DLE\n\ \\r\n\ - \\ENQ\EOT>\STX\SOH\ACK\DC2\EOT\215\ETX\STX\ACK\n\ + \\ENQ\EOT@\STX\SOH\ACK\DC2\EOT\244\ETX\STX\ACK\n\ \\r\n\ - \\ENQ\EOT>\STX\SOH\SOH\DC2\EOT\215\ETX\a\v\n\ + \\ENQ\EOT@\STX\SOH\SOH\DC2\EOT\244\ETX\a\v\n\ \\r\n\ - \\ENQ\EOT>\STX\SOH\ETX\DC2\EOT\215\ETX\SO\SI\n\ + \\ENQ\EOT@\STX\SOH\ETX\DC2\EOT\244\ETX\SO\SI\n\ \\f\n\ - \\EOT\EOT>\STX\STX\DC2\EOT\216\ETX\STX\DC2\n\ + \\EOT\EOT@\STX\STX\DC2\EOT\245\ETX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT>\STX\STX\ACK\DC2\EOT\216\ETX\STX\b\n\ + \\ENQ\EOT@\STX\STX\ACK\DC2\EOT\245\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT>\STX\STX\SOH\DC2\EOT\216\ETX\t\r\n\ + \\ENQ\EOT@\STX\STX\SOH\DC2\EOT\245\ETX\t\r\n\ \\r\n\ - \\ENQ\EOT>\STX\STX\ETX\DC2\EOT\216\ETX\DLE\DC1\n\ + \\ENQ\EOT@\STX\STX\ETX\DC2\EOT\245\ETX\DLE\DC1\n\ \\f\n\ - \\STX\EOT?\DC2\ACK\219\ETX\NUL\224\ETX\SOH\n\ + \\STX\EOTA\DC2\ACK\248\ETX\NUL\253\ETX\SOH\n\ \\v\n\ - \\ETX\EOT?\SOH\DC2\EOT\219\ETX\b\GS\n\ + \\ETX\EOTA\SOH\DC2\EOT\248\ETX\b\GS\n\ \\f\n\ - \\EOT\EOT?\STX\NUL\DC2\EOT\220\ETX\STX'\n\ + \\EOT\EOTA\STX\NUL\DC2\EOT\249\ETX\STX'\n\ \\r\n\ - \\ENQ\EOT?\STX\NUL\ACK\DC2\EOT\220\ETX\STX\DC1\n\ + \\ENQ\EOTA\STX\NUL\ACK\DC2\EOT\249\ETX\STX\DC1\n\ \\r\n\ - \\ENQ\EOT?\STX\NUL\SOH\DC2\EOT\220\ETX\DC2\"\n\ + \\ENQ\EOTA\STX\NUL\SOH\DC2\EOT\249\ETX\DC2\"\n\ \\r\n\ - \\ENQ\EOT?\STX\NUL\ETX\DC2\EOT\220\ETX%&\n\ + \\ENQ\EOTA\STX\NUL\ETX\DC2\EOT\249\ETX%&\n\ \\f\n\ - \\EOT\EOT?\STX\SOH\DC2\EOT\221\ETX\STX\EM\n\ + \\EOT\EOTA\STX\SOH\DC2\EOT\250\ETX\STX\EM\n\ \\r\n\ - \\ENQ\EOT?\STX\SOH\ENQ\DC2\EOT\221\ETX\STX\a\n\ + \\ENQ\EOTA\STX\SOH\ENQ\DC2\EOT\250\ETX\STX\a\n\ \\r\n\ - \\ENQ\EOT?\STX\SOH\SOH\DC2\EOT\221\ETX\b\DC4\n\ + \\ENQ\EOTA\STX\SOH\SOH\DC2\EOT\250\ETX\b\DC4\n\ \\r\n\ - \\ENQ\EOT?\STX\SOH\ETX\DC2\EOT\221\ETX\ETB\CAN\n\ + \\ENQ\EOTA\STX\SOH\ETX\DC2\EOT\250\ETX\ETB\CAN\n\ \\f\n\ - \\EOT\EOT?\STX\STX\DC2\EOT\222\ETX\STX\DLE\n\ + \\EOT\EOTA\STX\STX\DC2\EOT\251\ETX\STX\DLE\n\ \\r\n\ - \\ENQ\EOT?\STX\STX\ACK\DC2\EOT\222\ETX\STX\ACK\n\ + \\ENQ\EOTA\STX\STX\ACK\DC2\EOT\251\ETX\STX\ACK\n\ \\r\n\ - \\ENQ\EOT?\STX\STX\SOH\DC2\EOT\222\ETX\a\v\n\ + \\ENQ\EOTA\STX\STX\SOH\DC2\EOT\251\ETX\a\v\n\ \\r\n\ - \\ENQ\EOT?\STX\STX\ETX\DC2\EOT\222\ETX\SO\SI\n\ + \\ENQ\EOTA\STX\STX\ETX\DC2\EOT\251\ETX\SO\SI\n\ \\f\n\ - \\EOT\EOT?\STX\ETX\DC2\EOT\223\ETX\STX\DC2\n\ + \\EOT\EOTA\STX\ETX\DC2\EOT\252\ETX\STX\DC2\n\ \\r\n\ - \\ENQ\EOT?\STX\ETX\ACK\DC2\EOT\223\ETX\STX\b\n\ + \\ENQ\EOTA\STX\ETX\ACK\DC2\EOT\252\ETX\STX\b\n\ \\r\n\ - \\ENQ\EOT?\STX\ETX\SOH\DC2\EOT\223\ETX\t\r\n\ + \\ENQ\EOTA\STX\ETX\SOH\DC2\EOT\252\ETX\t\r\n\ \\r\n\ - \\ENQ\EOT?\STX\ETX\ETX\DC2\EOT\223\ETX\DLE\DC1\n\ + \\ENQ\EOTA\STX\ETX\ETX\DC2\EOT\252\ETX\DLE\DC1\n\ \\f\n\ - \\STX\EOT@\DC2\ACK\226\ETX\NUL\229\ETX\SOH\n\ + \\STX\EOTB\DC2\ACK\255\ETX\NUL\130\EOT\SOH\n\ \\v\n\ - \\ETX\EOT@\SOH\DC2\EOT\226\ETX\b\FS\n\ + \\ETX\EOTB\SOH\DC2\EOT\255\ETX\b\FS\n\ \\f\n\ - \\EOT\EOT@\STX\NUL\DC2\EOT\227\ETX\STX0\n\ + \\EOT\EOTB\STX\NUL\DC2\EOT\128\EOT\STX0\n\ \\r\n\ - \\ENQ\EOT@\STX\NUL\ACK\DC2\EOT\227\ETX\STX\DC1\n\ + \\ENQ\EOTB\STX\NUL\ACK\DC2\EOT\128\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOT@\STX\NUL\SOH\DC2\EOT\227\ETX\DC2+\n\ + \\ENQ\EOTB\STX\NUL\SOH\DC2\EOT\128\EOT\DC2+\n\ \\r\n\ - \\ENQ\EOT@\STX\NUL\ETX\DC2\EOT\227\ETX./\n\ + \\ENQ\EOTB\STX\NUL\ETX\DC2\EOT\128\EOT./\n\ \\f\n\ - \\EOT\EOT@\STX\SOH\DC2\EOT\228\ETX\STX/\n\ + \\EOT\EOTB\STX\SOH\DC2\EOT\129\EOT\STX/\n\ \\r\n\ - \\ENQ\EOT@\STX\SOH\ACK\DC2\EOT\228\ETX\STX\DC1\n\ + \\ENQ\EOTB\STX\SOH\ACK\DC2\EOT\129\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOT@\STX\SOH\SOH\DC2\EOT\228\ETX\DC2*\n\ + \\ENQ\EOTB\STX\SOH\SOH\DC2\EOT\129\EOT\DC2*\n\ \\r\n\ - \\ENQ\EOT@\STX\SOH\ETX\DC2\EOT\228\ETX-.\n\ + \\ENQ\EOTB\STX\SOH\ETX\DC2\EOT\129\EOT-.\n\ \\f\n\ - \\STX\EOTA\DC2\ACK\231\ETX\NUL\234\ETX\SOH\n\ + \\STX\EOTC\DC2\ACK\132\EOT\NUL\135\EOT\SOH\n\ \\v\n\ - \\ETX\EOTA\SOH\DC2\EOT\231\ETX\b\SO\n\ + \\ETX\EOTC\SOH\DC2\EOT\132\EOT\b\SO\n\ \\f\n\ - \\EOT\EOTA\STX\NUL\DC2\EOT\232\ETX\STX\DC1\n\ + \\EOT\EOTC\STX\NUL\DC2\EOT\133\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTA\STX\NUL\ENQ\DC2\EOT\232\ETX\STX\b\n\ + \\ENQ\EOTC\STX\NUL\ENQ\DC2\EOT\133\EOT\STX\b\n\ \\r\n\ - \\ENQ\EOTA\STX\NUL\SOH\DC2\EOT\232\ETX\t\f\n\ + \\ENQ\EOTC\STX\NUL\SOH\DC2\EOT\133\EOT\t\f\n\ \\r\n\ - \\ENQ\EOTA\STX\NUL\ETX\DC2\EOT\232\ETX\SI\DLE\n\ + \\ENQ\EOTC\STX\NUL\ETX\DC2\EOT\133\EOT\SI\DLE\n\ \\f\n\ - \\EOT\EOTA\STX\SOH\DC2\EOT\233\ETX\STX\EM\n\ + \\EOT\EOTC\STX\SOH\DC2\EOT\134\EOT\STX\EM\n\ \\r\n\ - \\ENQ\EOTA\STX\SOH\ENQ\DC2\EOT\233\ETX\STX\a\n\ + \\ENQ\EOTC\STX\SOH\ENQ\DC2\EOT\134\EOT\STX\a\n\ \\r\n\ - \\ENQ\EOTA\STX\SOH\SOH\DC2\EOT\233\ETX\b\DC4\n\ + \\ENQ\EOTC\STX\SOH\SOH\DC2\EOT\134\EOT\b\DC4\n\ \\r\n\ - \\ENQ\EOTA\STX\SOH\ETX\DC2\EOT\233\ETX\ETB\CAN\n\ + \\ENQ\EOTC\STX\SOH\ETX\DC2\EOT\134\EOT\ETB\CAN\n\ \\f\n\ - \\STX\EOTB\DC2\ACK\236\ETX\NUL\239\ETX\SOH\n\ + \\STX\EOTD\DC2\ACK\137\EOT\NUL\140\EOT\SOH\n\ \\v\n\ - \\ETX\EOTB\SOH\DC2\EOT\236\ETX\b\US\n\ + \\ETX\EOTD\SOH\DC2\EOT\137\EOT\b\US\n\ \\f\n\ - \\EOT\EOTB\STX\NUL\DC2\EOT\237\ETX\STX0\n\ + \\EOT\EOTD\STX\NUL\DC2\EOT\138\EOT\STX0\n\ \\r\n\ - \\ENQ\EOTB\STX\NUL\ACK\DC2\EOT\237\ETX\STX\DC1\n\ + \\ENQ\EOTD\STX\NUL\ACK\DC2\EOT\138\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTB\STX\NUL\SOH\DC2\EOT\237\ETX\DC2+\n\ + \\ENQ\EOTD\STX\NUL\SOH\DC2\EOT\138\EOT\DC2+\n\ \\r\n\ - \\ENQ\EOTB\STX\NUL\ETX\DC2\EOT\237\ETX./\n\ + \\ENQ\EOTD\STX\NUL\ETX\DC2\EOT\138\EOT./\n\ \\f\n\ - \\EOT\EOTB\STX\SOH\DC2\EOT\238\ETX\STX\DC4\n\ + \\EOT\EOTD\STX\SOH\DC2\EOT\139\EOT\STX\DC4\n\ \\r\n\ - \\ENQ\EOTB\STX\SOH\ACK\DC2\EOT\238\ETX\STX\b\n\ + \\ENQ\EOTD\STX\SOH\ACK\DC2\EOT\139\EOT\STX\b\n\ \\r\n\ - \\ENQ\EOTB\STX\SOH\SOH\DC2\EOT\238\ETX\t\SI\n\ + \\ENQ\EOTD\STX\SOH\SOH\DC2\EOT\139\EOT\t\SI\n\ \\r\n\ - \\ENQ\EOTB\STX\SOH\ETX\DC2\EOT\238\ETX\DC2\DC3\n\ + \\ENQ\EOTD\STX\SOH\ETX\DC2\EOT\139\EOT\DC2\DC3\n\ \\f\n\ - \\STX\EOTC\DC2\ACK\241\ETX\NUL\245\ETX\SOH\n\ + \\STX\EOTE\DC2\ACK\142\EOT\NUL\146\EOT\SOH\n\ \\v\n\ - \\ETX\EOTC\SOH\DC2\EOT\241\ETX\b\DC3\n\ + \\ETX\EOTE\SOH\DC2\EOT\142\EOT\b\DC3\n\ \\f\n\ - \\EOT\EOTC\STX\NUL\DC2\EOT\242\ETX\STX&\n\ + \\EOT\EOTE\STX\NUL\DC2\EOT\143\EOT\STX&\n\ \\r\n\ - \\ENQ\EOTC\STX\NUL\ACK\DC2\EOT\242\ETX\STX\DC1\n\ + \\ENQ\EOTE\STX\NUL\ACK\DC2\EOT\143\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTC\STX\NUL\SOH\DC2\EOT\242\ETX\DC2!\n\ + \\ENQ\EOTE\STX\NUL\SOH\DC2\EOT\143\EOT\DC2!\n\ \\r\n\ - \\ENQ\EOTC\STX\NUL\ETX\DC2\EOT\242\ETX$%\n\ + \\ENQ\EOTE\STX\NUL\ETX\DC2\EOT\143\EOT$%\n\ \\f\n\ - \\EOT\EOTC\STX\SOH\DC2\EOT\243\ETX\STX\DC2\n\ + \\EOT\EOTE\STX\SOH\DC2\EOT\144\EOT\STX\DC2\n\ \\r\n\ - \\ENQ\EOTC\STX\SOH\ACK\DC2\EOT\243\ETX\STX\b\n\ + \\ENQ\EOTE\STX\SOH\ACK\DC2\EOT\144\EOT\STX\b\n\ \\r\n\ - \\ENQ\EOTC\STX\SOH\SOH\DC2\EOT\243\ETX\t\r\n\ + \\ENQ\EOTE\STX\SOH\SOH\DC2\EOT\144\EOT\t\r\n\ \\r\n\ - \\ENQ\EOTC\STX\SOH\ETX\DC2\EOT\243\ETX\DLE\DC1\n\ + \\ENQ\EOTE\STX\SOH\ETX\DC2\EOT\144\EOT\DLE\DC1\n\ \\f\n\ - \\EOT\EOTC\STX\STX\DC2\EOT\244\ETX\STX\DC4\n\ + \\EOT\EOTE\STX\STX\DC2\EOT\145\EOT\STX\DC4\n\ \\r\n\ - \\ENQ\EOTC\STX\STX\ACK\DC2\EOT\244\ETX\STX\b\n\ + \\ENQ\EOTE\STX\STX\ACK\DC2\EOT\145\EOT\STX\b\n\ \\r\n\ - \\ENQ\EOTC\STX\STX\SOH\DC2\EOT\244\ETX\t\SI\n\ + \\ENQ\EOTE\STX\STX\SOH\DC2\EOT\145\EOT\t\SI\n\ \\r\n\ - \\ENQ\EOTC\STX\STX\ETX\DC2\EOT\244\ETX\DC2\DC3\n\ + \\ENQ\EOTE\STX\STX\ETX\DC2\EOT\145\EOT\DC2\DC3\n\ \\f\n\ - \\STX\EOTD\DC2\ACK\247\ETX\NUL\250\ETX\SOH\n\ + \\STX\EOTF\DC2\ACK\148\EOT\NUL\151\EOT\SOH\n\ \\v\n\ - \\ETX\EOTD\SOH\DC2\EOT\247\ETX\b\NAK\n\ + \\ETX\EOTF\SOH\DC2\EOT\148\EOT\b\NAK\n\ \\f\n\ - \\EOT\EOTD\STX\NUL\DC2\EOT\248\ETX\STX&\n\ + \\EOT\EOTF\STX\NUL\DC2\EOT\149\EOT\STX&\n\ \\r\n\ - \\ENQ\EOTD\STX\NUL\ACK\DC2\EOT\248\ETX\STX\DC1\n\ + \\ENQ\EOTF\STX\NUL\ACK\DC2\EOT\149\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTD\STX\NUL\SOH\DC2\EOT\248\ETX\DC2!\n\ + \\ENQ\EOTF\STX\NUL\SOH\DC2\EOT\149\EOT\DC2!\n\ \\r\n\ - \\ENQ\EOTD\STX\NUL\ETX\DC2\EOT\248\ETX$%\n\ + \\ENQ\EOTF\STX\NUL\ETX\DC2\EOT\149\EOT$%\n\ \\f\n\ - \\EOT\EOTD\STX\SOH\DC2\EOT\249\ETX\STX\DC2\n\ + \\EOT\EOTF\STX\SOH\DC2\EOT\150\EOT\STX\DC2\n\ \\r\n\ - \\ENQ\EOTD\STX\SOH\ACK\DC2\EOT\249\ETX\STX\b\n\ + \\ENQ\EOTF\STX\SOH\ACK\DC2\EOT\150\EOT\STX\b\n\ \\r\n\ - \\ENQ\EOTD\STX\SOH\SOH\DC2\EOT\249\ETX\t\r\n\ + \\ENQ\EOTF\STX\SOH\SOH\DC2\EOT\150\EOT\t\r\n\ \\r\n\ - \\ENQ\EOTD\STX\SOH\ETX\DC2\EOT\249\ETX\DLE\DC1\n\ + \\ENQ\EOTF\STX\SOH\ETX\DC2\EOT\150\EOT\DLE\DC1\n\ \\f\n\ - \\STX\EOTE\DC2\ACK\252\ETX\NUL\255\ETX\SOH\n\ + \\STX\EOTG\DC2\ACK\153\EOT\NUL\156\EOT\SOH\n\ \\v\n\ - \\ETX\EOTE\SOH\DC2\EOT\252\ETX\b\SYN\n\ + \\ETX\EOTG\SOH\DC2\EOT\153\EOT\b\SYN\n\ \\f\n\ - \\EOT\EOTE\STX\NUL\DC2\EOT\253\ETX\STX&\n\ + \\EOT\EOTG\STX\NUL\DC2\EOT\154\EOT\STX&\n\ \\r\n\ - \\ENQ\EOTE\STX\NUL\ACK\DC2\EOT\253\ETX\STX\DC1\n\ + \\ENQ\EOTG\STX\NUL\ACK\DC2\EOT\154\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTE\STX\NUL\SOH\DC2\EOT\253\ETX\DC2!\n\ + \\ENQ\EOTG\STX\NUL\SOH\DC2\EOT\154\EOT\DC2!\n\ \\r\n\ - \\ENQ\EOTE\STX\NUL\ETX\DC2\EOT\253\ETX$%\n\ + \\ENQ\EOTG\STX\NUL\ETX\DC2\EOT\154\EOT$%\n\ \\f\n\ - \\EOT\EOTE\STX\SOH\DC2\EOT\254\ETX\STX\DC4\n\ + \\EOT\EOTG\STX\SOH\DC2\EOT\155\EOT\STX\DC4\n\ + \\r\n\ + \\ENQ\EOTG\STX\SOH\ACK\DC2\EOT\155\EOT\STX\b\n\ + \\r\n\ + \\ENQ\EOTG\STX\SOH\SOH\DC2\EOT\155\EOT\t\SI\n\ + \\r\n\ + \\ENQ\EOTG\STX\SOH\ETX\DC2\EOT\155\EOT\DC2\DC3\n\ + \\186\STX\n\ + \\STX\EOTH\DC2\ACK\166\EOT\NUL\170\EOT\SOH\SUB+ Envelope of a Cardano ledger-state query.\n\ + \2\254\SOH LEDGER-STATE QUERIES\n\ + \ ====================\n\ + \\n\ + \ Cardano-specific queries that mirror the Ouroboros node-to-client\n\ + \ LocalStateQuery mini-protocol. The oneof envelope lets new queries be\n\ + \ added later without changing the chain-agnostic QueryService surface.\n\ + \\n\ + \\v\n\ + \\ETX\EOTH\SOH\DC2\EOT\166\EOT\b\DC2\n\ + \\SO\n\ + \\EOT\EOTH\b\NUL\DC2\ACK\167\EOT\STX\169\EOT\ETX\n\ + \\r\n\ + \\ENQ\EOTH\b\NUL\SOH\DC2\EOT\167\EOT\b\r\n\ + \7\n\ + \\EOT\EOTH\STX\NUL\DC2\EOT\168\EOT\EOT9\") Active stake distribution across pools.\n\ + \\n\ + \\r\n\ + \\ENQ\EOTH\STX\NUL\ACK\DC2\EOT\168\EOT\EOT\FS\n\ + \\r\n\ + \\ENQ\EOTH\STX\NUL\SOH\DC2\EOT\168\EOT\GS4\n\ + \\r\n\ + \\ENQ\EOTH\STX\NUL\ETX\DC2\EOT\168\EOT78\n\ + \@\n\ + \\STX\EOTI\DC2\ACK\173\EOT\NUL\177\EOT\SOH\SUB2 Envelope of a Cardano ledger-state query result.\n\ + \\n\ + \\v\n\ + \\ETX\EOTI\SOH\DC2\EOT\173\EOT\b\DC1\n\ + \\SO\n\ + \\EOT\EOTI\b\NUL\DC2\ACK\174\EOT\STX\176\EOT\ETX\n\ + \\r\n\ + \\ENQ\EOTI\b\NUL\SOH\DC2\EOT\174\EOT\b\SO\n\ + \:\n\ + \\EOT\EOTI\STX\NUL\DC2\EOT\175\EOT\EOT6\", Result of a stake pool distribution query.\n\ + \\n\ + \\r\n\ + \\ENQ\EOTI\STX\NUL\ACK\DC2\EOT\175\EOT\EOT\EM\n\ + \\r\n\ + \\ENQ\EOTI\STX\NUL\SOH\DC2\EOT\175\EOT\SUB1\n\ + \\r\n\ + \\ENQ\EOTI\STX\NUL\ETX\DC2\EOT\175\EOT45\n\ + \e\n\ + \\STX\EOTJ\DC2\ACK\180\EOT\NUL\184\EOT\SOH\SUBW Stake pool distribution query. Mirrors Ouroboros GetPoolDistr / GetFilteredPoolDistr.\n\ + \\n\ + \\v\n\ + \\ETX\EOTJ\SOH\DC2\EOT\180\EOT\b \n\ + \\131\SOH\n\ + \\EOT\EOTJ\STX\NUL\DC2\EOT\183\EOT\STX$\SUBu If non-empty, restrict the result to the listed pool key hashes.\n\ + \ If empty, return the distribution for every pool.\n\ + \\n\ + \\r\n\ + \\ENQ\EOTJ\STX\NUL\EOT\DC2\EOT\183\EOT\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOTJ\STX\NUL\ENQ\DC2\EOT\183\EOT\v\DLE\n\ \\r\n\ - \\ENQ\EOTE\STX\SOH\ACK\DC2\EOT\254\ETX\STX\b\n\ + \\ENQ\EOTJ\STX\NUL\SOH\DC2\EOT\183\EOT\DC1\US\n\ \\r\n\ - \\ENQ\EOTE\STX\SOH\SOH\DC2\EOT\254\ETX\t\SI\n\ + \\ENQ\EOTJ\STX\NUL\ETX\DC2\EOT\183\EOT\"#\n\ + \L\n\ + \\STX\EOTK\DC2\ACK\187\EOT\NUL\191\EOT\SOH\SUB> Per-pool stake share. Mirrors Ouroboros IndividualPoolStake.\n\ + \\n\ + \\v\n\ + \\ETX\EOTK\SOH\DC2\EOT\187\EOT\b\SYN\n\ + \(\n\ + \\EOT\EOTK\STX\NUL\DC2\EOT\188\EOT\STX\EM\"\SUB Pool key hash (pool id).\n\ + \\n\ + \\r\n\ + \\ENQ\EOTK\STX\NUL\ENQ\DC2\EOT\188\EOT\STX\a\n\ + \\r\n\ + \\ENQ\EOTK\STX\NUL\SOH\DC2\EOT\188\EOT\b\DC4\n\ + \\r\n\ + \\ENQ\EOTK\STX\NUL\ETX\DC2\EOT\188\EOT\ETB\CAN\n\ + \F\n\ + \\EOT\EOTK\STX\SOH\DC2\EOT\189\EOT\STX$\"8 Fraction of total active stake delegated to this pool.\n\ + \\n\ \\r\n\ - \\ENQ\EOTE\STX\SOH\ETX\DC2\EOT\254\ETX\DC2\DC3\n\ + \\ENQ\EOTK\STX\SOH\ACK\DC2\EOT\189\EOT\STX\DLE\n\ + \\r\n\ + \\ENQ\EOTK\STX\SOH\SOH\DC2\EOT\189\EOT\DC1\US\n\ + \\r\n\ + \\ENQ\EOTK\STX\SOH\ETX\DC2\EOT\189\EOT\"#\n\ + \=\n\ + \\EOT\EOTK\STX\STX\DC2\EOT\190\EOT\STX\CAN\"/ Pool's VRF key hash, as reported by the node.\n\ + \\n\ + \\r\n\ + \\ENQ\EOTK\STX\STX\ENQ\DC2\EOT\190\EOT\STX\a\n\ + \\r\n\ + \\ENQ\EOTK\STX\STX\SOH\DC2\EOT\190\EOT\b\DC3\n\ + \\r\n\ + \\ENQ\EOTK\STX\STX\ETX\DC2\EOT\190\EOT\SYN\ETB\n\ + \:\n\ + \\STX\EOTL\DC2\ACK\194\EOT\NUL\196\EOT\SOH\SUB, Result of a stake pool distribution query.\n\ + \\n\ + \\v\n\ + \\ETX\EOTL\SOH\DC2\EOT\194\EOT\b\GS\n\ + \;\n\ + \\EOT\EOTL\STX\NUL\DC2\EOT\195\EOT\STX$\"- One entry per pool present in the snapshot.\n\ + \\n\ + \\r\n\ + \\ENQ\EOTL\STX\NUL\EOT\DC2\EOT\195\EOT\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOTL\STX\NUL\ACK\DC2\EOT\195\EOT\v\EM\n\ + \\r\n\ + \\ENQ\EOTL\STX\NUL\SOH\DC2\EOT\195\EOT\SUB\US\n\ + \\r\n\ + \\ENQ\EOTL\STX\NUL\ETX\DC2\EOT\195\EOT\"#\n\ \}\n\ - \\STX\EOTF\DC2\ACK\133\EOT\NUL\137\EOT\SOH\SUBI Pattern of an address that can be used to evaluate matching predicates.\n\ + \\STX\EOTM\DC2\ACK\202\EOT\NUL\206\EOT\SOH\SUBI Pattern of an address that can be used to evaluate matching predicates.\n\ \2$ PATTERN MATCHING\n\ \ ================\n\ \\n\ \\v\n\ - \\ETX\EOTF\SOH\DC2\EOT\133\EOT\b\SYN\n\ + \\ETX\EOTM\SOH\DC2\EOT\202\EOT\b\SYN\n\ \B\n\ - \\EOT\EOTF\STX\NUL\DC2\EOT\134\EOT\STX#\"4 The address should match this exact address value.\n\ + \\EOT\EOTM\STX\NUL\DC2\EOT\203\EOT\STX#\"4 The address should match this exact address value.\n\ \\n\ \\r\n\ - \\ENQ\EOTF\STX\NUL\EOT\DC2\EOT\134\EOT\STX\n\ + \\ENQ\EOTM\STX\NUL\EOT\DC2\EOT\203\EOT\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTF\STX\NUL\ENQ\DC2\EOT\134\EOT\v\DLE\n\ + \\ENQ\EOTM\STX\NUL\ENQ\DC2\EOT\203\EOT\v\DLE\n\ \\r\n\ - \\ENQ\EOTF\STX\NUL\SOH\DC2\EOT\134\EOT\DC1\RS\n\ + \\ENQ\EOTM\STX\NUL\SOH\DC2\EOT\203\EOT\DC1\RS\n\ \\r\n\ - \\ENQ\EOTF\STX\NUL\ETX\DC2\EOT\134\EOT!\"\n\ + \\ENQ\EOTM\STX\NUL\ETX\DC2\EOT\203\EOT!\"\n\ \H\n\ - \\EOT\EOTF\STX\SOH\DC2\EOT\135\EOT\STX\"\": The payment part of the address should match this value.\n\ + \\EOT\EOTM\STX\SOH\DC2\EOT\204\EOT\STX\"\": The payment part of the address should match this value.\n\ \\n\ \\r\n\ - \\ENQ\EOTF\STX\SOH\EOT\DC2\EOT\135\EOT\STX\n\ + \\ENQ\EOTM\STX\SOH\EOT\DC2\EOT\204\EOT\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTF\STX\SOH\ENQ\DC2\EOT\135\EOT\v\DLE\n\ + \\ENQ\EOTM\STX\SOH\ENQ\DC2\EOT\204\EOT\v\DLE\n\ \\r\n\ - \\ENQ\EOTF\STX\SOH\SOH\DC2\EOT\135\EOT\DC1\GS\n\ + \\ENQ\EOTM\STX\SOH\SOH\DC2\EOT\204\EOT\DC1\GS\n\ \\r\n\ - \\ENQ\EOTF\STX\SOH\ETX\DC2\EOT\135\EOT !\n\ + \\ENQ\EOTM\STX\SOH\ETX\DC2\EOT\204\EOT !\n\ \K\n\ - \\EOT\EOTF\STX\STX\DC2\EOT\136\EOT\STX%\"= The delegation part of the address should match this value.\n\ + \\EOT\EOTM\STX\STX\DC2\EOT\205\EOT\STX%\"= The delegation part of the address should match this value.\n\ \\n\ \\r\n\ - \\ENQ\EOTF\STX\STX\EOT\DC2\EOT\136\EOT\STX\n\ + \\ENQ\EOTM\STX\STX\EOT\DC2\EOT\205\EOT\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTF\STX\STX\ENQ\DC2\EOT\136\EOT\v\DLE\n\ + \\ENQ\EOTM\STX\STX\ENQ\DC2\EOT\205\EOT\v\DLE\n\ \\r\n\ - \\ENQ\EOTF\STX\STX\SOH\DC2\EOT\136\EOT\DC1 \n\ + \\ENQ\EOTM\STX\STX\SOH\DC2\EOT\205\EOT\DC1 \n\ \\r\n\ - \\ENQ\EOTF\STX\STX\ETX\DC2\EOT\136\EOT#$\n\ + \\ENQ\EOTM\STX\STX\ETX\DC2\EOT\205\EOT#$\n\ \[\n\ - \\STX\EOTG\DC2\ACK\140\EOT\NUL\143\EOT\SOH\SUBM Pattern of a native asset that can be used to evaluate matching predicates.\n\ + \\STX\EOTN\DC2\ACK\209\EOT\NUL\212\EOT\SOH\SUBM Pattern of a native asset that can be used to evaluate matching predicates.\n\ \\n\ \\v\n\ - \\ETX\EOTG\SOH\DC2\EOT\140\EOT\b\DC4\n\ + \\ETX\EOTN\SOH\DC2\EOT\209\EOT\b\DC4\n\ \9\n\ - \\EOT\EOTG\STX\NUL\DC2\EOT\141\EOT\STX\US\"+ The asset should belong to this policy id\n\ + \\EOT\EOTN\STX\NUL\DC2\EOT\210\EOT\STX\US\"+ The asset should belong to this policy id\n\ \\n\ \\r\n\ - \\ENQ\EOTG\STX\NUL\EOT\DC2\EOT\141\EOT\STX\n\ + \\ENQ\EOTN\STX\NUL\EOT\DC2\EOT\210\EOT\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTG\STX\NUL\ENQ\DC2\EOT\141\EOT\v\DLE\n\ + \\ENQ\EOTN\STX\NUL\ENQ\DC2\EOT\210\EOT\v\DLE\n\ \\r\n\ - \\ENQ\EOTG\STX\NUL\SOH\DC2\EOT\141\EOT\DC1\SUB\n\ + \\ENQ\EOTN\STX\NUL\SOH\DC2\EOT\210\EOT\DC1\SUB\n\ \\r\n\ - \\ENQ\EOTG\STX\NUL\ETX\DC2\EOT\141\EOT\GS\RS\n\ + \\ENQ\EOTN\STX\NUL\ETX\DC2\EOT\210\EOT\GS\RS\n\ \2\n\ - \\EOT\EOTG\STX\SOH\DC2\EOT\142\EOT\STX \"$ The asset should present this name\n\ + \\EOT\EOTN\STX\SOH\DC2\EOT\211\EOT\STX \"$ The asset should present this name\n\ \\n\ \\r\n\ - \\ENQ\EOTG\STX\SOH\EOT\DC2\EOT\142\EOT\STX\n\ + \\ENQ\EOTN\STX\SOH\EOT\DC2\EOT\211\EOT\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTG\STX\SOH\ENQ\DC2\EOT\142\EOT\v\DLE\n\ + \\ENQ\EOTN\STX\SOH\ENQ\DC2\EOT\211\EOT\v\DLE\n\ \\r\n\ - \\ENQ\EOTG\STX\SOH\SOH\DC2\EOT\142\EOT\DC1\ESC\n\ + \\ENQ\EOTN\STX\SOH\SOH\DC2\EOT\211\EOT\DC1\ESC\n\ \\r\n\ - \\ENQ\EOTG\STX\SOH\ETX\DC2\EOT\142\EOT\RS\US\n\ + \\ENQ\EOTN\STX\SOH\ETX\DC2\EOT\211\EOT\RS\US\n\ \Z\n\ - \\STX\EOTH\DC2\ACK\146\EOT\NUL\157\EOT\SOH\SUBL Pattern of a certificate that can be used to evaluate matching predicates.\n\ + \\STX\EOTO\DC2\ACK\215\EOT\NUL\226\EOT\SOH\SUBL Pattern of a certificate that can be used to evaluate matching predicates.\n\ \\n\ \\v\n\ - \\ETX\EOTH\SOH\DC2\EOT\146\EOT\b\SUB\n\ + \\ETX\EOTO\SOH\DC2\EOT\215\EOT\b\SUB\n\ \\SO\n\ - \\EOT\EOTH\b\NUL\DC2\ACK\147\EOT\STX\156\EOT\ETX\n\ + \\EOT\EOTO\b\NUL\DC2\ACK\216\EOT\STX\225\EOT\ETX\n\ \\r\n\ - \\ENQ\EOTH\b\NUL\SOH\DC2\EOT\147\EOT\b\CAN\n\ + \\ENQ\EOTO\b\NUL\SOH\DC2\EOT\216\EOT\b\CAN\n\ \<\n\ - \\EOT\EOTH\STX\NUL\DC2\EOT\148\EOT\EOT+\". Match stake registration for this credential\n\ + \\EOT\EOTO\STX\NUL\DC2\EOT\217\EOT\EOT+\". Match stake registration for this credential\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\NUL\ACK\DC2\EOT\148\EOT\EOT\DC3\n\ + \\ENQ\EOTO\STX\NUL\ACK\DC2\EOT\217\EOT\EOT\DC3\n\ \\r\n\ - \\ENQ\EOTH\STX\NUL\SOH\DC2\EOT\148\EOT\DC4&\n\ + \\ENQ\EOTO\STX\NUL\SOH\DC2\EOT\217\EOT\DC4&\n\ \\r\n\ - \\ENQ\EOTH\STX\NUL\ETX\DC2\EOT\148\EOT)*\n\ + \\ENQ\EOTO\STX\NUL\ETX\DC2\EOT\217\EOT)*\n\ \>\n\ - \\EOT\EOTH\STX\SOH\DC2\EOT\149\EOT\EOT-\"0 Match stake deregistration for this credential\n\ + \\EOT\EOTO\STX\SOH\DC2\EOT\218\EOT\EOT-\"0 Match stake deregistration for this credential\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\SOH\ACK\DC2\EOT\149\EOT\EOT\DC3\n\ + \\ENQ\EOTO\STX\SOH\ACK\DC2\EOT\218\EOT\EOT\DC3\n\ \\r\n\ - \\ENQ\EOTH\STX\SOH\SOH\DC2\EOT\149\EOT\DC4(\n\ + \\ENQ\EOTO\STX\SOH\SOH\DC2\EOT\218\EOT\DC4(\n\ \\r\n\ - \\ENQ\EOTH\STX\SOH\ETX\DC2\EOT\149\EOT+,\n\ + \\ENQ\EOTO\STX\SOH\ETX\DC2\EOT\218\EOT+,\n\ \.\n\ - \\EOT\EOTH\STX\STX\DC2\EOT\150\EOT\EOT0\" Match stake delegation pattern\n\ + \\EOT\EOTO\STX\STX\DC2\EOT\219\EOT\EOT0\" Match stake delegation pattern\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\STX\ACK\DC2\EOT\150\EOT\EOT\SUB\n\ + \\ENQ\EOTO\STX\STX\ACK\DC2\EOT\219\EOT\EOT\SUB\n\ \\r\n\ - \\ENQ\EOTH\STX\STX\SOH\DC2\EOT\150\EOT\ESC+\n\ + \\ENQ\EOTO\STX\STX\SOH\DC2\EOT\219\EOT\ESC+\n\ \\r\n\ - \\ENQ\EOTH\STX\STX\ETX\DC2\EOT\150\EOT./\n\ + \\ENQ\EOTO\STX\STX\ETX\DC2\EOT\219\EOT./\n\ \/\n\ - \\EOT\EOTH\STX\ETX\DC2\EOT\151\EOT\EOT2\"! Match pool registration pattern\n\ + \\EOT\EOTO\STX\ETX\DC2\EOT\220\EOT\EOT2\"! Match pool registration pattern\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\ETX\ACK\DC2\EOT\151\EOT\EOT\ESC\n\ + \\ENQ\EOTO\STX\ETX\ACK\DC2\EOT\220\EOT\EOT\ESC\n\ \\r\n\ - \\ENQ\EOTH\STX\ETX\SOH\DC2\EOT\151\EOT\FS-\n\ + \\ENQ\EOTO\STX\ETX\SOH\DC2\EOT\220\EOT\FS-\n\ \\r\n\ - \\ENQ\EOTH\STX\ETX\ETX\DC2\EOT\151\EOT01\n\ + \\ENQ\EOTO\STX\ETX\ETX\DC2\EOT\220\EOT01\n\ \-\n\ - \\EOT\EOTH\STX\EOT\DC2\EOT\152\EOT\EOT.\"\US Match pool retirement pattern\n\ + \\EOT\EOTO\STX\EOT\DC2\EOT\221\EOT\EOT.\"\US Match pool retirement pattern\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\EOT\ACK\DC2\EOT\152\EOT\EOT\EM\n\ + \\ENQ\EOTO\STX\EOT\ACK\DC2\EOT\221\EOT\EOT\EM\n\ \\r\n\ - \\ENQ\EOTH\STX\EOT\SOH\DC2\EOT\152\EOT\SUB)\n\ + \\ENQ\EOTO\STX\EOT\SOH\DC2\EOT\221\EOT\SUB)\n\ \\r\n\ - \\ENQ\EOTH\STX\EOT\ETX\DC2\EOT\152\EOT,-\n\ + \\ENQ\EOTO\STX\EOT\ETX\DC2\EOT\221\EOT,-\n\ \E\n\ - \\EOT\EOTH\STX\ENQ\DC2\EOT\153\EOT\EOT#\"7 Match any certificate involving this stake credential\n\ + \\EOT\EOTO\STX\ENQ\DC2\EOT\222\EOT\EOT#\"7 Match any certificate involving this stake credential\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\ENQ\ENQ\DC2\EOT\153\EOT\EOT\t\n\ + \\ENQ\EOTO\STX\ENQ\ENQ\DC2\EOT\222\EOT\EOT\t\n\ \\r\n\ - \\ENQ\EOTH\STX\ENQ\SOH\DC2\EOT\153\EOT\n\ + \\ENQ\EOTO\STX\ENQ\SOH\DC2\EOT\222\EOT\n\ \\RS\n\ \\r\n\ - \\ENQ\EOTH\STX\ENQ\ETX\DC2\EOT\153\EOT!\"\n\ + \\ENQ\EOTO\STX\ENQ\ETX\DC2\EOT\222\EOT!\"\n\ \9\n\ - \\EOT\EOTH\STX\ACK\DC2\EOT\154\EOT\EOT\US\"+ Match any certificate involving this pool\n\ + \\EOT\EOTO\STX\ACK\DC2\EOT\223\EOT\EOT\US\"+ Match any certificate involving this pool\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\ACK\ENQ\DC2\EOT\154\EOT\EOT\t\n\ + \\ENQ\EOTO\STX\ACK\ENQ\DC2\EOT\223\EOT\EOT\t\n\ \\r\n\ - \\ENQ\EOTH\STX\ACK\SOH\DC2\EOT\154\EOT\n\ + \\ENQ\EOTO\STX\ACK\SOH\DC2\EOT\223\EOT\n\ \\SUB\n\ \\r\n\ - \\ENQ\EOTH\STX\ACK\ETX\DC2\EOT\154\EOT\GS\RS\n\ + \\ENQ\EOTO\STX\ACK\ETX\DC2\EOT\223\EOT\GS\RS\n\ \9\n\ - \\EOT\EOTH\STX\a\DC2\EOT\155\EOT\EOT\ETB\"+ Match any certificate involving this DRep\n\ + \\EOT\EOTO\STX\a\DC2\EOT\224\EOT\EOT\ETB\"+ Match any certificate involving this DRep\n\ \\n\ \\r\n\ - \\ENQ\EOTH\STX\a\ENQ\DC2\EOT\155\EOT\EOT\t\n\ + \\ENQ\EOTO\STX\a\ENQ\DC2\EOT\224\EOT\EOT\t\n\ \\r\n\ - \\ENQ\EOTH\STX\a\SOH\DC2\EOT\155\EOT\n\ + \\ENQ\EOTO\STX\a\SOH\DC2\EOT\224\EOT\n\ \\DC2\n\ \\r\n\ - \\ENQ\EOTH\STX\a\ETX\DC2\EOT\155\EOT\NAK\SYN\n\ + \\ENQ\EOTO\STX\a\ETX\DC2\EOT\224\EOT\NAK\SYN\n\ \9\n\ - \\STX\EOTI\DC2\ACK\160\EOT\NUL\163\EOT\SOH\SUB+ Pattern for stake delegation certificates\n\ + \\STX\EOTP\DC2\ACK\229\EOT\NUL\232\EOT\SOH\SUB+ Pattern for stake delegation certificates\n\ \\n\ \\v\n\ - \\ETX\EOTI\SOH\DC2\EOT\160\EOT\b\RS\n\ + \\ETX\EOTP\SOH\DC2\EOT\229\EOT\b\RS\n\ \6\n\ - \\EOT\EOTI\STX\NUL\DC2\EOT\161\EOT\STX'\"( Match delegations from this credential\n\ + \\EOT\EOTP\STX\NUL\DC2\EOT\230\EOT\STX'\"( Match delegations from this credential\n\ \\n\ \\r\n\ - \\ENQ\EOTI\STX\NUL\ACK\DC2\EOT\161\EOT\STX\DC1\n\ + \\ENQ\EOTP\STX\NUL\ACK\DC2\EOT\230\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTI\STX\NUL\SOH\DC2\EOT\161\EOT\DC2\"\n\ + \\ENQ\EOTP\STX\NUL\SOH\DC2\EOT\230\EOT\DC2\"\n\ \\r\n\ - \\ENQ\EOTI\STX\NUL\ETX\DC2\EOT\161\EOT%&\n\ + \\ENQ\EOTP\STX\NUL\ETX\DC2\EOT\230\EOT%&\n\ \.\n\ - \\EOT\EOTI\STX\SOH\DC2\EOT\162\EOT\STX\EM\" Match delegations to this pool\n\ + \\EOT\EOTP\STX\SOH\DC2\EOT\231\EOT\STX\EM\" Match delegations to this pool\n\ \\n\ \\r\n\ - \\ENQ\EOTI\STX\SOH\ENQ\DC2\EOT\162\EOT\STX\a\n\ + \\ENQ\EOTP\STX\SOH\ENQ\DC2\EOT\231\EOT\STX\a\n\ \\r\n\ - \\ENQ\EOTI\STX\SOH\SOH\DC2\EOT\162\EOT\b\DC4\n\ + \\ENQ\EOTP\STX\SOH\SOH\DC2\EOT\231\EOT\b\DC4\n\ \\r\n\ - \\ENQ\EOTI\STX\SOH\ETX\DC2\EOT\162\EOT\ETB\CAN\n\ + \\ENQ\EOTP\STX\SOH\ETX\DC2\EOT\231\EOT\ETB\CAN\n\ \:\n\ - \\STX\EOTJ\DC2\ACK\166\EOT\NUL\169\EOT\SOH\SUB, Pattern for pool registration certificates\n\ + \\STX\EOTQ\DC2\ACK\235\EOT\NUL\238\EOT\SOH\SUB, Pattern for pool registration certificates\n\ \\n\ \\v\n\ - \\ETX\EOTJ\SOH\DC2\EOT\166\EOT\b\US\n\ + \\ETX\EOTQ\SOH\DC2\EOT\235\EOT\b\US\n\ \4\n\ - \\EOT\EOTJ\STX\NUL\DC2\EOT\167\EOT\STX\NAK\"& Match registrations by this operator\n\ + \\EOT\EOTQ\STX\NUL\DC2\EOT\236\EOT\STX\NAK\"& Match registrations by this operator\n\ \\n\ \\r\n\ - \\ENQ\EOTJ\STX\NUL\ENQ\DC2\EOT\167\EOT\STX\a\n\ + \\ENQ\EOTQ\STX\NUL\ENQ\DC2\EOT\236\EOT\STX\a\n\ \\r\n\ - \\ENQ\EOTJ\STX\NUL\SOH\DC2\EOT\167\EOT\b\DLE\n\ + \\ENQ\EOTQ\STX\NUL\SOH\DC2\EOT\236\EOT\b\DLE\n\ \\r\n\ - \\ENQ\EOTJ\STX\NUL\ETX\DC2\EOT\167\EOT\DC3\DC4\n\ + \\ENQ\EOTQ\STX\NUL\ETX\DC2\EOT\236\EOT\DC3\DC4\n\ \I\n\ - \\EOT\EOTJ\STX\SOH\DC2\EOT\168\EOT\STX\EM\"; Match registrations for this pool (derived from operator)\n\ + \\EOT\EOTQ\STX\SOH\DC2\EOT\237\EOT\STX\EM\"; Match registrations for this pool (derived from operator)\n\ \\n\ \\r\n\ - \\ENQ\EOTJ\STX\SOH\ENQ\DC2\EOT\168\EOT\STX\a\n\ + \\ENQ\EOTQ\STX\SOH\ENQ\DC2\EOT\237\EOT\STX\a\n\ \\r\n\ - \\ENQ\EOTJ\STX\SOH\SOH\DC2\EOT\168\EOT\b\DC4\n\ + \\ENQ\EOTQ\STX\SOH\SOH\DC2\EOT\237\EOT\b\DC4\n\ \\r\n\ - \\ENQ\EOTJ\STX\SOH\ETX\DC2\EOT\168\EOT\ETB\CAN\n\ + \\ENQ\EOTQ\STX\SOH\ETX\DC2\EOT\237\EOT\ETB\CAN\n\ \8\n\ - \\STX\EOTK\DC2\ACK\172\EOT\NUL\175\EOT\SOH\SUB* Pattern for pool retirement certificates\n\ + \\STX\EOTR\DC2\ACK\241\EOT\NUL\244\EOT\SOH\SUB* Pattern for pool retirement certificates\n\ \\n\ \\v\n\ - \\ETX\EOTK\SOH\DC2\EOT\172\EOT\b\GS\n\ + \\ETX\EOTR\SOH\DC2\EOT\241\EOT\b\GS\n\ \.\n\ - \\EOT\EOTK\STX\NUL\DC2\EOT\173\EOT\STX\EM\" Match retirements of this pool\n\ + \\EOT\EOTR\STX\NUL\DC2\EOT\242\EOT\STX\EM\" Match retirements of this pool\n\ \\n\ \\r\n\ - \\ENQ\EOTK\STX\NUL\ENQ\DC2\EOT\173\EOT\STX\a\n\ + \\ENQ\EOTR\STX\NUL\ENQ\DC2\EOT\242\EOT\STX\a\n\ \\r\n\ - \\ENQ\EOTK\STX\NUL\SOH\DC2\EOT\173\EOT\b\DC4\n\ + \\ENQ\EOTR\STX\NUL\SOH\DC2\EOT\242\EOT\b\DC4\n\ \\r\n\ - \\ENQ\EOTK\STX\NUL\ETX\DC2\EOT\173\EOT\ETB\CAN\n\ + \\ENQ\EOTR\STX\NUL\ETX\DC2\EOT\242\EOT\ETB\CAN\n\ \/\n\ - \\EOT\EOTK\STX\SOH\DC2\EOT\174\EOT\STX\DC3\"! Match retirements in this epoch\n\ + \\EOT\EOTR\STX\SOH\DC2\EOT\243\EOT\STX\DC3\"! Match retirements in this epoch\n\ \\n\ \\r\n\ - \\ENQ\EOTK\STX\SOH\ENQ\DC2\EOT\174\EOT\STX\b\n\ + \\ENQ\EOTR\STX\SOH\ENQ\DC2\EOT\243\EOT\STX\b\n\ \\r\n\ - \\ENQ\EOTK\STX\SOH\SOH\DC2\EOT\174\EOT\t\SO\n\ + \\ENQ\EOTR\STX\SOH\SOH\DC2\EOT\243\EOT\t\SO\n\ \\r\n\ - \\ENQ\EOTK\STX\SOH\ETX\DC2\EOT\174\EOT\DC1\DC2\n\ + \\ENQ\EOTR\STX\SOH\ETX\DC2\EOT\243\EOT\DC1\DC2\n\ \X\n\ - \\STX\EOTL\DC2\ACK\178\EOT\NUL\181\EOT\SOH\SUBJ Pattern of a tx output that can be used to evaluate matching predicates.\n\ + \\STX\EOTS\DC2\ACK\247\EOT\NUL\250\EOT\SOH\SUBJ Pattern of a tx output that can be used to evaluate matching predicates.\n\ \\n\ \\v\n\ - \\ETX\EOTL\SOH\DC2\EOT\178\EOT\b\ETB\n\ + \\ETX\EOTS\SOH\DC2\EOT\247\EOT\b\ETB\n\ \K\n\ - \\EOT\EOTL\STX\NUL\DC2\EOT\179\EOT\STX&\"= Match any address in the output that exhibits this pattern.\n\ + \\EOT\EOTS\STX\NUL\DC2\EOT\248\EOT\STX&\"= Match any address in the output that exhibits this pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTL\STX\NUL\EOT\DC2\EOT\179\EOT\STX\n\ + \\ENQ\EOTS\STX\NUL\EOT\DC2\EOT\248\EOT\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTL\STX\NUL\ACK\DC2\EOT\179\EOT\v\EM\n\ + \\ENQ\EOTS\STX\NUL\ACK\DC2\EOT\248\EOT\v\EM\n\ \\r\n\ - \\ENQ\EOTL\STX\NUL\SOH\DC2\EOT\179\EOT\SUB!\n\ + \\ENQ\EOTS\STX\NUL\SOH\DC2\EOT\248\EOT\SUB!\n\ \\r\n\ - \\ENQ\EOTL\STX\NUL\ETX\DC2\EOT\179\EOT$%\n\ + \\ENQ\EOTS\STX\NUL\ETX\DC2\EOT\248\EOT$%\n\ \I\n\ - \\EOT\EOTL\STX\SOH\DC2\EOT\180\EOT\STX\"\"; Match any asset in the output that exhibits this pattern.\n\ + \\EOT\EOTS\STX\SOH\DC2\EOT\249\EOT\STX\"\"; Match any asset in the output that exhibits this pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTL\STX\SOH\EOT\DC2\EOT\180\EOT\STX\n\ + \\ENQ\EOTS\STX\SOH\EOT\DC2\EOT\249\EOT\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTL\STX\SOH\ACK\DC2\EOT\180\EOT\v\ETB\n\ + \\ENQ\EOTS\STX\SOH\ACK\DC2\EOT\249\EOT\v\ETB\n\ \\r\n\ - \\ENQ\EOTL\STX\SOH\SOH\DC2\EOT\180\EOT\CAN\GS\n\ + \\ENQ\EOTS\STX\SOH\SOH\DC2\EOT\249\EOT\CAN\GS\n\ \\r\n\ - \\ENQ\EOTL\STX\SOH\ETX\DC2\EOT\180\EOT !\n\ + \\ENQ\EOTS\STX\SOH\ETX\DC2\EOT\249\EOT !\n\ \Q\n\ - \\STX\EOTM\DC2\ACK\184\EOT\NUL\191\EOT\SOH\SUBC Pattern of a Tx that can be used to evaluate matching predicates.\n\ + \\STX\EOTT\DC2\ACK\253\EOT\NUL\132\ENQ\SOH\SUBC Pattern of a Tx that can be used to evaluate matching predicates.\n\ \\n\ \\v\n\ - \\ETX\EOTM\SOH\DC2\EOT\184\EOT\b\DC1\n\ + \\ETX\EOTT\SOH\DC2\EOT\253\EOT\b\DC1\n\ \;\n\ - \\EOT\EOTM\STX\NUL\DC2\EOT\185\EOT\STX\US\"- Match any input that exhibits this pattern.\n\ + \\EOT\EOTT\STX\NUL\DC2\EOT\254\EOT\STX\US\"- Match any input that exhibits this pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTM\STX\NUL\ACK\DC2\EOT\185\EOT\STX\DC1\n\ + \\ENQ\EOTT\STX\NUL\ACK\DC2\EOT\254\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTM\STX\NUL\SOH\DC2\EOT\185\EOT\DC2\SUB\n\ + \\ENQ\EOTT\STX\NUL\SOH\DC2\EOT\254\EOT\DC2\SUB\n\ \\r\n\ - \\ENQ\EOTM\STX\NUL\ETX\DC2\EOT\185\EOT\GS\RS\n\ + \\ENQ\EOTT\STX\NUL\ETX\DC2\EOT\254\EOT\GS\RS\n\ \<\n\ - \\EOT\EOTM\STX\SOH\DC2\EOT\186\EOT\STX\US\". Match any output that exhibits this pattern.\n\ + \\EOT\EOTT\STX\SOH\DC2\EOT\255\EOT\STX\US\". Match any output that exhibits this pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTM\STX\SOH\ACK\DC2\EOT\186\EOT\STX\DC1\n\ + \\ENQ\EOTT\STX\SOH\ACK\DC2\EOT\255\EOT\STX\DC1\n\ \\r\n\ - \\ENQ\EOTM\STX\SOH\SOH\DC2\EOT\186\EOT\DC2\SUB\n\ + \\ENQ\EOTT\STX\SOH\SOH\DC2\EOT\255\EOT\DC2\SUB\n\ \\r\n\ - \\ENQ\EOTM\STX\SOH\ETX\DC2\EOT\186\EOT\GS\RS\n\ + \\ENQ\EOTT\STX\SOH\ETX\DC2\EOT\255\EOT\GS\RS\n\ \`\n\ - \\EOT\EOTM\STX\STX\DC2\EOT\187\EOT\STX!\"R Match any address (inputs, outputs, collateral, etc) that exhibits this pattern.\n\ + \\EOT\EOTT\STX\STX\DC2\EOT\128\ENQ\STX!\"R Match any address (inputs, outputs, collateral, etc) that exhibits this pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTM\STX\STX\ACK\DC2\EOT\187\EOT\STX\DLE\n\ + \\ENQ\EOTT\STX\STX\ACK\DC2\EOT\128\ENQ\STX\DLE\n\ \\r\n\ - \\ENQ\EOTM\STX\STX\SOH\DC2\EOT\187\EOT\DC1\FS\n\ + \\ENQ\EOTT\STX\STX\SOH\DC2\EOT\128\ENQ\DC1\FS\n\ \\r\n\ - \\ENQ\EOTM\STX\STX\ETX\DC2\EOT\187\EOT\US \n\ + \\ENQ\EOTT\STX\STX\ETX\DC2\EOT\128\ENQ\US \n\ \;\n\ - \\EOT\EOTM\STX\ETX\DC2\EOT\188\EOT\STX\US\"- Match any asset that exhibits this pattern.\n\ + \\EOT\EOTT\STX\ETX\DC2\EOT\129\ENQ\STX\US\"- Match any asset that exhibits this pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTM\STX\ETX\ACK\DC2\EOT\188\EOT\STX\SO\n\ + \\ENQ\EOTT\STX\ETX\ACK\DC2\EOT\129\ENQ\STX\SO\n\ \\r\n\ - \\ENQ\EOTM\STX\ETX\SOH\DC2\EOT\188\EOT\SI\SUB\n\ + \\ENQ\EOTT\STX\ETX\SOH\DC2\EOT\129\ENQ\SI\SUB\n\ \\r\n\ - \\ENQ\EOTM\STX\ETX\ETX\DC2\EOT\188\EOT\GS\RS\n\ + \\ENQ\EOTT\STX\ETX\ETX\DC2\EOT\129\ENQ\GS\RS\n\ \L\n\ - \\EOT\EOTM\STX\EOT\DC2\EOT\189\EOT\STX\US\"> Match any tx that either mint or burn the the asset pattern.\n\ + \\EOT\EOTT\STX\EOT\DC2\EOT\130\ENQ\STX\US\"> Match any tx that either mint or burn the the asset pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTM\STX\EOT\ACK\DC2\EOT\189\EOT\STX\SO\n\ + \\ENQ\EOTT\STX\EOT\ACK\DC2\EOT\130\ENQ\STX\SO\n\ \\r\n\ - \\ENQ\EOTM\STX\EOT\SOH\DC2\EOT\189\EOT\SI\SUB\n\ + \\ENQ\EOTT\STX\EOT\SOH\DC2\EOT\130\ENQ\SI\SUB\n\ \\r\n\ - \\ENQ\EOTM\STX\EOT\ETX\DC2\EOT\189\EOT\GS\RS\n\ + \\ENQ\EOTT\STX\EOT\ETX\DC2\EOT\130\ENQ\GS\RS\n\ \M\n\ - \\EOT\EOTM\STX\ENQ\DC2\EOT\190\EOT\STX)\"? Match any transaction that includes this certificate pattern.\n\ + \\EOT\EOTT\STX\ENQ\DC2\EOT\131\ENQ\STX)\"? Match any transaction that includes this certificate pattern.\n\ \\n\ \\r\n\ - \\ENQ\EOTM\STX\ENQ\ACK\DC2\EOT\190\EOT\STX\DC4\n\ + \\ENQ\EOTT\STX\ENQ\ACK\DC2\EOT\131\ENQ\STX\DC4\n\ \\r\n\ - \\ENQ\EOTM\STX\ENQ\SOH\DC2\EOT\190\EOT\NAK$\n\ + \\ENQ\EOTT\STX\ENQ\SOH\DC2\EOT\131\ENQ\NAK$\n\ \\r\n\ - \\ENQ\EOTM\STX\ENQ\ETX\DC2\EOT\190\EOT'(\n\ + \\ENQ\EOTT\STX\ENQ\ETX\DC2\EOT\131\ENQ'(\n\ \\RS\n\ - \\STX\EOTN\DC2\ACK\196\EOT\NUL\199\EOT\SOH2\DLE PARAMS\n\ + \\STX\EOTU\DC2\ACK\137\ENQ\NUL\140\ENQ\SOH2\DLE PARAMS\n\ \ ======\n\ \\n\ \\v\n\ - \\ETX\EOTN\SOH\DC2\EOT\196\EOT\b\SI\n\ + \\ETX\EOTU\SOH\DC2\EOT\137\ENQ\b\SI\n\ \\f\n\ - \\EOT\EOTN\STX\NUL\DC2\EOT\197\EOT\STX\DC3\n\ + \\EOT\EOTU\STX\NUL\DC2\EOT\138\ENQ\STX\DC3\n\ \\r\n\ - \\ENQ\EOTN\STX\NUL\ENQ\DC2\EOT\197\EOT\STX\b\n\ + \\ENQ\EOTU\STX\NUL\ENQ\DC2\EOT\138\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTN\STX\NUL\SOH\DC2\EOT\197\EOT\t\SO\n\ + \\ENQ\EOTU\STX\NUL\SOH\DC2\EOT\138\ENQ\t\SO\n\ \\r\n\ - \\ENQ\EOTN\STX\NUL\ETX\DC2\EOT\197\EOT\DC1\DC2\n\ + \\ENQ\EOTU\STX\NUL\ETX\DC2\EOT\138\ENQ\DC1\DC2\n\ \\f\n\ - \\EOT\EOTN\STX\SOH\DC2\EOT\198\EOT\STX\DC4\n\ + \\EOT\EOTU\STX\SOH\DC2\EOT\139\ENQ\STX\DC4\n\ \\r\n\ - \\ENQ\EOTN\STX\SOH\ENQ\DC2\EOT\198\EOT\STX\b\n\ + \\ENQ\EOTU\STX\SOH\ENQ\DC2\EOT\139\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTN\STX\SOH\SOH\DC2\EOT\198\EOT\t\SI\n\ + \\ENQ\EOTU\STX\SOH\SOH\DC2\EOT\139\ENQ\t\SI\n\ \\r\n\ - \\ENQ\EOTN\STX\SOH\ETX\DC2\EOT\198\EOT\DC2\DC3\n\ + \\ENQ\EOTU\STX\SOH\ETX\DC2\EOT\139\ENQ\DC2\DC3\n\ \\f\n\ - \\STX\EOTO\DC2\ACK\201\EOT\NUL\204\EOT\SOH\n\ + \\STX\EOTV\DC2\ACK\142\ENQ\NUL\145\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTO\SOH\DC2\EOT\201\EOT\b\DLE\n\ + \\ETX\EOTV\SOH\DC2\EOT\142\ENQ\b\DLE\n\ \\f\n\ - \\EOT\EOTO\STX\NUL\DC2\EOT\202\EOT\STX\ESC\n\ + \\EOT\EOTV\STX\NUL\DC2\EOT\143\ENQ\STX\ESC\n\ \\r\n\ - \\ENQ\EOTO\STX\NUL\ACK\DC2\EOT\202\EOT\STX\DLE\n\ + \\ENQ\EOTV\STX\NUL\ACK\DC2\EOT\143\ENQ\STX\DLE\n\ \\r\n\ - \\ENQ\EOTO\STX\NUL\SOH\DC2\EOT\202\EOT\DC1\SYN\n\ + \\ENQ\EOTV\STX\NUL\SOH\DC2\EOT\143\ENQ\DC1\SYN\n\ \\r\n\ - \\ENQ\EOTO\STX\NUL\ETX\DC2\EOT\202\EOT\EM\SUB\n\ + \\ENQ\EOTV\STX\NUL\ETX\DC2\EOT\143\ENQ\EM\SUB\n\ \\f\n\ - \\EOT\EOTO\STX\SOH\DC2\EOT\203\EOT\STX\FS\n\ + \\EOT\EOTV\STX\SOH\DC2\EOT\144\ENQ\STX\FS\n\ \\r\n\ - \\ENQ\EOTO\STX\SOH\ACK\DC2\EOT\203\EOT\STX\DLE\n\ + \\ENQ\EOTV\STX\SOH\ACK\DC2\EOT\144\ENQ\STX\DLE\n\ \\r\n\ - \\ENQ\EOTO\STX\SOH\SOH\DC2\EOT\203\EOT\DC1\ETB\n\ + \\ENQ\EOTV\STX\SOH\SOH\DC2\EOT\144\ENQ\DC1\ETB\n\ \\r\n\ - \\ENQ\EOTO\STX\SOH\ETX\DC2\EOT\203\EOT\SUB\ESC\n\ + \\ENQ\EOTV\STX\SOH\ETX\DC2\EOT\144\ENQ\SUB\ESC\n\ \\f\n\ - \\STX\EOTP\DC2\ACK\206\EOT\NUL\209\EOT\SOH\n\ + \\STX\EOTW\DC2\ACK\147\ENQ\NUL\150\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTP\SOH\DC2\EOT\206\EOT\b\ETB\n\ + \\ETX\EOTW\SOH\DC2\EOT\147\ENQ\b\ETB\n\ \\f\n\ - \\EOT\EOTP\STX\NUL\DC2\EOT\207\EOT\STX\DC3\n\ + \\EOT\EOTW\STX\NUL\DC2\EOT\148\ENQ\STX\DC3\n\ \\r\n\ - \\ENQ\EOTP\STX\NUL\ENQ\DC2\EOT\207\EOT\STX\b\n\ + \\ENQ\EOTW\STX\NUL\ENQ\DC2\EOT\148\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTP\STX\NUL\SOH\DC2\EOT\207\EOT\t\SO\n\ + \\ENQ\EOTW\STX\NUL\SOH\DC2\EOT\148\ENQ\t\SO\n\ \\r\n\ - \\ENQ\EOTP\STX\NUL\ETX\DC2\EOT\207\EOT\DC1\DC2\n\ + \\ENQ\EOTW\STX\NUL\ETX\DC2\EOT\148\ENQ\DC1\DC2\n\ \\f\n\ - \\EOT\EOTP\STX\SOH\DC2\EOT\208\EOT\STX\DC3\n\ + \\EOT\EOTW\STX\SOH\DC2\EOT\149\ENQ\STX\DC3\n\ \\r\n\ - \\ENQ\EOTP\STX\SOH\ENQ\DC2\EOT\208\EOT\STX\b\n\ + \\ENQ\EOTW\STX\SOH\ENQ\DC2\EOT\149\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTP\STX\SOH\SOH\DC2\EOT\208\EOT\t\SO\n\ + \\ENQ\EOTW\STX\SOH\SOH\DC2\EOT\149\ENQ\t\SO\n\ \\r\n\ - \\ENQ\EOTP\STX\SOH\ETX\DC2\EOT\208\EOT\DC1\DC2\n\ + \\ENQ\EOTW\STX\SOH\ETX\DC2\EOT\149\ENQ\DC1\DC2\n\ \\f\n\ - \\STX\EOTQ\DC2\ACK\211\EOT\NUL\213\EOT\SOH\n\ + \\STX\EOTX\DC2\ACK\152\ENQ\NUL\154\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTQ\SOH\DC2\EOT\211\EOT\b\DC1\n\ + \\ETX\EOTX\SOH\DC2\EOT\152\ENQ\b\DC1\n\ \\f\n\ - \\EOT\EOTQ\STX\NUL\DC2\EOT\212\EOT\STX\FS\n\ + \\EOT\EOTX\STX\NUL\DC2\EOT\153\ENQ\STX\FS\n\ \\r\n\ - \\ENQ\EOTQ\STX\NUL\EOT\DC2\EOT\212\EOT\STX\n\ + \\ENQ\EOTX\STX\NUL\EOT\DC2\EOT\153\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTQ\STX\NUL\ENQ\DC2\EOT\212\EOT\v\DLE\n\ + \\ENQ\EOTX\STX\NUL\ENQ\DC2\EOT\153\ENQ\v\DLE\n\ \\r\n\ - \\ENQ\EOTQ\STX\NUL\SOH\DC2\EOT\212\EOT\DC1\ETB\n\ + \\ENQ\EOTX\STX\NUL\SOH\DC2\EOT\153\ENQ\DC1\ETB\n\ \\r\n\ - \\ENQ\EOTQ\STX\NUL\ETX\DC2\EOT\212\EOT\SUB\ESC\n\ + \\ENQ\EOTX\STX\NUL\ETX\DC2\EOT\153\ENQ\SUB\ESC\n\ \\f\n\ - \\STX\EOTR\DC2\ACK\215\EOT\NUL\220\EOT\SOH\n\ + \\STX\EOTY\DC2\ACK\156\ENQ\NUL\161\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTR\SOH\DC2\EOT\215\EOT\b\DC2\n\ + \\ETX\EOTY\SOH\DC2\EOT\156\ENQ\b\DC2\n\ \\f\n\ - \\EOT\EOTR\STX\NUL\DC2\EOT\216\EOT\STX\SUB\n\ + \\EOT\EOTY\STX\NUL\DC2\EOT\157\ENQ\STX\SUB\n\ \\r\n\ - \\ENQ\EOTR\STX\NUL\ACK\DC2\EOT\216\EOT\STX\v\n\ + \\ENQ\EOTY\STX\NUL\ACK\DC2\EOT\157\ENQ\STX\v\n\ \\r\n\ - \\ENQ\EOTR\STX\NUL\SOH\DC2\EOT\216\EOT\f\NAK\n\ + \\ENQ\EOTY\STX\NUL\SOH\DC2\EOT\157\ENQ\f\NAK\n\ \\r\n\ - \\ENQ\EOTR\STX\NUL\ETX\DC2\EOT\216\EOT\CAN\EM\n\ + \\ENQ\EOTY\STX\NUL\ETX\DC2\EOT\157\ENQ\CAN\EM\n\ \\f\n\ - \\EOT\EOTR\STX\SOH\DC2\EOT\217\EOT\STX\SUB\n\ + \\EOT\EOTY\STX\SOH\DC2\EOT\158\ENQ\STX\SUB\n\ \\r\n\ - \\ENQ\EOTR\STX\SOH\ACK\DC2\EOT\217\EOT\STX\v\n\ + \\ENQ\EOTY\STX\SOH\ACK\DC2\EOT\158\ENQ\STX\v\n\ \\r\n\ - \\ENQ\EOTR\STX\SOH\SOH\DC2\EOT\217\EOT\f\NAK\n\ + \\ENQ\EOTY\STX\SOH\SOH\DC2\EOT\158\ENQ\f\NAK\n\ \\r\n\ - \\ENQ\EOTR\STX\SOH\ETX\DC2\EOT\217\EOT\CAN\EM\n\ + \\ENQ\EOTY\STX\SOH\ETX\DC2\EOT\158\ENQ\CAN\EM\n\ \\f\n\ - \\EOT\EOTR\STX\STX\DC2\EOT\218\EOT\STX\SUB\n\ + \\EOT\EOTY\STX\STX\DC2\EOT\159\ENQ\STX\SUB\n\ \\r\n\ - \\ENQ\EOTR\STX\STX\ACK\DC2\EOT\218\EOT\STX\v\n\ + \\ENQ\EOTY\STX\STX\ACK\DC2\EOT\159\ENQ\STX\v\n\ \\r\n\ - \\ENQ\EOTR\STX\STX\SOH\DC2\EOT\218\EOT\f\NAK\n\ + \\ENQ\EOTY\STX\STX\SOH\DC2\EOT\159\ENQ\f\NAK\n\ \\r\n\ - \\ENQ\EOTR\STX\STX\ETX\DC2\EOT\218\EOT\CAN\EM\n\ + \\ENQ\EOTY\STX\STX\ETX\DC2\EOT\159\ENQ\CAN\EM\n\ \\f\n\ - \\EOT\EOTR\STX\ETX\DC2\EOT\219\EOT\STX\SUB\n\ + \\EOT\EOTY\STX\ETX\DC2\EOT\160\ENQ\STX\SUB\n\ \\r\n\ - \\ENQ\EOTR\STX\ETX\ACK\DC2\EOT\219\EOT\STX\v\n\ + \\ENQ\EOTY\STX\ETX\ACK\DC2\EOT\160\ENQ\STX\v\n\ \\r\n\ - \\ENQ\EOTR\STX\ETX\SOH\DC2\EOT\219\EOT\f\NAK\n\ + \\ENQ\EOTY\STX\ETX\SOH\DC2\EOT\160\ENQ\f\NAK\n\ \\r\n\ - \\ENQ\EOTR\STX\ETX\ETX\DC2\EOT\219\EOT\CAN\EM\n\ + \\ENQ\EOTY\STX\ETX\ETX\DC2\EOT\160\ENQ\CAN\EM\n\ \\f\n\ - \\STX\EOTS\DC2\ACK\222\EOT\NUL\224\EOT\SOH\n\ + \\STX\EOTZ\DC2\ACK\163\ENQ\NUL\165\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTS\SOH\DC2\EOT\222\EOT\b\CAN\n\ + \\ETX\EOTZ\SOH\DC2\EOT\163\ENQ\b\CAN\n\ \\f\n\ - \\EOT\EOTS\STX\NUL\DC2\EOT\223\EOT\STX)\n\ + \\EOT\EOTZ\STX\NUL\DC2\EOT\164\ENQ\STX)\n\ \\r\n\ - \\ENQ\EOTS\STX\NUL\EOT\DC2\EOT\223\EOT\STX\n\ + \\ENQ\EOTZ\STX\NUL\EOT\DC2\EOT\164\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTS\STX\NUL\ACK\DC2\EOT\223\EOT\v\EM\n\ + \\ENQ\EOTZ\STX\NUL\ACK\DC2\EOT\164\ENQ\v\EM\n\ \\r\n\ - \\ENQ\EOTS\STX\NUL\SOH\DC2\EOT\223\EOT\SUB$\n\ + \\ENQ\EOTZ\STX\NUL\SOH\DC2\EOT\164\ENQ\SUB$\n\ \\r\n\ - \\ENQ\EOTS\STX\NUL\ETX\DC2\EOT\223\EOT'(\n\ + \\ENQ\EOTZ\STX\NUL\ETX\DC2\EOT\164\ENQ'(\n\ \\f\n\ - \\STX\EOTT\DC2\ACK\226\EOT\NUL\130\ENQ\SOH\n\ + \\STX\EOT[\DC2\ACK\167\ENQ\NUL\199\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTT\SOH\DC2\EOT\226\EOT\b\SI\n\ + \\ETX\EOT[\SOH\DC2\EOT\167\ENQ\b\SI\n\ \2\n\ - \\EOT\EOTT\STX\NUL\DC2\EOT\227\EOT\STX!\"$ The number of coins per UTXO byte.\n\ + \\EOT\EOT[\STX\NUL\DC2\EOT\168\ENQ\STX!\"$ The number of coins per UTXO byte.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\NUL\ACK\DC2\EOT\227\EOT\STX\b\n\ + \\ENQ\EOT[\STX\NUL\ACK\DC2\EOT\168\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\NUL\SOH\DC2\EOT\227\EOT\t\FS\n\ + \\ENQ\EOT[\STX\NUL\SOH\DC2\EOT\168\ENQ\t\FS\n\ \\r\n\ - \\ENQ\EOTT\STX\NUL\ETX\DC2\EOT\227\EOT\US \n\ + \\ENQ\EOT[\STX\NUL\ETX\DC2\EOT\168\ENQ\US \n\ \-\n\ - \\EOT\EOTT\STX\SOH\DC2\EOT\228\EOT\STX\EM\"\US The maximum transaction size.\n\ + \\EOT\EOT[\STX\SOH\DC2\EOT\169\ENQ\STX\EM\"\US The maximum transaction size.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\SOH\ENQ\DC2\EOT\228\EOT\STX\b\n\ + \\ENQ\EOT[\STX\SOH\ENQ\DC2\EOT\169\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\SOH\SOH\DC2\EOT\228\EOT\t\DC4\n\ + \\ENQ\EOT[\STX\SOH\SOH\DC2\EOT\169\ENQ\t\DC4\n\ \\r\n\ - \\ENQ\EOTT\STX\SOH\ETX\DC2\EOT\228\EOT\ETB\CAN\n\ + \\ENQ\EOT[\STX\SOH\ETX\DC2\EOT\169\ENQ\ETB\CAN\n\ \,\n\ - \\EOT\EOTT\STX\STX\DC2\EOT\229\EOT\STX!\"\RS The minimum fee coefficient.\n\ + \\EOT\EOT[\STX\STX\DC2\EOT\170\ENQ\STX!\"\RS The minimum fee coefficient.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\STX\ACK\DC2\EOT\229\EOT\STX\b\n\ + \\ENQ\EOT[\STX\STX\ACK\DC2\EOT\170\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\STX\SOH\DC2\EOT\229\EOT\t\FS\n\ + \\ENQ\EOT[\STX\STX\SOH\DC2\EOT\170\ENQ\t\FS\n\ \\r\n\ - \\ENQ\EOTT\STX\STX\ETX\DC2\EOT\229\EOT\US \n\ + \\ENQ\EOT[\STX\STX\ETX\DC2\EOT\170\ENQ\US \n\ \)\n\ - \\EOT\EOTT\STX\ETX\DC2\EOT\230\EOT\STX\RS\"\ESC The minimum fee constant.\n\ + \\EOT\EOT[\STX\ETX\DC2\EOT\171\ENQ\STX\RS\"\ESC The minimum fee constant.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\ETX\ACK\DC2\EOT\230\EOT\STX\b\n\ + \\ENQ\EOT[\STX\ETX\ACK\DC2\EOT\171\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\ETX\SOH\DC2\EOT\230\EOT\t\EM\n\ + \\ENQ\EOT[\STX\ETX\SOH\DC2\EOT\171\ENQ\t\EM\n\ \\r\n\ - \\ENQ\EOTT\STX\ETX\ETX\DC2\EOT\230\EOT\FS\GS\n\ + \\ENQ\EOT[\STX\ETX\ETX\DC2\EOT\171\ENQ\FS\GS\n\ \,\n\ - \\EOT\EOTT\STX\EOT\DC2\EOT\231\EOT\STX!\"\RS The maximum block body size.\n\ + \\EOT\EOT[\STX\EOT\DC2\EOT\172\ENQ\STX!\"\RS The maximum block body size.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\EOT\ENQ\DC2\EOT\231\EOT\STX\b\n\ + \\ENQ\EOT[\STX\EOT\ENQ\DC2\EOT\172\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\EOT\SOH\DC2\EOT\231\EOT\t\FS\n\ + \\ENQ\EOT[\STX\EOT\SOH\DC2\EOT\172\ENQ\t\FS\n\ \\r\n\ - \\ENQ\EOTT\STX\EOT\ETX\DC2\EOT\231\EOT\US \n\ + \\ENQ\EOT[\STX\EOT\ETX\DC2\EOT\172\ENQ\US \n\ \.\n\ - \\EOT\EOTT\STX\ENQ\DC2\EOT\232\EOT\STX#\" The maximum block header size.\n\ + \\EOT\EOT[\STX\ENQ\DC2\EOT\173\ENQ\STX#\" The maximum block header size.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\ENQ\ENQ\DC2\EOT\232\EOT\STX\b\n\ + \\ENQ\EOT[\STX\ENQ\ENQ\DC2\EOT\173\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\ENQ\SOH\DC2\EOT\232\EOT\t\RS\n\ + \\ENQ\EOT[\STX\ENQ\SOH\DC2\EOT\173\ENQ\t\RS\n\ \\r\n\ - \\ENQ\EOTT\STX\ENQ\ETX\DC2\EOT\232\EOT!\"\n\ + \\ENQ\EOT[\STX\ENQ\ETX\DC2\EOT\173\ENQ!\"\n\ \&\n\ - \\EOT\EOTT\STX\ACK\DC2\EOT\233\EOT\STX\US\"\CAN The stake key deposit.\n\ + \\EOT\EOT[\STX\ACK\DC2\EOT\174\ENQ\STX\US\"\CAN The stake key deposit.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\ACK\ACK\DC2\EOT\233\EOT\STX\b\n\ + \\ENQ\EOT[\STX\ACK\ACK\DC2\EOT\174\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\ACK\SOH\DC2\EOT\233\EOT\t\SUB\n\ + \\ENQ\EOT[\STX\ACK\SOH\DC2\EOT\174\ENQ\t\SUB\n\ \\r\n\ - \\ENQ\EOTT\STX\ACK\ETX\DC2\EOT\233\EOT\GS\RS\n\ + \\ENQ\EOT[\STX\ACK\ETX\DC2\EOT\174\ENQ\GS\RS\n\ \!\n\ - \\EOT\EOTT\STX\a\DC2\EOT\234\EOT\STX\SUB\"\DC3 The pool deposit.\n\ + \\EOT\EOT[\STX\a\DC2\EOT\175\ENQ\STX\SUB\"\DC3 The pool deposit.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\a\ACK\DC2\EOT\234\EOT\STX\b\n\ + \\ENQ\EOT[\STX\a\ACK\DC2\EOT\175\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\a\SOH\DC2\EOT\234\EOT\t\NAK\n\ + \\ENQ\EOT[\STX\a\SOH\DC2\EOT\175\ENQ\t\NAK\n\ \\r\n\ - \\ENQ\EOTT\STX\a\ETX\DC2\EOT\234\EOT\CAN\EM\n\ + \\ENQ\EOT[\STX\a\ETX\DC2\EOT\175\ENQ\CAN\EM\n\ \0\n\ - \\EOT\EOTT\STX\b\DC2\EOT\235\EOT\STX)\"\" The pool retirement epoch bound.\n\ + \\EOT\EOT[\STX\b\DC2\EOT\176\ENQ\STX)\"\" The pool retirement epoch bound.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\b\ENQ\DC2\EOT\235\EOT\STX\b\n\ + \\ENQ\EOT[\STX\b\ENQ\DC2\EOT\176\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\b\SOH\DC2\EOT\235\EOT\t$\n\ + \\ENQ\EOT[\STX\b\SOH\DC2\EOT\176\ENQ\t$\n\ \\r\n\ - \\ENQ\EOTT\STX\b\ETX\DC2\EOT\235\EOT'(\n\ + \\ENQ\EOT[\STX\b\ETX\DC2\EOT\176\ENQ'(\n\ \,\n\ - \\EOT\EOTT\STX\t\DC2\EOT\236\EOT\STX&\"\RS The desired number of pools.\n\ + \\EOT\EOT[\STX\t\DC2\EOT\177\ENQ\STX&\"\RS The desired number of pools.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\t\ENQ\DC2\EOT\236\EOT\STX\b\n\ + \\ENQ\EOT[\STX\t\ENQ\DC2\EOT\177\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\t\SOH\DC2\EOT\236\EOT\t \n\ + \\ENQ\EOT[\STX\t\SOH\DC2\EOT\177\ENQ\t \n\ \\r\n\ - \\ENQ\EOTT\STX\t\ETX\DC2\EOT\236\EOT#%\n\ + \\ENQ\EOT[\STX\t\ETX\DC2\EOT\177\ENQ#%\n\ \#\n\ - \\EOT\EOTT\STX\n\ - \\DC2\EOT\237\EOT\STX%\"\NAK The pool influence.\n\ + \\EOT\EOT[\STX\n\ + \\DC2\EOT\178\ENQ\STX%\"\NAK The pool influence.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\n\ - \\ACK\DC2\EOT\237\EOT\STX\DLE\n\ + \\ENQ\EOT[\STX\n\ + \\ACK\DC2\EOT\178\ENQ\STX\DLE\n\ \\r\n\ - \\ENQ\EOTT\STX\n\ - \\SOH\DC2\EOT\237\EOT\DC1\US\n\ + \\ENQ\EOT[\STX\n\ + \\SOH\DC2\EOT\178\ENQ\DC1\US\n\ \\r\n\ - \\ENQ\EOTT\STX\n\ - \\ETX\DC2\EOT\237\EOT\"$\n\ + \\ENQ\EOT[\STX\n\ + \\ETX\DC2\EOT\178\ENQ\"$\n\ \'\n\ - \\EOT\EOTT\STX\v\DC2\EOT\238\EOT\STX)\"\EM The monetary expansion.\n\ + \\EOT\EOT[\STX\v\DC2\EOT\179\ENQ\STX)\"\EM The monetary expansion.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\v\ACK\DC2\EOT\238\EOT\STX\DLE\n\ + \\ENQ\EOT[\STX\v\ACK\DC2\EOT\179\ENQ\STX\DLE\n\ \\r\n\ - \\ENQ\EOTT\STX\v\SOH\DC2\EOT\238\EOT\DC1#\n\ + \\ENQ\EOT[\STX\v\SOH\DC2\EOT\179\ENQ\DC1#\n\ \\r\n\ - \\ENQ\EOTT\STX\v\ETX\DC2\EOT\238\EOT&(\n\ + \\ENQ\EOT[\STX\v\ETX\DC2\EOT\179\ENQ&(\n\ \'\n\ - \\EOT\EOTT\STX\f\DC2\EOT\239\EOT\STX)\"\EM The treasury expansion.\n\ + \\EOT\EOT[\STX\f\DC2\EOT\180\ENQ\STX)\"\EM The treasury expansion.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\f\ACK\DC2\EOT\239\EOT\STX\DLE\n\ + \\ENQ\EOT[\STX\f\ACK\DC2\EOT\180\ENQ\STX\DLE\n\ \\r\n\ - \\ENQ\EOTT\STX\f\SOH\DC2\EOT\239\EOT\DC1#\n\ + \\ENQ\EOT[\STX\f\SOH\DC2\EOT\180\ENQ\DC1#\n\ \\r\n\ - \\ENQ\EOTT\STX\f\ETX\DC2\EOT\239\EOT&(\n\ + \\ENQ\EOT[\STX\f\ETX\DC2\EOT\180\ENQ&(\n\ \&\n\ - \\EOT\EOTT\STX\r\DC2\EOT\240\EOT\STX\FS\"\CAN The minimum pool cost.\n\ + \\EOT\EOT[\STX\r\DC2\EOT\181\ENQ\STX\FS\"\CAN The minimum pool cost.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\r\ACK\DC2\EOT\240\EOT\STX\b\n\ + \\ENQ\EOT[\STX\r\ACK\DC2\EOT\181\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\r\SOH\DC2\EOT\240\EOT\t\SYN\n\ + \\ENQ\EOT[\STX\r\SOH\DC2\EOT\181\ENQ\t\SYN\n\ \\r\n\ - \\ENQ\EOTT\STX\r\ETX\DC2\EOT\240\EOT\EM\ESC\n\ + \\ENQ\EOT[\STX\r\ETX\DC2\EOT\181\ENQ\EM\ESC\n\ \%\n\ - \\EOT\EOTT\STX\SO\DC2\EOT\241\EOT\STX(\"\ETB The protocol version.\n\ + \\EOT\EOT[\STX\SO\DC2\EOT\182\ENQ\STX(\"\ETB The protocol version.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\SO\ACK\DC2\EOT\241\EOT\STX\DC1\n\ + \\ENQ\EOT[\STX\SO\ACK\DC2\EOT\182\ENQ\STX\DC1\n\ \\r\n\ - \\ENQ\EOTT\STX\SO\SOH\DC2\EOT\241\EOT\DC2\"\n\ + \\ENQ\EOT[\STX\SO\SOH\DC2\EOT\182\ENQ\DC2\"\n\ \\r\n\ - \\ENQ\EOTT\STX\SO\ETX\DC2\EOT\241\EOT%'\n\ + \\ENQ\EOT[\STX\SO\ETX\DC2\EOT\182\ENQ%'\n\ \'\n\ - \\EOT\EOTT\STX\SI\DC2\EOT\242\EOT\STX\GS\"\EM The maximum value size.\n\ + \\EOT\EOT[\STX\SI\DC2\EOT\183\ENQ\STX\GS\"\EM The maximum value size.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\SI\ENQ\DC2\EOT\242\EOT\STX\b\n\ + \\ENQ\EOT[\STX\SI\ENQ\DC2\EOT\183\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\SI\SOH\DC2\EOT\242\EOT\t\ETB\n\ + \\ENQ\EOT[\STX\SI\SOH\DC2\EOT\183\ENQ\t\ETB\n\ \\r\n\ - \\ENQ\EOTT\STX\SI\ETX\DC2\EOT\242\EOT\SUB\FS\n\ + \\ENQ\EOT[\STX\SI\ETX\DC2\EOT\183\ENQ\SUB\FS\n\ \*\n\ - \\EOT\EOTT\STX\DLE\DC2\EOT\243\EOT\STX$\"\FS The collateral percentage.\n\ + \\EOT\EOT[\STX\DLE\DC2\EOT\184\ENQ\STX$\"\FS The collateral percentage.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\DLE\ENQ\DC2\EOT\243\EOT\STX\b\n\ + \\ENQ\EOT[\STX\DLE\ENQ\DC2\EOT\184\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\DLE\SOH\DC2\EOT\243\EOT\t\RS\n\ + \\ENQ\EOT[\STX\DLE\SOH\DC2\EOT\184\ENQ\t\RS\n\ \\r\n\ - \\ENQ\EOTT\STX\DLE\ETX\DC2\EOT\243\EOT!#\n\ + \\ENQ\EOT[\STX\DLE\ETX\DC2\EOT\184\ENQ!#\n\ \.\n\ - \\EOT\EOTT\STX\DC1\DC2\EOT\244\EOT\STX$\" The maximum collateral inputs.\n\ + \\EOT\EOT[\STX\DC1\DC2\EOT\185\ENQ\STX$\" The maximum collateral inputs.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\DC1\ENQ\DC2\EOT\244\EOT\STX\b\n\ + \\ENQ\EOT[\STX\DC1\ENQ\DC2\EOT\185\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\DC1\SOH\DC2\EOT\244\EOT\t\RS\n\ + \\ENQ\EOT[\STX\DC1\SOH\DC2\EOT\185\ENQ\t\RS\n\ \\r\n\ - \\ENQ\EOTT\STX\DC1\ETX\DC2\EOT\244\EOT!#\n\ + \\ENQ\EOT[\STX\DC1\ETX\DC2\EOT\185\ENQ!#\n\ \ \n\ - \\EOT\EOTT\STX\DC2\DC2\EOT\245\EOT\STX\RS\"\DC2 The cost models.\n\ + \\EOT\EOT[\STX\DC2\DC2\EOT\186\ENQ\STX\RS\"\DC2 The cost models.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\DC2\ACK\DC2\EOT\245\EOT\STX\f\n\ + \\ENQ\EOT[\STX\DC2\ACK\DC2\EOT\186\ENQ\STX\f\n\ \\r\n\ - \\ENQ\EOTT\STX\DC2\SOH\DC2\EOT\245\EOT\r\CAN\n\ + \\ENQ\EOT[\STX\DC2\SOH\DC2\EOT\186\ENQ\r\CAN\n\ \\r\n\ - \\ENQ\EOTT\STX\DC2\ETX\DC2\EOT\245\EOT\ESC\GS\n\ + \\ENQ\EOT[\STX\DC2\ETX\DC2\EOT\186\ENQ\ESC\GS\n\ \\ESC\n\ - \\EOT\EOTT\STX\DC3\DC2\EOT\246\EOT\STX\ETB\"\r The prices.\n\ + \\EOT\EOT[\STX\DC3\DC2\EOT\187\ENQ\STX\ETB\"\r The prices.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\DC3\ACK\DC2\EOT\246\EOT\STX\n\ + \\ENQ\EOT[\STX\DC3\ACK\DC2\EOT\187\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\DC3\SOH\DC2\EOT\246\EOT\v\DC1\n\ + \\ENQ\EOT[\STX\DC3\SOH\DC2\EOT\187\ENQ\v\DC1\n\ \\r\n\ - \\ENQ\EOTT\STX\DC3\ETX\DC2\EOT\246\EOT\DC4\SYN\n\ + \\ENQ\EOT[\STX\DC3\ETX\DC2\EOT\187\ENQ\DC4\SYN\n\ \<\n\ - \\EOT\EOTT\STX\DC4\DC2\EOT\247\EOT\STX3\". The maximum execution units per transaction.\n\ + \\EOT\EOT[\STX\DC4\DC2\EOT\188\ENQ\STX3\". The maximum execution units per transaction.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\DC4\ACK\DC2\EOT\247\EOT\STX\t\n\ + \\ENQ\EOT[\STX\DC4\ACK\DC2\EOT\188\ENQ\STX\t\n\ \\r\n\ - \\ENQ\EOTT\STX\DC4\SOH\DC2\EOT\247\EOT\n\ + \\ENQ\EOT[\STX\DC4\SOH\DC2\EOT\188\ENQ\n\ \-\n\ \\r\n\ - \\ENQ\EOTT\STX\DC4\ETX\DC2\EOT\247\EOT02\n\ + \\ENQ\EOT[\STX\DC4\ETX\DC2\EOT\188\ENQ02\n\ \6\n\ - \\EOT\EOTT\STX\NAK\DC2\EOT\248\EOT\STX-\"( The maximum execution units per block.\n\ + \\EOT\EOT[\STX\NAK\DC2\EOT\189\ENQ\STX-\"( The maximum execution units per block.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\NAK\ACK\DC2\EOT\248\EOT\STX\t\n\ + \\ENQ\EOT[\STX\NAK\ACK\DC2\EOT\189\ENQ\STX\t\n\ \\r\n\ - \\ENQ\EOTT\STX\NAK\SOH\DC2\EOT\248\EOT\n\ + \\ENQ\EOT[\STX\NAK\SOH\DC2\EOT\189\ENQ\n\ \'\n\ \\r\n\ - \\ENQ\EOTT\STX\NAK\ETX\DC2\EOT\248\EOT*,\n\ + \\ENQ\EOT[\STX\NAK\ETX\DC2\EOT\189\ENQ*,\n\ \:\n\ - \\EOT\EOTT\STX\SYN\DC2\EOT\249\EOT\STX7\", The minimum fee per script reference byte.\n\ + \\EOT\EOT[\STX\SYN\DC2\EOT\190\ENQ\STX7\", The minimum fee per script reference byte.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\SYN\ACK\DC2\EOT\249\EOT\STX\DLE\n\ + \\ENQ\EOT[\STX\SYN\ACK\DC2\EOT\190\ENQ\STX\DLE\n\ \\r\n\ - \\ENQ\EOTT\STX\SYN\SOH\DC2\EOT\249\EOT\DC11\n\ + \\ENQ\EOT[\STX\SYN\SOH\DC2\EOT\190\ENQ\DC11\n\ \\r\n\ - \\ENQ\EOTT\STX\SYN\ETX\DC2\EOT\249\EOT46\n\ + \\ENQ\EOT[\STX\SYN\ETX\DC2\EOT\190\ENQ46\n\ \+\n\ - \\EOT\EOTT\STX\ETB\DC2\EOT\250\EOT\STX/\"\GS The pool voting thresholds.\n\ + \\EOT\EOT[\STX\ETB\DC2\EOT\191\ENQ\STX/\"\GS The pool voting thresholds.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\ETB\ACK\DC2\EOT\250\EOT\STX\DC2\n\ + \\ENQ\EOT[\STX\ETB\ACK\DC2\EOT\191\ENQ\STX\DC2\n\ \\r\n\ - \\ENQ\EOTT\STX\ETB\SOH\DC2\EOT\250\EOT\DC3)\n\ + \\ENQ\EOT[\STX\ETB\SOH\DC2\EOT\191\ENQ\DC3)\n\ \\r\n\ - \\ENQ\EOTT\STX\ETB\ETX\DC2\EOT\250\EOT,.\n\ + \\ENQ\EOT[\STX\ETB\ETX\DC2\EOT\191\ENQ,.\n\ \+\n\ - \\EOT\EOTT\STX\CAN\DC2\EOT\251\EOT\STX/\"\GS The drep voting thresholds.\n\ + \\EOT\EOT[\STX\CAN\DC2\EOT\192\ENQ\STX/\"\GS The drep voting thresholds.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\CAN\ACK\DC2\EOT\251\EOT\STX\DC2\n\ + \\ENQ\EOT[\STX\CAN\ACK\DC2\EOT\192\ENQ\STX\DC2\n\ \\r\n\ - \\ENQ\EOTT\STX\CAN\SOH\DC2\EOT\251\EOT\DC3)\n\ + \\ENQ\EOT[\STX\CAN\SOH\DC2\EOT\192\ENQ\DC3)\n\ \\r\n\ - \\ENQ\EOTT\STX\CAN\ETX\DC2\EOT\251\EOT,.\n\ + \\ENQ\EOT[\STX\CAN\ETX\DC2\EOT\192\ENQ,.\n\ \+\n\ - \\EOT\EOTT\STX\EM\DC2\EOT\252\EOT\STX!\"\GS The minimum committee size.\n\ + \\EOT\EOT[\STX\EM\DC2\EOT\193\ENQ\STX!\"\GS The minimum committee size.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\EM\ENQ\DC2\EOT\252\EOT\STX\b\n\ + \\ENQ\EOT[\STX\EM\ENQ\DC2\EOT\193\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\EM\SOH\DC2\EOT\252\EOT\t\ESC\n\ + \\ENQ\EOT[\STX\EM\SOH\DC2\EOT\193\ENQ\t\ESC\n\ \\r\n\ - \\ENQ\EOTT\STX\EM\ETX\DC2\EOT\252\EOT\RS \n\ + \\ENQ\EOT[\STX\EM\ETX\DC2\EOT\193\ENQ\RS \n\ \)\n\ - \\EOT\EOTT\STX\SUB\DC2\EOT\253\EOT\STX#\"\ESC The committee term limit.\n\ + \\EOT\EOT[\STX\SUB\DC2\EOT\194\ENQ\STX#\"\ESC The committee term limit.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\SUB\ENQ\DC2\EOT\253\EOT\STX\b\n\ + \\ENQ\EOT[\STX\SUB\ENQ\DC2\EOT\194\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\SUB\SOH\DC2\EOT\253\EOT\t\GS\n\ + \\ENQ\EOT[\STX\SUB\SOH\DC2\EOT\194\ENQ\t\GS\n\ \\r\n\ - \\ENQ\EOTT\STX\SUB\ETX\DC2\EOT\253\EOT \"\n\ + \\ENQ\EOT[\STX\SUB\ETX\DC2\EOT\194\ENQ \"\n\ \6\n\ - \\EOT\EOTT\STX\ESC\DC2\EOT\254\EOT\STX0\"( The governance action validity period.\n\ + \\EOT\EOT[\STX\ESC\DC2\EOT\195\ENQ\STX0\"( The governance action validity period.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\ESC\ENQ\DC2\EOT\254\EOT\STX\b\n\ + \\ENQ\EOT[\STX\ESC\ENQ\DC2\EOT\195\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\ESC\SOH\DC2\EOT\254\EOT\t*\n\ + \\ENQ\EOT[\STX\ESC\SOH\DC2\EOT\195\ENQ\t*\n\ \\r\n\ - \\ENQ\EOTT\STX\ESC\ETX\DC2\EOT\254\EOT-/\n\ + \\ENQ\EOT[\STX\ESC\ETX\DC2\EOT\195\ENQ-/\n\ \.\n\ - \\EOT\EOTT\STX\FS\DC2\EOT\255\EOT\STX(\" The governance action deposit.\n\ + \\EOT\EOT[\STX\FS\DC2\EOT\196\ENQ\STX(\" The governance action deposit.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\FS\ACK\DC2\EOT\255\EOT\STX\b\n\ + \\ENQ\EOT[\STX\FS\ACK\DC2\EOT\196\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\FS\SOH\DC2\EOT\255\EOT\t\"\n\ + \\ENQ\EOT[\STX\FS\SOH\DC2\EOT\196\ENQ\t\"\n\ \\r\n\ - \\ENQ\EOTT\STX\FS\ETX\DC2\EOT\255\EOT%'\n\ + \\ENQ\EOT[\STX\FS\ETX\DC2\EOT\196\ENQ%'\n\ \!\n\ - \\EOT\EOTT\STX\GS\DC2\EOT\128\ENQ\STX\ESC\"\DC3 The drep deposit.\n\ + \\EOT\EOT[\STX\GS\DC2\EOT\197\ENQ\STX\ESC\"\DC3 The drep deposit.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\GS\ACK\DC2\EOT\128\ENQ\STX\b\n\ + \\ENQ\EOT[\STX\GS\ACK\DC2\EOT\197\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\GS\SOH\DC2\EOT\128\ENQ\t\NAK\n\ + \\ENQ\EOT[\STX\GS\SOH\DC2\EOT\197\ENQ\t\NAK\n\ \\r\n\ - \\ENQ\EOTT\STX\GS\ETX\DC2\EOT\128\ENQ\CAN\SUB\n\ + \\ENQ\EOT[\STX\GS\ETX\DC2\EOT\197\ENQ\CAN\SUB\n\ \+\n\ - \\EOT\EOTT\STX\RS\DC2\EOT\129\ENQ\STX%\"\GS The drep inactivity period.\n\ + \\EOT\EOT[\STX\RS\DC2\EOT\198\ENQ\STX%\"\GS The drep inactivity period.\n\ \\n\ \\r\n\ - \\ENQ\EOTT\STX\RS\ENQ\DC2\EOT\129\ENQ\STX\b\n\ + \\ENQ\EOT[\STX\RS\ENQ\DC2\EOT\198\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTT\STX\RS\SOH\DC2\EOT\129\ENQ\t\US\n\ + \\ENQ\EOT[\STX\RS\SOH\DC2\EOT\198\ENQ\t\US\n\ \\r\n\ - \\ENQ\EOTT\STX\RS\ETX\DC2\EOT\129\ENQ\"$\n\ + \\ENQ\EOT[\STX\RS\ETX\DC2\EOT\198\ENQ\"$\n\ \\f\n\ - \\STX\EOTU\DC2\ACK\132\ENQ\NUL\136\ENQ\SOH\n\ + \\STX\EOT\\\DC2\ACK\201\ENQ\NUL\205\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTU\SOH\DC2\EOT\132\ENQ\b\DC3\n\ + \\ETX\EOT\\\SOH\DC2\EOT\201\ENQ\b\DC3\n\ \\FS\n\ - \\EOT\EOTU\STX\NUL\DC2\EOT\133\ENQ\STX\DC2\"\SO ms timestamp\n\ + \\EOT\EOT\\\STX\NUL\DC2\EOT\202\ENQ\STX\DC2\"\SO ms timestamp\n\ \\n\ \\r\n\ - \\ENQ\EOTU\STX\NUL\ENQ\DC2\EOT\133\ENQ\STX\b\n\ + \\ENQ\EOT\\\STX\NUL\ENQ\DC2\EOT\202\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTU\STX\NUL\SOH\DC2\EOT\133\ENQ\t\r\n\ + \\ENQ\EOT\\\STX\NUL\SOH\DC2\EOT\202\ENQ\t\r\n\ \\r\n\ - \\ENQ\EOTU\STX\NUL\ETX\DC2\EOT\133\ENQ\DLE\DC1\n\ + \\ENQ\EOT\\\STX\NUL\ETX\DC2\EOT\202\ENQ\DLE\DC1\n\ \C\n\ - \\EOT\EOTU\STX\SOH\DC2\EOT\134\ENQ\STX\DC2\"5 absolute slot number of the first block of this era\n\ + \\EOT\EOT\\\STX\SOH\DC2\EOT\203\ENQ\STX\DC2\"5 absolute slot number of the first block of this era\n\ \\n\ \\r\n\ - \\ENQ\EOTU\STX\SOH\ENQ\DC2\EOT\134\ENQ\STX\b\n\ + \\ENQ\EOT\\\STX\SOH\ENQ\DC2\EOT\203\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTU\STX\SOH\SOH\DC2\EOT\134\ENQ\t\r\n\ + \\ENQ\EOT\\\STX\SOH\SOH\DC2\EOT\203\ENQ\t\r\n\ \\r\n\ - \\ENQ\EOTU\STX\SOH\ETX\DC2\EOT\134\ENQ\DLE\DC1\n\ + \\ENQ\EOT\\\STX\SOH\ETX\DC2\EOT\203\ENQ\DLE\DC1\n\ \(\n\ - \\EOT\EOTU\STX\STX\DC2\EOT\135\ENQ\STX\DC3\"\SUB first epoch for this era\n\ + \\EOT\EOT\\\STX\STX\DC2\EOT\204\ENQ\STX\DC3\"\SUB first epoch for this era\n\ \\n\ \\r\n\ - \\ENQ\EOTU\STX\STX\ENQ\DC2\EOT\135\ENQ\STX\b\n\ + \\ENQ\EOT\\\STX\STX\ENQ\DC2\EOT\204\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTU\STX\STX\SOH\DC2\EOT\135\ENQ\t\SO\n\ + \\ENQ\EOT\\\STX\STX\SOH\DC2\EOT\204\ENQ\t\SO\n\ \\r\n\ - \\ENQ\EOTU\STX\STX\ETX\DC2\EOT\135\ENQ\DC1\DC2\n\ + \\ENQ\EOT\\\STX\STX\ETX\DC2\EOT\204\ENQ\DC1\DC2\n\ \\f\n\ - \\STX\EOTV\DC2\ACK\138\ENQ\NUL\143\ENQ\SOH\n\ + \\STX\EOT]\DC2\ACK\207\ENQ\NUL\212\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTV\SOH\DC2\EOT\138\ENQ\b\DC2\n\ + \\ETX\EOT]\SOH\DC2\EOT\207\ENQ\b\DC2\n\ \/\n\ - \\EOT\EOTV\STX\NUL\DC2\EOT\139\ENQ\STX\DC2\"! name of the era (ex: \"shelley\")\n\ + \\EOT\EOT]\STX\NUL\DC2\EOT\208\ENQ\STX\DC2\"! name of the era (ex: \"shelley\")\n\ \\n\ \\r\n\ - \\ENQ\EOTV\STX\NUL\ENQ\DC2\EOT\139\ENQ\STX\b\n\ + \\ENQ\EOT]\STX\NUL\ENQ\DC2\EOT\208\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTV\STX\NUL\SOH\DC2\EOT\139\ENQ\t\r\n\ + \\ENQ\EOT]\STX\NUL\SOH\DC2\EOT\208\ENQ\t\r\n\ \\r\n\ - \\ENQ\EOTV\STX\NUL\ETX\DC2\EOT\139\ENQ\DLE\DC1\n\ + \\ENQ\EOT]\STX\NUL\ETX\DC2\EOT\208\ENQ\DLE\DC1\n\ \!\n\ - \\EOT\EOTV\STX\SOH\DC2\EOT\140\ENQ\STX\CAN\"\DC3 start of this era\n\ + \\EOT\EOT]\STX\SOH\DC2\EOT\209\ENQ\STX\CAN\"\DC3 start of this era\n\ \\n\ \\r\n\ - \\ENQ\EOTV\STX\SOH\ACK\DC2\EOT\140\ENQ\STX\r\n\ + \\ENQ\EOT]\STX\SOH\ACK\DC2\EOT\209\ENQ\STX\r\n\ \\r\n\ - \\ENQ\EOTV\STX\SOH\SOH\DC2\EOT\140\ENQ\SO\DC3\n\ + \\ENQ\EOT]\STX\SOH\SOH\DC2\EOT\209\ENQ\SO\DC3\n\ \\r\n\ - \\ENQ\EOTV\STX\SOH\ETX\DC2\EOT\140\ENQ\SYN\ETB\n\ + \\ENQ\EOT]\STX\SOH\ETX\DC2\EOT\209\ENQ\SYN\ETB\n\ \F\n\ - \\EOT\EOTV\STX\STX\DC2\EOT\141\ENQ\STX\SYN\"8 end of this era (if the era has a well-defined ending)\n\ + \\EOT\EOT]\STX\STX\DC2\EOT\210\ENQ\STX\SYN\"8 end of this era (if the era has a well-defined ending)\n\ \\n\ \\r\n\ - \\ENQ\EOTV\STX\STX\ACK\DC2\EOT\141\ENQ\STX\r\n\ + \\ENQ\EOT]\STX\STX\ACK\DC2\EOT\210\ENQ\STX\r\n\ \\r\n\ - \\ENQ\EOTV\STX\STX\SOH\DC2\EOT\141\ENQ\SO\DC1\n\ + \\ENQ\EOT]\STX\STX\SOH\DC2\EOT\210\ENQ\SO\DC1\n\ \\r\n\ - \\ENQ\EOTV\STX\STX\ETX\DC2\EOT\141\ENQ\DC4\NAK\n\ + \\ENQ\EOT]\STX\STX\ETX\DC2\EOT\210\ENQ\DC4\NAK\n\ \0\n\ - \\EOT\EOTV\STX\ETX\DC2\EOT\142\ENQ\STX\RS\"\" protocol parameters for this era\n\ + \\EOT\EOT]\STX\ETX\DC2\EOT\211\ENQ\STX\RS\"\" protocol parameters for this era\n\ \\n\ \\r\n\ - \\ENQ\EOTV\STX\ETX\ACK\DC2\EOT\142\ENQ\STX\t\n\ + \\ENQ\EOT]\STX\ETX\ACK\DC2\EOT\211\ENQ\STX\t\n\ \\r\n\ - \\ENQ\EOTV\STX\ETX\SOH\DC2\EOT\142\ENQ\n\ + \\ENQ\EOT]\STX\ETX\SOH\DC2\EOT\211\ENQ\n\ \\EM\n\ \\r\n\ - \\ENQ\EOTV\STX\ETX\ETX\DC2\EOT\142\ENQ\FS\GS\n\ + \\ENQ\EOT]\STX\ETX\ETX\DC2\EOT\211\ENQ\FS\GS\n\ \\f\n\ - \\STX\EOTW\DC2\ACK\145\ENQ\NUL\147\ENQ\SOH\n\ + \\STX\EOT^\DC2\ACK\214\ENQ\NUL\216\ENQ\SOH\n\ \\v\n\ - \\ETX\EOTW\SOH\DC2\EOT\145\ENQ\b\DC4\n\ + \\ETX\EOT^\SOH\DC2\EOT\214\ENQ\b\DC4\n\ \\f\n\ - \\EOT\EOTW\STX\NUL\DC2\EOT\146\ENQ\STX$\n\ + \\EOT\EOT^\STX\NUL\DC2\EOT\215\ENQ\STX$\n\ \\r\n\ - \\ENQ\EOTW\STX\NUL\EOT\DC2\EOT\146\ENQ\STX\n\ + \\ENQ\EOT^\STX\NUL\EOT\DC2\EOT\215\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTW\STX\NUL\ACK\DC2\EOT\146\ENQ\v\NAK\n\ + \\ENQ\EOT^\STX\NUL\ACK\DC2\EOT\215\ENQ\v\NAK\n\ \\r\n\ - \\ENQ\EOTW\STX\NUL\SOH\DC2\EOT\146\ENQ\SYN\US\n\ + \\ENQ\EOT^\STX\NUL\SOH\DC2\EOT\215\ENQ\SYN\US\n\ \\r\n\ - \\ENQ\EOTW\STX\NUL\ETX\DC2\EOT\146\ENQ\"#\n\ + \\ENQ\EOT^\STX\NUL\ETX\DC2\EOT\215\ENQ\"#\n\ \\199\STX\n\ - \\STX\EOTX\DC2\ACK\156\ENQ\NUL\160\ENQ\SOH\SUB\158\STX A single evaluation report entry, used for script errors, execution traces,\n\ + \\STX\EOT_\DC2\ACK\225\ENQ\NUL\229\ENQ\SOH\SUB\158\STX A single evaluation report entry, used for script errors, execution traces,\n\ \ and transaction-level evaluation errors (e.g. balance mismatches). When the\n\ \ entry relates to a specific redeemer, purpose and index identify which one;\n\ \ for transaction-level errors these fields are absent.\n\ @@ -35257,946 +37129,946 @@ packedFileDescriptor \ ==========\n\ \\n\ \\v\n\ - \\ETX\EOTX\SOH\DC2\EOT\156\ENQ\b\DC2\n\ + \\ETX\EOT_\SOH\DC2\EOT\225\ENQ\b\DC2\n\ \'\n\ - \\EOT\EOTX\STX\NUL\DC2\EOT\157\ENQ\STX\DC1\"\EM Human-readable message.\n\ + \\EOT\EOT_\STX\NUL\DC2\EOT\226\ENQ\STX\DC1\"\EM Human-readable message.\n\ \\n\ \\r\n\ - \\ENQ\EOTX\STX\NUL\ENQ\DC2\EOT\157\ENQ\STX\b\n\ + \\ENQ\EOT_\STX\NUL\ENQ\DC2\EOT\226\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTX\STX\NUL\SOH\DC2\EOT\157\ENQ\t\f\n\ + \\ENQ\EOT_\STX\NUL\SOH\DC2\EOT\226\ENQ\t\f\n\ \\r\n\ - \\ENQ\EOTX\STX\NUL\ETX\DC2\EOT\157\ENQ\SI\DLE\n\ + \\ENQ\EOT_\STX\NUL\ETX\DC2\EOT\226\ENQ\SI\DLE\n\ \A\n\ - \\EOT\EOTX\STX\SOH\DC2\EOT\158\ENQ\STX'\"3 Purpose of the redeemer that produced this entry.\n\ + \\EOT\EOT_\STX\SOH\DC2\EOT\227\ENQ\STX'\"3 Purpose of the redeemer that produced this entry.\n\ \\n\ \\r\n\ - \\ENQ\EOTX\STX\SOH\EOT\DC2\EOT\158\ENQ\STX\n\ + \\ENQ\EOT_\STX\SOH\EOT\DC2\EOT\227\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTX\STX\SOH\ACK\DC2\EOT\158\ENQ\v\SUB\n\ + \\ENQ\EOT_\STX\SOH\ACK\DC2\EOT\227\ENQ\v\SUB\n\ \\r\n\ - \\ENQ\EOTX\STX\SOH\SOH\DC2\EOT\158\ENQ\ESC\"\n\ + \\ENQ\EOT_\STX\SOH\SOH\DC2\EOT\227\ENQ\ESC\"\n\ \\r\n\ - \\ENQ\EOTX\STX\SOH\ETX\DC2\EOT\158\ENQ%&\n\ - \9\n\ - \\EOT\EOTX\STX\STX\DC2\EOT\159\ENQ\STX\FS\"+ Index of the redeemer within its purpose.\n\ + \\ENQ\EOT_\STX\SOH\ETX\DC2\EOT\227\ENQ%&\n\ + \A\n\ + \\EOT\EOT_\STX\STX\DC2\EOT\228\ENQ\STX\FS\"3 0-based index of the redeemer within its purpose.\n\ \\n\ \\r\n\ - \\ENQ\EOTX\STX\STX\EOT\DC2\EOT\159\ENQ\STX\n\ + \\ENQ\EOT_\STX\STX\EOT\DC2\EOT\228\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTX\STX\STX\ENQ\DC2\EOT\159\ENQ\v\DC1\n\ + \\ENQ\EOT_\STX\STX\ENQ\DC2\EOT\228\ENQ\v\DC1\n\ \\r\n\ - \\ENQ\EOTX\STX\STX\SOH\DC2\EOT\159\ENQ\DC2\ETB\n\ + \\ENQ\EOT_\STX\STX\SOH\DC2\EOT\228\ENQ\DC2\ETB\n\ \\r\n\ - \\ENQ\EOTX\STX\STX\ETX\DC2\EOT\159\ENQ\SUB\ESC\n\ + \\ENQ\EOT_\STX\STX\ETX\DC2\EOT\228\ENQ\SUB\ESC\n\ \T\n\ - \\STX\EOTY\DC2\ACK\163\ENQ\NUL\169\ENQ\SOH\SUBF Result of evaluating a transaction against the current ledger state.\n\ + \\STX\EOT`\DC2\ACK\232\ENQ\NUL\238\ENQ\SOH\SUBF Result of evaluating a transaction against the current ledger state.\n\ \\n\ \\v\n\ - \\ETX\EOTY\SOH\DC2\EOT\163\ENQ\b\SO\n\ + \\ETX\EOT`\SOH\DC2\EOT\232\ENQ\b\SO\n\ \9\n\ - \\EOT\EOTY\STX\NUL\DC2\EOT\164\ENQ\STX\DC1\"+ Computed minimum fee for the transaction.\n\ + \\EOT\EOT`\STX\NUL\DC2\EOT\233\ENQ\STX\DC1\"+ Computed minimum fee for the transaction.\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\NUL\ACK\DC2\EOT\164\ENQ\STX\b\n\ + \\ENQ\EOT`\STX\NUL\ACK\DC2\EOT\233\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTY\STX\NUL\SOH\DC2\EOT\164\ENQ\t\f\n\ + \\ENQ\EOT`\STX\NUL\SOH\DC2\EOT\233\ENQ\t\f\n\ \\r\n\ - \\ENQ\EOTY\STX\NUL\ETX\DC2\EOT\164\ENQ\SI\DLE\n\ + \\ENQ\EOT`\STX\NUL\ETX\DC2\EOT\233\ENQ\SI\DLE\n\ \D\n\ - \\EOT\EOTY\STX\SOH\DC2\EOT\165\ENQ\STX\ETB\"6 Total execution units consumed across all redeemers.\n\ + \\EOT\EOT`\STX\SOH\DC2\EOT\234\ENQ\STX\ETB\"6 Total execution units consumed across all redeemers.\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\SOH\ACK\DC2\EOT\165\ENQ\STX\t\n\ + \\ENQ\EOT`\STX\SOH\ACK\DC2\EOT\234\ENQ\STX\t\n\ \\r\n\ - \\ENQ\EOTY\STX\SOH\SOH\DC2\EOT\165\ENQ\n\ + \\ENQ\EOT`\STX\SOH\SOH\DC2\EOT\234\ENQ\n\ \\DC2\n\ \\r\n\ - \\ENQ\EOTY\STX\SOH\ETX\DC2\EOT\165\ENQ\NAK\SYN\n\ + \\ENQ\EOT`\STX\SOH\ETX\DC2\EOT\234\ENQ\NAK\SYN\n\ \I\n\ - \\EOT\EOTY\STX\STX\DC2\EOT\166\ENQ\STX!\"; Script execution and transaction-level evaluation errors.\n\ + \\EOT\EOT`\STX\STX\DC2\EOT\235\ENQ\STX!\"; Script execution and transaction-level evaluation errors.\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\STX\EOT\DC2\EOT\166\ENQ\STX\n\ + \\ENQ\EOT`\STX\STX\EOT\DC2\EOT\235\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\STX\ACK\DC2\EOT\166\ENQ\v\NAK\n\ + \\ENQ\EOT`\STX\STX\ACK\DC2\EOT\235\ENQ\v\NAK\n\ \\r\n\ - \\ENQ\EOTY\STX\STX\SOH\DC2\EOT\166\ENQ\SYN\FS\n\ + \\ENQ\EOT`\STX\STX\SOH\DC2\EOT\235\ENQ\SYN\FS\n\ \\r\n\ - \\ENQ\EOTY\STX\STX\ETX\DC2\EOT\166\ENQ\US \n\ + \\ENQ\EOT`\STX\STX\ETX\DC2\EOT\235\ENQ\US \n\ \5\n\ - \\EOT\EOTY\STX\ETX\DC2\EOT\167\ENQ\STX!\"' Per-redeemer script execution traces.\n\ + \\EOT\EOT`\STX\ETX\DC2\EOT\236\ENQ\STX!\"' Per-redeemer script execution traces.\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\ETX\EOT\DC2\EOT\167\ENQ\STX\n\ + \\ENQ\EOT`\STX\ETX\EOT\DC2\EOT\236\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\ETX\ACK\DC2\EOT\167\ENQ\v\NAK\n\ + \\ENQ\EOT`\STX\ETX\ACK\DC2\EOT\236\ENQ\v\NAK\n\ \\r\n\ - \\ENQ\EOTY\STX\ETX\SOH\DC2\EOT\167\ENQ\SYN\FS\n\ + \\ENQ\EOT`\STX\ETX\SOH\DC2\EOT\236\ENQ\SYN\FS\n\ \\r\n\ - \\ENQ\EOTY\STX\ETX\ETX\DC2\EOT\167\ENQ\US \n\ + \\ENQ\EOT`\STX\ETX\ETX\DC2\EOT\236\ENQ\US \n\ \9\n\ - \\EOT\EOTY\STX\EOT\DC2\EOT\168\ENQ\STX\"\"+ Redeemers with evaluated execution units.\n\ + \\EOT\EOT`\STX\EOT\DC2\EOT\237\ENQ\STX\"\"+ Redeemers with evaluated execution units.\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\EOT\EOT\DC2\EOT\168\ENQ\STX\n\ + \\ENQ\EOT`\STX\EOT\EOT\DC2\EOT\237\ENQ\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTY\STX\EOT\ACK\DC2\EOT\168\ENQ\v\DC3\n\ + \\ENQ\EOT`\STX\EOT\ACK\DC2\EOT\237\ENQ\v\DC3\n\ \\r\n\ - \\ENQ\EOTY\STX\EOT\SOH\DC2\EOT\168\ENQ\DC4\GS\n\ + \\ENQ\EOT`\STX\EOT\SOH\DC2\EOT\237\ENQ\DC4\GS\n\ \\r\n\ - \\ENQ\EOTY\STX\EOT\ETX\DC2\EOT\168\ENQ !\n\ + \\ENQ\EOT`\STX\EOT\ETX\DC2\EOT\237\ENQ !\n\ \0\n\ - \\STX\EOTZ\DC2\ACK\174\ENQ\NUL\176\ENQ\SOH2\" GENESIS CONFIGS\n\ + \\STX\EOTa\DC2\ACK\243\ENQ\NUL\245\ENQ\SOH2\" GENESIS CONFIGS\n\ \ ===============\n\ \\n\ \\v\n\ - \\ETX\EOTZ\SOH\DC2\EOT\174\ENQ\b\DC4\n\ + \\ETX\EOTa\SOH\DC2\EOT\243\ENQ\b\DC4\n\ \\f\n\ - \\EOT\EOTZ\STX\NUL\DC2\EOT\175\ENQ\STX\DC1\n\ + \\EOT\EOTa\STX\NUL\DC2\EOT\244\ENQ\STX\DC1\n\ \\r\n\ - \\ENQ\EOTZ\STX\NUL\ENQ\DC2\EOT\175\ENQ\STX\b\n\ + \\ENQ\EOTa\STX\NUL\ENQ\DC2\EOT\244\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOTZ\STX\NUL\SOH\DC2\EOT\175\ENQ\t\f\n\ + \\ENQ\EOTa\STX\NUL\SOH\DC2\EOT\244\ENQ\t\f\n\ \\r\n\ - \\ENQ\EOTZ\STX\NUL\ETX\DC2\EOT\175\ENQ\SI\DLE\n\ + \\ENQ\EOTa\STX\NUL\ETX\DC2\EOT\244\ENQ\SI\DLE\n\ \\f\n\ - \\STX\EOT[\DC2\ACK\178\ENQ\NUL\193\ENQ\SOH\n\ + \\STX\EOTb\DC2\ACK\247\ENQ\NUL\134\ACK\SOH\n\ \\v\n\ - \\ETX\EOT[\SOH\DC2\EOT\178\ENQ\b\CAN\n\ + \\ETX\EOTb\SOH\DC2\EOT\247\ENQ\b\CAN\n\ \\f\n\ - \\EOT\EOT[\STX\NUL\DC2\EOT\179\ENQ\STX\FS\n\ + \\EOT\EOTb\STX\NUL\DC2\EOT\248\ENQ\STX\FS\n\ \\r\n\ - \\ENQ\EOT[\STX\NUL\ENQ\DC2\EOT\179\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\NUL\ENQ\DC2\EOT\248\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\NUL\SOH\DC2\EOT\179\ENQ\t\ETB\n\ + \\ENQ\EOTb\STX\NUL\SOH\DC2\EOT\248\ENQ\t\ETB\n\ \\r\n\ - \\ENQ\EOT[\STX\NUL\ETX\DC2\EOT\179\ENQ\SUB\ESC\n\ + \\ENQ\EOTb\STX\NUL\ETX\DC2\EOT\248\ENQ\SUB\ESC\n\ \\f\n\ - \\EOT\EOT[\STX\SOH\DC2\EOT\180\ENQ\STX\ESC\n\ + \\EOT\EOTb\STX\SOH\DC2\EOT\249\ENQ\STX\ESC\n\ \\r\n\ - \\ENQ\EOT[\STX\SOH\ENQ\DC2\EOT\180\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\SOH\ENQ\DC2\EOT\249\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\SOH\SOH\DC2\EOT\180\ENQ\t\SYN\n\ + \\ENQ\EOTb\STX\SOH\SOH\DC2\EOT\249\ENQ\t\SYN\n\ \\r\n\ - \\ENQ\EOT[\STX\SOH\ETX\DC2\EOT\180\ENQ\EM\SUB\n\ + \\ENQ\EOTb\STX\SOH\ETX\DC2\EOT\249\ENQ\EM\SUB\n\ \\f\n\ - \\EOT\EOT[\STX\STX\DC2\EOT\181\ENQ\STX\FS\n\ + \\EOT\EOTb\STX\STX\DC2\EOT\250\ENQ\STX\FS\n\ \\r\n\ - \\ENQ\EOT[\STX\STX\ENQ\DC2\EOT\181\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\STX\ENQ\DC2\EOT\250\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\STX\SOH\DC2\EOT\181\ENQ\t\ETB\n\ + \\ENQ\EOTb\STX\STX\SOH\DC2\EOT\250\ENQ\t\ETB\n\ \\r\n\ - \\ENQ\EOT[\STX\STX\ETX\DC2\EOT\181\ENQ\SUB\ESC\n\ + \\ENQ\EOTb\STX\STX\ETX\DC2\EOT\250\ENQ\SUB\ESC\n\ \\f\n\ - \\EOT\EOT[\STX\ETX\DC2\EOT\182\ENQ\STX\GS\n\ + \\EOT\EOTb\STX\ETX\DC2\EOT\251\ENQ\STX\GS\n\ \\r\n\ - \\ENQ\EOT[\STX\ETX\ENQ\DC2\EOT\182\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\ETX\ENQ\DC2\EOT\251\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\ETX\SOH\DC2\EOT\182\ENQ\t\CAN\n\ + \\ENQ\EOTb\STX\ETX\SOH\DC2\EOT\251\ENQ\t\CAN\n\ \\r\n\ - \\ENQ\EOT[\STX\ETX\ETX\DC2\EOT\182\ENQ\ESC\FS\n\ + \\ENQ\EOTb\STX\ETX\ETX\DC2\EOT\251\ENQ\ESC\FS\n\ \\f\n\ - \\EOT\EOT[\STX\EOT\DC2\EOT\183\ENQ\STX\EM\n\ + \\EOT\EOTb\STX\EOT\DC2\EOT\252\ENQ\STX\EM\n\ \\r\n\ - \\ENQ\EOT[\STX\EOT\ENQ\DC2\EOT\183\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\EOT\ENQ\DC2\EOT\252\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\EOT\SOH\DC2\EOT\183\ENQ\t\DC4\n\ + \\ENQ\EOTb\STX\EOT\SOH\DC2\EOT\252\ENQ\t\DC4\n\ \\r\n\ - \\ENQ\EOT[\STX\EOT\ETX\DC2\EOT\183\ENQ\ETB\CAN\n\ + \\ENQ\EOTb\STX\EOT\ETX\DC2\EOT\252\ENQ\ETB\CAN\n\ \\f\n\ - \\EOT\EOT[\STX\ENQ\DC2\EOT\184\ENQ\STX\US\n\ + \\EOT\EOTb\STX\ENQ\DC2\EOT\253\ENQ\STX\US\n\ \\r\n\ - \\ENQ\EOT[\STX\ENQ\ENQ\DC2\EOT\184\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\ENQ\ENQ\DC2\EOT\253\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\ENQ\SOH\DC2\EOT\184\ENQ\t\SUB\n\ + \\ENQ\EOTb\STX\ENQ\SOH\DC2\EOT\253\ENQ\t\SUB\n\ \\r\n\ - \\ENQ\EOT[\STX\ENQ\ETX\DC2\EOT\184\ENQ\GS\RS\n\ + \\ENQ\EOTb\STX\ENQ\ETX\DC2\EOT\253\ENQ\GS\RS\n\ \\f\n\ - \\EOT\EOT[\STX\ACK\DC2\EOT\185\ENQ\STX\NAK\n\ + \\EOT\EOTb\STX\ACK\DC2\EOT\254\ENQ\STX\NAK\n\ \\r\n\ - \\ENQ\EOT[\STX\ACK\ENQ\DC2\EOT\185\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\ACK\ENQ\DC2\EOT\254\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\ACK\SOH\DC2\EOT\185\ENQ\t\DLE\n\ + \\ENQ\EOTb\STX\ACK\SOH\DC2\EOT\254\ENQ\t\DLE\n\ \\r\n\ - \\ENQ\EOT[\STX\ACK\ETX\DC2\EOT\185\ENQ\DC3\DC4\n\ + \\ENQ\EOTb\STX\ACK\ETX\DC2\EOT\254\ENQ\DC3\DC4\n\ \\f\n\ - \\EOT\EOT[\STX\a\DC2\EOT\186\ENQ\STX\ESC\n\ + \\EOT\EOTb\STX\a\DC2\EOT\255\ENQ\STX\ESC\n\ \\r\n\ - \\ENQ\EOT[\STX\a\ENQ\DC2\EOT\186\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\a\ENQ\DC2\EOT\255\ENQ\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\a\SOH\DC2\EOT\186\ENQ\t\SYN\n\ + \\ENQ\EOTb\STX\a\SOH\DC2\EOT\255\ENQ\t\SYN\n\ \\r\n\ - \\ENQ\EOT[\STX\a\ETX\DC2\EOT\186\ENQ\EM\SUB\n\ + \\ENQ\EOTb\STX\a\ETX\DC2\EOT\255\ENQ\EM\SUB\n\ \\f\n\ - \\EOT\EOT[\STX\b\DC2\EOT\187\ENQ\STX\GS\n\ + \\EOT\EOTb\STX\b\DC2\EOT\128\ACK\STX\GS\n\ \\r\n\ - \\ENQ\EOT[\STX\b\ENQ\DC2\EOT\187\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\b\ENQ\DC2\EOT\128\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\b\SOH\DC2\EOT\187\ENQ\t\CAN\n\ + \\ENQ\EOTb\STX\b\SOH\DC2\EOT\128\ACK\t\CAN\n\ \\r\n\ - \\ENQ\EOT[\STX\b\ETX\DC2\EOT\187\ENQ\ESC\FS\n\ + \\ENQ\EOTb\STX\b\ETX\DC2\EOT\128\ACK\ESC\FS\n\ \\f\n\ - \\EOT\EOT[\STX\t\DC2\EOT\188\ENQ\STX\"\n\ + \\EOT\EOTb\STX\t\DC2\EOT\129\ACK\STX\"\n\ \\r\n\ - \\ENQ\EOT[\STX\t\ENQ\DC2\EOT\188\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\t\ENQ\DC2\EOT\129\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\t\SOH\DC2\EOT\188\ENQ\t\FS\n\ + \\ENQ\EOTb\STX\t\SOH\DC2\EOT\129\ACK\t\FS\n\ \\r\n\ - \\ENQ\EOT[\STX\t\ETX\DC2\EOT\188\ENQ\US!\n\ + \\ENQ\EOTb\STX\t\ETX\DC2\EOT\129\ACK\US!\n\ \\f\n\ - \\EOT\EOT[\STX\n\ - \\DC2\EOT\189\ENQ\STX\RS\n\ + \\EOT\EOTb\STX\n\ + \\DC2\EOT\130\ACK\STX\RS\n\ \\r\n\ - \\ENQ\EOT[\STX\n\ - \\ENQ\DC2\EOT\189\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\n\ + \\ENQ\DC2\EOT\130\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\n\ - \\SOH\DC2\EOT\189\ENQ\t\CAN\n\ + \\ENQ\EOTb\STX\n\ + \\SOH\DC2\EOT\130\ACK\t\CAN\n\ \\r\n\ - \\ENQ\EOT[\STX\n\ - \\ETX\DC2\EOT\189\ENQ\ESC\GS\n\ + \\ENQ\EOTb\STX\n\ + \\ETX\DC2\EOT\130\ACK\ESC\GS\n\ \\f\n\ - \\EOT\EOT[\STX\v\DC2\EOT\190\ENQ\STX\"\n\ + \\EOT\EOTb\STX\v\DC2\EOT\131\ACK\STX\"\n\ \\r\n\ - \\ENQ\EOT[\STX\v\ACK\DC2\EOT\190\ENQ\STX\SO\n\ + \\ENQ\EOTb\STX\v\ACK\DC2\EOT\131\ACK\STX\SO\n\ \\r\n\ - \\ENQ\EOT[\STX\v\SOH\DC2\EOT\190\ENQ\SI\FS\n\ + \\ENQ\EOTb\STX\v\SOH\DC2\EOT\131\ACK\SI\FS\n\ \\r\n\ - \\ENQ\EOT[\STX\v\ETX\DC2\EOT\190\ENQ\US!\n\ + \\ENQ\EOTb\STX\v\ETX\DC2\EOT\131\ACK\US!\n\ \\f\n\ - \\EOT\EOT[\STX\f\DC2\EOT\191\ENQ\STX!\n\ + \\EOT\EOTb\STX\f\DC2\EOT\132\ACK\STX!\n\ \\r\n\ - \\ENQ\EOT[\STX\f\ACK\DC2\EOT\191\ENQ\STX\r\n\ + \\ENQ\EOTb\STX\f\ACK\DC2\EOT\132\ACK\STX\r\n\ \\r\n\ - \\ENQ\EOT[\STX\f\SOH\DC2\EOT\191\ENQ\SO\ESC\n\ + \\ENQ\EOTb\STX\f\SOH\DC2\EOT\132\ACK\SO\ESC\n\ \\r\n\ - \\ENQ\EOT[\STX\f\ETX\DC2\EOT\191\ENQ\RS \n\ + \\ENQ\EOTb\STX\f\ETX\DC2\EOT\132\ACK\RS \n\ \\f\n\ - \\EOT\EOT[\STX\r\DC2\EOT\192\ENQ\STX!\n\ + \\EOT\EOTb\STX\r\DC2\EOT\133\ACK\STX!\n\ \\r\n\ - \\ENQ\EOT[\STX\r\ENQ\DC2\EOT\192\ENQ\STX\b\n\ + \\ENQ\EOTb\STX\r\ENQ\DC2\EOT\133\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT[\STX\r\SOH\DC2\EOT\192\ENQ\t\ESC\n\ + \\ENQ\EOTb\STX\r\SOH\DC2\EOT\133\ACK\t\ESC\n\ \\r\n\ - \\ENQ\EOT[\STX\r\ETX\DC2\EOT\192\ENQ\RS \n\ + \\ENQ\EOTb\STX\r\ETX\DC2\EOT\133\ACK\RS \n\ \\f\n\ - \\STX\EOT\\\DC2\ACK\195\ENQ\NUL\199\ENQ\SOH\n\ + \\STX\EOTc\DC2\ACK\136\ACK\NUL\140\ACK\SOH\n\ \\v\n\ - \\ETX\EOT\\\SOH\DC2\EOT\195\ENQ\b\DC4\n\ + \\ETX\EOTc\SOH\DC2\EOT\136\ACK\b\DC4\n\ \\f\n\ - \\EOT\EOT\\\STX\NUL\DC2\EOT\196\ENQ\STX\SYN\n\ + \\EOT\EOTc\STX\NUL\DC2\EOT\137\ACK\STX\SYN\n\ \\r\n\ - \\ENQ\EOT\\\STX\NUL\ENQ\DC2\EOT\196\ENQ\STX\b\n\ + \\ENQ\EOTc\STX\NUL\ENQ\DC2\EOT\137\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT\\\STX\NUL\SOH\DC2\EOT\196\ENQ\t\DC1\n\ + \\ENQ\EOTc\STX\NUL\SOH\DC2\EOT\137\ACK\t\DC1\n\ \\r\n\ - \\ENQ\EOT\\\STX\NUL\ETX\DC2\EOT\196\ENQ\DC4\NAK\n\ + \\ENQ\EOTc\STX\NUL\ETX\DC2\EOT\137\ACK\DC4\NAK\n\ \\f\n\ - \\EOT\EOT\\\STX\SOH\DC2\EOT\197\ENQ\STX\NAK\n\ + \\EOT\EOTc\STX\SOH\DC2\EOT\138\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOT\\\STX\SOH\ENQ\DC2\EOT\197\ENQ\STX\b\n\ + \\ENQ\EOTc\STX\SOH\ENQ\DC2\EOT\138\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT\\\STX\SOH\SOH\DC2\EOT\197\ENQ\t\DLE\n\ + \\ENQ\EOTc\STX\SOH\SOH\DC2\EOT\138\ACK\t\DLE\n\ \\r\n\ - \\ENQ\EOT\\\STX\SOH\ETX\DC2\EOT\197\ENQ\DC3\DC4\n\ + \\ENQ\EOTc\STX\SOH\ETX\DC2\EOT\138\ACK\DC3\DC4\n\ \\f\n\ - \\EOT\EOT\\\STX\STX\DC2\EOT\198\ENQ\STX\ESC\n\ + \\EOT\EOTc\STX\STX\DC2\EOT\139\ACK\STX\ESC\n\ \\r\n\ - \\ENQ\EOT\\\STX\STX\ENQ\DC2\EOT\198\ENQ\STX\b\n\ + \\ENQ\EOTc\STX\STX\ENQ\DC2\EOT\139\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT\\\STX\STX\SOH\DC2\EOT\198\ENQ\t\SYN\n\ + \\ENQ\EOTc\STX\STX\SOH\DC2\EOT\139\ACK\t\SYN\n\ \\r\n\ - \\ENQ\EOT\\\STX\STX\ETX\DC2\EOT\198\ENQ\EM\SUB\n\ + \\ENQ\EOTc\STX\STX\ETX\DC2\EOT\139\ACK\EM\SUB\n\ \\f\n\ - \\STX\EOT]\DC2\ACK\201\ENQ\NUL\204\ENQ\SOH\n\ + \\STX\EOTd\DC2\ACK\142\ACK\NUL\145\ACK\SOH\n\ \\v\n\ - \\ETX\EOT]\SOH\DC2\EOT\201\ENQ\b\DC3\n\ + \\ETX\EOTd\SOH\DC2\EOT\142\ACK\b\DC3\n\ \\f\n\ - \\EOT\EOT]\STX\NUL\DC2\EOT\202\ENQ\STX\CAN\n\ + \\EOT\EOTd\STX\NUL\DC2\EOT\143\ACK\STX\CAN\n\ \\r\n\ - \\ENQ\EOT]\STX\NUL\ENQ\DC2\EOT\202\ENQ\STX\b\n\ + \\ENQ\EOTd\STX\NUL\ENQ\DC2\EOT\143\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT]\STX\NUL\SOH\DC2\EOT\202\ENQ\t\DC3\n\ + \\ENQ\EOTd\STX\NUL\SOH\DC2\EOT\143\ACK\t\DC3\n\ \\r\n\ - \\ENQ\EOT]\STX\NUL\ETX\DC2\EOT\202\ENQ\SYN\ETB\n\ + \\ENQ\EOTd\STX\NUL\ETX\DC2\EOT\143\ACK\SYN\ETB\n\ \\f\n\ - \\EOT\EOT]\STX\SOH\DC2\EOT\203\ENQ\STX\NAK\n\ + \\EOT\EOTd\STX\SOH\DC2\EOT\144\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOT]\STX\SOH\ENQ\DC2\EOT\203\ENQ\STX\b\n\ + \\ENQ\EOTd\STX\SOH\ENQ\DC2\EOT\144\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT]\STX\SOH\SOH\DC2\EOT\203\ENQ\t\DLE\n\ + \\ENQ\EOTd\STX\SOH\SOH\DC2\EOT\144\ACK\t\DLE\n\ \\r\n\ - \\ENQ\EOT]\STX\SOH\ETX\DC2\EOT\203\ENQ\DC3\DC4\n\ + \\ENQ\EOTd\STX\SOH\ETX\DC2\EOT\144\ACK\DC3\DC4\n\ \\f\n\ - \\STX\EOT^\DC2\ACK\206\ENQ\NUL\211\ENQ\SOH\n\ + \\STX\EOTe\DC2\ACK\147\ACK\NUL\152\ACK\SOH\n\ \\v\n\ - \\ETX\EOT^\SOH\DC2\EOT\206\ENQ\b\SYN\n\ + \\ETX\EOTe\SOH\DC2\EOT\147\ACK\b\SYN\n\ \\f\n\ - \\EOT\EOT^\STX\NUL\DC2\EOT\207\ENQ\STX\SI\n\ + \\EOT\EOTe\STX\NUL\DC2\EOT\148\ACK\STX\SI\n\ \\r\n\ - \\ENQ\EOT^\STX\NUL\ENQ\DC2\EOT\207\ENQ\STX\b\n\ + \\ENQ\EOTe\STX\NUL\ENQ\DC2\EOT\148\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT^\STX\NUL\SOH\DC2\EOT\207\ENQ\t\n\ + \\ENQ\EOTe\STX\NUL\SOH\DC2\EOT\148\ACK\t\n\ \\n\ \\r\n\ - \\ENQ\EOT^\STX\NUL\ETX\DC2\EOT\207\ENQ\r\SO\n\ + \\ENQ\EOTe\STX\NUL\ETX\DC2\EOT\148\ACK\r\SO\n\ \\f\n\ - \\EOT\EOT^\STX\SOH\DC2\EOT\208\ENQ\STX\FS\n\ + \\EOT\EOTe\STX\SOH\DC2\EOT\149\ACK\STX\FS\n\ \\r\n\ - \\ENQ\EOT^\STX\SOH\ENQ\DC2\EOT\208\ENQ\STX\b\n\ + \\ENQ\EOTe\STX\SOH\ENQ\DC2\EOT\149\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT^\STX\SOH\SOH\DC2\EOT\208\ENQ\t\ETB\n\ + \\ENQ\EOTe\STX\SOH\SOH\DC2\EOT\149\ACK\t\ETB\n\ \\r\n\ - \\ENQ\EOT^\STX\SOH\ETX\DC2\EOT\208\ENQ\SUB\ESC\n\ + \\ENQ\EOTe\STX\SOH\ETX\DC2\EOT\149\ACK\SUB\ESC\n\ \\f\n\ - \\EOT\EOT^\STX\STX\DC2\EOT\209\ENQ\STX\EM\n\ + \\EOT\EOTe\STX\STX\DC2\EOT\150\ACK\STX\EM\n\ \\r\n\ - \\ENQ\EOT^\STX\STX\ENQ\DC2\EOT\209\ENQ\STX\b\n\ + \\ENQ\EOTe\STX\STX\ENQ\DC2\EOT\150\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT^\STX\STX\SOH\DC2\EOT\209\ENQ\t\DC4\n\ + \\ENQ\EOTe\STX\STX\SOH\DC2\EOT\150\ACK\t\DC4\n\ \\r\n\ - \\ENQ\EOT^\STX\STX\ETX\DC2\EOT\209\ENQ\ETB\CAN\n\ + \\ENQ\EOTe\STX\STX\ETX\DC2\EOT\150\ACK\ETB\CAN\n\ \\f\n\ - \\EOT\EOT^\STX\ETX\DC2\EOT\210\ENQ\STX\EM\n\ + \\EOT\EOTe\STX\ETX\DC2\EOT\151\ACK\STX\EM\n\ \\r\n\ - \\ENQ\EOT^\STX\ETX\ENQ\DC2\EOT\210\ENQ\STX\b\n\ + \\ENQ\EOTe\STX\ETX\ENQ\DC2\EOT\151\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT^\STX\ETX\SOH\DC2\EOT\210\ENQ\t\DC4\n\ + \\ENQ\EOTe\STX\ETX\SOH\DC2\EOT\151\ACK\t\DC4\n\ \\r\n\ - \\ENQ\EOT^\STX\ETX\ETX\DC2\EOT\210\ENQ\ETB\CAN\n\ + \\ENQ\EOTe\STX\ETX\ETX\DC2\EOT\151\ACK\ETB\CAN\n\ \\f\n\ - \\STX\EOT_\DC2\ACK\213\ENQ\NUL\218\ENQ\SOH\n\ + \\STX\EOTf\DC2\ACK\154\ACK\NUL\159\ACK\SOH\n\ \\v\n\ - \\ETX\EOT_\SOH\DC2\EOT\213\ENQ\b\ETB\n\ + \\ETX\EOTf\SOH\DC2\EOT\154\ACK\b\ETB\n\ \\f\n\ - \\EOT\EOT_\STX\NUL\DC2\EOT\214\ENQ\STX\DC2\n\ + \\EOT\EOTf\STX\NUL\DC2\EOT\155\ACK\STX\DC2\n\ \\r\n\ - \\ENQ\EOT_\STX\NUL\ENQ\DC2\EOT\214\ENQ\STX\b\n\ + \\ENQ\EOTf\STX\NUL\ENQ\DC2\EOT\155\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT_\STX\NUL\SOH\DC2\EOT\214\ENQ\t\r\n\ + \\ENQ\EOTf\STX\NUL\SOH\DC2\EOT\155\ACK\t\r\n\ \\r\n\ - \\ENQ\EOT_\STX\NUL\ETX\DC2\EOT\214\ENQ\DLE\DC1\n\ + \\ENQ\EOTf\STX\NUL\ETX\DC2\EOT\155\ACK\DLE\DC1\n\ \\f\n\ - \\EOT\EOT_\STX\SOH\DC2\EOT\215\ENQ\STX\EM\n\ + \\EOT\EOTf\STX\SOH\DC2\EOT\156\ACK\STX\EM\n\ \\r\n\ - \\ENQ\EOT_\STX\SOH\ENQ\DC2\EOT\215\ENQ\STX\b\n\ + \\ENQ\EOTf\STX\SOH\ENQ\DC2\EOT\156\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT_\STX\SOH\SOH\DC2\EOT\215\ENQ\t\DC4\n\ + \\ENQ\EOTf\STX\SOH\SOH\DC2\EOT\156\ACK\t\DC4\n\ \\r\n\ - \\ENQ\EOT_\STX\SOH\ETX\DC2\EOT\215\ENQ\ETB\CAN\n\ + \\ENQ\EOTf\STX\SOH\ETX\DC2\EOT\156\ACK\ETB\CAN\n\ \\f\n\ - \\EOT\EOT_\STX\STX\DC2\EOT\216\ENQ\STX\ETB\n\ + \\EOT\EOTf\STX\STX\DC2\EOT\157\ACK\STX\ETB\n\ \\r\n\ - \\ENQ\EOT_\STX\STX\ENQ\DC2\EOT\216\ENQ\STX\b\n\ + \\ENQ\EOTf\STX\STX\ENQ\DC2\EOT\157\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT_\STX\STX\SOH\DC2\EOT\216\ENQ\t\DC2\n\ + \\ENQ\EOTf\STX\STX\SOH\DC2\EOT\157\ACK\t\DC2\n\ \\r\n\ - \\ENQ\EOT_\STX\STX\ETX\DC2\EOT\216\ENQ\NAK\SYN\n\ + \\ENQ\EOTf\STX\STX\ETX\DC2\EOT\157\ACK\NAK\SYN\n\ \\f\n\ - \\EOT\EOT_\STX\ETX\DC2\EOT\217\ENQ\STX\DC3\n\ + \\EOT\EOTf\STX\ETX\DC2\EOT\158\ACK\STX\DC3\n\ \\r\n\ - \\ENQ\EOT_\STX\ETX\ENQ\DC2\EOT\217\ENQ\STX\b\n\ + \\ENQ\EOTf\STX\ETX\ENQ\DC2\EOT\158\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT_\STX\ETX\SOH\DC2\EOT\217\ENQ\t\SO\n\ + \\ENQ\EOTf\STX\ETX\SOH\DC2\EOT\158\ACK\t\SO\n\ \\r\n\ - \\ENQ\EOT_\STX\ETX\ETX\DC2\EOT\217\ENQ\DC1\DC2\n\ + \\ENQ\EOTf\STX\ETX\ETX\DC2\EOT\158\ACK\DC1\DC2\n\ \\f\n\ - \\STX\EOT`\DC2\ACK\220\ENQ\NUL\225\ENQ\SOH\n\ + \\STX\EOTg\DC2\ACK\161\ACK\NUL\166\ACK\SOH\n\ \\v\n\ - \\ETX\EOT`\SOH\DC2\EOT\220\ENQ\b\SI\n\ + \\ETX\EOTg\SOH\DC2\EOT\161\ACK\b\SI\n\ \\f\n\ - \\EOT\EOT`\STX\NUL\DC2\EOT\221\ENQ\STX\SUB\n\ + \\EOT\EOTg\STX\NUL\DC2\EOT\162\ACK\STX\SUB\n\ \\r\n\ - \\ENQ\EOT`\STX\NUL\ENQ\DC2\EOT\221\ENQ\STX\b\n\ + \\ENQ\EOTg\STX\NUL\ENQ\DC2\EOT\162\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT`\STX\NUL\SOH\DC2\EOT\221\ENQ\t\NAK\n\ + \\ENQ\EOTg\STX\NUL\SOH\DC2\EOT\162\ACK\t\NAK\n\ \\r\n\ - \\ENQ\EOT`\STX\NUL\ETX\DC2\EOT\221\ENQ\CAN\EM\n\ + \\ENQ\EOTg\STX\NUL\ETX\DC2\EOT\162\ACK\CAN\EM\n\ \\f\n\ - \\EOT\EOT`\STX\SOH\DC2\EOT\222\ENQ\STX\ETB\n\ + \\EOT\EOTg\STX\SOH\DC2\EOT\163\ACK\STX\ETB\n\ \\r\n\ - \\ENQ\EOT`\STX\SOH\ENQ\DC2\EOT\222\ENQ\STX\b\n\ + \\ENQ\EOTg\STX\SOH\ENQ\DC2\EOT\163\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT`\STX\SOH\SOH\DC2\EOT\222\ENQ\t\DC2\n\ + \\ENQ\EOTg\STX\SOH\SOH\DC2\EOT\163\ACK\t\DC2\n\ \\r\n\ - \\ENQ\EOT`\STX\SOH\ETX\DC2\EOT\222\ENQ\NAK\SYN\n\ + \\ENQ\EOTg\STX\SOH\ETX\DC2\EOT\163\ACK\NAK\SYN\n\ \\f\n\ - \\EOT\EOT`\STX\STX\DC2\EOT\223\ENQ\STX\EM\n\ + \\EOT\EOTg\STX\STX\DC2\EOT\164\ACK\STX\EM\n\ \\r\n\ - \\ENQ\EOT`\STX\STX\ENQ\DC2\EOT\223\ENQ\STX\b\n\ + \\ENQ\EOTg\STX\STX\ENQ\DC2\EOT\164\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT`\STX\STX\SOH\DC2\EOT\223\ENQ\t\DC4\n\ + \\ENQ\EOTg\STX\STX\SOH\DC2\EOT\164\ACK\t\DC4\n\ \\r\n\ - \\ENQ\EOT`\STX\STX\ETX\DC2\EOT\223\ENQ\ETB\CAN\n\ + \\ENQ\EOTg\STX\STX\ETX\DC2\EOT\164\ACK\ETB\CAN\n\ \\f\n\ - \\EOT\EOT`\STX\ETX\DC2\EOT\224\ENQ\STX\NAK\n\ + \\EOT\EOTg\STX\ETX\DC2\EOT\165\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOT`\STX\ETX\ENQ\DC2\EOT\224\ENQ\STX\b\n\ + \\ENQ\EOTg\STX\ETX\ENQ\DC2\EOT\165\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOT`\STX\ETX\SOH\DC2\EOT\224\ENQ\t\DLE\n\ + \\ENQ\EOTg\STX\ETX\SOH\DC2\EOT\165\ACK\t\DLE\n\ \\r\n\ - \\ENQ\EOT`\STX\ETX\ETX\DC2\EOT\224\ENQ\DC3\DC4\n\ + \\ENQ\EOTg\STX\ETX\ETX\DC2\EOT\165\ACK\DC3\DC4\n\ \\f\n\ - \\STX\EOTa\DC2\ACK\227\ENQ\NUL\230\ENQ\SOH\n\ + \\STX\EOTh\DC2\ACK\168\ACK\NUL\171\ACK\SOH\n\ \\v\n\ - \\ETX\EOTa\SOH\DC2\EOT\227\ENQ\b\DC1\n\ + \\ETX\EOTh\SOH\DC2\EOT\168\ACK\b\DC1\n\ \\f\n\ - \\EOT\EOTa\STX\NUL\DC2\EOT\228\ENQ\STX\SYN\n\ + \\EOT\EOTh\STX\NUL\DC2\EOT\169\ACK\STX\SYN\n\ \\r\n\ - \\ENQ\EOTa\STX\NUL\ENQ\DC2\EOT\228\ENQ\STX\b\n\ + \\ENQ\EOTh\STX\NUL\ENQ\DC2\EOT\169\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTa\STX\NUL\SOH\DC2\EOT\228\ENQ\t\DC1\n\ + \\ENQ\EOTh\STX\NUL\SOH\DC2\EOT\169\ACK\t\DC1\n\ \\r\n\ - \\ENQ\EOTa\STX\NUL\ETX\DC2\EOT\228\ENQ\DC4\NAK\n\ + \\ENQ\EOTh\STX\NUL\ETX\DC2\EOT\169\ACK\DC4\NAK\n\ \\f\n\ - \\EOT\EOTa\STX\SOH\DC2\EOT\229\ENQ\STX\DC1\n\ + \\EOT\EOTh\STX\SOH\DC2\EOT\170\ACK\STX\DC1\n\ \\r\n\ - \\ENQ\EOTa\STX\SOH\ENQ\DC2\EOT\229\ENQ\STX\b\n\ + \\ENQ\EOTh\STX\SOH\ENQ\DC2\EOT\170\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTa\STX\SOH\SOH\DC2\EOT\229\ENQ\t\f\n\ + \\ENQ\EOTh\STX\SOH\SOH\DC2\EOT\170\ACK\t\f\n\ \\r\n\ - \\ENQ\EOTa\STX\SOH\ETX\DC2\EOT\229\ENQ\SI\DLE\n\ + \\ENQ\EOTh\STX\SOH\ETX\DC2\EOT\170\ACK\SI\DLE\n\ \\f\n\ - \\STX\EOTb\DC2\ACK\232\ENQ\NUL\238\ENQ\SOH\n\ + \\STX\EOTi\DC2\ACK\173\ACK\NUL\179\ACK\SOH\n\ \\v\n\ - \\ETX\EOTb\SOH\DC2\EOT\232\ENQ\b\FS\n\ + \\ETX\EOTi\SOH\DC2\EOT\173\ACK\b\FS\n\ \\f\n\ - \\EOT\EOTb\STX\NUL\DC2\EOT\233\ENQ\STX*\n\ + \\EOT\EOTi\STX\NUL\DC2\EOT\174\ACK\STX*\n\ \\r\n\ - \\ENQ\EOTb\STX\NUL\ACK\DC2\EOT\233\ENQ\STX\DLE\n\ + \\ENQ\EOTi\STX\NUL\ACK\DC2\EOT\174\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTb\STX\NUL\SOH\DC2\EOT\233\ENQ\DC1%\n\ + \\ENQ\EOTi\STX\NUL\SOH\DC2\EOT\174\ACK\DC1%\n\ \\r\n\ - \\ENQ\EOTb\STX\NUL\ETX\DC2\EOT\233\ENQ()\n\ + \\ENQ\EOTi\STX\NUL\ETX\DC2\EOT\174\ACK()\n\ \\f\n\ - \\EOT\EOTb\STX\SOH\DC2\EOT\234\ENQ\STX&\n\ + \\EOT\EOTi\STX\SOH\DC2\EOT\175\ACK\STX&\n\ \\r\n\ - \\ENQ\EOTb\STX\SOH\ACK\DC2\EOT\234\ENQ\STX\DLE\n\ + \\ENQ\EOTi\STX\SOH\ACK\DC2\EOT\175\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTb\STX\SOH\SOH\DC2\EOT\234\ENQ\DC1!\n\ + \\ENQ\EOTi\STX\SOH\SOH\DC2\EOT\175\ACK\DC1!\n\ \\r\n\ - \\ENQ\EOTb\STX\SOH\ETX\DC2\EOT\234\ENQ$%\n\ + \\ENQ\EOTi\STX\SOH\ETX\DC2\EOT\175\ACK$%\n\ \\f\n\ - \\EOT\EOTb\STX\STX\DC2\EOT\235\ENQ\STX-\n\ + \\EOT\EOTi\STX\STX\DC2\EOT\176\ACK\STX-\n\ \\r\n\ - \\ENQ\EOTb\STX\STX\ACK\DC2\EOT\235\ENQ\STX\DLE\n\ + \\ENQ\EOTi\STX\STX\ACK\DC2\EOT\176\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTb\STX\STX\SOH\DC2\EOT\235\ENQ\DC1(\n\ + \\ENQ\EOTi\STX\STX\SOH\DC2\EOT\176\ACK\DC1(\n\ \\r\n\ - \\ENQ\EOTb\STX\STX\ETX\DC2\EOT\235\ENQ+,\n\ + \\ENQ\EOTi\STX\STX\ETX\DC2\EOT\176\ACK+,\n\ \\f\n\ - \\EOT\EOTb\STX\ETX\DC2\EOT\236\ENQ\STX*\n\ + \\EOT\EOTi\STX\ETX\DC2\EOT\177\ACK\STX*\n\ \\r\n\ - \\ENQ\EOTb\STX\ETX\ACK\DC2\EOT\236\ENQ\STX\DLE\n\ + \\ENQ\EOTi\STX\ETX\ACK\DC2\EOT\177\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTb\STX\ETX\SOH\DC2\EOT\236\ENQ\DC1%\n\ + \\ENQ\EOTi\STX\ETX\SOH\DC2\EOT\177\ACK\DC1%\n\ \\r\n\ - \\ENQ\EOTb\STX\ETX\ETX\DC2\EOT\236\ENQ()\n\ + \\ENQ\EOTi\STX\ETX\ETX\DC2\EOT\177\ACK()\n\ \\f\n\ - \\EOT\EOTb\STX\EOT\DC2\EOT\237\ENQ\STX'\n\ + \\EOT\EOTi\STX\EOT\DC2\EOT\178\ACK\STX'\n\ \\r\n\ - \\ENQ\EOTb\STX\EOT\ACK\DC2\EOT\237\ENQ\STX\DLE\n\ + \\ENQ\EOTi\STX\EOT\ACK\DC2\EOT\178\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTb\STX\EOT\SOH\DC2\EOT\237\ENQ\DC1\"\n\ + \\ENQ\EOTi\STX\EOT\SOH\DC2\EOT\178\ACK\DC1\"\n\ \\r\n\ - \\ENQ\EOTb\STX\EOT\ETX\DC2\EOT\237\ENQ%&\n\ + \\ENQ\EOTi\STX\EOT\ETX\DC2\EOT\178\ACK%&\n\ \\f\n\ - \\STX\EOTc\DC2\ACK\240\ENQ\NUL\251\ENQ\SOH\n\ + \\STX\EOTj\DC2\ACK\181\ACK\NUL\192\ACK\SOH\n\ \\v\n\ - \\ETX\EOTc\SOH\DC2\EOT\240\ENQ\b\FS\n\ + \\ETX\EOTj\SOH\DC2\EOT\181\ACK\b\FS\n\ \\f\n\ - \\EOT\EOTc\STX\NUL\DC2\EOT\241\ENQ\STX*\n\ + \\EOT\EOTj\STX\NUL\DC2\EOT\182\ACK\STX*\n\ \\r\n\ - \\ENQ\EOTc\STX\NUL\ACK\DC2\EOT\241\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\NUL\ACK\DC2\EOT\182\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\NUL\SOH\DC2\EOT\241\ENQ\DC1%\n\ + \\ENQ\EOTj\STX\NUL\SOH\DC2\EOT\182\ACK\DC1%\n\ \\r\n\ - \\ENQ\EOTc\STX\NUL\ETX\DC2\EOT\241\ENQ()\n\ + \\ENQ\EOTj\STX\NUL\ETX\DC2\EOT\182\ACK()\n\ \\f\n\ - \\EOT\EOTc\STX\SOH\DC2\EOT\242\ENQ\STX&\n\ + \\EOT\EOTj\STX\SOH\DC2\EOT\183\ACK\STX&\n\ \\r\n\ - \\ENQ\EOTc\STX\SOH\ACK\DC2\EOT\242\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\SOH\ACK\DC2\EOT\183\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\SOH\SOH\DC2\EOT\242\ENQ\DC1!\n\ + \\ENQ\EOTj\STX\SOH\SOH\DC2\EOT\183\ACK\DC1!\n\ \\r\n\ - \\ENQ\EOTc\STX\SOH\ETX\DC2\EOT\242\ENQ$%\n\ + \\ENQ\EOTj\STX\SOH\ETX\DC2\EOT\183\ACK$%\n\ \\f\n\ - \\EOT\EOTc\STX\STX\DC2\EOT\243\ENQ\STX-\n\ + \\EOT\EOTj\STX\STX\DC2\EOT\184\ACK\STX-\n\ \\r\n\ - \\ENQ\EOTc\STX\STX\ACK\DC2\EOT\243\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\STX\ACK\DC2\EOT\184\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\STX\SOH\DC2\EOT\243\ENQ\DC1(\n\ + \\ENQ\EOTj\STX\STX\SOH\DC2\EOT\184\ACK\DC1(\n\ \\r\n\ - \\ENQ\EOTc\STX\STX\ETX\DC2\EOT\243\ENQ+,\n\ + \\ENQ\EOTj\STX\STX\ETX\DC2\EOT\184\ACK+,\n\ \\f\n\ - \\EOT\EOTc\STX\ETX\DC2\EOT\244\ENQ\STX,\n\ + \\EOT\EOTj\STX\ETX\DC2\EOT\185\ACK\STX,\n\ \\r\n\ - \\ENQ\EOTc\STX\ETX\ACK\DC2\EOT\244\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\ETX\ACK\DC2\EOT\185\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\ETX\SOH\DC2\EOT\244\ENQ\DC1'\n\ + \\ENQ\EOTj\STX\ETX\SOH\DC2\EOT\185\ACK\DC1'\n\ \\r\n\ - \\ENQ\EOTc\STX\ETX\ETX\DC2\EOT\244\ENQ*+\n\ + \\ENQ\EOTj\STX\ETX\ETX\DC2\EOT\185\ACK*+\n\ \\f\n\ - \\EOT\EOTc\STX\EOT\DC2\EOT\245\ENQ\STX*\n\ + \\EOT\EOTj\STX\EOT\DC2\EOT\186\ACK\STX*\n\ \\r\n\ - \\ENQ\EOTc\STX\EOT\ACK\DC2\EOT\245\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\EOT\ACK\DC2\EOT\186\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\EOT\SOH\DC2\EOT\245\ENQ\DC1%\n\ + \\ENQ\EOTj\STX\EOT\SOH\DC2\EOT\186\ACK\DC1%\n\ \\r\n\ - \\ENQ\EOTc\STX\EOT\ETX\DC2\EOT\245\ENQ()\n\ + \\ENQ\EOTj\STX\EOT\ETX\DC2\EOT\186\ACK()\n\ \\f\n\ - \\EOT\EOTc\STX\ENQ\DC2\EOT\246\ENQ\STX&\n\ + \\EOT\EOTj\STX\ENQ\DC2\EOT\187\ACK\STX&\n\ \\r\n\ - \\ENQ\EOTc\STX\ENQ\ACK\DC2\EOT\246\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\ENQ\ACK\DC2\EOT\187\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\ENQ\SOH\DC2\EOT\246\ENQ\DC1!\n\ + \\ENQ\EOTj\STX\ENQ\SOH\DC2\EOT\187\ACK\DC1!\n\ \\r\n\ - \\ENQ\EOTc\STX\ENQ\ETX\DC2\EOT\246\ENQ$%\n\ + \\ENQ\EOTj\STX\ENQ\ETX\DC2\EOT\187\ACK$%\n\ \\f\n\ - \\EOT\EOTc\STX\ACK\DC2\EOT\247\ENQ\STX'\n\ + \\EOT\EOTj\STX\ACK\DC2\EOT\188\ACK\STX'\n\ \\r\n\ - \\ENQ\EOTc\STX\ACK\ACK\DC2\EOT\247\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\ACK\ACK\DC2\EOT\188\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\ACK\SOH\DC2\EOT\247\ENQ\DC1\"\n\ + \\ENQ\EOTj\STX\ACK\SOH\DC2\EOT\188\ACK\DC1\"\n\ \\r\n\ - \\ENQ\EOTc\STX\ACK\ETX\DC2\EOT\247\ENQ%&\n\ + \\ENQ\EOTj\STX\ACK\ETX\DC2\EOT\188\ACK%&\n\ \\f\n\ - \\EOT\EOTc\STX\a\DC2\EOT\248\ENQ\STX(\n\ + \\EOT\EOTj\STX\a\DC2\EOT\189\ACK\STX(\n\ \\r\n\ - \\ENQ\EOTc\STX\a\ACK\DC2\EOT\248\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\a\ACK\DC2\EOT\189\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\a\SOH\DC2\EOT\248\ENQ\DC1#\n\ + \\ENQ\EOTj\STX\a\SOH\DC2\EOT\189\ACK\DC1#\n\ \\r\n\ - \\ENQ\EOTc\STX\a\ETX\DC2\EOT\248\ENQ&'\n\ + \\ENQ\EOTj\STX\a\ETX\DC2\EOT\189\ACK&'\n\ \\f\n\ - \\EOT\EOTc\STX\b\DC2\EOT\249\ENQ\STX\"\n\ + \\EOT\EOTj\STX\b\DC2\EOT\190\ACK\STX\"\n\ \\r\n\ - \\ENQ\EOTc\STX\b\ACK\DC2\EOT\249\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\b\ACK\DC2\EOT\190\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\b\SOH\DC2\EOT\249\ENQ\DC1\GS\n\ + \\ENQ\EOTj\STX\b\SOH\DC2\EOT\190\ACK\DC1\GS\n\ \\r\n\ - \\ENQ\EOTc\STX\b\ETX\DC2\EOT\249\ENQ !\n\ + \\ENQ\EOTj\STX\b\ETX\DC2\EOT\190\ACK !\n\ \\f\n\ - \\EOT\EOTc\STX\t\DC2\EOT\250\ENQ\STX*\n\ + \\EOT\EOTj\STX\t\DC2\EOT\191\ACK\STX*\n\ \\r\n\ - \\ENQ\EOTc\STX\t\ACK\DC2\EOT\250\ENQ\STX\DLE\n\ + \\ENQ\EOTj\STX\t\ACK\DC2\EOT\191\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTc\STX\t\SOH\DC2\EOT\250\ENQ\DC1$\n\ + \\ENQ\EOTj\STX\t\SOH\DC2\EOT\191\ACK\DC1$\n\ \\r\n\ - \\ENQ\EOTc\STX\t\ETX\DC2\EOT\250\ENQ')\n\ + \\ENQ\EOTj\STX\t\ETX\DC2\EOT\191\ACK')\n\ \\f\n\ - \\STX\EOTd\DC2\ACK\253\ENQ\NUL\128\ACK\SOH\n\ + \\STX\EOTk\DC2\ACK\194\ACK\NUL\197\ACK\SOH\n\ \\v\n\ - \\ETX\EOTd\SOH\DC2\EOT\253\ENQ\b\DC1\n\ + \\ETX\EOTk\SOH\DC2\EOT\194\ACK\b\DC1\n\ \\f\n\ - \\EOT\EOTd\STX\NUL\DC2\EOT\254\ENQ\STX\"\n\ + \\EOT\EOTk\STX\NUL\DC2\EOT\195\ACK\STX\"\n\ \\r\n\ - \\ENQ\EOTd\STX\NUL\ACK\DC2\EOT\254\ENQ\STX\NAK\n\ + \\ENQ\EOTk\STX\NUL\ACK\DC2\EOT\195\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOTd\STX\NUL\SOH\DC2\EOT\254\ENQ\SYN\GS\n\ + \\ENQ\EOTk\STX\NUL\SOH\DC2\EOT\195\ACK\SYN\GS\n\ \\r\n\ - \\ENQ\EOTd\STX\NUL\ETX\DC2\EOT\254\ENQ !\n\ + \\ENQ\EOTk\STX\NUL\ETX\DC2\EOT\195\ACK !\n\ \\f\n\ - \\EOT\EOTd\STX\SOH\DC2\EOT\255\ENQ\STX\US\n\ + \\EOT\EOTk\STX\SOH\DC2\EOT\196\ACK\STX\US\n\ \\r\n\ - \\ENQ\EOTd\STX\SOH\ACK\DC2\EOT\255\ENQ\STX\DLE\n\ + \\ENQ\EOTk\STX\SOH\ACK\DC2\EOT\196\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTd\STX\SOH\SOH\DC2\EOT\255\ENQ\DC1\SUB\n\ + \\ENQ\EOTk\STX\SOH\SOH\DC2\EOT\196\ACK\DC1\SUB\n\ \\r\n\ - \\ENQ\EOTd\STX\SOH\ETX\DC2\EOT\255\ENQ\GS\RS\n\ + \\ENQ\EOTk\STX\SOH\ETX\DC2\EOT\196\ACK\GS\RS\n\ \\f\n\ - \\STX\EOTe\DC2\ACK\130\ACK\NUL\135\ACK\SOH\n\ + \\STX\EOTl\DC2\ACK\199\ACK\NUL\204\ACK\SOH\n\ \\v\n\ - \\ETX\EOTe\SOH\DC2\EOT\130\ACK\b\DC4\n\ + \\ETX\EOTl\SOH\DC2\EOT\199\ACK\b\DC4\n\ \\f\n\ - \\EOT\EOTe\STX\NUL\DC2\EOT\131\ACK\STX\SUB\n\ + \\EOT\EOTl\STX\NUL\DC2\EOT\200\ACK\STX\SUB\n\ \\r\n\ - \\ENQ\EOTe\STX\NUL\ACK\DC2\EOT\131\ACK\STX\v\n\ + \\ENQ\EOTl\STX\NUL\ACK\DC2\EOT\200\ACK\STX\v\n\ \\r\n\ - \\ENQ\EOTe\STX\NUL\SOH\DC2\EOT\131\ACK\f\NAK\n\ + \\ENQ\EOTl\STX\NUL\SOH\DC2\EOT\200\ACK\f\NAK\n\ \\r\n\ - \\ENQ\EOTe\STX\NUL\ETX\DC2\EOT\131\ACK\CAN\EM\n\ + \\ENQ\EOTl\STX\NUL\ETX\DC2\EOT\200\ACK\CAN\EM\n\ \\f\n\ - \\EOT\EOTe\STX\SOH\DC2\EOT\132\ACK\STX\SUB\n\ + \\EOT\EOTl\STX\SOH\DC2\EOT\201\ACK\STX\SUB\n\ \\r\n\ - \\ENQ\EOTe\STX\SOH\ACK\DC2\EOT\132\ACK\STX\v\n\ + \\ENQ\EOTl\STX\SOH\ACK\DC2\EOT\201\ACK\STX\v\n\ \\r\n\ - \\ENQ\EOTe\STX\SOH\SOH\DC2\EOT\132\ACK\f\NAK\n\ + \\ENQ\EOTl\STX\SOH\SOH\DC2\EOT\201\ACK\f\NAK\n\ \\r\n\ - \\ENQ\EOTe\STX\SOH\ETX\DC2\EOT\132\ACK\CAN\EM\n\ + \\ENQ\EOTl\STX\SOH\ETX\DC2\EOT\201\ACK\CAN\EM\n\ \\f\n\ - \\EOT\EOTe\STX\STX\DC2\EOT\133\ACK\STX\SUB\n\ + \\EOT\EOTl\STX\STX\DC2\EOT\202\ACK\STX\SUB\n\ \\r\n\ - \\ENQ\EOTe\STX\STX\ACK\DC2\EOT\133\ACK\STX\v\n\ + \\ENQ\EOTl\STX\STX\ACK\DC2\EOT\202\ACK\STX\v\n\ \\r\n\ - \\ENQ\EOTe\STX\STX\SOH\DC2\EOT\133\ACK\f\NAK\n\ + \\ENQ\EOTl\STX\STX\SOH\DC2\EOT\202\ACK\f\NAK\n\ \\r\n\ - \\ENQ\EOTe\STX\STX\ETX\DC2\EOT\133\ACK\CAN\EM\n\ + \\ENQ\EOTl\STX\STX\ETX\DC2\EOT\202\ACK\CAN\EM\n\ \\f\n\ - \\EOT\EOTe\STX\ETX\DC2\EOT\134\ACK\STX\SUB\n\ + \\EOT\EOTl\STX\ETX\DC2\EOT\203\ACK\STX\SUB\n\ \\r\n\ - \\ENQ\EOTe\STX\ETX\ACK\DC2\EOT\134\ACK\STX\v\n\ + \\ENQ\EOTl\STX\ETX\ACK\DC2\EOT\203\ACK\STX\v\n\ \\r\n\ - \\ENQ\EOTe\STX\ETX\SOH\DC2\EOT\134\ACK\f\NAK\n\ + \\ENQ\EOTl\STX\ETX\SOH\DC2\EOT\203\ACK\f\NAK\n\ \\r\n\ - \\ENQ\EOTe\STX\ETX\ETX\DC2\EOT\134\ACK\CAN\EM\n\ + \\ENQ\EOTl\STX\ETX\ETX\DC2\EOT\203\ACK\CAN\EM\n\ \U\n\ - \\STX\EOTf\DC2\ACK\138\ACK\NUL\188\ACK\SOH\SUBG Unified Genesis configuration containing all parameters from all eras\n\ + \\STX\EOTm\DC2\ACK\207\ACK\NUL\129\a\SOH\SUBG Unified Genesis configuration containing all parameters from all eras\n\ \\n\ \\v\n\ - \\ETX\EOTf\SOH\DC2\EOT\138\ACK\b\SI\n\ + \\ETX\EOTm\SOH\DC2\EOT\207\ACK\b\SI\n\ \:\n\ - \\EOT\EOTf\STX\NUL\DC2\EOT\140\ACK\STX%\SUB, ============ Byron Era Fields ============\n\ + \\EOT\EOTm\STX\NUL\DC2\EOT\209\ACK\STX%\SUB, ============ Byron Era Fields ============\n\ \\n\ \\r\n\ - \\ENQ\EOTf\STX\NUL\ACK\DC2\EOT\140\ACK\STX\NAK\n\ + \\ENQ\EOTm\STX\NUL\ACK\DC2\EOT\209\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX\NUL\SOH\DC2\EOT\140\ACK\SYN \n\ + \\ENQ\EOTm\STX\NUL\SOH\DC2\EOT\209\ACK\SYN \n\ \\r\n\ - \\ENQ\EOTf\STX\NUL\ETX\DC2\EOT\140\ACK#$\n\ + \\ENQ\EOTm\STX\NUL\ETX\DC2\EOT\209\ACK#$\n\ \\f\n\ - \\EOT\EOTf\STX\SOH\DC2\EOT\141\ACK\STX*\n\ + \\EOT\EOTm\STX\SOH\DC2\EOT\210\ACK\STX*\n\ \\r\n\ - \\ENQ\EOTf\STX\SOH\ACK\DC2\EOT\141\ACK\STX\DC2\n\ + \\ENQ\EOTm\STX\SOH\ACK\DC2\EOT\210\ACK\STX\DC2\n\ \\r\n\ - \\ENQ\EOTf\STX\SOH\SOH\DC2\EOT\141\ACK\DC3%\n\ + \\ENQ\EOTm\STX\SOH\SOH\DC2\EOT\210\ACK\DC3%\n\ \\r\n\ - \\ENQ\EOTf\STX\SOH\ETX\DC2\EOT\141\ACK()\n\ + \\ENQ\EOTm\STX\SOH\ETX\DC2\EOT\210\ACK()\n\ \\f\n\ - \\EOT\EOTf\STX\STX\DC2\EOT\142\ACK\STX\SYN\n\ + \\EOT\EOTm\STX\STX\DC2\EOT\211\ACK\STX\SYN\n\ \\r\n\ - \\ENQ\EOTf\STX\STX\ENQ\DC2\EOT\142\ACK\STX\b\n\ + \\ENQ\EOTm\STX\STX\ENQ\DC2\EOT\211\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\STX\SOH\DC2\EOT\142\ACK\t\DC1\n\ + \\ENQ\EOTm\STX\STX\SOH\DC2\EOT\211\ACK\t\DC1\n\ \\r\n\ - \\ENQ\EOTf\STX\STX\ETX\DC2\EOT\142\ACK\DC4\NAK\n\ + \\ENQ\EOTm\STX\STX\ETX\DC2\EOT\211\ACK\DC4\NAK\n\ \\f\n\ - \\EOT\EOTf\STX\ETX\DC2\EOT\143\ACK\STX%\n\ + \\EOT\EOTm\STX\ETX\DC2\EOT\212\ACK\STX%\n\ \\r\n\ - \\ENQ\EOTf\STX\ETX\ACK\DC2\EOT\143\ACK\STX\DLE\n\ + \\ENQ\EOTm\STX\ETX\ACK\DC2\EOT\212\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTf\STX\ETX\SOH\DC2\EOT\143\ACK\DC1 \n\ + \\ENQ\EOTm\STX\ETX\SOH\DC2\EOT\212\ACK\DC1 \n\ \\r\n\ - \\ENQ\EOTf\STX\ETX\ETX\DC2\EOT\143\ACK#$\n\ + \\ENQ\EOTm\STX\ETX\ETX\DC2\EOT\212\ACK#$\n\ \\f\n\ - \\EOT\EOTf\STX\EOT\DC2\EOT\144\ACK\STX\CAN\n\ + \\EOT\EOTm\STX\EOT\DC2\EOT\213\ACK\STX\CAN\n\ \\r\n\ - \\ENQ\EOTf\STX\EOT\ENQ\DC2\EOT\144\ACK\STX\b\n\ + \\ENQ\EOTm\STX\EOT\ENQ\DC2\EOT\213\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\EOT\SOH\DC2\EOT\144\ACK\t\DC3\n\ + \\ENQ\EOTm\STX\EOT\SOH\DC2\EOT\213\ACK\t\DC3\n\ \\r\n\ - \\ENQ\EOTf\STX\EOT\ETX\DC2\EOT\144\ACK\SYN\ETB\n\ + \\ENQ\EOTm\STX\EOT\ETX\DC2\EOT\213\ACK\SYN\ETB\n\ \\f\n\ - \\EOT\EOTf\STX\ENQ\DC2\EOT\145\ACK\STX,\n\ + \\EOT\EOTm\STX\ENQ\DC2\EOT\214\ACK\STX,\n\ \\r\n\ - \\ENQ\EOTf\STX\ENQ\ACK\DC2\EOT\145\ACK\STX\NAK\n\ + \\ENQ\EOTm\STX\ENQ\ACK\DC2\EOT\214\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX\ENQ\SOH\DC2\EOT\145\ACK\SYN'\n\ + \\ENQ\EOTm\STX\ENQ\SOH\DC2\EOT\214\ACK\SYN'\n\ \\r\n\ - \\ENQ\EOTf\STX\ENQ\ETX\DC2\EOT\145\ACK*+\n\ + \\ENQ\EOTm\STX\ENQ\ETX\DC2\EOT\214\ACK*+\n\ \\f\n\ - \\EOT\EOTf\STX\ACK\DC2\EOT\146\ACK\STX4\n\ + \\EOT\EOTm\STX\ACK\DC2\EOT\215\ACK\STX4\n\ \\r\n\ - \\ENQ\EOTf\STX\ACK\ACK\DC2\EOT\146\ACK\STX\RS\n\ + \\ENQ\EOTm\STX\ACK\ACK\DC2\EOT\215\ACK\STX\RS\n\ \\r\n\ - \\ENQ\EOTf\STX\ACK\SOH\DC2\EOT\146\ACK\US/\n\ + \\ENQ\EOTm\STX\ACK\SOH\DC2\EOT\215\ACK\US/\n\ \\r\n\ - \\ENQ\EOTf\STX\ACK\ETX\DC2\EOT\146\ACK23\n\ + \\ENQ\EOTm\STX\ACK\ETX\DC2\EOT\215\ACK23\n\ \\f\n\ - \\EOT\EOTf\STX\a\DC2\EOT\147\ACK\STX,\n\ + \\EOT\EOTm\STX\a\DC2\EOT\216\ACK\STX,\n\ \\r\n\ - \\ENQ\EOTf\STX\a\ACK\DC2\EOT\147\ACK\STX\NAK\n\ + \\ENQ\EOTm\STX\a\ACK\DC2\EOT\216\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX\a\SOH\DC2\EOT\147\ACK\SYN'\n\ + \\ENQ\EOTm\STX\a\SOH\DC2\EOT\216\ACK\SYN'\n\ \\r\n\ - \\ENQ\EOTf\STX\a\ETX\DC2\EOT\147\ACK*+\n\ + \\ENQ\EOTm\STX\a\ETX\DC2\EOT\216\ACK*+\n\ \\f\n\ - \\EOT\EOTf\STX\b\DC2\EOT\148\ACK\STX%\n\ + \\EOT\EOTm\STX\b\DC2\EOT\217\ACK\STX%\n\ \\r\n\ - \\ENQ\EOTf\STX\b\ACK\DC2\EOT\148\ACK\STX\SYN\n\ + \\ENQ\EOTm\STX\b\ACK\DC2\EOT\217\ACK\STX\SYN\n\ \\r\n\ - \\ENQ\EOTf\STX\b\SOH\DC2\EOT\148\ACK\ETB \n\ + \\ENQ\EOTm\STX\b\SOH\DC2\EOT\217\ACK\ETB \n\ \\r\n\ - \\ENQ\EOTf\STX\b\ETX\DC2\EOT\148\ACK#$\n\ + \\ENQ\EOTm\STX\b\ETX\DC2\EOT\217\ACK#$\n\ \<\n\ - \\EOT\EOTf\STX\t\DC2\EOT\151\ACK\STX)\SUB. ============ Shelley Era Fields ============\n\ + \\EOT\EOTm\STX\t\DC2\EOT\220\ACK\STX)\SUB. ============ Shelley Era Fields ============\n\ \\n\ \\r\n\ - \\ENQ\EOTf\STX\t\ACK\DC2\EOT\151\ACK\STX\DLE\n\ + \\ENQ\EOTm\STX\t\ACK\DC2\EOT\220\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTf\STX\t\SOH\DC2\EOT\151\ACK\DC1#\n\ + \\ENQ\EOTm\STX\t\SOH\DC2\EOT\220\ACK\DC1#\n\ \\r\n\ - \\ENQ\EOTf\STX\t\ETX\DC2\EOT\151\ACK&(\n\ + \\ENQ\EOTm\STX\t\ETX\DC2\EOT\220\ACK&(\n\ \\f\n\ - \\EOT\EOTf\STX\n\ - \\DC2\EOT\152\ACK\STX\ESC\n\ + \\EOT\EOTm\STX\n\ + \\DC2\EOT\221\ACK\STX\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX\n\ - \\ENQ\DC2\EOT\152\ACK\STX\b\n\ + \\ENQ\EOTm\STX\n\ + \\ENQ\DC2\EOT\221\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\n\ - \\SOH\DC2\EOT\152\ACK\t\NAK\n\ + \\ENQ\EOTm\STX\n\ + \\SOH\DC2\EOT\221\ACK\t\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX\n\ - \\ETX\DC2\EOT\152\ACK\CAN\SUB\n\ + \\ENQ\EOTm\STX\n\ + \\ETX\DC2\EOT\221\ACK\CAN\SUB\n\ \\f\n\ - \\EOT\EOTf\STX\v\DC2\EOT\153\ACK\STX)\n\ + \\EOT\EOTm\STX\v\DC2\EOT\222\ACK\STX)\n\ \\r\n\ - \\ENQ\EOTf\STX\v\ACK\DC2\EOT\153\ACK\STX\CAN\n\ + \\ENQ\EOTm\STX\v\ACK\DC2\EOT\222\ACK\STX\CAN\n\ \\r\n\ - \\ENQ\EOTf\STX\v\SOH\DC2\EOT\153\ACK\EM#\n\ + \\ENQ\EOTm\STX\v\SOH\DC2\EOT\222\ACK\EM#\n\ \\r\n\ - \\ENQ\EOTf\STX\v\ETX\DC2\EOT\153\ACK&(\n\ + \\ENQ\EOTm\STX\v\ETX\DC2\EOT\222\ACK&(\n\ \\f\n\ - \\EOT\EOTf\STX\f\DC2\EOT\154\ACK\STX)\n\ + \\EOT\EOTm\STX\f\DC2\EOT\223\ACK\STX)\n\ \\r\n\ - \\ENQ\EOTf\STX\f\ACK\DC2\EOT\154\ACK\STX\NAK\n\ + \\ENQ\EOTm\STX\f\ACK\DC2\EOT\223\ACK\STX\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX\f\SOH\DC2\EOT\154\ACK\SYN#\n\ + \\ENQ\EOTm\STX\f\SOH\DC2\EOT\223\ACK\SYN#\n\ \\r\n\ - \\ENQ\EOTf\STX\f\ETX\DC2\EOT\154\ACK&(\n\ + \\ENQ\EOTm\STX\f\ETX\DC2\EOT\223\ACK&(\n\ \\f\n\ - \\EOT\EOTf\STX\r\DC2\EOT\155\ACK\STX!\n\ + \\EOT\EOTm\STX\r\DC2\EOT\224\ACK\STX!\n\ \\r\n\ - \\ENQ\EOTf\STX\r\ENQ\DC2\EOT\155\ACK\STX\b\n\ + \\ENQ\EOTm\STX\r\ENQ\DC2\EOT\224\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\r\SOH\DC2\EOT\155\ACK\t\ESC\n\ + \\ENQ\EOTm\STX\r\SOH\DC2\EOT\224\ACK\t\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX\r\ETX\DC2\EOT\155\ACK\RS \n\ + \\ENQ\EOTm\STX\r\ETX\DC2\EOT\224\ACK\RS \n\ \\f\n\ - \\EOT\EOTf\STX\SO\DC2\EOT\156\ACK\STX\"\n\ + \\EOT\EOTm\STX\SO\DC2\EOT\225\ACK\STX\"\n\ \\r\n\ - \\ENQ\EOTf\STX\SO\ACK\DC2\EOT\156\ACK\STX\b\n\ + \\ENQ\EOTm\STX\SO\ACK\DC2\EOT\225\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\SO\SOH\DC2\EOT\156\ACK\t\FS\n\ + \\ENQ\EOTm\STX\SO\SOH\DC2\EOT\225\ACK\t\FS\n\ \\r\n\ - \\ENQ\EOTf\STX\SO\ETX\DC2\EOT\156\ACK\US!\n\ + \\ENQ\EOTm\STX\SO\ETX\DC2\EOT\225\ACK\US!\n\ \\f\n\ - \\EOT\EOTf\STX\SI\DC2\EOT\157\ACK\STX\EM\n\ + \\EOT\EOTm\STX\SI\DC2\EOT\226\ACK\STX\EM\n\ \\r\n\ - \\ENQ\EOTf\STX\SI\ENQ\DC2\EOT\157\ACK\STX\b\n\ + \\ENQ\EOTm\STX\SI\ENQ\DC2\EOT\226\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\SI\SOH\DC2\EOT\157\ACK\t\DC3\n\ + \\ENQ\EOTm\STX\SI\SOH\DC2\EOT\226\ACK\t\DC3\n\ \\r\n\ - \\ENQ\EOTf\STX\SI\ETX\DC2\EOT\157\ACK\SYN\CAN\n\ + \\ENQ\EOTm\STX\SI\ETX\DC2\EOT\226\ACK\SYN\CAN\n\ \\f\n\ - \\EOT\EOTf\STX\DLE\DC2\EOT\158\ACK\STX\FS\n\ + \\EOT\EOTm\STX\DLE\DC2\EOT\227\ACK\STX\FS\n\ \\r\n\ - \\ENQ\EOTf\STX\DLE\ENQ\DC2\EOT\158\ACK\STX\b\n\ + \\ENQ\EOTm\STX\DLE\ENQ\DC2\EOT\227\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\DLE\SOH\DC2\EOT\158\ACK\t\SYN\n\ + \\ENQ\EOTm\STX\DLE\SOH\DC2\EOT\227\ACK\t\SYN\n\ \\r\n\ - \\ENQ\EOTf\STX\DLE\ETX\DC2\EOT\158\ACK\EM\ESC\n\ + \\ENQ\EOTm\STX\DLE\ETX\DC2\EOT\227\ACK\EM\ESC\n\ \K\n\ - \\EOT\EOTf\STX\DC1\DC2\EOT\159\ACK\STX\US\"= Using PParams as it's a superset of all protocol parameters\n\ + \\EOT\EOTm\STX\DC1\DC2\EOT\228\ACK\STX\US\"= Using PParams as it's a superset of all protocol parameters\n\ \\n\ \\r\n\ - \\ENQ\EOTf\STX\DC1\ACK\DC2\EOT\159\ACK\STX\t\n\ + \\ENQ\EOTm\STX\DC1\ACK\DC2\EOT\228\ACK\STX\t\n\ \\r\n\ - \\ENQ\EOTf\STX\DC1\SOH\DC2\EOT\159\ACK\n\ + \\ENQ\EOTm\STX\DC1\SOH\DC2\EOT\228\ACK\n\ \\EM\n\ \\r\n\ - \\ENQ\EOTf\STX\DC1\ETX\DC2\EOT\159\ACK\FS\RS\n\ + \\ENQ\EOTm\STX\DC1\ETX\DC2\EOT\228\ACK\FS\RS\n\ \\f\n\ - \\EOT\EOTf\STX\DC2\DC2\EOT\160\ACK\STX\GS\n\ + \\EOT\EOTm\STX\DC2\DC2\EOT\229\ACK\STX\GS\n\ \\r\n\ - \\ENQ\EOTf\STX\DC2\ENQ\DC2\EOT\160\ACK\STX\b\n\ + \\ENQ\EOTm\STX\DC2\ENQ\DC2\EOT\229\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\DC2\SOH\DC2\EOT\160\ACK\t\ETB\n\ + \\ENQ\EOTm\STX\DC2\SOH\DC2\EOT\229\ACK\t\ETB\n\ \\r\n\ - \\ENQ\EOTf\STX\DC2\ETX\DC2\EOT\160\ACK\SUB\FS\n\ + \\ENQ\EOTm\STX\DC2\ETX\DC2\EOT\229\ACK\SUB\FS\n\ \\f\n\ - \\EOT\EOTf\STX\DC3\DC2\EOT\161\ACK\STX\SUB\n\ + \\EOT\EOTm\STX\DC3\DC2\EOT\230\ACK\STX\SUB\n\ \\r\n\ - \\ENQ\EOTf\STX\DC3\ENQ\DC2\EOT\161\ACK\STX\b\n\ + \\ENQ\EOTm\STX\DC3\ENQ\DC2\EOT\230\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\DC3\SOH\DC2\EOT\161\ACK\t\DC4\n\ + \\ENQ\EOTm\STX\DC3\SOH\DC2\EOT\230\ACK\t\DC4\n\ \\r\n\ - \\ENQ\EOTf\STX\DC3\ETX\DC2\EOT\161\ACK\ETB\EM\n\ + \\ENQ\EOTm\STX\DC3\ETX\DC2\EOT\230\ACK\ETB\EM\n\ \\f\n\ - \\EOT\EOTf\STX\DC4\DC2\EOT\162\ACK\STX#\n\ + \\EOT\EOTm\STX\DC4\DC2\EOT\231\ACK\STX#\n\ \\r\n\ - \\ENQ\EOTf\STX\DC4\ENQ\DC2\EOT\162\ACK\STX\b\n\ + \\ENQ\EOTm\STX\DC4\ENQ\DC2\EOT\231\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\DC4\SOH\DC2\EOT\162\ACK\t\GS\n\ + \\ENQ\EOTm\STX\DC4\SOH\DC2\EOT\231\ACK\t\GS\n\ \\r\n\ - \\ENQ\EOTf\STX\DC4\ETX\DC2\EOT\162\ACK \"\n\ + \\ENQ\EOTm\STX\DC4\ETX\DC2\EOT\231\ACK \"\n\ \\f\n\ - \\EOT\EOTf\STX\NAK\DC2\EOT\163\ACK\STX\ESC\n\ + \\EOT\EOTm\STX\NAK\DC2\EOT\232\ACK\STX\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX\NAK\ENQ\DC2\EOT\163\ACK\STX\b\n\ + \\ENQ\EOTm\STX\NAK\ENQ\DC2\EOT\232\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\NAK\SOH\DC2\EOT\163\ACK\t\NAK\n\ + \\ENQ\EOTm\STX\NAK\SOH\DC2\EOT\232\ACK\t\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX\NAK\ETX\DC2\EOT\163\ACK\CAN\SUB\n\ + \\ENQ\EOTm\STX\NAK\ETX\DC2\EOT\232\ACK\CAN\SUB\n\ \\f\n\ - \\EOT\EOTf\STX\SYN\DC2\EOT\164\ACK\STX\FS\n\ + \\EOT\EOTm\STX\SYN\DC2\EOT\233\ACK\STX\FS\n\ \\r\n\ - \\ENQ\EOTf\STX\SYN\ENQ\DC2\EOT\164\ACK\STX\b\n\ + \\ENQ\EOTm\STX\SYN\ENQ\DC2\EOT\233\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\SYN\SOH\DC2\EOT\164\ACK\t\SYN\n\ + \\ENQ\EOTm\STX\SYN\SOH\DC2\EOT\233\ACK\t\SYN\n\ \\r\n\ - \\ENQ\EOTf\STX\SYN\ETX\DC2\EOT\164\ACK\EM\ESC\n\ + \\ENQ\EOTm\STX\SYN\ETX\DC2\EOT\233\ACK\EM\ESC\n\ \;\n\ - \\EOT\EOTf\STX\ETB\DC2\EOT\167\ACK\STX%\SUB- ============ Alonzo Era Fields ============\n\ + \\EOT\EOTm\STX\ETB\DC2\EOT\236\ACK\STX%\SUB- ============ Alonzo Era Fields ============\n\ \\n\ \\r\n\ - \\ENQ\EOTf\STX\ETB\ACK\DC2\EOT\167\ACK\STX\b\n\ + \\ENQ\EOTm\STX\ETB\ACK\DC2\EOT\236\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\ETB\SOH\DC2\EOT\167\ACK\t\US\n\ + \\ENQ\EOTm\STX\ETB\SOH\DC2\EOT\236\ACK\t\US\n\ \\r\n\ - \\ENQ\EOTf\STX\ETB\ETX\DC2\EOT\167\ACK\"$\n\ + \\ENQ\EOTm\STX\ETB\ETX\DC2\EOT\236\ACK\"$\n\ \\f\n\ - \\EOT\EOTf\STX\CAN\DC2\EOT\168\ACK\STX!\n\ + \\EOT\EOTm\STX\CAN\DC2\EOT\237\ACK\STX!\n\ \\r\n\ - \\ENQ\EOTf\STX\CAN\ACK\DC2\EOT\168\ACK\STX\n\ + \\ENQ\EOTm\STX\CAN\ACK\DC2\EOT\237\ACK\STX\n\ \\n\ \\r\n\ - \\ENQ\EOTf\STX\CAN\SOH\DC2\EOT\168\ACK\v\ESC\n\ + \\ENQ\EOTm\STX\CAN\SOH\DC2\EOT\237\ACK\v\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX\CAN\ETX\DC2\EOT\168\ACK\RS \n\ + \\ENQ\EOTm\STX\CAN\ETX\DC2\EOT\237\ACK\RS \n\ \\f\n\ - \\EOT\EOTf\STX\EM\DC2\EOT\169\ACK\STX\US\n\ + \\EOT\EOTm\STX\EM\DC2\EOT\238\ACK\STX\US\n\ \\r\n\ - \\ENQ\EOTf\STX\EM\ACK\DC2\EOT\169\ACK\STX\t\n\ + \\ENQ\EOTm\STX\EM\ACK\DC2\EOT\238\ACK\STX\t\n\ \\r\n\ - \\ENQ\EOTf\STX\EM\SOH\DC2\EOT\169\ACK\n\ + \\ENQ\EOTm\STX\EM\SOH\DC2\EOT\238\ACK\n\ \\EM\n\ \\r\n\ - \\ENQ\EOTf\STX\EM\ETX\DC2\EOT\169\ACK\FS\RS\n\ + \\ENQ\EOTm\STX\EM\ETX\DC2\EOT\238\ACK\FS\RS\n\ \\f\n\ - \\EOT\EOTf\STX\SUB\DC2\EOT\170\ACK\STX\"\n\ + \\EOT\EOTm\STX\SUB\DC2\EOT\239\ACK\STX\"\n\ \\r\n\ - \\ENQ\EOTf\STX\SUB\ACK\DC2\EOT\170\ACK\STX\t\n\ + \\ENQ\EOTm\STX\SUB\ACK\DC2\EOT\239\ACK\STX\t\n\ \\r\n\ - \\ENQ\EOTf\STX\SUB\SOH\DC2\EOT\170\ACK\n\ + \\ENQ\EOTm\STX\SUB\SOH\DC2\EOT\239\ACK\n\ \\FS\n\ \\r\n\ - \\ENQ\EOTf\STX\SUB\ETX\DC2\EOT\170\ACK\US!\n\ + \\ENQ\EOTm\STX\SUB\ETX\DC2\EOT\239\ACK\US!\n\ \\f\n\ - \\EOT\EOTf\STX\ESC\DC2\EOT\171\ACK\STX\GS\n\ + \\EOT\EOTm\STX\ESC\DC2\EOT\240\ACK\STX\GS\n\ \\r\n\ - \\ENQ\EOTf\STX\ESC\ENQ\DC2\EOT\171\ACK\STX\b\n\ + \\ENQ\EOTm\STX\ESC\ENQ\DC2\EOT\240\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\ESC\SOH\DC2\EOT\171\ACK\t\ETB\n\ + \\ENQ\EOTm\STX\ESC\SOH\DC2\EOT\240\ACK\t\ETB\n\ \\r\n\ - \\ENQ\EOTf\STX\ESC\ETX\DC2\EOT\171\ACK\SUB\FS\n\ + \\ENQ\EOTm\STX\ESC\ETX\DC2\EOT\240\ACK\SUB\FS\n\ \\f\n\ - \\EOT\EOTf\STX\FS\DC2\EOT\172\ACK\STX$\n\ + \\EOT\EOTm\STX\FS\DC2\EOT\241\ACK\STX$\n\ \\r\n\ - \\ENQ\EOTf\STX\FS\ENQ\DC2\EOT\172\ACK\STX\b\n\ + \\ENQ\EOTm\STX\FS\ENQ\DC2\EOT\241\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\FS\SOH\DC2\EOT\172\ACK\t\RS\n\ + \\ENQ\EOTm\STX\FS\SOH\DC2\EOT\241\ACK\t\RS\n\ \\r\n\ - \\ENQ\EOTf\STX\FS\ETX\DC2\EOT\172\ACK!#\n\ + \\ENQ\EOTm\STX\FS\ETX\DC2\EOT\241\ACK!#\n\ \\f\n\ - \\EOT\EOTf\STX\GS\DC2\EOT\173\ACK\STX$\n\ + \\EOT\EOTm\STX\GS\DC2\EOT\242\ACK\STX$\n\ \\r\n\ - \\ENQ\EOTf\STX\GS\ENQ\DC2\EOT\173\ACK\STX\b\n\ + \\ENQ\EOTm\STX\GS\ENQ\DC2\EOT\242\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\GS\SOH\DC2\EOT\173\ACK\t\RS\n\ + \\ENQ\EOTm\STX\GS\SOH\DC2\EOT\242\ACK\t\RS\n\ \\r\n\ - \\ENQ\EOTf\STX\GS\ETX\DC2\EOT\173\ACK!#\n\ + \\ENQ\EOTm\STX\GS\ETX\DC2\EOT\242\ACK!#\n\ \\f\n\ - \\EOT\EOTf\STX\RS\DC2\EOT\174\ACK\STX \n\ + \\EOT\EOTm\STX\RS\DC2\EOT\243\ACK\STX \n\ \\r\n\ - \\ENQ\EOTf\STX\RS\ACK\DC2\EOT\174\ACK\STX\SO\n\ + \\ENQ\EOTm\STX\RS\ACK\DC2\EOT\243\ACK\STX\SO\n\ \\r\n\ - \\ENQ\EOTf\STX\RS\SOH\DC2\EOT\174\ACK\SI\SUB\n\ + \\ENQ\EOTm\STX\RS\SOH\DC2\EOT\243\ACK\SI\SUB\n\ \\r\n\ - \\ENQ\EOTf\STX\RS\ETX\DC2\EOT\174\ACK\GS\US\n\ + \\ENQ\EOTm\STX\RS\ETX\DC2\EOT\243\ACK\GS\US\n\ \;\n\ - \\EOT\EOTf\STX\US\DC2\EOT\177\ACK\STX\ESC\SUB- ============ Conway Era Fields ============\n\ + \\EOT\EOTm\STX\US\DC2\EOT\246\ACK\STX\ESC\SUB- ============ Conway Era Fields ============\n\ \\n\ \\r\n\ - \\ENQ\EOTf\STX\US\ACK\DC2\EOT\177\ACK\STX\v\n\ + \\ENQ\EOTm\STX\US\ACK\DC2\EOT\246\ACK\STX\v\n\ \\r\n\ - \\ENQ\EOTf\STX\US\SOH\DC2\EOT\177\ACK\f\NAK\n\ + \\ENQ\EOTm\STX\US\SOH\DC2\EOT\246\ACK\f\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX\US\ETX\DC2\EOT\177\ACK\CAN\SUB\n\ + \\ENQ\EOTm\STX\US\ETX\DC2\EOT\246\ACK\CAN\SUB\n\ \\f\n\ - \\EOT\EOTf\STX \DC2\EOT\178\ACK\STX!\n\ + \\EOT\EOTm\STX \DC2\EOT\247\ACK\STX!\n\ \\r\n\ - \\ENQ\EOTf\STX \ACK\DC2\EOT\178\ACK\STX\SO\n\ + \\ENQ\EOTm\STX \ACK\DC2\EOT\247\ACK\STX\SO\n\ \\r\n\ - \\ENQ\EOTf\STX \SOH\DC2\EOT\178\ACK\SI\ESC\n\ + \\ENQ\EOTm\STX \SOH\DC2\EOT\247\ACK\SI\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX \ETX\DC2\EOT\178\ACK\RS \n\ + \\ENQ\EOTm\STX \ETX\DC2\EOT\247\ACK\RS \n\ \\f\n\ - \\EOT\EOTf\STX!\DC2\EOT\179\ACK\STX!\n\ + \\EOT\EOTm\STX!\DC2\EOT\248\ACK\STX!\n\ \\r\n\ - \\ENQ\EOTf\STX!\ENQ\DC2\EOT\179\ACK\STX\b\n\ + \\ENQ\EOTm\STX!\ENQ\DC2\EOT\248\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX!\SOH\DC2\EOT\179\ACK\t\ESC\n\ + \\ENQ\EOTm\STX!\SOH\DC2\EOT\248\ACK\t\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX!\ETX\DC2\EOT\179\ACK\RS \n\ + \\ENQ\EOTm\STX!\ETX\DC2\EOT\248\ACK\RS \n\ \\f\n\ - \\EOT\EOTf\STX\"\DC2\EOT\180\ACK\STX(\n\ + \\EOT\EOTm\STX\"\DC2\EOT\249\ACK\STX(\n\ \\r\n\ - \\ENQ\EOTf\STX\"\ENQ\DC2\EOT\180\ACK\STX\b\n\ + \\ENQ\EOTm\STX\"\ENQ\DC2\EOT\249\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX\"\SOH\DC2\EOT\180\ACK\t\"\n\ + \\ENQ\EOTm\STX\"\SOH\DC2\EOT\249\ACK\t\"\n\ \\r\n\ - \\ENQ\EOTf\STX\"\ETX\DC2\EOT\180\ACK%'\n\ + \\ENQ\EOTm\STX\"\ETX\DC2\EOT\249\ACK%'\n\ \\f\n\ - \\EOT\EOTf\STX#\DC2\EOT\181\ACK\STX\"\n\ + \\EOT\EOTm\STX#\DC2\EOT\250\ACK\STX\"\n\ \\r\n\ - \\ENQ\EOTf\STX#\ENQ\DC2\EOT\181\ACK\STX\b\n\ + \\ENQ\EOTm\STX#\ENQ\DC2\EOT\250\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX#\SOH\DC2\EOT\181\ACK\t\FS\n\ + \\ENQ\EOTm\STX#\SOH\DC2\EOT\250\ACK\t\FS\n\ \\r\n\ - \\ENQ\EOTf\STX#\ETX\DC2\EOT\181\ACK\US!\n\ + \\ENQ\EOTm\STX#\ETX\DC2\EOT\250\ACK\US!\n\ \\f\n\ - \\EOT\EOTf\STX$\DC2\EOT\182\ACK\STX!\n\ + \\EOT\EOTm\STX$\DC2\EOT\251\ACK\STX!\n\ \\r\n\ - \\ENQ\EOTf\STX$\ACK\DC2\EOT\182\ACK\STX\b\n\ + \\ENQ\EOTm\STX$\ACK\DC2\EOT\251\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX$\SOH\DC2\EOT\182\ACK\t\ESC\n\ + \\ENQ\EOTm\STX$\SOH\DC2\EOT\251\ACK\t\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX$\ETX\DC2\EOT\182\ACK\RS \n\ + \\ENQ\EOTm\STX$\ETX\DC2\EOT\251\ACK\RS \n\ \\f\n\ - \\EOT\EOTf\STX%\DC2\EOT\183\ACK\STX\ESC\n\ + \\EOT\EOTm\STX%\DC2\EOT\252\ACK\STX\ESC\n\ \\r\n\ - \\ENQ\EOTf\STX%\ACK\DC2\EOT\183\ACK\STX\b\n\ + \\ENQ\EOTm\STX%\ACK\DC2\EOT\252\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX%\SOH\DC2\EOT\183\ACK\t\NAK\n\ + \\ENQ\EOTm\STX%\SOH\DC2\EOT\252\ACK\t\NAK\n\ \\r\n\ - \\ENQ\EOTf\STX%\ETX\DC2\EOT\183\ACK\CAN\SUB\n\ + \\ENQ\EOTm\STX%\ETX\DC2\EOT\252\ACK\CAN\SUB\n\ \\f\n\ - \\EOT\EOTf\STX&\DC2\EOT\184\ACK\STX\FS\n\ + \\EOT\EOTm\STX&\DC2\EOT\253\ACK\STX\FS\n\ \\r\n\ - \\ENQ\EOTf\STX&\ENQ\DC2\EOT\184\ACK\STX\b\n\ + \\ENQ\EOTm\STX&\ENQ\DC2\EOT\253\ACK\STX\b\n\ \\r\n\ - \\ENQ\EOTf\STX&\SOH\DC2\EOT\184\ACK\t\SYN\n\ + \\ENQ\EOTm\STX&\SOH\DC2\EOT\253\ACK\t\SYN\n\ \\r\n\ - \\ENQ\EOTf\STX&\ETX\DC2\EOT\184\ACK\EM\ESC\n\ + \\ENQ\EOTm\STX&\ETX\DC2\EOT\253\ACK\EM\ESC\n\ \\f\n\ - \\EOT\EOTf\STX'\DC2\EOT\185\ACK\STX7\n\ + \\EOT\EOTm\STX'\DC2\EOT\254\ACK\STX7\n\ \\r\n\ - \\ENQ\EOTf\STX'\ACK\DC2\EOT\185\ACK\STX\DLE\n\ + \\ENQ\EOTm\STX'\ACK\DC2\EOT\254\ACK\STX\DLE\n\ \\r\n\ - \\ENQ\EOTf\STX'\SOH\DC2\EOT\185\ACK\DC11\n\ + \\ENQ\EOTm\STX'\SOH\DC2\EOT\254\ACK\DC11\n\ \\r\n\ - \\ENQ\EOTf\STX'\ETX\DC2\EOT\185\ACK46\n\ + \\ENQ\EOTm\STX'\ETX\DC2\EOT\254\ACK46\n\ \\f\n\ - \\EOT\EOTf\STX(\DC2\EOT\186\ACK\STX3\n\ + \\EOT\EOTm\STX(\DC2\EOT\255\ACK\STX3\n\ \\r\n\ - \\ENQ\EOTf\STX(\ACK\DC2\EOT\186\ACK\STX\SYN\n\ + \\ENQ\EOTm\STX(\ACK\DC2\EOT\255\ACK\STX\SYN\n\ \\r\n\ - \\ENQ\EOTf\STX(\SOH\DC2\EOT\186\ACK\ETB-\n\ + \\ENQ\EOTm\STX(\SOH\DC2\EOT\255\ACK\ETB-\n\ \\r\n\ - \\ENQ\EOTf\STX(\ETX\DC2\EOT\186\ACK02\n\ + \\ENQ\EOTm\STX(\ETX\DC2\EOT\255\ACK02\n\ \\f\n\ - \\EOT\EOTf\STX)\DC2\EOT\187\ACK\STX3\n\ + \\EOT\EOTm\STX)\DC2\EOT\128\a\STX3\n\ \\r\n\ - \\ENQ\EOTf\STX)\ACK\DC2\EOT\187\ACK\STX\SYN\n\ + \\ENQ\EOTm\STX)\ACK\DC2\EOT\128\a\STX\SYN\n\ \\r\n\ - \\ENQ\EOTf\STX)\SOH\DC2\EOT\187\ACK\ETB-\n\ + \\ENQ\EOTm\STX)\SOH\DC2\EOT\128\a\ETB-\n\ \\r\n\ - \\ENQ\EOTf\STX)\ETX\DC2\EOT\187\ACK02b\ACKproto3" \ No newline at end of file + \\ENQ\EOTm\STX)\ETX\DC2\EOT\128\a02b\ACKproto3" \ No newline at end of file diff --git a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano_Fields.hs b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano_Fields.hs index 8f257e13b7..df8e6630c5 100644 --- a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano_Fields.hs +++ b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Cardano/Cardano_Fields.hs @@ -286,6 +286,13 @@ constitution :: Data.ProtoLens.Field.HasField s "constitution" a) => Lens.Family2.LensLike' f s a constitution = Data.ProtoLens.Field.field @"constitution" +constitutionalCommittee :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "constitutionalCommittee" a) => + Lens.Family2.LensLike' f s a +constitutionalCommittee + = Data.ProtoLens.Field.field @"constitutionalCommittee" constr :: forall f s a. (Prelude.Functor f, Data.ProtoLens.Field.HasField s "constr" a) => @@ -999,6 +1006,13 @@ maybe'constitution :: Lens.Family2.LensLike' f s a maybe'constitution = Data.ProtoLens.Field.field @"maybe'constitution" +maybe'constitutionalCommittee :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'constitutionalCommittee" a) => + Lens.Family2.LensLike' f s a +maybe'constitutionalCommittee + = Data.ProtoLens.Field.field @"maybe'constitutionalCommittee" maybe'constr :: forall f s a. (Prelude.Functor f, @@ -1586,6 +1600,12 @@ maybe'quantity :: Data.ProtoLens.Field.HasField s "maybe'quantity" a) => Lens.Family2.LensLike' f s a maybe'quantity = Data.ProtoLens.Field.field @"maybe'quantity" +maybe'query :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'query" a) => + Lens.Family2.LensLike' f s a +maybe'query = Data.ProtoLens.Field.field @"maybe'query" maybe'redeemer :: forall f s a. (Prelude.Functor f, @@ -1611,6 +1631,12 @@ maybe'resignCommitteeColdCert :: Lens.Family2.LensLike' f s a maybe'resignCommitteeColdCert = Data.ProtoLens.Field.field @"maybe'resignCommitteeColdCert" +maybe'result :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'result" a) => + Lens.Family2.LensLike' f s a +maybe'result = Data.ProtoLens.Field.field @"maybe'result" maybe'script :: forall f s a. (Prelude.Functor f, @@ -1655,6 +1681,12 @@ maybe'softforkRule :: Lens.Family2.LensLike' f s a maybe'softforkRule = Data.ProtoLens.Field.field @"maybe'softforkRule" +maybe'spo :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'spo" a) => + Lens.Family2.LensLike' f s a +maybe'spo = Data.ProtoLens.Field.field @"maybe'spo" maybe'stakeCredential :: forall f s a. (Prelude.Functor f, @@ -1676,6 +1708,13 @@ maybe'stakeDeregistration :: Lens.Family2.LensLike' f s a maybe'stakeDeregistration = Data.ProtoLens.Field.field @"maybe'stakeDeregistration" +maybe'stakeFraction :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'stakeFraction" a) => + Lens.Family2.LensLike' f s a +maybe'stakeFraction + = Data.ProtoLens.Field.field @"maybe'stakeFraction" maybe'stakeKeyDeposit :: forall f s a. (Prelude.Functor f, @@ -1683,6 +1722,13 @@ maybe'stakeKeyDeposit :: Lens.Family2.LensLike' f s a maybe'stakeKeyDeposit = Data.ProtoLens.Field.field @"maybe'stakeKeyDeposit" +maybe'stakePoolDistribution :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'stakePoolDistribution" a) => + Lens.Family2.LensLike' f s a +maybe'stakePoolDistribution + = Data.ProtoLens.Field.field @"maybe'stakePoolDistribution" maybe'stakeRegDelegCert :: forall f s a. (Prelude.Functor f, @@ -1829,6 +1875,12 @@ maybe'voteRegDelegCert :: Lens.Family2.LensLike' f s a maybe'voteRegDelegCert = Data.ProtoLens.Field.field @"maybe'voteRegDelegCert" +maybe'voter :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'voter" a) => + Lens.Family2.LensLike' f s a +maybe'voter = Data.ProtoLens.Field.field @"maybe'voter" maybe'witnesses :: forall f s a. (Prelude.Functor f, @@ -2140,6 +2192,12 @@ poolKeyhash :: Data.ProtoLens.Field.HasField s "poolKeyhash" a) => Lens.Family2.LensLike' f s a poolKeyhash = Data.ProtoLens.Field.field @"poolKeyhash" +poolKeyhashes :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "poolKeyhashes" a) => + Lens.Family2.LensLike' f s a +poolKeyhashes = Data.ProtoLens.Field.field @"poolKeyhashes" poolMetadata :: forall f s a. (Prelude.Functor f, @@ -2178,6 +2236,11 @@ poolVotingThresholds :: Lens.Family2.LensLike' f s a poolVotingThresholds = Data.ProtoLens.Field.field @"poolVotingThresholds" +pools :: + forall f s a. + (Prelude.Functor f, Data.ProtoLens.Field.HasField s "pools" a) => + Lens.Family2.LensLike' f s a +pools = Data.ProtoLens.Field.field @"pools" port :: forall f s a. (Prelude.Functor f, Data.ProtoLens.Field.HasField s "port" a) => @@ -2419,6 +2482,11 @@ softforkRule :: Data.ProtoLens.Field.HasField s "softforkRule" a) => Lens.Family2.LensLike' f s a softforkRule = Data.ProtoLens.Field.field @"softforkRule" +spo :: + forall f s a. + (Prelude.Functor f, Data.ProtoLens.Field.HasField s "spo" a) => + Lens.Family2.LensLike' f s a +spo = Data.ProtoLens.Field.field @"spo" stakeCredential :: forall f s a. (Prelude.Functor f, @@ -2438,12 +2506,25 @@ stakeDeregistration :: Lens.Family2.LensLike' f s a stakeDeregistration = Data.ProtoLens.Field.field @"stakeDeregistration" +stakeFraction :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "stakeFraction" a) => + Lens.Family2.LensLike' f s a +stakeFraction = Data.ProtoLens.Field.field @"stakeFraction" stakeKeyDeposit :: forall f s a. (Prelude.Functor f, Data.ProtoLens.Field.HasField s "stakeKeyDeposit" a) => Lens.Family2.LensLike' f s a stakeKeyDeposit = Data.ProtoLens.Field.field @"stakeKeyDeposit" +stakePoolDistribution :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "stakePoolDistribution" a) => + Lens.Family2.LensLike' f s a +stakePoolDistribution + = Data.ProtoLens.Field.field @"stakePoolDistribution" stakeRegDelegCert :: forall f s a. (Prelude.Functor f, @@ -2780,12 +2861,24 @@ vec'plutusDatums :: Data.ProtoLens.Field.HasField s "vec'plutusDatums" a) => Lens.Family2.LensLike' f s a vec'plutusDatums = Data.ProtoLens.Field.field @"vec'plutusDatums" +vec'poolKeyhashes :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "vec'poolKeyhashes" a) => + Lens.Family2.LensLike' f s a +vec'poolKeyhashes = Data.ProtoLens.Field.field @"vec'poolKeyhashes" vec'poolOwners :: forall f s a. (Prelude.Functor f, Data.ProtoLens.Field.HasField s "vec'poolOwners" a) => Lens.Family2.LensLike' f s a vec'poolOwners = Data.ProtoLens.Field.field @"vec'poolOwners" +vec'pools :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "vec'pools" a) => + Lens.Family2.LensLike' f s a +vec'pools = Data.ProtoLens.Field.field @"vec'pools" vec'proposals :: forall f s a. (Prelude.Functor f, @@ -2870,6 +2963,12 @@ vec'vkeywitness :: Data.ProtoLens.Field.HasField s "vec'vkeywitness" a) => Lens.Family2.LensLike' f s a vec'vkeywitness = Data.ProtoLens.Field.field @"vec'vkeywitness" +vec'votes :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "vec'votes" a) => + Lens.Family2.LensLike' f s a +vec'votes = Data.ProtoLens.Field.field @"vec'votes" vec'withdrawals :: forall f s a. (Prelude.Functor f, @@ -2887,6 +2986,11 @@ vkeywitness :: Data.ProtoLens.Field.HasField s "vkeywitness" a) => Lens.Family2.LensLike' f s a vkeywitness = Data.ProtoLens.Field.field @"vkeywitness" +vote :: + forall f s a. + (Prelude.Functor f, Data.ProtoLens.Field.HasField s "vote" a) => + Lens.Family2.LensLike' f s a +vote = Data.ProtoLens.Field.field @"vote" voteDelegCert :: forall f s a. (Prelude.Functor f, @@ -2899,6 +3003,11 @@ voteRegDelegCert :: Data.ProtoLens.Field.HasField s "voteRegDelegCert" a) => Lens.Family2.LensLike' f s a voteRegDelegCert = Data.ProtoLens.Field.field @"voteRegDelegCert" +votes :: + forall f s a. + (Prelude.Functor f, Data.ProtoLens.Field.HasField s "votes" a) => + Lens.Family2.LensLike' f s a +votes = Data.ProtoLens.Field.field @"votes" vrf :: forall f s a. (Prelude.Functor f, Data.ProtoLens.Field.HasField s "vrf" a) => diff --git a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Query/Query.hs b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Query/Query.hs index 8ba43cf1b0..e67dbdfa4e 100644 --- a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Query/Query.hs +++ b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Query/Query.hs @@ -8,7 +8,10 @@ module Proto.Utxorpc.V1beta.Query.Query ( _AnyChainBlock'Cardano, AnyChainDatum(), AnyChainDatum'ParsedState(..), _AnyChainDatum'Cardano, AnyChainParams(), AnyChainParams'Params(..), - _AnyChainParams'Cardano, AnyChainTx(), AnyChainTx'Chain(..), + _AnyChainParams'Cardano, AnyChainStateData(), + AnyChainStateData'Result(..), _AnyChainStateData'Cardano, + AnyChainStateQuery(), AnyChainStateQuery'Query(..), + _AnyChainStateQuery'Cardano, AnyChainTx(), AnyChainTx'Chain(..), _AnyChainTx'Cardano, AnyUtxoData(), AnyUtxoData'ParsedState(..), _AnyUtxoData'Cardano, AnyUtxoPattern(), AnyUtxoPattern'UtxoPattern(..), _AnyUtxoPattern'Cardano, @@ -18,9 +21,10 @@ module Proto.Utxorpc.V1beta.Query.Query ( _ReadEraSummaryResponse'Cardano, ReadGenesisRequest(), ReadGenesisResponse(), ReadGenesisResponse'Config(..), _ReadGenesisResponse'Cardano, ReadParamsRequest(), - ReadParamsResponse(), ReadTxRequest(), ReadTxResponse(), - ReadUtxosRequest(), ReadUtxosResponse(), SearchUtxosRequest(), - SearchUtxosResponse(), TxoRef(), UtxoPredicate() + ReadParamsResponse(), ReadStateRequest(), ReadStateResponse(), + ReadTxRequest(), ReadTxResponse(), ReadUtxosRequest(), + ReadUtxosResponse(), SearchUtxosRequest(), SearchUtxosResponse(), + TxoRef(), UtxoPredicate() ) where import qualified Data.ProtoLens.Runtime.Control.DeepSeq as Control.DeepSeq import qualified Data.ProtoLens.Runtime.Data.ProtoLens.Prism as Data.ProtoLens.Prism @@ -655,6 +659,320 @@ _AnyChainParams'Cardano (AnyChainParams'Cardano p__val) -> Prelude.Just p__val) {- | Fields : + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'result' @:: Lens' AnyChainStateData (Prelude.Maybe AnyChainStateData'Result)@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'cardano' @:: Lens' AnyChainStateData (Prelude.Maybe Proto.Utxorpc.V1beta.Cardano.Cardano.StateData)@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.cardano' @:: Lens' AnyChainStateData Proto.Utxorpc.V1beta.Cardano.Cardano.StateData@ -} +data AnyChainStateData + = AnyChainStateData'_constructor {_AnyChainStateData'result :: !(Prelude.Maybe AnyChainStateData'Result), + _AnyChainStateData'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show AnyChainStateData where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +data AnyChainStateData'Result + = AnyChainStateData'Cardano !Proto.Utxorpc.V1beta.Cardano.Cardano.StateData + deriving stock (Prelude.Show, Prelude.Eq, Prelude.Ord) +instance Data.ProtoLens.Field.HasField AnyChainStateData "maybe'result" (Prelude.Maybe AnyChainStateData'Result) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _AnyChainStateData'result + (\ x__ y__ -> x__ {_AnyChainStateData'result = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField AnyChainStateData "maybe'cardano" (Prelude.Maybe Proto.Utxorpc.V1beta.Cardano.Cardano.StateData) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _AnyChainStateData'result + (\ x__ y__ -> x__ {_AnyChainStateData'result = y__})) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (AnyChainStateData'Cardano x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap AnyChainStateData'Cardano y__)) +instance Data.ProtoLens.Field.HasField AnyChainStateData "cardano" Proto.Utxorpc.V1beta.Cardano.Cardano.StateData where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _AnyChainStateData'result + (\ x__ y__ -> x__ {_AnyChainStateData'result = y__})) + ((Prelude..) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (AnyChainStateData'Cardano x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap AnyChainStateData'Cardano y__)) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage)) +instance Data.ProtoLens.Message AnyChainStateData where + messageName _ + = Data.Text.pack "utxorpc.v1beta.query.AnyChainStateData" + packedMessageDescriptor _ + = "\n\ + \\DC1AnyChainStateData\DC2=\n\ + \\acardano\CAN\SOH \SOH(\v2!.utxorpc.v1beta.cardano.StateDataH\NULR\acardanoB\b\n\ + \\ACKresult" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + cardano__field_descriptor + = Data.ProtoLens.FieldDescriptor + "cardano" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor Proto.Utxorpc.V1beta.Cardano.Cardano.StateData) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'cardano")) :: + Data.ProtoLens.FieldDescriptor AnyChainStateData + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, cardano__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _AnyChainStateData'_unknownFields + (\ x__ y__ -> x__ {_AnyChainStateData'_unknownFields = y__}) + defMessage + = AnyChainStateData'_constructor + {_AnyChainStateData'result = Prelude.Nothing, + _AnyChainStateData'_unknownFields = []} + parseMessage + = let + loop :: + AnyChainStateData + -> Data.ProtoLens.Encoding.Bytes.Parser AnyChainStateData + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "cardano" + loop (Lens.Family2.set (Data.ProtoLens.Field.field @"cardano") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "AnyChainStateData" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (case + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'result") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just (AnyChainStateData'Cardano v)) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)) +instance Control.DeepSeq.NFData AnyChainStateData where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_AnyChainStateData'_unknownFields x__) + (Control.DeepSeq.deepseq (_AnyChainStateData'result x__) ()) +instance Control.DeepSeq.NFData AnyChainStateData'Result where + rnf (AnyChainStateData'Cardano x__) = Control.DeepSeq.rnf x__ +_AnyChainStateData'Cardano :: + Data.ProtoLens.Prism.Prism' AnyChainStateData'Result Proto.Utxorpc.V1beta.Cardano.Cardano.StateData +_AnyChainStateData'Cardano + = Data.ProtoLens.Prism.prism' + AnyChainStateData'Cardano + (\ p__ + -> case p__ of + (AnyChainStateData'Cardano p__val) -> Prelude.Just p__val) +{- | Fields : + + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'query' @:: Lens' AnyChainStateQuery (Prelude.Maybe AnyChainStateQuery'Query)@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'cardano' @:: Lens' AnyChainStateQuery (Prelude.Maybe Proto.Utxorpc.V1beta.Cardano.Cardano.StateQuery)@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.cardano' @:: Lens' AnyChainStateQuery Proto.Utxorpc.V1beta.Cardano.Cardano.StateQuery@ -} +data AnyChainStateQuery + = AnyChainStateQuery'_constructor {_AnyChainStateQuery'query :: !(Prelude.Maybe AnyChainStateQuery'Query), + _AnyChainStateQuery'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show AnyChainStateQuery where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +data AnyChainStateQuery'Query + = AnyChainStateQuery'Cardano !Proto.Utxorpc.V1beta.Cardano.Cardano.StateQuery + deriving stock (Prelude.Show, Prelude.Eq, Prelude.Ord) +instance Data.ProtoLens.Field.HasField AnyChainStateQuery "maybe'query" (Prelude.Maybe AnyChainStateQuery'Query) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _AnyChainStateQuery'query + (\ x__ y__ -> x__ {_AnyChainStateQuery'query = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField AnyChainStateQuery "maybe'cardano" (Prelude.Maybe Proto.Utxorpc.V1beta.Cardano.Cardano.StateQuery) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _AnyChainStateQuery'query + (\ x__ y__ -> x__ {_AnyChainStateQuery'query = y__})) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (AnyChainStateQuery'Cardano x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap AnyChainStateQuery'Cardano y__)) +instance Data.ProtoLens.Field.HasField AnyChainStateQuery "cardano" Proto.Utxorpc.V1beta.Cardano.Cardano.StateQuery where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _AnyChainStateQuery'query + (\ x__ y__ -> x__ {_AnyChainStateQuery'query = y__})) + ((Prelude..) + (Lens.Family2.Unchecked.lens + (\ x__ + -> case x__ of + (Prelude.Just (AnyChainStateQuery'Cardano x__val)) + -> Prelude.Just x__val + _otherwise -> Prelude.Nothing) + (\ _ y__ -> Prelude.fmap AnyChainStateQuery'Cardano y__)) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage)) +instance Data.ProtoLens.Message AnyChainStateQuery where + messageName _ + = Data.Text.pack "utxorpc.v1beta.query.AnyChainStateQuery" + packedMessageDescriptor _ + = "\n\ + \\DC2AnyChainStateQuery\DC2>\n\ + \\acardano\CAN\SOH \SOH(\v2\".utxorpc.v1beta.cardano.StateQueryH\NULR\acardanoB\a\n\ + \\ENQquery" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + cardano__field_descriptor + = Data.ProtoLens.FieldDescriptor + "cardano" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor Proto.Utxorpc.V1beta.Cardano.Cardano.StateQuery) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'cardano")) :: + Data.ProtoLens.FieldDescriptor AnyChainStateQuery + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, cardano__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _AnyChainStateQuery'_unknownFields + (\ x__ y__ -> x__ {_AnyChainStateQuery'_unknownFields = y__}) + defMessage + = AnyChainStateQuery'_constructor + {_AnyChainStateQuery'query = Prelude.Nothing, + _AnyChainStateQuery'_unknownFields = []} + parseMessage + = let + loop :: + AnyChainStateQuery + -> Data.ProtoLens.Encoding.Bytes.Parser AnyChainStateQuery + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "cardano" + loop (Lens.Family2.set (Data.ProtoLens.Field.field @"cardano") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "AnyChainStateQuery" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (case + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'query") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just (AnyChainStateQuery'Cardano v)) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)) +instance Control.DeepSeq.NFData AnyChainStateQuery where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_AnyChainStateQuery'_unknownFields x__) + (Control.DeepSeq.deepseq (_AnyChainStateQuery'query x__) ()) +instance Control.DeepSeq.NFData AnyChainStateQuery'Query where + rnf (AnyChainStateQuery'Cardano x__) = Control.DeepSeq.rnf x__ +_AnyChainStateQuery'Cardano :: + Data.ProtoLens.Prism.Prism' AnyChainStateQuery'Query Proto.Utxorpc.V1beta.Cardano.Cardano.StateQuery +_AnyChainStateQuery'Cardano + = Data.ProtoLens.Prism.prism' + AnyChainStateQuery'Cardano + (\ p__ + -> case p__ of + (AnyChainStateQuery'Cardano p__val) -> Prelude.Just p__val) +{- | Fields : + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.nativeBytes' @:: Lens' AnyChainTx Data.ByteString.ByteString@ * 'Proto.Utxorpc.V1beta.Query.Query_Fields.blockRef' @:: Lens' AnyChainTx ChainPoint@ * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'blockRef' @:: Lens' AnyChainTx (Prelude.Maybe ChainPoint)@ @@ -2654,23 +2972,351 @@ instance Data.ProtoLens.Message ReadParamsRequest where Data.ProtoLens.FieldTypeDescriptor Proto.Google.Protobuf.FieldMask.FieldMask) (Data.ProtoLens.OptionalField (Data.ProtoLens.Field.field @"maybe'fieldMask")) :: - Data.ProtoLens.FieldDescriptor ReadParamsRequest + Data.ProtoLens.FieldDescriptor ReadParamsRequest + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, fieldMask__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _ReadParamsRequest'_unknownFields + (\ x__ y__ -> x__ {_ReadParamsRequest'_unknownFields = y__}) + defMessage + = ReadParamsRequest'_constructor + {_ReadParamsRequest'fieldMask = Prelude.Nothing, + _ReadParamsRequest'_unknownFields = []} + parseMessage + = let + loop :: + ReadParamsRequest + -> Data.ProtoLens.Encoding.Bytes.Parser ReadParamsRequest + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "field_mask" + loop + (Lens.Family2.set (Data.ProtoLens.Field.field @"fieldMask") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "ReadParamsRequest" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (case + Lens.Family2.view + (Data.ProtoLens.Field.field @"maybe'fieldMask") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x)) +instance Control.DeepSeq.NFData ReadParamsRequest where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_ReadParamsRequest'_unknownFields x__) + (Control.DeepSeq.deepseq (_ReadParamsRequest'fieldMask x__) ()) +{- | Fields : + + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.values' @:: Lens' ReadParamsResponse AnyChainParams@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'values' @:: Lens' ReadParamsResponse (Prelude.Maybe AnyChainParams)@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.ledgerTip' @:: Lens' ReadParamsResponse ChainPoint@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'ledgerTip' @:: Lens' ReadParamsResponse (Prelude.Maybe ChainPoint)@ -} +data ReadParamsResponse + = ReadParamsResponse'_constructor {_ReadParamsResponse'values :: !(Prelude.Maybe AnyChainParams), + _ReadParamsResponse'ledgerTip :: !(Prelude.Maybe ChainPoint), + _ReadParamsResponse'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show ReadParamsResponse where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +instance Data.ProtoLens.Field.HasField ReadParamsResponse "values" AnyChainParams where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadParamsResponse'values + (\ x__ y__ -> x__ {_ReadParamsResponse'values = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) +instance Data.ProtoLens.Field.HasField ReadParamsResponse "maybe'values" (Prelude.Maybe AnyChainParams) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadParamsResponse'values + (\ x__ y__ -> x__ {_ReadParamsResponse'values = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField ReadParamsResponse "ledgerTip" ChainPoint where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadParamsResponse'ledgerTip + (\ x__ y__ -> x__ {_ReadParamsResponse'ledgerTip = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) +instance Data.ProtoLens.Field.HasField ReadParamsResponse "maybe'ledgerTip" (Prelude.Maybe ChainPoint) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadParamsResponse'ledgerTip + (\ x__ y__ -> x__ {_ReadParamsResponse'ledgerTip = y__})) + Prelude.id +instance Data.ProtoLens.Message ReadParamsResponse where + messageName _ + = Data.Text.pack "utxorpc.v1beta.query.ReadParamsResponse" + packedMessageDescriptor _ + = "\n\ + \\DC2ReadParamsResponse\DC2<\n\ + \\ACKvalues\CAN\SOH \SOH(\v2$.utxorpc.v1beta.query.AnyChainParamsR\ACKvalues\DC2?\n\ + \\n\ + \ledger_tip\CAN\STX \SOH(\v2 .utxorpc.v1beta.query.ChainPointR\tledgerTip" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + values__field_descriptor + = Data.ProtoLens.FieldDescriptor + "values" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor AnyChainParams) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'values")) :: + Data.ProtoLens.FieldDescriptor ReadParamsResponse + ledgerTip__field_descriptor + = Data.ProtoLens.FieldDescriptor + "ledger_tip" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor ChainPoint) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'ledgerTip")) :: + Data.ProtoLens.FieldDescriptor ReadParamsResponse + in + Data.Map.fromList + [(Data.ProtoLens.Tag 1, values__field_descriptor), + (Data.ProtoLens.Tag 2, ledgerTip__field_descriptor)] + unknownFields + = Lens.Family2.Unchecked.lens + _ReadParamsResponse'_unknownFields + (\ x__ y__ -> x__ {_ReadParamsResponse'_unknownFields = y__}) + defMessage + = ReadParamsResponse'_constructor + {_ReadParamsResponse'values = Prelude.Nothing, + _ReadParamsResponse'ledgerTip = Prelude.Nothing, + _ReadParamsResponse'_unknownFields = []} + parseMessage + = let + loop :: + ReadParamsResponse + -> Data.ProtoLens.Encoding.Bytes.Parser ReadParamsResponse + loop x + = do end <- Data.ProtoLens.Encoding.Bytes.atEnd + if end then + do (let missing = [] + in + if Prelude.null missing then + Prelude.return () + else + Prelude.fail + ((Prelude.++) + "Missing required fields: " + (Prelude.show (missing :: [Prelude.String])))) + Prelude.return + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + else + do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt + case tag of + 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "values" + loop (Lens.Family2.set (Data.ProtoLens.Field.field @"values") y x) + 18 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "ledger_tip" + loop + (Lens.Family2.set (Data.ProtoLens.Field.field @"ledgerTip") y x) + wire + -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire + wire + loop + (Lens.Family2.over + Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + in + (Data.ProtoLens.Encoding.Bytes.) + (do loop Data.ProtoLens.defMessage) "ReadParamsResponse" + buildMessage + = \ _x + -> (Data.Monoid.<>) + (case + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'values") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + ((Data.Monoid.<>) + (case + Lens.Family2.view + (Data.ProtoLens.Field.field @"maybe'ledgerTip") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 18) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x))) +instance Control.DeepSeq.NFData ReadParamsResponse where + rnf + = \ x__ + -> Control.DeepSeq.deepseq + (_ReadParamsResponse'_unknownFields x__) + (Control.DeepSeq.deepseq + (_ReadParamsResponse'values x__) + (Control.DeepSeq.deepseq (_ReadParamsResponse'ledgerTip x__) ())) +{- | Fields : + + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.query' @:: Lens' ReadStateRequest AnyChainStateQuery@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'query' @:: Lens' ReadStateRequest (Prelude.Maybe AnyChainStateQuery)@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.fieldMask' @:: Lens' ReadStateRequest Proto.Google.Protobuf.FieldMask.FieldMask@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'fieldMask' @:: Lens' ReadStateRequest (Prelude.Maybe Proto.Google.Protobuf.FieldMask.FieldMask)@ -} +data ReadStateRequest + = ReadStateRequest'_constructor {_ReadStateRequest'query :: !(Prelude.Maybe AnyChainStateQuery), + _ReadStateRequest'fieldMask :: !(Prelude.Maybe Proto.Google.Protobuf.FieldMask.FieldMask), + _ReadStateRequest'_unknownFields :: !Data.ProtoLens.FieldSet} + deriving stock (Prelude.Eq, Prelude.Ord) +instance Prelude.Show ReadStateRequest where + showsPrec _ __x __s + = Prelude.showChar + '{' + (Prelude.showString + (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) +instance Data.ProtoLens.Field.HasField ReadStateRequest "query" AnyChainStateQuery where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadStateRequest'query + (\ x__ y__ -> x__ {_ReadStateRequest'query = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) +instance Data.ProtoLens.Field.HasField ReadStateRequest "maybe'query" (Prelude.Maybe AnyChainStateQuery) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadStateRequest'query + (\ x__ y__ -> x__ {_ReadStateRequest'query = y__})) + Prelude.id +instance Data.ProtoLens.Field.HasField ReadStateRequest "fieldMask" Proto.Google.Protobuf.FieldMask.FieldMask where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadStateRequest'fieldMask + (\ x__ y__ -> x__ {_ReadStateRequest'fieldMask = y__})) + (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) +instance Data.ProtoLens.Field.HasField ReadStateRequest "maybe'fieldMask" (Prelude.Maybe Proto.Google.Protobuf.FieldMask.FieldMask) where + fieldOf _ + = (Prelude..) + (Lens.Family2.Unchecked.lens + _ReadStateRequest'fieldMask + (\ x__ y__ -> x__ {_ReadStateRequest'fieldMask = y__})) + Prelude.id +instance Data.ProtoLens.Message ReadStateRequest where + messageName _ + = Data.Text.pack "utxorpc.v1beta.query.ReadStateRequest" + packedMessageDescriptor _ + = "\n\ + \\DLEReadStateRequest\DC2>\n\ + \\ENQquery\CAN\SOH \SOH(\v2(.utxorpc.v1beta.query.AnyChainStateQueryR\ENQquery\DC29\n\ + \\n\ + \field_mask\CAN\STX \SOH(\v2\SUB.google.protobuf.FieldMaskR\tfieldMask" + packedFileDescriptor _ = packedFileDescriptor + fieldsByTag + = let + query__field_descriptor + = Data.ProtoLens.FieldDescriptor + "query" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor AnyChainStateQuery) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'query")) :: + Data.ProtoLens.FieldDescriptor ReadStateRequest + fieldMask__field_descriptor + = Data.ProtoLens.FieldDescriptor + "field_mask" + (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: + Data.ProtoLens.FieldTypeDescriptor Proto.Google.Protobuf.FieldMask.FieldMask) + (Data.ProtoLens.OptionalField + (Data.ProtoLens.Field.field @"maybe'fieldMask")) :: + Data.ProtoLens.FieldDescriptor ReadStateRequest in Data.Map.fromList - [(Data.ProtoLens.Tag 1, fieldMask__field_descriptor)] + [(Data.ProtoLens.Tag 1, query__field_descriptor), + (Data.ProtoLens.Tag 2, fieldMask__field_descriptor)] unknownFields = Lens.Family2.Unchecked.lens - _ReadParamsRequest'_unknownFields - (\ x__ y__ -> x__ {_ReadParamsRequest'_unknownFields = y__}) + _ReadStateRequest'_unknownFields + (\ x__ y__ -> x__ {_ReadStateRequest'_unknownFields = y__}) defMessage - = ReadParamsRequest'_constructor - {_ReadParamsRequest'fieldMask = Prelude.Nothing, - _ReadParamsRequest'_unknownFields = []} + = ReadStateRequest'_constructor + {_ReadStateRequest'query = Prelude.Nothing, + _ReadStateRequest'fieldMask = Prelude.Nothing, + _ReadStateRequest'_unknownFields = []} parseMessage = let loop :: - ReadParamsRequest - -> Data.ProtoLens.Encoding.Bytes.Parser ReadParamsRequest + ReadStateRequest + -> Data.ProtoLens.Encoding.Bytes.Parser ReadStateRequest loop x = do end <- Data.ProtoLens.Encoding.Bytes.atEnd if end then @@ -2690,6 +3336,13 @@ instance Data.ProtoLens.Message ReadParamsRequest where do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt case tag of 10 + -> do y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) + "query" + loop (Lens.Family2.set (Data.ProtoLens.Field.field @"query") y x) + 18 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt Data.ProtoLens.Encoding.Bytes.isolate @@ -2705,13 +3358,12 @@ instance Data.ProtoLens.Message ReadParamsRequest where Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) in (Data.ProtoLens.Encoding.Bytes.) - (do loop Data.ProtoLens.defMessage) "ReadParamsRequest" + (do loop Data.ProtoLens.defMessage) "ReadStateRequest" buildMessage = \ _x -> (Data.Monoid.<>) (case - Lens.Family2.view - (Data.ProtoLens.Field.field @"maybe'fieldMask") _x + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'query") _x of Prelude.Nothing -> Data.Monoid.mempty (Prelude.Just _v) @@ -2724,79 +3376,97 @@ instance Data.ProtoLens.Message ReadParamsRequest where (Prelude.fromIntegral (Data.ByteString.length bs))) (Data.ProtoLens.Encoding.Bytes.putBytes bs)) Data.ProtoLens.encodeMessage _v)) - (Data.ProtoLens.Encoding.Wire.buildFieldSet - (Lens.Family2.view Data.ProtoLens.unknownFields _x)) -instance Control.DeepSeq.NFData ReadParamsRequest where + ((Data.Monoid.<>) + (case + Lens.Family2.view + (Data.ProtoLens.Field.field @"maybe'fieldMask") _x + of + Prelude.Nothing -> Data.Monoid.mempty + (Prelude.Just _v) + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 18) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Data.ProtoLens.Encoding.Wire.buildFieldSet + (Lens.Family2.view Data.ProtoLens.unknownFields _x))) +instance Control.DeepSeq.NFData ReadStateRequest where rnf = \ x__ -> Control.DeepSeq.deepseq - (_ReadParamsRequest'_unknownFields x__) - (Control.DeepSeq.deepseq (_ReadParamsRequest'fieldMask x__) ()) + (_ReadStateRequest'_unknownFields x__) + (Control.DeepSeq.deepseq + (_ReadStateRequest'query x__) + (Control.DeepSeq.deepseq (_ReadStateRequest'fieldMask x__) ())) {- | Fields : - * 'Proto.Utxorpc.V1beta.Query.Query_Fields.values' @:: Lens' ReadParamsResponse AnyChainParams@ - * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'values' @:: Lens' ReadParamsResponse (Prelude.Maybe AnyChainParams)@ - * 'Proto.Utxorpc.V1beta.Query.Query_Fields.ledgerTip' @:: Lens' ReadParamsResponse ChainPoint@ - * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'ledgerTip' @:: Lens' ReadParamsResponse (Prelude.Maybe ChainPoint)@ -} -data ReadParamsResponse - = ReadParamsResponse'_constructor {_ReadParamsResponse'values :: !(Prelude.Maybe AnyChainParams), - _ReadParamsResponse'ledgerTip :: !(Prelude.Maybe ChainPoint), - _ReadParamsResponse'_unknownFields :: !Data.ProtoLens.FieldSet} + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.result' @:: Lens' ReadStateResponse AnyChainStateData@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'result' @:: Lens' ReadStateResponse (Prelude.Maybe AnyChainStateData)@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.ledgerTip' @:: Lens' ReadStateResponse ChainPoint@ + * 'Proto.Utxorpc.V1beta.Query.Query_Fields.maybe'ledgerTip' @:: Lens' ReadStateResponse (Prelude.Maybe ChainPoint)@ -} +data ReadStateResponse + = ReadStateResponse'_constructor {_ReadStateResponse'result :: !(Prelude.Maybe AnyChainStateData), + _ReadStateResponse'ledgerTip :: !(Prelude.Maybe ChainPoint), + _ReadStateResponse'_unknownFields :: !Data.ProtoLens.FieldSet} deriving stock (Prelude.Eq, Prelude.Ord) -instance Prelude.Show ReadParamsResponse where +instance Prelude.Show ReadStateResponse where showsPrec _ __x __s = Prelude.showChar '{' (Prelude.showString (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) -instance Data.ProtoLens.Field.HasField ReadParamsResponse "values" AnyChainParams where +instance Data.ProtoLens.Field.HasField ReadStateResponse "result" AnyChainStateData where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens - _ReadParamsResponse'values - (\ x__ y__ -> x__ {_ReadParamsResponse'values = y__})) + _ReadStateResponse'result + (\ x__ y__ -> x__ {_ReadStateResponse'result = y__})) (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) -instance Data.ProtoLens.Field.HasField ReadParamsResponse "maybe'values" (Prelude.Maybe AnyChainParams) where +instance Data.ProtoLens.Field.HasField ReadStateResponse "maybe'result" (Prelude.Maybe AnyChainStateData) where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens - _ReadParamsResponse'values - (\ x__ y__ -> x__ {_ReadParamsResponse'values = y__})) + _ReadStateResponse'result + (\ x__ y__ -> x__ {_ReadStateResponse'result = y__})) Prelude.id -instance Data.ProtoLens.Field.HasField ReadParamsResponse "ledgerTip" ChainPoint where +instance Data.ProtoLens.Field.HasField ReadStateResponse "ledgerTip" ChainPoint where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens - _ReadParamsResponse'ledgerTip - (\ x__ y__ -> x__ {_ReadParamsResponse'ledgerTip = y__})) + _ReadStateResponse'ledgerTip + (\ x__ y__ -> x__ {_ReadStateResponse'ledgerTip = y__})) (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) -instance Data.ProtoLens.Field.HasField ReadParamsResponse "maybe'ledgerTip" (Prelude.Maybe ChainPoint) where +instance Data.ProtoLens.Field.HasField ReadStateResponse "maybe'ledgerTip" (Prelude.Maybe ChainPoint) where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens - _ReadParamsResponse'ledgerTip - (\ x__ y__ -> x__ {_ReadParamsResponse'ledgerTip = y__})) + _ReadStateResponse'ledgerTip + (\ x__ y__ -> x__ {_ReadStateResponse'ledgerTip = y__})) Prelude.id -instance Data.ProtoLens.Message ReadParamsResponse where +instance Data.ProtoLens.Message ReadStateResponse where messageName _ - = Data.Text.pack "utxorpc.v1beta.query.ReadParamsResponse" + = Data.Text.pack "utxorpc.v1beta.query.ReadStateResponse" packedMessageDescriptor _ = "\n\ - \\DC2ReadParamsResponse\DC2<\n\ - \\ACKvalues\CAN\SOH \SOH(\v2$.utxorpc.v1beta.query.AnyChainParamsR\ACKvalues\DC2?\n\ + \\DC1ReadStateResponse\DC2?\n\ + \\ACKresult\CAN\SOH \SOH(\v2'.utxorpc.v1beta.query.AnyChainStateDataR\ACKresult\DC2?\n\ \\n\ \ledger_tip\CAN\STX \SOH(\v2 .utxorpc.v1beta.query.ChainPointR\tledgerTip" packedFileDescriptor _ = packedFileDescriptor fieldsByTag = let - values__field_descriptor + result__field_descriptor = Data.ProtoLens.FieldDescriptor - "values" + "result" (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: - Data.ProtoLens.FieldTypeDescriptor AnyChainParams) + Data.ProtoLens.FieldTypeDescriptor AnyChainStateData) (Data.ProtoLens.OptionalField - (Data.ProtoLens.Field.field @"maybe'values")) :: - Data.ProtoLens.FieldDescriptor ReadParamsResponse + (Data.ProtoLens.Field.field @"maybe'result")) :: + Data.ProtoLens.FieldDescriptor ReadStateResponse ledgerTip__field_descriptor = Data.ProtoLens.FieldDescriptor "ledger_tip" @@ -2804,25 +3474,25 @@ instance Data.ProtoLens.Message ReadParamsResponse where Data.ProtoLens.FieldTypeDescriptor ChainPoint) (Data.ProtoLens.OptionalField (Data.ProtoLens.Field.field @"maybe'ledgerTip")) :: - Data.ProtoLens.FieldDescriptor ReadParamsResponse + Data.ProtoLens.FieldDescriptor ReadStateResponse in Data.Map.fromList - [(Data.ProtoLens.Tag 1, values__field_descriptor), + [(Data.ProtoLens.Tag 1, result__field_descriptor), (Data.ProtoLens.Tag 2, ledgerTip__field_descriptor)] unknownFields = Lens.Family2.Unchecked.lens - _ReadParamsResponse'_unknownFields - (\ x__ y__ -> x__ {_ReadParamsResponse'_unknownFields = y__}) + _ReadStateResponse'_unknownFields + (\ x__ y__ -> x__ {_ReadStateResponse'_unknownFields = y__}) defMessage - = ReadParamsResponse'_constructor - {_ReadParamsResponse'values = Prelude.Nothing, - _ReadParamsResponse'ledgerTip = Prelude.Nothing, - _ReadParamsResponse'_unknownFields = []} + = ReadStateResponse'_constructor + {_ReadStateResponse'result = Prelude.Nothing, + _ReadStateResponse'ledgerTip = Prelude.Nothing, + _ReadStateResponse'_unknownFields = []} parseMessage = let loop :: - ReadParamsResponse - -> Data.ProtoLens.Encoding.Bytes.Parser ReadParamsResponse + ReadStateResponse + -> Data.ProtoLens.Encoding.Bytes.Parser ReadStateResponse loop x = do end <- Data.ProtoLens.Encoding.Bytes.atEnd if end then @@ -2846,8 +3516,8 @@ instance Data.ProtoLens.Message ReadParamsResponse where (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt Data.ProtoLens.Encoding.Bytes.isolate (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) - "values" - loop (Lens.Family2.set (Data.ProtoLens.Field.field @"values") y x) + "result" + loop (Lens.Family2.set (Data.ProtoLens.Field.field @"result") y x) 18 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -2864,12 +3534,12 @@ instance Data.ProtoLens.Message ReadParamsResponse where Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) in (Data.ProtoLens.Encoding.Bytes.) - (do loop Data.ProtoLens.defMessage) "ReadParamsResponse" + (do loop Data.ProtoLens.defMessage) "ReadStateResponse" buildMessage = \ _x -> (Data.Monoid.<>) (case - Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'values") _x + Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'result") _x of Prelude.Nothing -> Data.Monoid.mempty (Prelude.Just _v) @@ -2900,14 +3570,14 @@ instance Data.ProtoLens.Message ReadParamsResponse where Data.ProtoLens.encodeMessage _v)) (Data.ProtoLens.Encoding.Wire.buildFieldSet (Lens.Family2.view Data.ProtoLens.unknownFields _x))) -instance Control.DeepSeq.NFData ReadParamsResponse where +instance Control.DeepSeq.NFData ReadStateResponse where rnf = \ x__ -> Control.DeepSeq.deepseq - (_ReadParamsResponse'_unknownFields x__) + (_ReadStateResponse'_unknownFields x__) (Control.DeepSeq.deepseq - (_ReadParamsResponse'values x__) - (Control.DeepSeq.deepseq (_ReadParamsResponse'ledgerTip x__) ())) + (_ReadStateResponse'result x__) + (Control.DeepSeq.deepseq (_ReadStateResponse'ledgerTip x__) ())) {- | Fields : * 'Proto.Utxorpc.V1beta.Query.Query_Fields.hash' @:: Lens' ReadTxRequest Data.ByteString.ByteString@ @@ -4618,8 +5288,12 @@ data QueryService = QueryService {} instance Data.ProtoLens.Service.Types.Service QueryService where type ServiceName QueryService = "QueryService" type ServicePackage QueryService = "utxorpc.v1beta.query" - type ServiceMethods QueryService = '["readGenesis", + type ServiceMethods QueryService = '["readData", + "readEraSummary", + "readGenesis", "readParams", + "readState", + "readTx", "readUtxos", "searchUtxos"] packedServiceDescriptor _ @@ -4628,8 +5302,12 @@ instance Data.ProtoLens.Service.Types.Service QueryService where \\n\ \ReadParams\DC2'.utxorpc.v1beta.query.ReadParamsRequest\SUB(.utxorpc.v1beta.query.ReadParamsResponse\DC2\\\n\ \\tReadUtxos\DC2&.utxorpc.v1beta.query.ReadUtxosRequest\SUB'.utxorpc.v1beta.query.ReadUtxosResponse\DC2b\n\ - \\vSearchUtxos\DC2(.utxorpc.v1beta.query.SearchUtxosRequest\SUB).utxorpc.v1beta.query.SearchUtxosResponse\DC2b\n\ - \\vReadGenesis\DC2(.utxorpc.v1beta.query.ReadGenesisRequest\SUB).utxorpc.v1beta.query.ReadGenesisResponse" + \\vSearchUtxos\DC2(.utxorpc.v1beta.query.SearchUtxosRequest\SUB).utxorpc.v1beta.query.SearchUtxosResponse\DC2Y\n\ + \\bReadData\DC2%.utxorpc.v1beta.query.ReadDataRequest\SUB&.utxorpc.v1beta.query.ReadDataResponse\DC2S\n\ + \\ACKReadTx\DC2#.utxorpc.v1beta.query.ReadTxRequest\SUB$.utxorpc.v1beta.query.ReadTxResponse\DC2b\n\ + \\vReadGenesis\DC2(.utxorpc.v1beta.query.ReadGenesisRequest\SUB).utxorpc.v1beta.query.ReadGenesisResponse\DC2k\n\ + \\SOReadEraSummary\DC2+.utxorpc.v1beta.query.ReadEraSummaryRequest\SUB,.utxorpc.v1beta.query.ReadEraSummaryResponse\DC2\\\n\ + \\tReadState\DC2&.utxorpc.v1beta.query.ReadStateRequest\SUB'.utxorpc.v1beta.query.ReadStateResponse" instance Data.ProtoLens.Service.Types.HasMethodImpl QueryService "readParams" where type MethodName QueryService "readParams" = "ReadParams" type MethodInput QueryService "readParams" = ReadParamsRequest @@ -4645,11 +5323,31 @@ instance Data.ProtoLens.Service.Types.HasMethodImpl QueryService "searchUtxos" w type MethodInput QueryService "searchUtxos" = SearchUtxosRequest type MethodOutput QueryService "searchUtxos" = SearchUtxosResponse type MethodStreamingType QueryService "searchUtxos" = 'Data.ProtoLens.Service.Types.NonStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl QueryService "readData" where + type MethodName QueryService "readData" = "ReadData" + type MethodInput QueryService "readData" = ReadDataRequest + type MethodOutput QueryService "readData" = ReadDataResponse + type MethodStreamingType QueryService "readData" = 'Data.ProtoLens.Service.Types.NonStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl QueryService "readTx" where + type MethodName QueryService "readTx" = "ReadTx" + type MethodInput QueryService "readTx" = ReadTxRequest + type MethodOutput QueryService "readTx" = ReadTxResponse + type MethodStreamingType QueryService "readTx" = 'Data.ProtoLens.Service.Types.NonStreaming instance Data.ProtoLens.Service.Types.HasMethodImpl QueryService "readGenesis" where type MethodName QueryService "readGenesis" = "ReadGenesis" type MethodInput QueryService "readGenesis" = ReadGenesisRequest type MethodOutput QueryService "readGenesis" = ReadGenesisResponse type MethodStreamingType QueryService "readGenesis" = 'Data.ProtoLens.Service.Types.NonStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl QueryService "readEraSummary" where + type MethodName QueryService "readEraSummary" = "ReadEraSummary" + type MethodInput QueryService "readEraSummary" = ReadEraSummaryRequest + type MethodOutput QueryService "readEraSummary" = ReadEraSummaryResponse + type MethodStreamingType QueryService "readEraSummary" = 'Data.ProtoLens.Service.Types.NonStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl QueryService "readState" where + type MethodName QueryService "readState" = "ReadState" + type MethodInput QueryService "readState" = ReadStateRequest + type MethodOutput QueryService "readState" = ReadStateResponse + type MethodStreamingType QueryService "readState" = 'Data.ProtoLens.Service.Types.NonStreaming packedFileDescriptor :: Data.ByteString.ByteString packedFileDescriptor = "\n\ @@ -4690,6 +5388,20 @@ packedFileDescriptor \\DC2ReadParamsResponse\DC2<\n\ \\ACKvalues\CAN\SOH \SOH(\v2$.utxorpc.v1beta.query.AnyChainParamsR\ACKvalues\DC2?\n\ \\n\ + \ledger_tip\CAN\STX \SOH(\v2 .utxorpc.v1beta.query.ChainPointR\tledgerTip\"]\n\ + \\DC2AnyChainStateQuery\DC2>\n\ + \\acardano\CAN\SOH \SOH(\v2\".utxorpc.v1beta.cardano.StateQueryH\NULR\acardanoB\a\n\ + \\ENQquery\"\\\n\ + \\DC1AnyChainStateData\DC2=\n\ + \\acardano\CAN\SOH \SOH(\v2!.utxorpc.v1beta.cardano.StateDataH\NULR\acardanoB\b\n\ + \\ACKresult\"\141\SOH\n\ + \\DLEReadStateRequest\DC2>\n\ + \\ENQquery\CAN\SOH \SOH(\v2(.utxorpc.v1beta.query.AnyChainStateQueryR\ENQquery\DC29\n\ + \\n\ + \field_mask\CAN\STX \SOH(\v2\SUB.google.protobuf.FieldMaskR\tfieldMask\"\149\SOH\n\ + \\DC1ReadStateResponse\DC2?\n\ + \\ACKresult\CAN\SOH \SOH(\v2'.utxorpc.v1beta.query.AnyChainStateDataR\ACKresult\DC2?\n\ + \\n\ \ledger_tip\CAN\STX \SOH(\v2 .utxorpc.v1beta.query.ChainPointR\tledgerTip\"e\n\ \\SOAnyUtxoPattern\DC2C\n\ \\acardano\CAN\SOH \SOH(\v2'.utxorpc.v1beta.cardano.TxOutputPatternH\NULR\acardanoB\SO\n\ @@ -4759,16 +5471,20 @@ packedFileDescriptor \\SOReadTxResponse\DC20\n\ \\STXtx\CAN\SOH \SOH(\v2 .utxorpc.v1beta.query.AnyChainTxR\STXtx\DC2?\n\ \\n\ - \ledger_tip\CAN\STX \SOH(\v2 .utxorpc.v1beta.query.ChainPointR\tledgerTip2\149\ETX\n\ + \ledger_tip\CAN\STX \SOH(\v2 .utxorpc.v1beta.query.ChainPointR\tledgerTip2\144\ACK\n\ \\fQueryService\DC2_\n\ \\n\ \ReadParams\DC2'.utxorpc.v1beta.query.ReadParamsRequest\SUB(.utxorpc.v1beta.query.ReadParamsResponse\DC2\\\n\ \\tReadUtxos\DC2&.utxorpc.v1beta.query.ReadUtxosRequest\SUB'.utxorpc.v1beta.query.ReadUtxosResponse\DC2b\n\ - \\vSearchUtxos\DC2(.utxorpc.v1beta.query.SearchUtxosRequest\SUB).utxorpc.v1beta.query.SearchUtxosResponse\DC2b\n\ - \\vReadGenesis\DC2(.utxorpc.v1beta.query.ReadGenesisRequest\SUB).utxorpc.v1beta.query.ReadGenesisResponseB\152\SOH\n\ + \\vSearchUtxos\DC2(.utxorpc.v1beta.query.SearchUtxosRequest\SUB).utxorpc.v1beta.query.SearchUtxosResponse\DC2Y\n\ + \\bReadData\DC2%.utxorpc.v1beta.query.ReadDataRequest\SUB&.utxorpc.v1beta.query.ReadDataResponse\DC2S\n\ + \\ACKReadTx\DC2#.utxorpc.v1beta.query.ReadTxRequest\SUB$.utxorpc.v1beta.query.ReadTxResponse\DC2b\n\ + \\vReadGenesis\DC2(.utxorpc.v1beta.query.ReadGenesisRequest\SUB).utxorpc.v1beta.query.ReadGenesisResponse\DC2k\n\ + \\SOReadEraSummary\DC2+.utxorpc.v1beta.query.ReadEraSummaryRequest\SUB,.utxorpc.v1beta.query.ReadEraSummaryResponse\DC2\\\n\ + \\tReadState\DC2&.utxorpc.v1beta.query.ReadStateRequest\SUB'.utxorpc.v1beta.query.ReadStateResponseB\152\SOH\n\ \\CANcom.utxorpc.v1beta.queryB\n\ - \QueryProtoP\SOH\162\STX\ETXUVQ\170\STX\DC4Utxorpc.V1beta.Query\202\STX\DC4Utxorpc\\V1beta\\Query\226\STX Utxorpc\\V1beta\\Query\\GPBMetadata\234\STX\SYNUtxorpc::V1beta::QueryJ\236;\n\ - \\a\DC2\ENQ\STX\NUL\178\SOH\SOH\n\ + \QueryProtoP\SOH\162\STX\ETXUVQ\170\STX\DC4Utxorpc.V1beta.Query\202\STX\DC4Utxorpc\\V1beta\\Query\226\STX Utxorpc\\V1beta\\Query\\GPBMetadata\234\STX\SYNUtxorpc::V1beta::QueryJ\179G\n\ + \\a\DC2\ENQ\STX\NUL\208\SOH\SOH\n\ \9\n\ \\SOH\f\DC2\ETX\STX\NUL\DC22// A consistent view of the state of the ledger\n\ \\n\ @@ -5019,483 +5735,601 @@ packedFileDescriptor \\ENQ\EOT\t\STX\SOH\SOH\DC2\ETXG\r\ETB\n\ \\f\n\ \\ENQ\EOT\t\STX\SOH\ETX\DC2\ETXG\SUB\ESC\n\ - \S\n\ + \I\n\ \\STX\EOT\n\ - \\DC2\EOTK\NULO\SOH\SUBG An evenlope that holds an UTxO patterns from any of compatible chains\n\ + \\DC2\EOTK\NULO\SOH\SUB= An envelope that wraps a chain-specific ledger-state query.\n\ \\n\ \\n\ \\n\ \\ETX\EOT\n\ - \\SOH\DC2\ETXK\b\SYN\n\ + \\SOH\DC2\ETXK\b\SUB\n\ \\f\n\ \\EOT\EOT\n\ \\b\NUL\DC2\EOTL\STXN\ETX\n\ \\f\n\ \\ENQ\EOT\n\ - \\b\NUL\SOH\DC2\ETXL\b\DC4\n\ - \\v\n\ + \\b\NUL\SOH\DC2\ETXL\b\r\n\ + \,\n\ \\EOT\EOT\n\ - \\STX\NUL\DC2\ETXM\EOT7\n\ + \\STX\NUL\DC2\ETXM\EOT2\"\US A Cardano ledger-state query.\n\ + \\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\NUL\ACK\DC2\ETXM\EOT*\n\ + \\STX\NUL\ACK\DC2\ETXM\EOT%\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\NUL\SOH\DC2\ETXM+2\n\ + \\STX\NUL\SOH\DC2\ETXM&-\n\ \\f\n\ \\ENQ\EOT\n\ - \\STX\NUL\ETX\DC2\ETXM56\n\ - \^\n\ - \\STX\EOT\v\DC2\EOTR\NULW\SOH\SUBR Represents a simple utxo predicate that can composed to create more complex ones\n\ - \\n\ + \\STX\NUL\ETX\DC2\ETXM01\n\ + \P\n\ + \\STX\EOT\v\DC2\EOTR\NULV\SOH\SUBD An envelope that wraps a chain-specific ledger-state query result.\n\ \\n\ \\n\ - \\ETX\EOT\v\SOH\DC2\ETXR\b\NAK\n\ - \8\n\ - \\EOT\EOT\v\STX\NUL\DC2\ETXS\STX$\"+ Predicate is true if tx exhibits pattern.\n\ \\n\ + \\ETX\EOT\v\SOH\DC2\ETXR\b\EM\n\ + \\f\n\ + \\EOT\EOT\v\b\NUL\DC2\EOTS\STXU\ETX\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\EOT\DC2\ETXS\STX\n\ + \\ENQ\EOT\v\b\NUL\SOH\DC2\ETXS\b\SO\n\ + \3\n\ + \\EOT\EOT\v\STX\NUL\DC2\ETXT\EOT1\"& A Cardano ledger-state query result.\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\ACK\DC2\ETXS\v\EM\n\ + \\ENQ\EOT\v\STX\NUL\ACK\DC2\ETXT\EOT$\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\SOH\DC2\ETXS\SUB\US\n\ + \\ENQ\EOT\v\STX\NUL\SOH\DC2\ETXT%,\n\ \\f\n\ - \\ENQ\EOT\v\STX\NUL\ETX\DC2\ETXS\"#\n\ - \?\n\ - \\EOT\EOT\v\STX\SOH\DC2\ETXT\STX!\"2 Predicate is true if tx doesn't exhibit pattern.\n\ + \\ENQ\EOT\v\STX\NUL\ETX\DC2\ETXT/0\n\ + \e\n\ + \\STX\EOT\f\DC2\EOTY\NUL\\\SOH\SUBY Request to run a chain-specific ledger-state query against the current ledger snapshot.\n\ \\n\ - \\f\n\ - \\ENQ\EOT\v\STX\SOH\EOT\DC2\ETXT\STX\n\ \\n\ - \\f\n\ - \\ENQ\EOT\v\STX\SOH\ACK\DC2\ETXT\v\CAN\n\ - \\f\n\ - \\ENQ\EOT\v\STX\SOH\SOH\DC2\ETXT\EM\FS\n\ - \\f\n\ - \\ENQ\EOT\v\STX\SOH\ETX\DC2\ETXT\US \n\ - \F\n\ - \\EOT\EOT\v\STX\STX\DC2\ETXU\STX$\"9 Predicate is true if utxo exhibits all of the patterns.\n\ \\n\ - \\f\n\ - \\ENQ\EOT\v\STX\STX\EOT\DC2\ETXU\STX\n\ + \\ETX\EOT\f\SOH\DC2\ETXY\b\CAN\n\ + \4\n\ + \\EOT\EOT\f\STX\NUL\DC2\ETXZ\STX\US\"' The chain-specific query to evaluate.\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\STX\ACK\DC2\ETXU\v\CAN\n\ - \\f\n\ - \\ENQ\EOT\v\STX\STX\SOH\DC2\ETXU\EM\US\n\ + \\ENQ\EOT\f\STX\NUL\ACK\DC2\ETXZ\STX\DC4\n\ \\f\n\ - \\ENQ\EOT\v\STX\STX\ETX\DC2\ETXU\"#\n\ - \F\n\ - \\EOT\EOT\v\STX\ETX\DC2\ETXV\STX$\"9 Predicate is true if utxo exhibits any of the patterns.\n\ - \\n\ + \\ENQ\EOT\f\STX\NUL\SOH\DC2\ETXZ\NAK\SUB\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\EOT\DC2\ETXV\STX\n\ + \\ENQ\EOT\f\STX\NUL\ETX\DC2\ETXZ\GS\RS\n\ + \7\n\ + \\EOT\EOT\f\STX\SOH\DC2\ETX[\STX+\"* Field mask to selectively return fields.\n\ \\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\ACK\DC2\ETXV\v\CAN\n\ + \\ENQ\EOT\f\STX\SOH\ACK\DC2\ETX[\STX\ESC\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\SOH\DC2\ETXV\EM\US\n\ + \\ENQ\EOT\f\STX\SOH\SOH\DC2\ETX[\FS&\n\ \\f\n\ - \\ENQ\EOT\v\STX\ETX\ETX\DC2\ETXV\"#\n\ - \J\n\ - \\STX\EOT\f\DC2\EOTZ\NULa\SOH\SUB> An evenlope that holds an UTxO from any of compatible chains\n\ + \\ENQ\EOT\f\STX\SOH\ETX\DC2\ETX[)*\n\ + \>\n\ + \\STX\EOT\r\DC2\EOT_\NULb\SOH\SUB2 Response carrying the ledger-state query result.\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\f\SOH\DC2\ETXZ\b\DC3\n\ - \5\n\ - \\EOT\EOT\f\STX\NUL\DC2\ETX[\STX\EM\"( Original bytes as defined by the chain\n\ + \\ETX\EOT\r\SOH\DC2\ETX_\b\EM\n\ + \ \n\ + \\EOT\EOT\r\STX\NUL\DC2\ETX`\STX\US\"\DC3 The query result.\n\ \\n\ \\f\n\ - \\ENQ\EOT\f\STX\NUL\ENQ\DC2\ETX[\STX\a\n\ + \\ENQ\EOT\r\STX\NUL\ACK\DC2\ETX`\STX\DC3\n\ \\f\n\ - \\ENQ\EOT\f\STX\NUL\SOH\DC2\ETX[\b\DC4\n\ + \\ENQ\EOT\r\STX\NUL\SOH\DC2\ETX`\DC4\SUB\n\ \\f\n\ - \\ENQ\EOT\f\STX\NUL\ETX\DC2\ETX[\ETB\CAN\n\ - \0\n\ - \\EOT\EOT\f\STX\SOH\DC2\ETX\\\STX\NAK\"# Hash of the previous transaction.\n\ + \\ENQ\EOT\r\STX\NUL\ETX\DC2\ETX`\GS\RS\n\ + \U\n\ + \\EOT\EOT\r\STX\SOH\DC2\ETXa\STX\FS\"H Chain point representing the snapshot the query was evaluated against.\n\ \\n\ \\f\n\ - \\ENQ\EOT\f\STX\SOH\ACK\DC2\ETX\\\STX\b\n\ + \\ENQ\EOT\r\STX\SOH\ACK\DC2\ETXa\STX\f\n\ \\f\n\ - \\ENQ\EOT\f\STX\SOH\SOH\DC2\ETX\\\t\DLE\n\ + \\ENQ\EOT\r\STX\SOH\SOH\DC2\ETXa\r\ETB\n\ \\f\n\ - \\ENQ\EOT\f\STX\SOH\ETX\DC2\ETX\\\DC3\DC4\n\ - \\f\n\ - \\EOT\EOT\f\b\NUL\DC2\EOT]\STX_\ETX\n\ - \\f\n\ - \\ENQ\EOT\f\b\NUL\SOH\DC2\ETX]\b\DC4\n\ - \\GS\n\ - \\EOT\EOT\f\STX\STX\DC2\ETX^\EOT0\"\DLE A cardano UTxO\n\ + \\ENQ\EOT\r\STX\SOH\ETX\DC2\ETXa\SUB\ESC\n\ + \S\n\ + \\STX\EOT\SO\DC2\EOTe\NULi\SOH\SUBG An evenlope that holds an UTxO patterns from any of compatible chains\n\ \\n\ + \\n\ + \\n\ + \\ETX\EOT\SO\SOH\DC2\ETXe\b\SYN\n\ \\f\n\ - \\ENQ\EOT\f\STX\STX\ACK\DC2\ETX^\EOT#\n\ - \\f\n\ - \\ENQ\EOT\f\STX\STX\SOH\DC2\ETX^$+\n\ + \\EOT\EOT\SO\b\NUL\DC2\EOTf\STXh\ETX\n\ \\f\n\ - \\ENQ\EOT\f\STX\STX\ETX\DC2\ETX^./\n\ - \R\n\ - \\EOT\EOT\f\STX\ETX\DC2\ETX`\STX\ESC\"E The chain point that represents the block this UTxO was created in.\n\ - \\n\ + \\ENQ\EOT\SO\b\NUL\SOH\DC2\ETXf\b\DC4\n\ + \\v\n\ + \\EOT\EOT\SO\STX\NUL\DC2\ETXg\EOT7\n\ \\f\n\ - \\ENQ\EOT\f\STX\ETX\ACK\DC2\ETX`\STX\f\n\ + \\ENQ\EOT\SO\STX\NUL\ACK\DC2\ETXg\EOT*\n\ \\f\n\ - \\ENQ\EOT\f\STX\ETX\SOH\DC2\ETX`\r\SYN\n\ + \\ENQ\EOT\SO\STX\NUL\SOH\DC2\ETXg+2\n\ \\f\n\ - \\ENQ\EOT\f\STX\ETX\ETX\DC2\ETX`\EM\SUB\n\ - \+\n\ - \\STX\EOT\r\DC2\EOTd\NULg\SOH\SUB\US Request to get specific UTxOs\n\ + \\ENQ\EOT\SO\STX\NUL\ETX\DC2\ETXg56\n\ + \^\n\ + \\STX\EOT\SI\DC2\EOTl\NULq\SOH\SUBR Represents a simple utxo predicate that can composed to create more complex ones\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\r\SOH\DC2\ETXd\b\CAN\n\ - \\"\n\ - \\EOT\EOT\r\STX\NUL\DC2\ETXe\STX\ESC\"\NAK List of keys UTxOs.\n\ + \\ETX\EOT\SI\SOH\DC2\ETXl\b\NAK\n\ + \8\n\ + \\EOT\EOT\SI\STX\NUL\DC2\ETXm\STX$\"+ Predicate is true if tx exhibits pattern.\n\ \\n\ \\f\n\ - \\ENQ\EOT\r\STX\NUL\EOT\DC2\ETXe\STX\n\ + \\ENQ\EOT\SI\STX\NUL\EOT\DC2\ETXm\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\r\STX\NUL\ACK\DC2\ETXe\v\DC1\n\ + \\ENQ\EOT\SI\STX\NUL\ACK\DC2\ETXm\v\EM\n\ \\f\n\ - \\ENQ\EOT\r\STX\NUL\SOH\DC2\ETXe\DC2\SYN\n\ + \\ENQ\EOT\SI\STX\NUL\SOH\DC2\ETXm\SUB\US\n\ \\f\n\ - \\ENQ\EOT\r\STX\NUL\ETX\DC2\ETXe\EM\SUB\n\ - \7\n\ - \\EOT\EOT\r\STX\SOH\DC2\ETXf\STX+\"* Field mask to selectively return fields.\n\ + \\ENQ\EOT\SI\STX\NUL\ETX\DC2\ETXm\"#\n\ + \?\n\ + \\EOT\EOT\SI\STX\SOH\DC2\ETXn\STX!\"2 Predicate is true if tx doesn't exhibit pattern.\n\ \\n\ \\f\n\ - \\ENQ\EOT\r\STX\SOH\ACK\DC2\ETXf\STX\ESC\n\ + \\ENQ\EOT\SI\STX\SOH\EOT\DC2\ETXn\STX\n\ + \\n\ \\f\n\ - \\ENQ\EOT\r\STX\SOH\SOH\DC2\ETXf\FS&\n\ + \\ENQ\EOT\SI\STX\SOH\ACK\DC2\ETXn\v\CAN\n\ \\f\n\ - \\ENQ\EOT\r\STX\SOH\ETX\DC2\ETXf)*\n\ - \T\n\ - \\STX\EOT\SO\DC2\EOTj\NULm\SOH\SUBH Response containing the UTxOs associated with the requested addresses.\n\ - \\n\ - \\n\ - \\n\ - \\ETX\EOT\SO\SOH\DC2\ETXj\b\EM\n\ - \\GS\n\ - \\EOT\EOT\SO\STX\NUL\DC2\ETXk\STX!\"\DLE List of UTxOs.\n\ + \\ENQ\EOT\SI\STX\SOH\SOH\DC2\ETXn\EM\FS\n\ + \\f\n\ + \\ENQ\EOT\SI\STX\SOH\ETX\DC2\ETXn\US \n\ + \F\n\ + \\EOT\EOT\SI\STX\STX\DC2\ETXo\STX$\"9 Predicate is true if utxo exhibits all of the patterns.\n\ \\n\ \\f\n\ - \\ENQ\EOT\SO\STX\NUL\EOT\DC2\ETXk\STX\n\ + \\ENQ\EOT\SI\STX\STX\EOT\DC2\ETXo\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\SO\STX\NUL\ACK\DC2\ETXk\v\SYN\n\ + \\ENQ\EOT\SI\STX\STX\ACK\DC2\ETXo\v\CAN\n\ \\f\n\ - \\ENQ\EOT\SO\STX\NUL\SOH\DC2\ETXk\ETB\FS\n\ + \\ENQ\EOT\SI\STX\STX\SOH\DC2\ETXo\EM\US\n\ \\f\n\ - \\ENQ\EOT\SO\STX\NUL\ETX\DC2\ETXk\US \n\ - \J\n\ - \\EOT\EOT\SO\STX\SOH\DC2\ETXl\STX\FS\"= The chain point that represent the ledger current position.\n\ + \\ENQ\EOT\SI\STX\STX\ETX\DC2\ETXo\"#\n\ + \F\n\ + \\EOT\EOT\SI\STX\ETX\DC2\ETXp\STX$\"9 Predicate is true if utxo exhibits any of the patterns.\n\ \\n\ \\f\n\ - \\ENQ\EOT\SO\STX\SOH\ACK\DC2\ETXl\STX\f\n\ + \\ENQ\EOT\SI\STX\ETX\EOT\DC2\ETXp\STX\n\ + \\n\ \\f\n\ - \\ENQ\EOT\SO\STX\SOH\SOH\DC2\ETXl\r\ETB\n\ + \\ENQ\EOT\SI\STX\ETX\ACK\DC2\ETXp\v\CAN\n\ \\f\n\ - \\ENQ\EOT\SO\STX\SOH\ETX\DC2\ETXl\SUB\ESC\n\ - \<\n\ - \\STX\EOT\SI\DC2\EOTp\NULu\SOH\SUB0 Request to search for UTxO based on a pattern.\n\ - \\n\ + \\ENQ\EOT\SI\STX\ETX\SOH\DC2\ETXp\EM\US\n\ + \\f\n\ + \\ENQ\EOT\SI\STX\ETX\ETX\DC2\ETXp\"#\n\ + \J\n\ + \\STX\EOT\DLE\DC2\EOTt\NUL{\SOH\SUB> An evenlope that holds an UTxO from any of compatible chains\n\ \\n\ \\n\ - \\ETX\EOT\SI\SOH\DC2\ETXp\b\SUB\n\ - \)\n\ - \\EOT\EOT\SI\STX\NUL\DC2\ETXq\STX'\"\FS Pattern to match UTxOs by.\n\ \\n\ - \\f\n\ - \\ENQ\EOT\SI\STX\NUL\EOT\DC2\ETXq\STX\n\ + \\ETX\EOT\DLE\SOH\DC2\ETXt\b\DC3\n\ + \5\n\ + \\EOT\EOT\DLE\STX\NUL\DC2\ETXu\STX\EM\"( Original bytes as defined by the chain\n\ \\n\ \\f\n\ - \\ENQ\EOT\SI\STX\NUL\ACK\DC2\ETXq\v\CAN\n\ + \\ENQ\EOT\DLE\STX\NUL\ENQ\DC2\ETXu\STX\a\n\ \\f\n\ - \\ENQ\EOT\SI\STX\NUL\SOH\DC2\ETXq\EM\"\n\ + \\ENQ\EOT\DLE\STX\NUL\SOH\DC2\ETXu\b\DC4\n\ \\f\n\ - \\ENQ\EOT\SI\STX\NUL\ETX\DC2\ETXq%&\n\ - \7\n\ - \\EOT\EOT\SI\STX\SOH\DC2\ETXr\STX+\"* Field mask to selectively return fields.\n\ + \\ENQ\EOT\DLE\STX\NUL\ETX\DC2\ETXu\ETB\CAN\n\ + \0\n\ + \\EOT\EOT\DLE\STX\SOH\DC2\ETXv\STX\NAK\"# Hash of the previous transaction.\n\ \\n\ \\f\n\ - \\ENQ\EOT\SI\STX\SOH\ACK\DC2\ETXr\STX\ESC\n\ + \\ENQ\EOT\DLE\STX\SOH\ACK\DC2\ETXv\STX\b\n\ \\f\n\ - \\ENQ\EOT\SI\STX\SOH\SOH\DC2\ETXr\FS&\n\ + \\ENQ\EOT\DLE\STX\SOH\SOH\DC2\ETXv\t\DLE\n\ \\f\n\ - \\ENQ\EOT\SI\STX\SOH\ETX\DC2\ETXr)*\n\ - \5\n\ - \\EOT\EOT\SI\STX\STX\DC2\ETXs\STX\US\"( The maximum number of items to return.\n\ - \\n\ + \\ENQ\EOT\DLE\STX\SOH\ETX\DC2\ETXv\DC3\DC4\n\ + \\f\n\ + \\EOT\EOT\DLE\b\NUL\DC2\EOTw\STXy\ETX\n\ \\f\n\ - \\ENQ\EOT\SI\STX\STX\EOT\DC2\ETXs\STX\n\ + \\ENQ\EOT\DLE\b\NUL\SOH\DC2\ETXw\b\DC4\n\ + \\GS\n\ + \\EOT\EOT\DLE\STX\STX\DC2\ETXx\EOT0\"\DLE A cardano UTxO\n\ \\n\ \\f\n\ - \\ENQ\EOT\SI\STX\STX\ENQ\DC2\ETXs\v\DLE\n\ + \\ENQ\EOT\DLE\STX\STX\ACK\DC2\ETXx\EOT#\n\ \\f\n\ - \\ENQ\EOT\SI\STX\STX\SOH\DC2\ETXs\DC1\SUB\n\ + \\ENQ\EOT\DLE\STX\STX\SOH\DC2\ETXx$+\n\ \\f\n\ - \\ENQ\EOT\SI\STX\STX\ETX\DC2\ETXs\GS\RS\n\ + \\ENQ\EOT\DLE\STX\STX\ETX\DC2\ETXx./\n\ \R\n\ - \\EOT\EOT\SI\STX\ETX\DC2\ETXt\STX\"\"E The next_page_token value returned from a previous request, if any.\n\ - \\n\ - \\f\n\ - \\ENQ\EOT\SI\STX\ETX\EOT\DC2\ETXt\STX\n\ + \\EOT\EOT\DLE\STX\ETX\DC2\ETXz\STX\ESC\"E The chain point that represents the block this UTxO was created in.\n\ \\n\ \\f\n\ - \\ENQ\EOT\SI\STX\ETX\ENQ\DC2\ETXt\v\DC1\n\ + \\ENQ\EOT\DLE\STX\ETX\ACK\DC2\ETXz\STX\f\n\ \\f\n\ - \\ENQ\EOT\SI\STX\ETX\SOH\DC2\ETXt\DC2\GS\n\ + \\ENQ\EOT\DLE\STX\ETX\SOH\DC2\ETXz\r\SYN\n\ \\f\n\ - \\ENQ\EOT\SI\STX\ETX\ETX\DC2\ETXt !\n\ - \O\n\ - \\STX\EOT\DLE\DC2\EOTx\NUL|\SOH\SUBC Response containing the UTxOs that match the requested addresses.\n\ + \\ENQ\EOT\DLE\STX\ETX\ETX\DC2\ETXz\EM\SUB\n\ + \,\n\ + \\STX\EOT\DC1\DC2\ENQ~\NUL\129\SOH\SOH\SUB\US Request to get specific UTxOs\n\ \\n\ \\n\ \\n\ - \\ETX\EOT\DLE\SOH\DC2\ETXx\b\ESC\n\ - \\GS\n\ - \\EOT\EOT\DLE\STX\NUL\DC2\ETXy\STX!\"\DLE List of UTxOs.\n\ + \\ETX\EOT\DC1\SOH\DC2\ETX~\b\CAN\n\ + \\"\n\ + \\EOT\EOT\DC1\STX\NUL\DC2\ETX\DEL\STX\ESC\"\NAK List of keys UTxOs.\n\ \\n\ \\f\n\ - \\ENQ\EOT\DLE\STX\NUL\EOT\DC2\ETXy\STX\n\ + \\ENQ\EOT\DC1\STX\NUL\EOT\DC2\ETX\DEL\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\DLE\STX\NUL\ACK\DC2\ETXy\v\SYN\n\ + \\ENQ\EOT\DC1\STX\NUL\ACK\DC2\ETX\DEL\v\DC1\n\ \\f\n\ - \\ENQ\EOT\DLE\STX\NUL\SOH\DC2\ETXy\ETB\FS\n\ + \\ENQ\EOT\DC1\STX\NUL\SOH\DC2\ETX\DEL\DC2\SYN\n\ \\f\n\ - \\ENQ\EOT\DLE\STX\NUL\ETX\DC2\ETXy\US \n\ - \J\n\ - \\EOT\EOT\DLE\STX\SOH\DC2\ETXz\STX\FS\"= The chain point that represent the ledger current position.\n\ + \\ENQ\EOT\DC1\STX\NUL\ETX\DC2\ETX\DEL\EM\SUB\n\ + \8\n\ + \\EOT\EOT\DC1\STX\SOH\DC2\EOT\128\SOH\STX+\"* Field mask to selectively return fields.\n\ \\n\ - \\f\n\ - \\ENQ\EOT\DLE\STX\SOH\ACK\DC2\ETXz\STX\f\n\ - \\f\n\ - \\ENQ\EOT\DLE\STX\SOH\SOH\DC2\ETXz\r\ETB\n\ - \\f\n\ - \\ENQ\EOT\DLE\STX\SOH\ETX\DC2\ETXz\SUB\ESC\n\ - \_\n\ - \\EOT\EOT\DLE\STX\STX\DC2\ETX{\STX!\"R Token to retrieve the next page of results, absent if there are no more results.\n\ + \\r\n\ + \\ENQ\EOT\DC1\STX\SOH\ACK\DC2\EOT\128\SOH\STX\ESC\n\ + \\r\n\ + \\ENQ\EOT\DC1\STX\SOH\SOH\DC2\EOT\128\SOH\FS&\n\ + \\r\n\ + \\ENQ\EOT\DC1\STX\SOH\ETX\DC2\EOT\128\SOH)*\n\ + \V\n\ + \\STX\EOT\DC2\DC2\ACK\132\SOH\NUL\135\SOH\SOH\SUBH Response containing the UTxOs associated with the requested addresses.\n\ \\n\ - \\f\n\ - \\ENQ\EOT\DLE\STX\STX\EOT\DC2\ETX{\STX\n\ + \\v\n\ + \\ETX\EOT\DC2\SOH\DC2\EOT\132\SOH\b\EM\n\ + \\RS\n\ + \\EOT\EOT\DC2\STX\NUL\DC2\EOT\133\SOH\STX!\"\DLE List of UTxOs.\n\ \\n\ - \\f\n\ - \\ENQ\EOT\DLE\STX\STX\ENQ\DC2\ETX{\v\DC1\n\ - \\f\n\ - \\ENQ\EOT\DLE\STX\STX\SOH\DC2\ETX{\DC2\FS\n\ - \\f\n\ - \\ENQ\EOT\DLE\STX\STX\ETX\DC2\ETX{\US \n\ - \:\n\ - \\STX\EOT\DC1\DC2\ENQ\DEL\NUL\130\SOH\SOH\SUB- Request to get data (as in plural of datum)\n\ + \\r\n\ + \\ENQ\EOT\DC2\STX\NUL\EOT\DC2\EOT\133\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC2\STX\NUL\ACK\DC2\EOT\133\SOH\v\SYN\n\ + \\r\n\ + \\ENQ\EOT\DC2\STX\NUL\SOH\DC2\EOT\133\SOH\ETB\FS\n\ + \\r\n\ + \\ENQ\EOT\DC2\STX\NUL\ETX\DC2\EOT\133\SOH\US \n\ + \K\n\ + \\EOT\EOT\DC2\STX\SOH\DC2\EOT\134\SOH\STX\FS\"= The chain point that represent the ledger current position.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC2\STX\SOH\ACK\DC2\EOT\134\SOH\STX\f\n\ + \\r\n\ + \\ENQ\EOT\DC2\STX\SOH\SOH\DC2\EOT\134\SOH\r\ETB\n\ + \\r\n\ + \\ENQ\EOT\DC2\STX\SOH\ETX\DC2\EOT\134\SOH\SUB\ESC\n\ + \>\n\ + \\STX\EOT\DC3\DC2\ACK\138\SOH\NUL\143\SOH\SOH\SUB0 Request to search for UTxO based on a pattern.\n\ + \\n\ + \\v\n\ + \\ETX\EOT\DC3\SOH\DC2\EOT\138\SOH\b\SUB\n\ + \*\n\ + \\EOT\EOT\DC3\STX\NUL\DC2\EOT\139\SOH\STX'\"\FS Pattern to match UTxOs by.\n\ \\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\NUL\EOT\DC2\EOT\139\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\NUL\ACK\DC2\EOT\139\SOH\v\CAN\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\NUL\SOH\DC2\EOT\139\SOH\EM\"\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\NUL\ETX\DC2\EOT\139\SOH%&\n\ + \8\n\ + \\EOT\EOT\DC3\STX\SOH\DC2\EOT\140\SOH\STX+\"* Field mask to selectively return fields.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\SOH\ACK\DC2\EOT\140\SOH\STX\ESC\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\SOH\SOH\DC2\EOT\140\SOH\FS&\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\SOH\ETX\DC2\EOT\140\SOH)*\n\ + \6\n\ + \\EOT\EOT\DC3\STX\STX\DC2\EOT\141\SOH\STX\US\"( The maximum number of items to return.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\STX\EOT\DC2\EOT\141\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\STX\ENQ\DC2\EOT\141\SOH\v\DLE\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\STX\SOH\DC2\EOT\141\SOH\DC1\SUB\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\STX\ETX\DC2\EOT\141\SOH\GS\RS\n\ + \S\n\ + \\EOT\EOT\DC3\STX\ETX\DC2\EOT\142\SOH\STX\"\"E The next_page_token value returned from a previous request, if any.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\ETX\EOT\DC2\EOT\142\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\ETX\ENQ\DC2\EOT\142\SOH\v\DC1\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\ETX\SOH\DC2\EOT\142\SOH\DC2\GS\n\ + \\r\n\ + \\ENQ\EOT\DC3\STX\ETX\ETX\DC2\EOT\142\SOH !\n\ + \Q\n\ + \\STX\EOT\DC4\DC2\ACK\146\SOH\NUL\150\SOH\SOH\SUBC Response containing the UTxOs that match the requested addresses.\n\ + \\n\ + \\v\n\ + \\ETX\EOT\DC4\SOH\DC2\EOT\146\SOH\b\ESC\n\ + \\RS\n\ + \\EOT\EOT\DC4\STX\NUL\DC2\EOT\147\SOH\STX!\"\DLE List of UTxOs.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\NUL\EOT\DC2\EOT\147\SOH\STX\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\NUL\ACK\DC2\EOT\147\SOH\v\SYN\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\NUL\SOH\DC2\EOT\147\SOH\ETB\FS\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\NUL\ETX\DC2\EOT\147\SOH\US \n\ + \K\n\ + \\EOT\EOT\DC4\STX\SOH\DC2\EOT\148\SOH\STX\FS\"= The chain point that represent the ledger current position.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\SOH\ACK\DC2\EOT\148\SOH\STX\f\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\SOH\SOH\DC2\EOT\148\SOH\r\ETB\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\SOH\ETX\DC2\EOT\148\SOH\SUB\ESC\n\ + \`\n\ + \\EOT\EOT\DC4\STX\STX\DC2\EOT\149\SOH\STX!\"R Token to retrieve the next page of results, absent if there are no more results.\n\ + \\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\STX\EOT\DC2\EOT\149\SOH\STX\n\ \\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\STX\ENQ\DC2\EOT\149\SOH\v\DC1\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\STX\SOH\DC2\EOT\149\SOH\DC2\FS\n\ + \\r\n\ + \\ENQ\EOT\DC4\STX\STX\ETX\DC2\EOT\149\SOH\US \n\ + \;\n\ + \\STX\EOT\NAK\DC2\ACK\153\SOH\NUL\156\SOH\SOH\SUB- Request to get data (as in plural of datum)\n\ \\n\ - \\ETX\EOT\DC1\SOH\DC2\ETX\DEL\b\ETB\n\ + \\v\n\ + \\ETX\EOT\NAK\SOH\DC2\EOT\153\SOH\b\ETB\n\ \\f\n\ - \\EOT\EOT\DC1\STX\NUL\DC2\EOT\128\SOH\STX\SUB\n\ + \\EOT\EOT\NAK\STX\NUL\DC2\EOT\154\SOH\STX\SUB\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\EOT\DC2\EOT\128\SOH\STX\n\ + \\ENQ\EOT\NAK\STX\NUL\EOT\DC2\EOT\154\SOH\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\ENQ\DC2\EOT\128\SOH\v\DLE\n\ + \\ENQ\EOT\NAK\STX\NUL\ENQ\DC2\EOT\154\SOH\v\DLE\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\SOH\DC2\EOT\128\SOH\DC1\NAK\n\ + \\ENQ\EOT\NAK\STX\NUL\SOH\DC2\EOT\154\SOH\DC1\NAK\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\NUL\ETX\DC2\EOT\128\SOH\CAN\EM\n\ + \\ENQ\EOT\NAK\STX\NUL\ETX\DC2\EOT\154\SOH\CAN\EM\n\ \H\n\ - \\EOT\EOT\DC1\STX\SOH\DC2\EOT\129\SOH\STX+\": Field mask to selectively return fields in the response.\n\ + \\EOT\EOT\NAK\STX\SOH\DC2\EOT\155\SOH\STX+\": Field mask to selectively return fields in the response.\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\SOH\ACK\DC2\EOT\129\SOH\STX\ESC\n\ + \\ENQ\EOT\NAK\STX\SOH\ACK\DC2\EOT\155\SOH\STX\ESC\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\SOH\SOH\DC2\EOT\129\SOH\FS&\n\ + \\ENQ\EOT\NAK\STX\SOH\SOH\DC2\EOT\155\SOH\FS&\n\ \\r\n\ - \\ENQ\EOT\DC1\STX\SOH\ETX\DC2\EOT\129\SOH)*\n\ + \\ENQ\EOT\NAK\STX\SOH\ETX\DC2\EOT\155\SOH)*\n\ \O\n\ - \\STX\EOT\DC2\DC2\ACK\133\SOH\NUL\139\SOH\SOH\SUBA An evenlope that holds a datum for any of the compatible chains\n\ + \\STX\EOT\SYN\DC2\ACK\159\SOH\NUL\165\SOH\SOH\SUBA An evenlope that holds a datum for any of the compatible chains\n\ \\n\ \\v\n\ - \\ETX\EOT\DC2\SOH\DC2\EOT\133\SOH\b\NAK\n\ + \\ETX\EOT\SYN\SOH\DC2\EOT\159\SOH\b\NAK\n\ \6\n\ - \\EOT\EOT\DC2\STX\NUL\DC2\EOT\134\SOH\STX\EM\"( Original bytes as defined by the chain\n\ + \\EOT\EOT\SYN\STX\NUL\DC2\EOT\160\SOH\STX\EM\"( Original bytes as defined by the chain\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\NUL\ENQ\DC2\EOT\134\SOH\STX\a\n\ + \\ENQ\EOT\SYN\STX\NUL\ENQ\DC2\EOT\160\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\NUL\SOH\DC2\EOT\134\SOH\b\DC4\n\ + \\ENQ\EOT\SYN\STX\NUL\SOH\DC2\EOT\160\SOH\b\DC4\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\NUL\ETX\DC2\EOT\134\SOH\ETB\CAN\n\ + \\ENQ\EOT\SYN\STX\NUL\ETX\DC2\EOT\160\SOH\ETB\CAN\n\ \\f\n\ - \\EOT\EOT\DC2\STX\SOH\DC2\EOT\135\SOH\STX\DLE\n\ + \\EOT\EOT\SYN\STX\SOH\DC2\EOT\161\SOH\STX\DLE\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\SOH\ENQ\DC2\EOT\135\SOH\STX\a\n\ + \\ENQ\EOT\SYN\STX\SOH\ENQ\DC2\EOT\161\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\SOH\SOH\DC2\EOT\135\SOH\b\v\n\ + \\ENQ\EOT\SYN\STX\SOH\SOH\DC2\EOT\161\SOH\b\v\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\SOH\ETX\DC2\EOT\135\SOH\SO\SI\n\ + \\ENQ\EOT\SYN\STX\SOH\ETX\DC2\EOT\161\SOH\SO\SI\n\ \\SO\n\ - \\EOT\EOT\DC2\b\NUL\DC2\ACK\136\SOH\STX\138\SOH\ETX\n\ + \\EOT\EOT\SYN\b\NUL\DC2\ACK\162\SOH\STX\164\SOH\ETX\n\ \\r\n\ - \\ENQ\EOT\DC2\b\NUL\SOH\DC2\EOT\136\SOH\b\DC4\n\ + \\ENQ\EOT\SYN\b\NUL\SOH\DC2\EOT\162\SOH\b\DC4\n\ \\RS\n\ - \\EOT\EOT\DC2\STX\STX\DC2\EOT\137\SOH\EOT2\"\DLE A cardano UTxO\n\ + \\EOT\EOT\SYN\STX\STX\DC2\EOT\163\SOH\EOT2\"\DLE A cardano UTxO\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\STX\ACK\DC2\EOT\137\SOH\EOT%\n\ + \\ENQ\EOT\SYN\STX\STX\ACK\DC2\EOT\163\SOH\EOT%\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\STX\SOH\DC2\EOT\137\SOH&-\n\ + \\ENQ\EOT\SYN\STX\STX\SOH\DC2\EOT\163\SOH&-\n\ \\r\n\ - \\ENQ\EOT\DC2\STX\STX\ETX\DC2\EOT\137\SOH01\n\ + \\ENQ\EOT\SYN\STX\STX\ETX\DC2\EOT\163\SOH01\n\ \@\n\ - \\STX\EOT\DC3\DC2\ACK\142\SOH\NUL\145\SOH\SOH\SUB2 Response containing data (as in plural of datum)\n\ + \\STX\EOT\ETB\DC2\ACK\168\SOH\NUL\171\SOH\SOH\SUB2 Response containing data (as in plural of datum)\n\ \\n\ \\v\n\ - \\ETX\EOT\DC3\SOH\DC2\EOT\142\SOH\b\CAN\n\ + \\ETX\EOT\ETB\SOH\DC2\EOT\168\SOH\b\CAN\n\ \(\n\ - \\EOT\EOT\DC3\STX\NUL\DC2\EOT\143\SOH\STX$\"\SUB The value of each datum.\n\ + \\EOT\EOT\ETB\STX\NUL\DC2\EOT\169\SOH\STX$\"\SUB The value of each datum.\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\NUL\EOT\DC2\EOT\143\SOH\STX\n\ + \\ENQ\EOT\ETB\STX\NUL\EOT\DC2\EOT\169\SOH\STX\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\NUL\ACK\DC2\EOT\143\SOH\v\CAN\n\ + \\ENQ\EOT\ETB\STX\NUL\ACK\DC2\EOT\169\SOH\v\CAN\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\NUL\SOH\DC2\EOT\143\SOH\EM\US\n\ + \\ENQ\EOT\ETB\STX\NUL\SOH\DC2\EOT\169\SOH\EM\US\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\NUL\ETX\DC2\EOT\143\SOH\"#\n\ + \\ENQ\EOT\ETB\STX\NUL\ETX\DC2\EOT\169\SOH\"#\n\ \K\n\ - \\EOT\EOT\DC3\STX\SOH\DC2\EOT\144\SOH\STX\FS\"= The chain point that represent the ledger current position.\n\ + \\EOT\EOT\ETB\STX\SOH\DC2\EOT\170\SOH\STX\FS\"= The chain point that represent the ledger current position.\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\SOH\ACK\DC2\EOT\144\SOH\STX\f\n\ + \\ENQ\EOT\ETB\STX\SOH\ACK\DC2\EOT\170\SOH\STX\f\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\SOH\SOH\DC2\EOT\144\SOH\r\ETB\n\ + \\ENQ\EOT\ETB\STX\SOH\SOH\DC2\EOT\170\SOH\r\ETB\n\ \\r\n\ - \\ENQ\EOT\DC3\STX\SOH\ETX\DC2\EOT\144\SOH\SUB\ESC\n\ + \\ENQ\EOT\ETB\STX\SOH\ETX\DC2\EOT\170\SOH\SUB\ESC\n\ \4\n\ - \\STX\EOT\DC4\DC2\ACK\148\SOH\NUL\151\SOH\SOH\SUB& Request to get a transaction by hash\n\ + \\STX\EOT\CAN\DC2\ACK\174\SOH\NUL\177\SOH\SOH\SUB& Request to get a transaction by hash\n\ \\n\ \\v\n\ - \\ETX\EOT\DC4\SOH\DC2\EOT\148\SOH\b\NAK\n\ + \\ETX\EOT\CAN\SOH\DC2\EOT\174\SOH\b\NAK\n\ \,\n\ - \\EOT\EOT\DC4\STX\NUL\DC2\EOT\149\SOH\STX\DC1\"\RS The hash of the transaction.\n\ + \\EOT\EOT\CAN\STX\NUL\DC2\EOT\175\SOH\STX\DC1\"\RS The hash of the transaction.\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\NUL\ENQ\DC2\EOT\149\SOH\STX\a\n\ + \\ENQ\EOT\CAN\STX\NUL\ENQ\DC2\EOT\175\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\NUL\SOH\DC2\EOT\149\SOH\b\f\n\ + \\ENQ\EOT\CAN\STX\NUL\SOH\DC2\EOT\175\SOH\b\f\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\NUL\ETX\DC2\EOT\149\SOH\SI\DLE\n\ + \\ENQ\EOT\CAN\STX\NUL\ETX\DC2\EOT\175\SOH\SI\DLE\n\ \H\n\ - \\EOT\EOT\DC4\STX\SOH\DC2\EOT\150\SOH\STX+\": Field mask to selectively return fields in the response.\n\ + \\EOT\EOT\CAN\STX\SOH\DC2\EOT\176\SOH\STX+\": Field mask to selectively return fields in the response.\n\ \\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\SOH\ACK\DC2\EOT\150\SOH\STX\ESC\n\ + \\ENQ\EOT\CAN\STX\SOH\ACK\DC2\EOT\176\SOH\STX\ESC\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\SOH\SOH\DC2\EOT\150\SOH\FS&\n\ + \\ENQ\EOT\CAN\STX\SOH\SOH\DC2\EOT\176\SOH\FS&\n\ \\r\n\ - \\ENQ\EOT\DC4\STX\SOH\ETX\DC2\EOT\150\SOH)*\n\ + \\ENQ\EOT\CAN\STX\SOH\ETX\DC2\EOT\176\SOH)*\n\ \G\n\ - \\STX\EOT\NAK\DC2\ACK\154\SOH\NUL\160\SOH\SOH\SUB9 Represents a transaction from any supported blockchain.\n\ + \\STX\EOT\EM\DC2\ACK\180\SOH\NUL\186\SOH\SOH\SUB9 Represents a transaction from any supported blockchain.\n\ \\n\ \\v\n\ - \\ETX\EOT\NAK\SOH\DC2\EOT\154\SOH\b\DC2\n\ + \\ETX\EOT\EM\SOH\DC2\EOT\180\SOH\b\DC2\n\ \6\n\ - \\EOT\EOT\NAK\STX\NUL\DC2\EOT\155\SOH\STX\EM\"( Original bytes as defined by the chain\n\ + \\EOT\EOT\EM\STX\NUL\DC2\EOT\181\SOH\STX\EM\"( Original bytes as defined by the chain\n\ \\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\NUL\ENQ\DC2\EOT\155\SOH\STX\a\n\ + \\ENQ\EOT\EM\STX\NUL\ENQ\DC2\EOT\181\SOH\STX\a\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\NUL\SOH\DC2\EOT\155\SOH\b\DC4\n\ + \\ENQ\EOT\EM\STX\NUL\SOH\DC2\EOT\181\SOH\b\DC4\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\NUL\ETX\DC2\EOT\155\SOH\ETB\CAN\n\ + \\ENQ\EOT\EM\STX\NUL\ETX\DC2\EOT\181\SOH\ETB\CAN\n\ \\SO\n\ - \\EOT\EOT\NAK\b\NUL\DC2\ACK\156\SOH\STX\158\SOH\ETX\n\ + \\EOT\EOT\EM\b\NUL\DC2\ACK\182\SOH\STX\184\SOH\ETX\n\ \\r\n\ - \\ENQ\EOT\NAK\b\NUL\SOH\DC2\EOT\156\SOH\b\r\n\ + \\ENQ\EOT\EM\b\NUL\SOH\DC2\EOT\182\SOH\b\r\n\ \&\n\ - \\EOT\EOT\NAK\STX\SOH\DC2\EOT\157\SOH\EOT*\"\CAN A Cardano transaction.\n\ + \\EOT\EOT\EM\STX\SOH\DC2\EOT\183\SOH\EOT*\"\CAN A Cardano transaction.\n\ \\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\SOH\ACK\DC2\EOT\157\SOH\EOT\GS\n\ + \\ENQ\EOT\EM\STX\SOH\ACK\DC2\EOT\183\SOH\EOT\GS\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\SOH\SOH\DC2\EOT\157\SOH\RS%\n\ + \\ENQ\EOT\EM\STX\SOH\SOH\DC2\EOT\183\SOH\RS%\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\SOH\ETX\DC2\EOT\157\SOH()\n\ + \\ENQ\EOT\EM\STX\SOH\ETX\DC2\EOT\183\SOH()\n\ \V\n\ - \\EOT\EOT\NAK\STX\STX\DC2\EOT\159\SOH\STX\ESC\"H The chain point that represents the block this transaction belongs to.\n\ + \\EOT\EOT\EM\STX\STX\DC2\EOT\185\SOH\STX\ESC\"H The chain point that represents the block this transaction belongs to.\n\ \\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\STX\ACK\DC2\EOT\159\SOH\STX\f\n\ + \\ENQ\EOT\EM\STX\STX\ACK\DC2\EOT\185\SOH\STX\f\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\STX\SOH\DC2\EOT\159\SOH\r\SYN\n\ + \\ENQ\EOT\EM\STX\STX\SOH\DC2\EOT\185\SOH\r\SYN\n\ \\r\n\ - \\ENQ\EOT\NAK\STX\STX\ETX\DC2\EOT\159\SOH\EM\SUB\n\ + \\ENQ\EOT\EM\STX\STX\ETX\DC2\EOT\185\SOH\EM\SUB\n\ \W\n\ - \\STX\EOT\SYN\DC2\ACK\163\SOH\NUL\166\SOH\SOH\SUBI Response containing the transaction associated with the requested hash.\n\ + \\STX\EOT\SUB\DC2\ACK\189\SOH\NUL\192\SOH\SOH\SUBI Response containing the transaction associated with the requested hash.\n\ \\n\ \\v\n\ - \\ETX\EOT\SYN\SOH\DC2\EOT\163\SOH\b\SYN\n\ + \\ETX\EOT\SUB\SOH\DC2\EOT\189\SOH\b\SYN\n\ \ \n\ - \\EOT\EOT\SYN\STX\NUL\DC2\EOT\164\SOH\STX\DC4\"\DC2 The transaction.\n\ + \\EOT\EOT\SUB\STX\NUL\DC2\EOT\190\SOH\STX\DC4\"\DC2 The transaction.\n\ \\n\ \\r\n\ - \\ENQ\EOT\SYN\STX\NUL\ACK\DC2\EOT\164\SOH\STX\f\n\ + \\ENQ\EOT\SUB\STX\NUL\ACK\DC2\EOT\190\SOH\STX\f\n\ \\r\n\ - \\ENQ\EOT\SYN\STX\NUL\SOH\DC2\EOT\164\SOH\r\SI\n\ + \\ENQ\EOT\SUB\STX\NUL\SOH\DC2\EOT\190\SOH\r\SI\n\ \\r\n\ - \\ENQ\EOT\SYN\STX\NUL\ETX\DC2\EOT\164\SOH\DC2\DC3\n\ + \\ENQ\EOT\SUB\STX\NUL\ETX\DC2\EOT\190\SOH\DC2\DC3\n\ \K\n\ - \\EOT\EOT\SYN\STX\SOH\DC2\EOT\165\SOH\STX\FS\"= The chain point that represent the ledger current position.\n\ + \\EOT\EOT\SUB\STX\SOH\DC2\EOT\191\SOH\STX\FS\"= The chain point that represent the ledger current position.\n\ \\n\ \\r\n\ - \\ENQ\EOT\SYN\STX\SOH\ACK\DC2\EOT\165\SOH\STX\f\n\ + \\ENQ\EOT\SUB\STX\SOH\ACK\DC2\EOT\191\SOH\STX\f\n\ \\r\n\ - \\ENQ\EOT\SYN\STX\SOH\SOH\DC2\EOT\165\SOH\r\ETB\n\ + \\ENQ\EOT\SUB\STX\SOH\SOH\DC2\EOT\191\SOH\r\ETB\n\ \\r\n\ - \\ENQ\EOT\SYN\STX\SOH\ETX\DC2\EOT\165\SOH\SUB\ESC\n\ + \\ENQ\EOT\SUB\STX\SOH\ETX\DC2\EOT\191\SOH\SUB\ESC\n\ \G\n\ - \\STX\ACK\NUL\DC2\ACK\169\SOH\NUL\178\SOH\SOH\SUB9 Service definition for querying the state of the chain.\n\ + \\STX\ACK\NUL\DC2\ACK\195\SOH\NUL\208\SOH\SOH\SUB9 Service definition for querying the state of the chain.\n\ \\n\ \\v\n\ - \\ETX\ACK\NUL\SOH\DC2\EOT\169\SOH\b\DC4\n\ + \\ETX\ACK\NUL\SOH\DC2\EOT\195\SOH\b\DC4\n\ \(\n\ - \\EOT\ACK\NUL\STX\NUL\DC2\EOT\170\SOH\STXA\"\SUB Get overall chain state.\n\ + \\EOT\ACK\NUL\STX\NUL\DC2\EOT\196\SOH\STXA\"\SUB Get overall chain state.\n\ \\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\NUL\SOH\DC2\EOT\170\SOH\ACK\DLE\n\ + \\ENQ\ACK\NUL\STX\NUL\SOH\DC2\EOT\196\SOH\ACK\DLE\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\NUL\STX\DC2\EOT\170\SOH\DC1\"\n\ + \\ENQ\ACK\NUL\STX\NUL\STX\DC2\EOT\196\SOH\DC1\"\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\NUL\ETX\DC2\EOT\170\SOH-?\n\ + \\ENQ\ACK\NUL\STX\NUL\ETX\DC2\EOT\196\SOH-?\n\ \1\n\ - \\EOT\ACK\NUL\STX\SOH\DC2\EOT\171\SOH\STX>\"# Read specific UTxOs by reference.\n\ + \\EOT\ACK\NUL\STX\SOH\DC2\EOT\197\SOH\STX>\"# Read specific UTxOs by reference.\n\ + \\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\SOH\SOH\DC2\EOT\197\SOH\ACK\SI\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\SOH\STX\DC2\EOT\197\SOH\DLE \n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\SOH\ETX\DC2\EOT\197\SOH+<\n\ + \3\n\ + \\EOT\ACK\NUL\STX\STX\DC2\EOT\198\SOH\STXD\"% Search for UTxO based on a pattern.\n\ + \\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\STX\SOH\DC2\EOT\198\SOH\ACK\DC1\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\STX\STX\DC2\EOT\198\SOH\DC2$\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\STX\ETX\DC2\EOT\198\SOH/B\n\ + \+\n\ + \\EOT\ACK\NUL\STX\ETX\DC2\EOT\199\SOH\STX;\"\GS Read specific datum by hash\n\ \\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\SOH\SOH\DC2\EOT\171\SOH\ACK\SI\n\ + \\ENQ\ACK\NUL\STX\ETX\SOH\DC2\EOT\199\SOH\ACK\SO\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\SOH\STX\DC2\EOT\171\SOH\DLE \n\ + \\ENQ\ACK\NUL\STX\ETX\STX\DC2\EOT\199\SOH\SI\RS\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\SOH\ETX\DC2\EOT\171\SOH+<\n\ + \\ENQ\ACK\NUL\STX\ETX\ETX\DC2\EOT\199\SOH)9\n\ \3\n\ - \\EOT\ACK\NUL\STX\STX\DC2\EOT\172\SOH\STXD\"% Search for UTxO based on a pattern.\n\ + \\EOT\ACK\NUL\STX\EOT\DC2\EOT\200\SOH\STX5\"% Get Txs by chain-specific criteria.\n\ \\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\STX\SOH\DC2\EOT\172\SOH\ACK\DC1\n\ + \\ENQ\ACK\NUL\STX\EOT\SOH\DC2\EOT\200\SOH\ACK\f\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\STX\STX\DC2\EOT\172\SOH\DC2$\n\ + \\ENQ\ACK\NUL\STX\EOT\STX\DC2\EOT\200\SOH\r\SUB\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\STX\ETX\DC2\EOT\172\SOH/B\n\ + \\ENQ\ACK\NUL\STX\EOT\ETX\DC2\EOT\200\SOH%3\n\ \-\n\ - \\EOT\ACK\NUL\STX\ETX\DC2\EOT\173\SOH\STXD\"\US Get the chain genesis config.\n\ + \\EOT\ACK\NUL\STX\ENQ\DC2\EOT\201\SOH\STXD\"\US Get the genesis configuration\n\ + \\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\ENQ\SOH\DC2\EOT\201\SOH\ACK\DC1\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\ENQ\STX\DC2\EOT\201\SOH\DC2$\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\ENQ\ETX\DC2\EOT\201\SOH/B\n\ + \)\n\ + \\EOT\ACK\NUL\STX\ACK\DC2\EOT\202\SOH\STXM\"\ESC Get the chain era summary\n\ + \\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\ACK\SOH\DC2\EOT\202\SOH\ACK\DC4\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\ACK\STX\DC2\EOT\202\SOH\NAK*\n\ + \\r\n\ + \\ENQ\ACK\NUL\STX\ACK\ETX\DC2\EOT\202\SOH5K\n\ + \W\n\ + \\EOT\ACK\NUL\STX\a\DC2\EOT\203\SOH\STX>\"I Run a chain-specific ledger-state query (e.g. stake pool distribution).\n\ \\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\ETX\SOH\DC2\EOT\173\SOH\ACK\DC1\n\ + \\ENQ\ACK\NUL\STX\a\SOH\DC2\EOT\203\SOH\ACK\SI\n\ \\r\n\ - \\ENQ\ACK\NUL\STX\ETX\STX\DC2\EOT\173\SOH\DC2$\n\ + \\ENQ\ACK\NUL\STX\a\STX\DC2\EOT\203\SOH\DLE \n\ \\r\n\ - \\ENQ\ACK\NUL\STX\ETX\ETX\DC2\EOT\173\SOH/Bb\ACKproto3" \ No newline at end of file + \\ENQ\ACK\NUL\STX\a\ETX\DC2\EOT\203\SOH+ Lens.Family2.LensLike' f s a maybe'predicate = Data.ProtoLens.Field.field @"maybe'predicate" +maybe'query :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'query" a) => + Lens.Family2.LensLike' f s a +maybe'query = Data.ProtoLens.Field.field @"maybe'query" +maybe'result :: + forall f s a. + (Prelude.Functor f, + Data.ProtoLens.Field.HasField s "maybe'result" a) => + Lens.Family2.LensLike' f s a +maybe'result = Data.ProtoLens.Field.field @"maybe'result" maybe'startToken :: forall f s a. (Prelude.Functor f, @@ -244,6 +256,16 @@ predicate :: Data.ProtoLens.Field.HasField s "predicate" a) => Lens.Family2.LensLike' f s a predicate = Data.ProtoLens.Field.field @"predicate" +query :: + forall f s a. + (Prelude.Functor f, Data.ProtoLens.Field.HasField s "query" a) => + Lens.Family2.LensLike' f s a +query = Data.ProtoLens.Field.field @"query" +result :: + forall f s a. + (Prelude.Functor f, Data.ProtoLens.Field.HasField s "result" a) => + Lens.Family2.LensLike' f s a +result = Data.ProtoLens.Field.field @"result" slot :: forall f s a. (Prelude.Functor f, Data.ProtoLens.Field.HasField s "slot" a) => diff --git a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Submit/Submit.hs b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Submit/Submit.hs index 24682a8d54..60fe08e2f2 100644 --- a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Submit/Submit.hs +++ b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Submit/Submit.hs @@ -2416,22 +2416,44 @@ data SubmitService = SubmitService {} instance Data.ProtoLens.Service.Types.Service SubmitService where type ServiceName SubmitService = "SubmitService" type ServicePackage SubmitService = "utxorpc.v1beta.submit" - type ServiceMethods SubmitService = '["evalTx", "submitTx"] + type ServiceMethods SubmitService = '["evalTx", + "readMempool", + "submitTx", + "waitForTx", + "watchMempool"] packedServiceDescriptor _ = "\n\ - \\rSubmitService\DC2[\n\ - \\bSubmitTx\DC2&.utxorpc.v1beta.submit.SubmitTxRequest\SUB'.utxorpc.v1beta.submit.SubmitTxResponse\DC2U\n\ - \\ACKEvalTx\DC2$.utxorpc.v1beta.submit.EvalTxRequest\SUB%.utxorpc.v1beta.submit.EvalTxResponse" -instance Data.ProtoLens.Service.Types.HasMethodImpl SubmitService "submitTx" where - type MethodName SubmitService "submitTx" = "SubmitTx" - type MethodInput SubmitService "submitTx" = SubmitTxRequest - type MethodOutput SubmitService "submitTx" = SubmitTxResponse - type MethodStreamingType SubmitService "submitTx" = 'Data.ProtoLens.Service.Types.NonStreaming + \\rSubmitService\DC2U\n\ + \\ACKEvalTx\DC2$.utxorpc.v1beta.submit.EvalTxRequest\SUB%.utxorpc.v1beta.submit.EvalTxResponse\DC2[\n\ + \\bSubmitTx\DC2&.utxorpc.v1beta.submit.SubmitTxRequest\SUB'.utxorpc.v1beta.submit.SubmitTxResponse\DC2`\n\ + \\tWaitForTx\DC2'.utxorpc.v1beta.submit.WaitForTxRequest\SUB(.utxorpc.v1beta.submit.WaitForTxResponse0\SOH\DC2d\n\ + \\vReadMempool\DC2).utxorpc.v1beta.submit.ReadMempoolRequest\SUB*.utxorpc.v1beta.submit.ReadMempoolResponse\DC2i\n\ + \\fWatchMempool\DC2*.utxorpc.v1beta.submit.WatchMempoolRequest\SUB+.utxorpc.v1beta.submit.WatchMempoolResponse0\SOH" instance Data.ProtoLens.Service.Types.HasMethodImpl SubmitService "evalTx" where type MethodName SubmitService "evalTx" = "EvalTx" type MethodInput SubmitService "evalTx" = EvalTxRequest type MethodOutput SubmitService "evalTx" = EvalTxResponse type MethodStreamingType SubmitService "evalTx" = 'Data.ProtoLens.Service.Types.NonStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl SubmitService "submitTx" where + type MethodName SubmitService "submitTx" = "SubmitTx" + type MethodInput SubmitService "submitTx" = SubmitTxRequest + type MethodOutput SubmitService "submitTx" = SubmitTxResponse + type MethodStreamingType SubmitService "submitTx" = 'Data.ProtoLens.Service.Types.NonStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl SubmitService "waitForTx" where + type MethodName SubmitService "waitForTx" = "WaitForTx" + type MethodInput SubmitService "waitForTx" = WaitForTxRequest + type MethodOutput SubmitService "waitForTx" = WaitForTxResponse + type MethodStreamingType SubmitService "waitForTx" = 'Data.ProtoLens.Service.Types.ServerStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl SubmitService "readMempool" where + type MethodName SubmitService "readMempool" = "ReadMempool" + type MethodInput SubmitService "readMempool" = ReadMempoolRequest + type MethodOutput SubmitService "readMempool" = ReadMempoolResponse + type MethodStreamingType SubmitService "readMempool" = 'Data.ProtoLens.Service.Types.NonStreaming +instance Data.ProtoLens.Service.Types.HasMethodImpl SubmitService "watchMempool" where + type MethodName SubmitService "watchMempool" = "WatchMempool" + type MethodInput SubmitService "watchMempool" = WatchMempoolRequest + type MethodOutput SubmitService "watchMempool" = WatchMempoolResponse + type MethodStreamingType SubmitService "watchMempool" = 'Data.ProtoLens.Service.Types.ServerStreaming packedFileDescriptor :: Data.ByteString.ByteString packedFileDescriptor = "\n\ @@ -2484,12 +2506,15 @@ packedFileDescriptor \\DC2STAGE_ACKNOWLEDGED\DLE\SOH\DC2\DC1\n\ \\rSTAGE_MEMPOOL\DLE\STX\DC2\DC1\n\ \\rSTAGE_NETWORK\DLE\ETX\DC2\DC3\n\ - \\SISTAGE_CONFIRMED\DLE\EOT2\195\SOH\n\ - \\rSubmitService\DC2[\n\ - \\bSubmitTx\DC2&.utxorpc.v1beta.submit.SubmitTxRequest\SUB'.utxorpc.v1beta.submit.SubmitTxResponse\DC2U\n\ - \\ACKEvalTx\DC2$.utxorpc.v1beta.submit.EvalTxRequest\SUB%.utxorpc.v1beta.submit.EvalTxResponseB\158\SOH\n\ - \\EMcom.utxorpc.v1beta.submitB\vSubmitProtoP\SOH\162\STX\ETXUVS\170\STX\NAKUtxorpc.V1beta.Submit\202\STX\NAKUtxorpc\\V1beta\\Submit\226\STX!Utxorpc\\V1beta\\Submit\\GPBMetadata\234\STX\ETBUtxorpc::V1beta::SubmitJ\252!\n\ - \\ACK\DC2\EOT\NUL\NULl\SOH\n\ + \\SISTAGE_CONFIRMED\DLE\EOT2\246\ETX\n\ + \\rSubmitService\DC2U\n\ + \\ACKEvalTx\DC2$.utxorpc.v1beta.submit.EvalTxRequest\SUB%.utxorpc.v1beta.submit.EvalTxResponse\DC2[\n\ + \\bSubmitTx\DC2&.utxorpc.v1beta.submit.SubmitTxRequest\SUB'.utxorpc.v1beta.submit.SubmitTxResponse\DC2`\n\ + \\tWaitForTx\DC2'.utxorpc.v1beta.submit.WaitForTxRequest\SUB(.utxorpc.v1beta.submit.WaitForTxResponse0\SOH\DC2d\n\ + \\vReadMempool\DC2).utxorpc.v1beta.submit.ReadMempoolRequest\SUB*.utxorpc.v1beta.submit.ReadMempoolResponse\DC2i\n\ + \\fWatchMempool\DC2*.utxorpc.v1beta.submit.WatchMempoolRequest\SUB+.utxorpc.v1beta.submit.WatchMempoolResponse0\SOHB\158\SOH\n\ + \\EMcom.utxorpc.v1beta.submitB\vSubmitProtoP\SOH\162\STX\ETXUVS\170\STX\NAKUtxorpc.V1beta.Submit\202\STX\NAKUtxorpc\\V1beta\\Submit\226\STX!Utxorpc\\V1beta\\Submit\\GPBMetadata\234\STX\ETBUtxorpc::V1beta::SubmitJ\135%\n\ + \\ACK\DC2\EOT\NUL\NULo\SOH\n\ \\b\n\ \\SOH\f\DC2\ETX\NUL\NUL\DC2\n\ \\b\n\ @@ -2874,26 +2899,57 @@ packedFileDescriptor \\f\n\ \\ENQ\EOT\SO\STX\NUL\ETX\DC2\ETXe\DC3\DC4\n\ \W\n\ - \\STX\ACK\NUL\DC2\EOTi\NULl\SOH\SUBK Service definition for submitting transactions and checking their status.\n\ + \\STX\ACK\NUL\DC2\EOTi\NULo\SOH\SUBK Service definition for submitting transactions and checking their status.\n\ \\n\ \\n\ \\n\ \\ETX\ACK\NUL\SOH\DC2\ETXi\b\NAK\n\ + \=\n\ + \\EOT\ACK\NUL\STX\NUL\DC2\ETXj\STX5\"0 Evaluates a transaction without submitting it.\n\ + \\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\NUL\SOH\DC2\ETXj\ACK\f\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\NUL\STX\DC2\ETXj\r\SUB\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\NUL\ETX\DC2\ETXj%3\n\ \5\n\ - \\EOT\ACK\NUL\STX\NUL\DC2\ETXj\STX;\"( Submit transactions to the blockchain.\n\ + \\EOT\ACK\NUL\STX\SOH\DC2\ETXk\STX;\"( Submit transactions to the blockchain.\n\ \\n\ \\f\n\ - \\ENQ\ACK\NUL\STX\NUL\SOH\DC2\ETXj\ACK\SO\n\ + \\ENQ\ACK\NUL\STX\SOH\SOH\DC2\ETXk\ACK\SO\n\ \\f\n\ - \\ENQ\ACK\NUL\STX\NUL\STX\DC2\ETXj\SI\RS\n\ + \\ENQ\ACK\NUL\STX\SOH\STX\DC2\ETXk\SI\RS\n\ \\f\n\ - \\ENQ\ACK\NUL\STX\NUL\ETX\DC2\ETXj)9\n\ - \<\n\ - \\EOT\ACK\NUL\STX\SOH\DC2\ETXk\STX5\"/ Evaluate a transaction without submitting it.\n\ + \\ENQ\ACK\NUL\STX\SOH\ETX\DC2\ETXk)9\n\ + \U\n\ + \\EOT\ACK\NUL\STX\STX\DC2\ETXl\STXE\"H Wait for transactions to reach a certain stage and stream the updates.\n\ \\n\ \\f\n\ - \\ENQ\ACK\NUL\STX\SOH\SOH\DC2\ETXk\ACK\f\n\ + \\ENQ\ACK\NUL\STX\STX\SOH\DC2\ETXl\ACK\SI\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\STX\STX\DC2\ETXl\DLE \n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\STX\ACK\DC2\ETXl+1\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\STX\ETX\DC2\ETXl2C\n\ + \?\n\ + \\EOT\ACK\NUL\STX\ETX\DC2\ETXm\STXD\"2 Returns a point-in-time snapshot of the mempool.\n\ + \\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\ETX\SOH\DC2\ETXm\ACK\DC1\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\ETX\STX\DC2\ETXm\DC2$\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\ETX\ETX\DC2\ETXm/B\n\ + \V\n\ + \\EOT\ACK\NUL\STX\EOT\DC2\ETXn\STXN\"I Stream transactions from the mempool matching the specified predicates.\n\ + \\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\EOT\SOH\DC2\ETXn\ACK\DC2\n\ + \\f\n\ + \\ENQ\ACK\NUL\STX\EOT\STX\DC2\ETXn\DC3&\n\ \\f\n\ - \\ENQ\ACK\NUL\STX\SOH\STX\DC2\ETXk\r\SUB\n\ + \\ENQ\ACK\NUL\STX\EOT\ACK\DC2\ETXn17\n\ \\f\n\ - \\ENQ\ACK\NUL\STX\SOH\ETX\DC2\ETXk%3b\ACKproto3" \ No newline at end of file + \\ENQ\ACK\NUL\STX\EOT\ETX\DC2\ETXn8Lb\ACKproto3" \ No newline at end of file diff --git a/cardano-rpc/proto/utxorpc/v1beta/cardano/cardano.proto b/cardano-rpc/proto/utxorpc/v1beta/cardano/cardano.proto index ead1dd6912..94fba8f093 100644 --- a/cardano-rpc/proto/utxorpc/v1beta/cardano/cardano.proto +++ b/cardano-rpc/proto/utxorpc/v1beta/cardano/cardano.proto @@ -37,6 +37,7 @@ message TxOutput { repeated Multiasset assets = 3; // Additional native (non-ADA) assets in the output. optional Datum datum = 4; // Plutus data associated with the output. optional Script script = 5; // Script associated with the output. + optional bytes original_cbor = 6; // Original cbor-encoded output as seen on-chain. } message Datum { @@ -108,6 +109,7 @@ message Tx { AuxData auxiliary = 12; // Auxiliary data not directly tied to the validation process bytes hash = 13; // Hash of the transaction that serves as main identifier repeated GovernanceActionProposal proposals = 14; // List of governance actions proposed + repeated VoterVotes votes = 15; // List of voters and their corresponding votes cast in this transaction } // Define a governance action proposal @@ -136,6 +138,33 @@ message GovernanceActionId { uint32 governance_action_index = 2; } +// Valid vote choices for a governance action (CIP-1694). +// On-chain CBOR mapping: No=0, Yes=1, Abstain=2. +enum Vote { + VOTE_UNSPECIFIED = 0; + VOTE_NO = 1; + VOTE_YES = 2; + VOTE_ABSTAIN = 3; +} + +// A single cast vote on a governance action. +message VotingProcedure { + GovernanceActionId gov_action_id = 1; // ID of the governance action being voted on. + Vote vote = 2; // The vote cast. + optional Anchor anchor = 3; // Optional anchor for voter rationale. +} + +// Groups a voter with all votes they cast in the transaction. +// SPOs can only identify via pool key hash; DReps and CC members may use key or script hash. +message VoterVotes { + oneof voter { + StakeCredential constitutional_committee = 1; // Constitutional Committee member. + StakeCredential drep = 2; // Delegated Representative. + bytes spo = 3; // Stake Pool Operator (pool key hash). + } + repeated VotingProcedure votes = 4; // Votes cast by this voter. +} + message ParameterChangeAction { GovernanceActionId gov_action_id = 1; PParams protocol_param_update = 2; // The updates proposed @@ -511,6 +540,46 @@ message UpdateDRepCert { Anchor anchor = 2; } +// LEDGER-STATE QUERIES +// ==================== +// +// Cardano-specific queries that mirror the Ouroboros node-to-client +// LocalStateQuery mini-protocol. The oneof envelope lets new queries be +// added later without changing the chain-agnostic QueryService surface. + +// Envelope of a Cardano ledger-state query. +message StateQuery { + oneof query { + GetStakePoolDistribution stake_pool_distribution = 1; // Active stake distribution across pools. + } +} + +// Envelope of a Cardano ledger-state query result. +message StateData { + oneof result { + StakePoolDistribution stake_pool_distribution = 1; // Result of a stake pool distribution query. + } +} + +// Stake pool distribution query. Mirrors Ouroboros GetPoolDistr / GetFilteredPoolDistr. +message GetStakePoolDistribution { + // If non-empty, restrict the result to the listed pool key hashes. + // If empty, return the distribution for every pool. + repeated bytes pool_keyhashes = 1; +} + +// Per-pool stake share. Mirrors Ouroboros IndividualPoolStake. +message PoolStakeShare { + bytes pool_keyhash = 1; // Pool key hash (pool id). + RationalNumber stake_fraction = 2; // Fraction of total active stake delegated to this pool. + bytes vrf_keyhash = 3; // Pool's VRF key hash, as reported by the node. +} + +// Result of a stake pool distribution query. +message StakePoolDistribution { + repeated PoolStakeShare pools = 1; // One entry per pool present in the snapshot. +} + // PATTERN MATCHING // ================ @@ -669,7 +738,7 @@ message EraSummaries { message EvalReport { string msg = 1; // Human-readable message. optional RedeemerPurpose purpose = 2; // Purpose of the redeemer that produced this entry. - optional uint32 index = 3; // Index of the redeemer within its purpose. + optional uint32 index = 3; // 0-based index of the redeemer within its purpose. } // Result of evaluating a transaction against the current ledger state. diff --git a/cardano-rpc/proto/utxorpc/v1beta/query/query.proto b/cardano-rpc/proto/utxorpc/v1beta/query/query.proto index d69b8a0b02..6fb1b62612 100644 --- a/cardano-rpc/proto/utxorpc/v1beta/query/query.proto +++ b/cardano-rpc/proto/utxorpc/v1beta/query/query.proto @@ -72,6 +72,32 @@ message ReadParamsResponse { ChainPoint ledger_tip = 2; // The chain point that represent the ledger current position. } +// An envelope that wraps a chain-specific ledger-state query. +message AnyChainStateQuery { + oneof query { + utxorpc.v1beta.cardano.StateQuery cardano = 1; // A Cardano ledger-state query. + } +} + +// An envelope that wraps a chain-specific ledger-state query result. +message AnyChainStateData { + oneof result { + utxorpc.v1beta.cardano.StateData cardano = 1; // A Cardano ledger-state query result. + } +} + +// Request to run a chain-specific ledger-state query against the current ledger snapshot. +message ReadStateRequest { + AnyChainStateQuery query = 1; // The chain-specific query to evaluate. + google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields. +} + +// Response carrying the ledger-state query result. +message ReadStateResponse { + AnyChainStateData result = 1; // The query result. + ChainPoint ledger_tip = 2; // Chain point representing the snapshot the query was evaluated against. +} + // An evenlope that holds an UTxO patterns from any of compatible chains message AnyUtxoPattern { oneof utxo_pattern { @@ -171,7 +197,11 @@ service QueryService { rpc ReadParams(ReadParamsRequest) returns (ReadParamsResponse); // Get overall chain state. rpc ReadUtxos(ReadUtxosRequest) returns (ReadUtxosResponse); // Read specific UTxOs by reference. rpc SearchUtxos(SearchUtxosRequest) returns (SearchUtxosResponse); // Search for UTxO based on a pattern. - rpc ReadGenesis(ReadGenesisRequest) returns (ReadGenesisResponse); // Get the chain genesis config. + rpc ReadData(ReadDataRequest) returns (ReadDataResponse); // Read specific datum by hash + rpc ReadTx(ReadTxRequest) returns (ReadTxResponse); // Get Txs by chain-specific criteria. + rpc ReadGenesis(ReadGenesisRequest) returns (ReadGenesisResponse); // Get the genesis configuration + rpc ReadEraSummary(ReadEraSummaryRequest) returns (ReadEraSummaryResponse); // Get the chain era summary + rpc ReadState(ReadStateRequest) returns (ReadStateResponse); // Run a chain-specific ledger-state query (e.g. stake pool distribution). // TODO: decide if we want to expand the scope // rpc DumpUtxos(ReadUtxosRequest) returns (stream ReadUtxosResponse); // Dump all available utxos diff --git a/cardano-rpc/proto/utxorpc/v1beta/submit/submit.proto b/cardano-rpc/proto/utxorpc/v1beta/submit/submit.proto index b8ec26a564..be70dd48a1 100644 --- a/cardano-rpc/proto/utxorpc/v1beta/submit/submit.proto +++ b/cardano-rpc/proto/utxorpc/v1beta/submit/submit.proto @@ -104,6 +104,9 @@ message WatchMempoolResponse { // Service definition for submitting transactions and checking their status. service SubmitService { + rpc EvalTx(EvalTxRequest) returns (EvalTxResponse); // Evaluates a transaction without submitting it. rpc SubmitTx(SubmitTxRequest) returns (SubmitTxResponse); // Submit transactions to the blockchain. - rpc EvalTx(EvalTxRequest) returns (EvalTxResponse); // Evaluate a transaction without submitting it. + rpc WaitForTx(WaitForTxRequest) returns (stream WaitForTxResponse); // Wait for transactions to reach a certain stage and stream the updates. + rpc ReadMempool(ReadMempoolRequest) returns (ReadMempoolResponse); // Returns a point-in-time snapshot of the mempool. + rpc WatchMempool(WatchMempoolRequest) returns (stream WatchMempoolResponse); // Stream transactions from the mempool matching the specified predicates. } From 6afc05924a07064581e6fa4b61c82265c3df7f88 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Wed, 19 Aug 2026 18:48:03 +0200 Subject: [PATCH 30/62] cardano-rpc: Fix conflicting field re-exports after the proto update The new AnyChainStateQuery/AnyChainStateData oneofs in query.proto generate maybe'query/maybe'result lenses that collide with the ones from cardano.proto's StateQuery/StateData envelopes, making the wholesale re-export of both Fields modules ambiguous. Hide the Cardano_Fields copies, following the module's existing convention. --- cardano-rpc/src/Cardano/Rpc/Proto/Api/UtxoRpc/Query.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cardano-rpc/src/Cardano/Rpc/Proto/Api/UtxoRpc/Query.hs b/cardano-rpc/src/Cardano/Rpc/Proto/Api/UtxoRpc/Query.hs index f9167bf17e..ed892c8960 100644 --- a/cardano-rpc/src/Cardano/Rpc/Proto/Api/UtxoRpc/Query.hs +++ b/cardano-rpc/src/Cardano/Rpc/Proto/Api/UtxoRpc/Query.hs @@ -19,6 +19,8 @@ import Proto.Utxorpc.V1beta.Cardano.Cardano_Fields hiding , index , items , key + , maybe'query + , maybe'result , slot , timestamp , tx From 0961e7d22b3ad1e07f64900bd0df21555403a881 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Wed, 19 Aug 2026 18:48:24 +0200 Subject: [PATCH 31/62] cardano-rpc: Expose all UTxO RPC v1beta service methods Wire every method of QueryService, SubmitService and SyncService into the grapesy method tables. Methods without an implementation (ReadData, ReadEraSummary, ReadState, ReadTx, ReadMempool, WaitForTx, WatchMempool, DumpHistory) are declared with UnsupportedMethod, which makes the server respond with the UNIMPLEMENTED gRPC status; the previous hand-rolled dumpHistory stub is converted to the same mechanism. Document the behaviour and the new ReadState method in the README support matrix. --- cardano-rpc/README.md | 3 +++ cardano-rpc/src/Cardano/Rpc/Server.hs | 26 +++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/cardano-rpc/README.md b/cardano-rpc/README.md index e0af3d601b..513e32e379 100644 --- a/cardano-rpc/README.md +++ b/cardano-rpc/README.md @@ -7,6 +7,8 @@ It implements [UTxO RPC](https://utxorpc.org/introduction) protobuf communicatio ## UTxO RPC v1beta spec coverage +Methods marked as not supported are exposed by the server but respond with the `UNIMPLEMENTED` gRPC status. + ### [QueryService](https://utxorpc.org/query/spec/) | Method | Status | @@ -18,6 +20,7 @@ It implements [UTxO RPC](https://utxorpc.org/introduction) protobuf communicatio | [ReadTx](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | | [ReadGenesis](https://utxorpc.org/query/spec/#queryservice) | ✅ Supported | | [ReadEraSummary](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | +| [ReadState](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | ### [SubmitService](https://utxorpc.org/submit/spec/) diff --git a/cardano-rpc/src/Cardano/Rpc/Server.hs b/cardano-rpc/src/Cardano/Rpc/Server.hs index 5d14019541..7f43cc00c8 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server.hs @@ -62,45 +62,49 @@ methodsNodeRpc = $ NoMoreMethods -- | gRPC method table for the UTxO RPC @QueryService@. +-- Method order must match 'ServiceMethods': readData, readEraSummary, readGenesis, readParams, +-- readState, readTx, readUtxos, searchUtxos. +-- 'UnsupportedMethod' makes the server respond with the @UNIMPLEMENTED@ gRPC status. methodsUtxoRpc :: MonadRpc e m => Methods m (ProtobufMethodsOf UtxoRpc.QueryService) methodsUtxoRpc = - Method (mkNonStreaming $ wrapInSpan TraceRpcQueryReadGenesisSpan . readGenesisMethod) + UnsupportedMethod -- readData + . UnsupportedMethod -- readEraSummary + . Method (mkNonStreaming $ wrapInSpan TraceRpcQueryReadGenesisSpan . readGenesisMethod) . Method (mkNonStreaming $ wrapInSpan TraceRpcQueryParamsSpan . readParamsMethod) + . UnsupportedMethod -- readState + . UnsupportedMethod -- readTx . Method (mkNonStreaming $ wrapInSpan TraceRpcQueryReadUtxosSpan . readUtxosMethod) . Method (mkNonStreaming $ wrapInSpan TraceRpcQuerySearchUtxosSpan . searchUtxosMethod) $ NoMoreMethods -- | gRPC method table for the UTxO RPC @SubmitService@. +-- Method order must match 'ServiceMethods': evalTx, readMempool, submitTx, waitForTx, watchMempool. +-- 'UnsupportedMethod' makes the server respond with the @UNIMPLEMENTED@ gRPC status. methodsUtxoRpcSubmit :: MonadRpc e m => Methods m (ProtobufMethodsOf UtxoRpc.SubmitService) methodsUtxoRpcSubmit = Method (mkNonStreaming $ wrapInSpan TraceRpcEvalTxSpan . evalTxMethod) + . UnsupportedMethod -- readMempool . Method (mkNonStreaming $ wrapInSpan TraceRpcSubmitSpan . submitTxMethod) + . UnsupportedMethod -- waitForTx + . UnsupportedMethod -- watchMempool $ NoMoreMethods -- | gRPC method table for the UTxO RPC @SyncService@. -- Method order must match 'ServiceMethods': dumpHistory, fetchBlock, followTip, readTip. +-- 'UnsupportedMethod' makes the server respond with the @UNIMPLEMENTED@ gRPC status. methodsSyncRpc :: MonadRpc e m => Methods m (ProtobufMethodsOf UtxoRpc.SyncService) methodsSyncRpc = - Method (mkNonStreaming $ const unimplemented) -- dumpHistory + UnsupportedMethod -- dumpHistory . Method (mkNonStreaming $ wrapInSpan TraceRpcFetchBlockSpan . fetchBlockMethod) . Method (mkServerStreaming $ \req -> wrapInSpan TraceRpcFollowTipSpan . followTipMethod req) . Method (mkNonStreaming $ wrapInSpan TraceRpcReadTipSpan . readTipMethod) $ NoMoreMethods - where - unimplemented = - throwIO - GrpcException - { grpcError = GrpcUnimplemented - , grpcErrorMessage = Just "Not yet implemented" - , grpcErrorDetails = Nothing - , grpcErrorMetadata = [] - } -- | Start the gRPC server, registering all RPC service handlers. -- Does nothing when the RPC server is disabled in configuration. From 04fe6bb1721f2bbbe04d88d239adf927e233ebd2 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Wed, 19 Aug 2026 18:48:45 +0200 Subject: [PATCH 32/62] cardano-rpc: Populate Tx.votes with governance voting procedures Convert the voting procedures of Conway-onwards transactions to the UTxO RPC VoterVotes messages: DRep and constitutional committee voters map to stake credentials, stake pool voters to their pool key hash, each with their votes, gov action ids and optional anchors. Read through the any-era getter, so earlier eras yield the empty list. --- .../Internal/UtxoRpc/Type/Governance.hs | 40 +++++++++++++ .../Rpc/Server/Internal/UtxoRpc/Type/Tx.hs | 15 ++++- .../Test/Cardano/Rpc/ByronTx.hs | 1 + .../Test/Cardano/Rpc/FetchBlockTx.hs | 59 ++++++++++++++++++- 4 files changed, 111 insertions(+), 4 deletions(-) diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Governance.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Governance.hs index 98ecb23e50..c19b5ca341 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Governance.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Governance.hs @@ -3,6 +3,7 @@ module Cardano.Rpc.Server.Internal.UtxoRpc.Type.Governance ( proposalProcedureToUtxoRpcProposal + , voterVotesToUtxoRpcVoterVotes ) where @@ -18,6 +19,7 @@ import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Certificate ( anchorToUtxoRpcAnchor , constitutionToUtxoRpcConstitution , credentialToUtxoRpcStakeCredential + , keyHashToBytes , scriptHashToBytes ) import Cardano.Rpc.Server.Internal.UtxoRpc.Type.ProtocolParameters @@ -46,6 +48,44 @@ proposalProcedureToUtxoRpcProposal proposal = & U5c.govAction .~ govActionToUtxoRpcGovernanceAction (L.pProcGovAction proposal) & U5c.anchor .~ anchorToUtxoRpcAnchor (L.pProcAnchor proposal) +-- | Convert a ledger voter together with all votes they cast in a transaction +-- to the UTxO RPC 'UtxoRpc.VoterVotes' message, dispatching on the voter type +-- to select the corresponding oneof field. +voterVotesToUtxoRpcVoterVotes + :: L.Voter + -> Map L.GovActionId (L.VotingProcedure era) + -> Proto UtxoRpc.VoterVotes +voterVotesToUtxoRpcVoterVotes voter voterVotes = + defMessage + & setVoter + & U5c.votes .~ map (uncurry votingProcedureToUtxoRpcVotingProcedure) (M.toList voterVotes) + where + setVoter = case voter of + L.CommitteeVoter credential -> + U5c.constitutionalCommittee .~ credentialToUtxoRpcStakeCredential credential + L.DRepVoter credential -> + U5c.drep .~ credentialToUtxoRpcStakeCredential credential + L.StakePoolVoter poolKeyHash -> + U5c.spo .~ keyHashToBytes poolKeyHash + +-- | Convert a single ledger vote cast on a governance action to the UTxO RPC +-- 'UtxoRpc.VotingProcedure' message. +votingProcedureToUtxoRpcVotingProcedure + :: L.GovActionId + -> L.VotingProcedure era + -> Proto UtxoRpc.VotingProcedure +votingProcedureToUtxoRpcVotingProcedure govActionId votingProcedure = + defMessage + & U5c.govActionId .~ govActionIdToUtxoRpcGovernanceActionId govActionId + & U5c.vote .~ vote + & U5c.maybe'anchor + .~ fmap anchorToUtxoRpcAnchor (L.strictMaybeToMaybe (L.vProcAnchor votingProcedure)) + where + vote = case L.vProcVote votingProcedure of + L.VoteNo -> Proto U5c.VOTE_NO + L.VoteYes -> Proto U5c.VOTE_YES + L.Abstain -> Proto U5c.VOTE_ABSTAIN + -- | Convert a ledger governance action to the UTxO RPC 'UtxoRpc.GovernanceAction' -- message, dispatching on the action type to select the corresponding oneof field. govActionToUtxoRpcGovernanceAction diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs index 04c70d3cf5..21be2fa74c 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs @@ -31,7 +31,10 @@ import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as U5c import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as UtxoRpc import Cardano.Rpc.Server.Internal.Orphans () import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Certificate (txCertToUtxoRpcCertificate) -import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Governance (proposalProcedureToUtxoRpcProposal) +import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Governance + ( proposalProcedureToUtxoRpcProposal + , voterVotesToUtxoRpcVoterVotes + ) import Cardano.Rpc.Server.Internal.UtxoRpc.Type.PlutusData (scriptDataToUtxoRpcPlutusData) import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Script (ledgerScriptToUtxoRpcScript) import Cardano.Rpc.Server.Internal.UtxoRpc.Type.TxEval (mkProtoRedeemer) @@ -58,8 +61,8 @@ import Network.GRPC.Spec -- | Convert a ledger transaction to the UTxO RPC 'UtxoRpc.Tx' message. -- Populates hash, fee, successful, inputs, outputs, reference inputs, validity, --- mint, withdrawals, collateral, certificates, witnesses, auxiliary data and --- governance proposals, with spending, withdrawal and certificate redeemers +-- mint, withdrawals, collateral, certificates, witnesses, auxiliary data, +-- governance proposals and votes, with spending, withdrawal and certificate redeemers -- wired to their respective entries. Era-gated fields are read through the -- any-era getters, whose 'Nothing' maps to the proto default; the -- 'ShelleyBasedEra' witness is recovered from 'IsShelleyBasedEra' and brings @@ -218,6 +221,11 @@ txToUtxoRpcTx ledgerTx = anyEraTxConstraints sbe $ do conwayOnwardsProposals = maybe [] (map proposalProcedureToUtxoRpcProposal . toList) $ body ^. L.proposalProceduresTxBodyG + -- governance votes exist from Conway onwards + votes :: [Proto UtxoRpc.VoterVotes] + votes = + maybe [] (map (uncurry voterVotesToUtxoRpcVoterVotes) . M.toList . L.unVotingProcedures) $ + body ^. L.votingProceduresTxBodyG defMessage & U5c.hash .~ serialiseToRawBytes (fromShelleyTxId (L.txIdTx ledgerTx)) & U5c.inputs .~ inputs @@ -233,6 +241,7 @@ txToUtxoRpcTx ledgerTx = anyEraTxConstraints sbe $ do & U5c.successful .~ isValid & U5c.maybe'auxiliary .~ auxiliary & U5c.proposals .~ proposals + & U5c.votes .~ votes where sbe = shelleyBasedEra @era diff --git a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs index cccf8f04a9..3f544b2a06 100644 --- a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs +++ b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs @@ -135,6 +135,7 @@ hprop_byron_tx_to_utxorpc_tx = H.property $ do protoTx ^. U5c.mint === [] protoTx ^. U5c.referenceInputs === [] protoTx ^. U5c.proposals === [] + protoTx ^. U5c.votes === [] protoTx ^. U5c.maybe'validity === Nothing protoTx ^. U5c.maybe'collateral === Nothing protoTx ^. U5c.maybe'auxiliary === Nothing diff --git a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/FetchBlockTx.hs b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/FetchBlockTx.hs index e24fd14514..153d428ccc 100644 --- a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/FetchBlockTx.hs +++ b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/FetchBlockTx.hs @@ -6,7 +6,12 @@ module Test.Cardano.Rpc.FetchBlockTx where -import Cardano.Api (SlotNo (..)) +import Cardano.Api + ( AsType (AsDRepKey, AsStakePoolKey) + , SlotNo (..) + , unDRepKeyHash + , unStakePoolKeyHash + ) import Cardano.Api.Address ( toShelleyAddr , toShelleyStakeAddr @@ -41,6 +46,7 @@ import Test.Gen.Cardano.Api.Typed , genStakeCredential , genTx , genTxIn + , genVerificationKeyHash ) import Hedgehog as H @@ -245,6 +251,9 @@ txToUtxoRpcTxProjections sbe = H.withTests 40 . H.property $ anyEraTxConstraints referenceInputsCount H.note_ "Proposal count" length (protoTx ^. U5c.proposals) === length (toList (body ^. L.proposalProceduresTxBodyL)) + H.note_ "Vote count" + length (protoTx ^. U5c.votes) + === M.size (L.unVotingProcedures (body ^. L.votingProceduresTxBodyL)) alonzoOnwardsChecks AlonzoEraOnwardsConway ( isJust . L.strictMaybeToMaybe $ body ^. L.collateralReturnTxBodyL @@ -289,6 +298,9 @@ hprop_tx_to_utxorpc_tx_injected_optional_fields = H.withTests 10 . H.property $ collateralInput <- forAll genTxIn returnAddress <- forAll $ genAddressInEra sbe stakeAddress <- forAll genStakeAddress + votedGovActionTxIn <- forAll genTxIn + drepKeyHash <- forAll $ unDRepKeyHash <$> genVerificationKeyHash AsDRepKey + poolKeyHash <- forAll $ unStakePoolKeyHash <$> genVerificationKeyHash AsStakePoolKey anchorUrl <- H.nothingFail $ L.textToUrl 64 expectedAnchorUrl let anchor = L.Anchor anchorUrl (L.hashAnnotated (L.AnchorData expectedAnchorData)) returnCoin = 3000000 @@ -306,6 +318,22 @@ hprop_tx_to_utxorpc_tx_injected_optional_fields = H.withTests 10 . H.property $ , L.pProcGovAction = L.InfoAction , L.pProcAnchor = anchor } + -- the DRep vote carries the shared anchor, the pool vote carries none, + -- so both the anchor-present and anchor-absent paths are exercised + L.TxIn votedGovActionTxId _ = toShelleyTxIn votedGovActionTxIn + votedGovActionId = L.GovActionId votedGovActionTxId (L.GovActionIx 0) + votingProcedures = + L.VotingProcedures $ + M.fromList + [ + ( L.DRepVoter (L.KeyHashObj drepKeyHash) + , M.singleton votedGovActionId (L.VotingProcedure L.VoteYes (L.SJust anchor)) + ) + , + ( L.StakePoolVoter poolKeyHash + , M.singleton votedGovActionId (L.VotingProcedure L.VoteNo L.SNothing) + ) + ] modifiedLedgerTx = ledgerTx & L.auxDataTxL .~ L.SJust auxData @@ -313,6 +341,7 @@ hprop_tx_to_utxorpc_tx_injected_optional_fields = H.withTests 10 . H.property $ & L.bodyTxL . L.collateralReturnTxBodyL .~ L.SJust returnTxOut & L.bodyTxL . L.totalCollateralTxBodyL .~ L.SJust (L.Coin totalCollateralCoin) & L.bodyTxL . L.proposalProceduresTxBodyL .~ fromList [proposal] + & L.bodyTxL . L.votingProceduresTxBodyL .~ votingProcedures protoTx = txToUtxoRpcTx modifiedLedgerTx H.note_ "The auxiliary data carries the injected metadata and the native script" @@ -341,6 +370,31 @@ hprop_tx_to_utxorpc_tx_injected_optional_fields = H.withTests 10 . H.property $ === L.hashToBytes (L.extractHash (L.hashAnnotated (L.AnchorData expectedAnchorData))) H.assertWith (protoProposal ^. U5c.govAction) $ isJust . (^. U5c.maybe'infoAction) + H.note_ "The DRep and pool votes route to the expected voter oneof arms" + let isDrepVoterVotes = isJust . (^. U5c.maybe'drep) + isPoolVoterVotes = isJust . (^. U5c.maybe'spo) + [drepVoterVotes] <- H.noteShow $ filter isDrepVoterVotes (protoTx ^. U5c.votes) + [poolVoterVotes] <- H.noteShow $ filter isPoolVoterVotes (protoTx ^. U5c.votes) + + H.note_ "The DRep vote carries the injected gov action id, vote and anchor" + [drepVotingProcedure] <- H.noteShow $ drepVoterVotes ^. U5c.votes + drepVotingProcedure ^. U5c.govActionId . U5c.transactionId + === serialiseToRawBytes (fromShelleyTxId votedGovActionTxId) + drepVotingProcedure ^. U5c.govActionId . U5c.governanceActionIndex === 0 + drepVotingProcedure ^. U5c.vote === Proto U5c.VOTE_YES + drepAnchor <- H.nothingFail $ drepVotingProcedure ^. U5c.maybe'anchor + drepAnchor ^. U5c.url === expectedAnchorUrl + drepAnchor ^. U5c.contentHash + === L.hashToBytes (L.extractHash (L.hashAnnotated (L.AnchorData expectedAnchorData))) + + H.note_ "The pool vote carries the injected gov action id and vote, and no anchor" + [poolVotingProcedure] <- H.noteShow $ poolVoterVotes ^. U5c.votes + poolVotingProcedure ^. U5c.govActionId . U5c.transactionId + === serialiseToRawBytes (fromShelleyTxId votedGovActionTxId) + poolVotingProcedure ^. U5c.govActionId . U5c.governanceActionIndex === 0 + poolVotingProcedure ^. U5c.vote === Proto U5c.VOTE_NO + poolVotingProcedure ^. U5c.maybe'anchor === Nothing + -- | Totality of 'txToUtxoRpcTx' at one era: the proto message roundtrips at -- the protobuf wire level, which also forces every field, so a partial -- pattern or bottom in the era's branch fails the property. @@ -366,6 +420,7 @@ txToUtxoRpcTxTotality sbe = H.withTests 20 . H.property $ do supportsPlutus = supportsFrom sbe ShelleyBasedEraAlonzo supportsReferenceInputs = supportsFrom sbe ShelleyBasedEraBabbage supportsProposals = supportsFrom sbe ShelleyBasedEraConway + supportsVotes = supportsFrom sbe ShelleyBasedEraConway unless supportsMint $ protoTx ^. U5c.mint === [] unless supportsPlutus $ do @@ -377,6 +432,8 @@ txToUtxoRpcTxTotality sbe = H.withTests 20 . H.property $ do protoTx ^. U5c.referenceInputs === [] unless supportsProposals $ protoTx ^. U5c.proposals === [] + unless supportsVotes $ + protoTx ^. U5c.votes === [] -- | One totality test per Shelley-based era, from the 'Bounded' enumeration -- of 'AnyShelleyBasedEra'. From 8fe30dad36481b1b8a4ff2dd087fc4f1c94e86b3 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Wed, 19 Aug 2026 18:49:03 +0200 Subject: [PATCH 33/62] cardano-rpc: Populate TxOutput.original_cbor Fill the field with the era-encoded CBOR of the output. This is a canonical re-encoding, not guaranteed to be the original on-chain bytes: the ledger does not memoise TxOut and its decoders accept non-canonical encodings, so decode-then-encode may differ for historical outputs. No protocol hash uses a standalone TxOut as preimage, and the memoised components inside it (inline datums, plutus scripts) keep their original bytes, so datum and script hashes remain verifiable. --- .../Server/Internal/UtxoRpc/Type/TxOutput.hs | 17 +++++++++++++++-- .../Test/Cardano/Rpc/ByronTx.hs | 1 + .../Test/Cardano/Rpc/TxOutput.hs | 7 +++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/TxOutput.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/TxOutput.hs index 3ab4ff22dd..91f72fc9ff 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/TxOutput.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/TxOutput.hs @@ -32,6 +32,8 @@ import Cardano.Rpc.Server.Internal.UtxoRpc.Type.BigInt import Cardano.Rpc.Server.Internal.UtxoRpc.Type.PlutusData import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Script +import Cardano.Ledger.Api qualified as L + import RIO hiding (toList) import Data.ByteString.Base16 qualified as Base16 @@ -104,11 +106,21 @@ policyAssetsToUtxoRpcMultiassets policyAssetsMap = & U5c.assets .~ assets txOutToUtxoRpcTxOutput - :: ShelleyBasedEra era + :: forall era + . ShelleyBasedEra era -> TxOut CtxUTxO era -> Proto UtxoRpc.TxOutput -txOutToUtxoRpcTxOutput sbe (TxOut addressInEra txOutValue datum script) = do +txOutToUtxoRpcTxOutput sbe txOut@(TxOut addressInEra txOutValue datum script) = do let multiAsset = policyAssetsToUtxoRpcMultiassets . valueToPolicyAssets $ txOutValueToValue txOutValue + -- CAVEAT: this is a canonical re-encoding, not guaranteed to be the + -- original on-chain bytes. The ledger does not memoise TxOut (unlike + -- TxBody, Data and scripts), and its decoders accept non-canonical + -- encodings, so decode-then-encode may differ from the submitter's + -- bytes for historical outputs. + originalCbor = + shelleyBasedEraConstraints sbe $ + L.serialize' (L.eraProtVerHigh @(ShelleyLedgerEra era)) $ + toShelleyTxOut sbe txOut datumRpc = case datum of TxOutDatumNone -> Nothing @@ -131,6 +143,7 @@ txOutToUtxoRpcTxOutput sbe (TxOut addressInEra txOutValue datum script) = do & U5c.assets .~ multiAsset & U5c.maybe'datum .~ datumRpc & U5c.script .~ referenceScriptToUtxoRpcScript script + & U5c.originalCbor .~ originalCbor utxoRpcTxOutputToTxOut :: forall era m diff --git a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs index 3f544b2a06..cdc56530eb 100644 --- a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs +++ b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/ByronTx.hs @@ -98,6 +98,7 @@ hprop_byron_tx_to_utxorpc_tx = H.property $ do protoOutput ^. U5c.address === serialiseToRawBytes (ByronAddress address) coin <- utxoRpcBigIntToInteger $ protoOutput ^. U5c.coin coin === lovelaceToInteger value + protoOutput ^. U5c.originalCbor === mempty H.note_ "Witness arm routing: VKWitness -> bootstrap, RedeemWitness -> vkey" let protoWitnessSet :: Proto U5c.WitnessSet diff --git a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/TxOutput.hs b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/TxOutput.hs index bfe2aad143..27b1be07d6 100644 --- a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/TxOutput.hs +++ b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/TxOutput.hs @@ -12,6 +12,8 @@ import Cardano.Api.Tx import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as U5c import Cardano.Rpc.Server.Internal.UtxoRpc.Type +import Cardano.Ledger.Binary (decodeFull') + import RIO import Test.Gen.Cardano.Api.Typed @@ -45,6 +47,11 @@ hprop_tx_output_wire_format = H.property $ do H.note_ "Address field carries raw ledger address bytes" protoTxOutput ^. U5c.address === serialiseToRawBytes addressInEra + H.note_ "Original CBOR field roundtrips to the ledger-serialised TxOut" + decodedTxOut <- + H.leftFail $ decodeFull' (eraProtVerHigh era) (protoTxOutput ^. U5c.originalCbor) + decodedTxOut === obtainCommonConstraints era (toShelleyTxOut (convert era) txOut) + case datum of TxOutDatumNone -> pure () TxOutDatumHash _ scriptDataHash -> do From 3a3dcaca06bce82a50e4f1aba14bdf9d9b41a2f2 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Thu, 20 Aug 2026 16:11:24 +0200 Subject: [PATCH 34/62] cardano-rpc: Reset FetchBlock to the upstream repeated shape The single-item FetchBlock variant moved to the upcoming utxorpc v1 (utxorpc/spec#208 was retargeted there), so v1beta keeps the repeated request refs and response blocks. Regenerate the proto-lens Sync modules and make the handler fetch every referenced block, failing the whole call with NOT_FOUND naming the first missing ref's slot and header hash, matching Dolos's all-or-nothing behaviour. Mark the changelog fragment as breaking accordingly. --- .../gen/Proto/Utxorpc/V1beta/Sync/Sync.hs | 198 ++++++++++-------- .../Proto/Utxorpc/V1beta/Sync/Sync_Fields.hs | 19 +- .../proto/utxorpc/v1beta/sync/sync.proto | 6 +- .../Rpc/Server/Internal/UtxoRpc/Sync.hs | 31 +-- 4 files changed, 141 insertions(+), 113 deletions(-) diff --git a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync.hs b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync.hs index 83ae385731..dbc61f182a 100644 --- a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync.hs +++ b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync.hs @@ -866,12 +866,12 @@ instance Control.DeepSeq.NFData DumpHistoryResponse where (Control.DeepSeq.deepseq (_DumpHistoryResponse'nextToken x__) ())) {- | Fields : - * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.ref' @:: Lens' FetchBlockRequest BlockRef@ - * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.maybe'ref' @:: Lens' FetchBlockRequest (Prelude.Maybe BlockRef)@ + * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.ref' @:: Lens' FetchBlockRequest [BlockRef]@ + * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.vec'ref' @:: Lens' FetchBlockRequest (Data.Vector.Vector BlockRef)@ * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.fieldMask' @:: Lens' FetchBlockRequest Proto.Google.Protobuf.FieldMask.FieldMask@ * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.maybe'fieldMask' @:: Lens' FetchBlockRequest (Prelude.Maybe Proto.Google.Protobuf.FieldMask.FieldMask)@ -} data FetchBlockRequest - = FetchBlockRequest'_constructor {_FetchBlockRequest'ref :: !(Prelude.Maybe BlockRef), + = FetchBlockRequest'_constructor {_FetchBlockRequest'ref :: !(Data.Vector.Vector BlockRef), _FetchBlockRequest'fieldMask :: !(Prelude.Maybe Proto.Google.Protobuf.FieldMask.FieldMask), _FetchBlockRequest'_unknownFields :: !Data.ProtoLens.FieldSet} deriving stock (Prelude.Eq, Prelude.Ord) @@ -881,14 +881,16 @@ instance Prelude.Show FetchBlockRequest where '{' (Prelude.showString (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) -instance Data.ProtoLens.Field.HasField FetchBlockRequest "ref" BlockRef where +instance Data.ProtoLens.Field.HasField FetchBlockRequest "ref" [BlockRef] where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens _FetchBlockRequest'ref (\ x__ y__ -> x__ {_FetchBlockRequest'ref = y__})) - (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) -instance Data.ProtoLens.Field.HasField FetchBlockRequest "maybe'ref" (Prelude.Maybe BlockRef) where + (Lens.Family2.Unchecked.lens + Data.Vector.Generic.toList + (\ _ y__ -> Data.Vector.Generic.fromList y__)) +instance Data.ProtoLens.Field.HasField FetchBlockRequest "vec'ref" (Data.Vector.Vector BlockRef) where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens @@ -915,7 +917,7 @@ instance Data.ProtoLens.Message FetchBlockRequest where packedMessageDescriptor _ = "\n\ \\DC1FetchBlockRequest\DC2/\n\ - \\ETXref\CAN\SOH \SOH(\v2\GS.utxorpc.v1beta.sync.BlockRefR\ETXref\DC29\n\ + \\ETXref\CAN\SOH \ETX(\v2\GS.utxorpc.v1beta.sync.BlockRefR\ETXref\DC29\n\ \\n\ \field_mask\CAN\STX \SOH(\v2\SUB.google.protobuf.FieldMaskR\tfieldMask" packedFileDescriptor _ = packedFileDescriptor @@ -926,8 +928,8 @@ instance Data.ProtoLens.Message FetchBlockRequest where "ref" (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: Data.ProtoLens.FieldTypeDescriptor BlockRef) - (Data.ProtoLens.OptionalField - (Data.ProtoLens.Field.field @"maybe'ref")) :: + (Data.ProtoLens.RepeatedField + Data.ProtoLens.Unpacked (Data.ProtoLens.Field.field @"ref")) :: Data.ProtoLens.FieldDescriptor FetchBlockRequest fieldMask__field_descriptor = Data.ProtoLens.FieldDescriptor @@ -947,18 +949,21 @@ instance Data.ProtoLens.Message FetchBlockRequest where (\ x__ y__ -> x__ {_FetchBlockRequest'_unknownFields = y__}) defMessage = FetchBlockRequest'_constructor - {_FetchBlockRequest'ref = Prelude.Nothing, + {_FetchBlockRequest'ref = Data.Vector.Generic.empty, _FetchBlockRequest'fieldMask = Prelude.Nothing, _FetchBlockRequest'_unknownFields = []} parseMessage = let loop :: FetchBlockRequest - -> Data.ProtoLens.Encoding.Bytes.Parser FetchBlockRequest - loop x + -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld BlockRef + -> Data.ProtoLens.Encoding.Bytes.Parser FetchBlockRequest + loop x mutable'ref = do end <- Data.ProtoLens.Encoding.Bytes.atEnd if end then - do (let missing = [] + do frozen'ref <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.unsafeFreeze mutable'ref) + (let missing = [] in if Prelude.null missing then Prelude.return () @@ -969,17 +974,22 @@ instance Data.ProtoLens.Message FetchBlockRequest where (Prelude.show (missing :: [Prelude.String])))) Prelude.return (Lens.Family2.over - Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) + (Lens.Family2.set + (Data.ProtoLens.Field.field @"vec'ref") frozen'ref x)) else do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt case tag of 10 - -> do y <- (Data.ProtoLens.Encoding.Bytes.) - (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt - Data.ProtoLens.Encoding.Bytes.isolate - (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) - "ref" - loop (Lens.Family2.set (Data.ProtoLens.Field.field @"ref") y x) + -> do !y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) + Data.ProtoLens.parseMessage) + "ref" + v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.append mutable'ref y) + loop x v 18 -> do y <- (Data.ProtoLens.Encoding.Bytes.) (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt @@ -988,32 +998,35 @@ instance Data.ProtoLens.Message FetchBlockRequest where "field_mask" loop (Lens.Family2.set (Data.ProtoLens.Field.field @"fieldMask") y x) + mutable'ref wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire wire loop (Lens.Family2.over Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + mutable'ref in (Data.ProtoLens.Encoding.Bytes.) - (do loop Data.ProtoLens.defMessage) "FetchBlockRequest" + (do mutable'ref <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + Data.ProtoLens.Encoding.Growing.new + loop Data.ProtoLens.defMessage mutable'ref) + "FetchBlockRequest" buildMessage = \ _x -> (Data.Monoid.<>) - (case - Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'ref") _x - of - Prelude.Nothing -> Data.Monoid.mempty - (Prelude.Just _v) - -> (Data.Monoid.<>) - (Data.ProtoLens.Encoding.Bytes.putVarInt 10) - ((Prelude..) - (\ bs - -> (Data.Monoid.<>) - (Data.ProtoLens.Encoding.Bytes.putVarInt - (Prelude.fromIntegral (Data.ByteString.length bs))) - (Data.ProtoLens.Encoding.Bytes.putBytes bs)) - Data.ProtoLens.encodeMessage _v)) + (Data.ProtoLens.Encoding.Bytes.foldMapBuilder + (\ _v + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Lens.Family2.view (Data.ProtoLens.Field.field @"vec'ref") _x)) ((Data.Monoid.<>) (case Lens.Family2.view @@ -1042,10 +1055,10 @@ instance Control.DeepSeq.NFData FetchBlockRequest where (Control.DeepSeq.deepseq (_FetchBlockRequest'fieldMask x__) ())) {- | Fields : - * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.block' @:: Lens' FetchBlockResponse AnyChainBlock@ - * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.maybe'block' @:: Lens' FetchBlockResponse (Prelude.Maybe AnyChainBlock)@ -} + * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.block' @:: Lens' FetchBlockResponse [AnyChainBlock]@ + * 'Proto.Utxorpc.V1beta.Sync.Sync_Fields.vec'block' @:: Lens' FetchBlockResponse (Data.Vector.Vector AnyChainBlock)@ -} data FetchBlockResponse - = FetchBlockResponse'_constructor {_FetchBlockResponse'block :: !(Prelude.Maybe AnyChainBlock), + = FetchBlockResponse'_constructor {_FetchBlockResponse'block :: !(Data.Vector.Vector AnyChainBlock), _FetchBlockResponse'_unknownFields :: !Data.ProtoLens.FieldSet} deriving stock (Prelude.Eq, Prelude.Ord) instance Prelude.Show FetchBlockResponse where @@ -1054,14 +1067,16 @@ instance Prelude.Show FetchBlockResponse where '{' (Prelude.showString (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s)) -instance Data.ProtoLens.Field.HasField FetchBlockResponse "block" AnyChainBlock where +instance Data.ProtoLens.Field.HasField FetchBlockResponse "block" [AnyChainBlock] where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens _FetchBlockResponse'block (\ x__ y__ -> x__ {_FetchBlockResponse'block = y__})) - (Data.ProtoLens.maybeLens Data.ProtoLens.defMessage) -instance Data.ProtoLens.Field.HasField FetchBlockResponse "maybe'block" (Prelude.Maybe AnyChainBlock) where + (Lens.Family2.Unchecked.lens + Data.Vector.Generic.toList + (\ _ y__ -> Data.Vector.Generic.fromList y__)) +instance Data.ProtoLens.Field.HasField FetchBlockResponse "vec'block" (Data.Vector.Vector AnyChainBlock) where fieldOf _ = (Prelude..) (Lens.Family2.Unchecked.lens @@ -1074,7 +1089,7 @@ instance Data.ProtoLens.Message FetchBlockResponse where packedMessageDescriptor _ = "\n\ \\DC2FetchBlockResponse\DC28\n\ - \\ENQblock\CAN\SOH \SOH(\v2\".utxorpc.v1beta.sync.AnyChainBlockR\ENQblock" + \\ENQblock\CAN\SOH \ETX(\v2\".utxorpc.v1beta.sync.AnyChainBlockR\ENQblock" packedFileDescriptor _ = packedFileDescriptor fieldsByTag = let @@ -1083,8 +1098,8 @@ instance Data.ProtoLens.Message FetchBlockResponse where "block" (Data.ProtoLens.MessageField Data.ProtoLens.MessageType :: Data.ProtoLens.FieldTypeDescriptor AnyChainBlock) - (Data.ProtoLens.OptionalField - (Data.ProtoLens.Field.field @"maybe'block")) :: + (Data.ProtoLens.RepeatedField + Data.ProtoLens.Unpacked (Data.ProtoLens.Field.field @"block")) :: Data.ProtoLens.FieldDescriptor FetchBlockResponse in Data.Map.fromList [(Data.ProtoLens.Tag 1, block__field_descriptor)] @@ -1094,17 +1109,20 @@ instance Data.ProtoLens.Message FetchBlockResponse where (\ x__ y__ -> x__ {_FetchBlockResponse'_unknownFields = y__}) defMessage = FetchBlockResponse'_constructor - {_FetchBlockResponse'block = Prelude.Nothing, + {_FetchBlockResponse'block = Data.Vector.Generic.empty, _FetchBlockResponse'_unknownFields = []} parseMessage = let loop :: FetchBlockResponse - -> Data.ProtoLens.Encoding.Bytes.Parser FetchBlockResponse - loop x + -> Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector Data.ProtoLens.Encoding.Growing.RealWorld AnyChainBlock + -> Data.ProtoLens.Encoding.Bytes.Parser FetchBlockResponse + loop x mutable'block = do end <- Data.ProtoLens.Encoding.Bytes.atEnd if end then - do (let missing = [] + do frozen'block <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.unsafeFreeze mutable'block) + (let missing = [] in if Prelude.null missing then Prelude.return () @@ -1115,43 +1133,50 @@ instance Data.ProtoLens.Message FetchBlockResponse where (Prelude.show (missing :: [Prelude.String])))) Prelude.return (Lens.Family2.over - Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) x) + Data.ProtoLens.unknownFields (\ !t -> Prelude.reverse t) + (Lens.Family2.set + (Data.ProtoLens.Field.field @"vec'block") frozen'block x)) else do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt case tag of 10 - -> do y <- (Data.ProtoLens.Encoding.Bytes.) - (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt - Data.ProtoLens.Encoding.Bytes.isolate - (Prelude.fromIntegral len) Data.ProtoLens.parseMessage) - "block" - loop (Lens.Family2.set (Data.ProtoLens.Field.field @"block") y x) + -> do !y <- (Data.ProtoLens.Encoding.Bytes.) + (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt + Data.ProtoLens.Encoding.Bytes.isolate + (Prelude.fromIntegral len) + Data.ProtoLens.parseMessage) + "block" + v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + (Data.ProtoLens.Encoding.Growing.append mutable'block y) + loop x v wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire wire loop (Lens.Family2.over Data.ProtoLens.unknownFields (\ !t -> (:) y t) x) + mutable'block in (Data.ProtoLens.Encoding.Bytes.) - (do loop Data.ProtoLens.defMessage) "FetchBlockResponse" + (do mutable'block <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO + Data.ProtoLens.Encoding.Growing.new + loop Data.ProtoLens.defMessage mutable'block) + "FetchBlockResponse" buildMessage = \ _x -> (Data.Monoid.<>) - (case - Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'block") _x - of - Prelude.Nothing -> Data.Monoid.mempty - (Prelude.Just _v) - -> (Data.Monoid.<>) - (Data.ProtoLens.Encoding.Bytes.putVarInt 10) - ((Prelude..) - (\ bs - -> (Data.Monoid.<>) - (Data.ProtoLens.Encoding.Bytes.putVarInt - (Prelude.fromIntegral (Data.ByteString.length bs))) - (Data.ProtoLens.Encoding.Bytes.putBytes bs)) - Data.ProtoLens.encodeMessage _v)) + (Data.ProtoLens.Encoding.Bytes.foldMapBuilder + (\ _v + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt 10) + ((Prelude..) + (\ bs + -> (Data.Monoid.<>) + (Data.ProtoLens.Encoding.Bytes.putVarInt + (Prelude.fromIntegral (Data.ByteString.length bs))) + (Data.ProtoLens.Encoding.Bytes.putBytes bs)) + Data.ProtoLens.encodeMessage _v)) + (Lens.Family2.view (Data.ProtoLens.Field.field @"vec'block") _x)) (Data.ProtoLens.Encoding.Wire.buildFieldSet (Lens.Family2.view Data.ProtoLens.unknownFields _x)) instance Control.DeepSeq.NFData FetchBlockResponse where @@ -1932,11 +1957,11 @@ packedFileDescriptor \\acardano\CAN\STX \SOH(\v2\GS.utxorpc.v1beta.cardano.BlockH\NULR\acardanoB\a\n\ \\ENQchain\"\DEL\n\ \\DC1FetchBlockRequest\DC2/\n\ - \\ETXref\CAN\SOH \SOH(\v2\GS.utxorpc.v1beta.sync.BlockRefR\ETXref\DC29\n\ + \\ETXref\CAN\SOH \ETX(\v2\GS.utxorpc.v1beta.sync.BlockRefR\ETXref\DC29\n\ \\n\ \field_mask\CAN\STX \SOH(\v2\SUB.google.protobuf.FieldMaskR\tfieldMask\"N\n\ \\DC2FetchBlockResponse\DC28\n\ - \\ENQblock\CAN\SOH \SOH(\v2\".utxorpc.v1beta.sync.AnyChainBlockR\ENQblock\"\172\SOH\n\ + \\ENQblock\CAN\SOH \ETX(\v2\".utxorpc.v1beta.sync.AnyChainBlockR\ENQblock\"\172\SOH\n\ \\DC2DumpHistoryRequest\DC2>\n\ \\vstart_token\CAN\STX \SOH(\v2\GS.utxorpc.v1beta.sync.BlockRefR\n\ \startToken\DC2\ESC\n\ @@ -1966,7 +1991,7 @@ packedFileDescriptor \\vDumpHistory\DC2'.utxorpc.v1beta.sync.DumpHistoryRequest\SUB(.utxorpc.v1beta.sync.DumpHistoryResponse\DC2\\\n\ \\tFollowTip\DC2%.utxorpc.v1beta.sync.FollowTipRequest\SUB&.utxorpc.v1beta.sync.FollowTipResponse0\SOH\DC2T\n\ \\aReadTip\DC2#.utxorpc.v1beta.sync.ReadTipRequest\SUB$.utxorpc.v1beta.sync.ReadTipResponseB\146\SOH\n\ - \\ETBcom.utxorpc.v1beta.syncB\tSyncProtoP\SOH\162\STX\ETXUVS\170\STX\DC3Utxorpc.V1beta.Sync\202\STX\DC3Utxorpc\\V1beta\\Sync\226\STX\USUtxorpc\\V1beta\\Sync\\GPBMetadata\234\STX\NAKUtxorpc::V1beta::SyncJ\139\EM\n\ + \\ETBcom.utxorpc.v1beta.syncB\tSyncProtoP\SOH\162\STX\ETXUVS\170\STX\DC3Utxorpc.V1beta.Sync\202\STX\DC3Utxorpc\\V1beta\\Sync\226\STX\USUtxorpc\\V1beta\\Sync\\GPBMetadata\234\STX\NAKUtxorpc::V1beta::SyncJ\173\EM\n\ \\ACK\DC2\EOT\NUL\NULL\SOH\n\ \\b\n\ \\SOH\f\DC2\ETX\NUL\NUL\DC2\n\ @@ -2057,15 +2082,17 @@ packedFileDescriptor \\n\ \\ETX\EOT\STX\SOH\DC2\ETX\ETB\b\EM\n\ \(\n\ - \\EOT\EOT\STX\STX\NUL\DC2\ETX\CAN\STX\DC3\"\ESC Block reference to fetch.\n\ + \\EOT\EOT\STX\STX\NUL\DC2\ETX\CAN\STX\FS\"\ESC List of block references.\n\ \\n\ \\f\n\ - \\ENQ\EOT\STX\STX\NUL\ACK\DC2\ETX\CAN\STX\n\ + \\ENQ\EOT\STX\STX\NUL\EOT\DC2\ETX\CAN\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\STX\STX\NUL\SOH\DC2\ETX\CAN\v\SO\n\ + \\ENQ\EOT\STX\STX\NUL\ACK\DC2\ETX\CAN\v\DC3\n\ + \\f\n\ + \\ENQ\EOT\STX\STX\NUL\SOH\DC2\ETX\CAN\DC4\ETB\n\ \\f\n\ - \\ENQ\EOT\STX\STX\NUL\ETX\DC2\ETX\CAN\DC1\DC2\n\ + \\ENQ\EOT\STX\STX\NUL\ETX\DC2\ETX\CAN\SUB\ESC\n\ \7\n\ \\EOT\EOT\STX\STX\SOH\DC2\ETX\EM\STX+\"* Field mask to selectively return fields.\n\ \\n\ @@ -2075,21 +2102,24 @@ packedFileDescriptor \\ENQ\EOT\STX\STX\SOH\SOH\DC2\ETX\EM\FS&\n\ \\f\n\ \\ENQ\EOT\STX\STX\SOH\ETX\DC2\ETX\EM)*\n\ - \4\n\ - \\STX\EOT\ETX\DC2\EOT\GS\NUL\US\SOH\SUB( Response containing the fetched block.\n\ + \5\n\ + \\STX\EOT\ETX\DC2\EOT\GS\NUL\US\SOH\SUB) Response containing the fetched blocks.\n\ \\n\ \\n\ \\n\ \\ETX\EOT\ETX\SOH\DC2\ETX\GS\b\SUB\n\ - \!\n\ - \\EOT\EOT\ETX\STX\NUL\DC2\ETX\RS\STX\SUB\"\DC4 The fetched block.\n\ + \&\n\ + \\EOT\EOT\ETX\STX\NUL\DC2\ETX\RS\STX#\"\EM List of fetched blocks.\n\ + \\n\ + \\f\n\ + \\ENQ\EOT\ETX\STX\NUL\EOT\DC2\ETX\RS\STX\n\ \\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\NUL\ACK\DC2\ETX\RS\STX\SI\n\ + \\ENQ\EOT\ETX\STX\NUL\ACK\DC2\ETX\RS\v\CAN\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\NUL\SOH\DC2\ETX\RS\DLE\NAK\n\ + \\ENQ\EOT\ETX\STX\NUL\SOH\DC2\ETX\RS\EM\RS\n\ \\f\n\ - \\ENQ\EOT\ETX\STX\NUL\ETX\DC2\ETX\RS\CAN\EM\n\ + \\ENQ\EOT\ETX\STX\NUL\ETX\DC2\ETX\RS!\"\n\ \0\n\ \\STX\EOT\EOT\DC2\EOT\"\NUL&\SOH\SUB$ Request to dump the block history.\n\ \\n\ diff --git a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync_Fields.hs b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync_Fields.hs index 5601d1e21f..697ab23c73 100644 --- a/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync_Fields.hs +++ b/cardano-rpc/gen/Proto/Utxorpc/V1beta/Sync/Sync_Fields.hs @@ -84,12 +84,6 @@ maybe'apply :: Data.ProtoLens.Field.HasField s "maybe'apply" a) => Lens.Family2.LensLike' f s a maybe'apply = Data.ProtoLens.Field.field @"maybe'apply" -maybe'block :: - forall f s a. - (Prelude.Functor f, - Data.ProtoLens.Field.HasField s "maybe'block" a) => - Lens.Family2.LensLike' f s a -maybe'block = Data.ProtoLens.Field.field @"maybe'block" maybe'cardano :: forall f s a. (Prelude.Functor f, @@ -114,12 +108,6 @@ maybe'nextToken :: Data.ProtoLens.Field.HasField s "maybe'nextToken" a) => Lens.Family2.LensLike' f s a maybe'nextToken = Data.ProtoLens.Field.field @"maybe'nextToken" -maybe'ref :: - forall f s a. - (Prelude.Functor f, - Data.ProtoLens.Field.HasField s "maybe'ref" a) => - Lens.Family2.LensLike' f s a -maybe'ref = Data.ProtoLens.Field.field @"maybe'ref" maybe'reset :: forall f s a. (Prelude.Functor f, @@ -204,4 +192,9 @@ vec'intersect :: (Prelude.Functor f, Data.ProtoLens.Field.HasField s "vec'intersect" a) => Lens.Family2.LensLike' f s a -vec'intersect = Data.ProtoLens.Field.field @"vec'intersect" \ No newline at end of file +vec'intersect = Data.ProtoLens.Field.field @"vec'intersect" +vec'ref :: + forall f s a. + (Prelude.Functor f, Data.ProtoLens.Field.HasField s "vec'ref" a) => + Lens.Family2.LensLike' f s a +vec'ref = Data.ProtoLens.Field.field @"vec'ref" \ No newline at end of file diff --git a/cardano-rpc/proto/utxorpc/v1beta/sync/sync.proto b/cardano-rpc/proto/utxorpc/v1beta/sync/sync.proto index be26ea37bf..8ce911544a 100644 --- a/cardano-rpc/proto/utxorpc/v1beta/sync/sync.proto +++ b/cardano-rpc/proto/utxorpc/v1beta/sync/sync.proto @@ -22,13 +22,13 @@ message AnyChainBlock { // Request to fetch a block by its reference. message FetchBlockRequest { - BlockRef ref = 1; // Block reference to fetch. + repeated BlockRef ref = 1; // List of block references. google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields. } -// Response containing the fetched block. +// Response containing the fetched blocks. message FetchBlockResponse { - AnyChainBlock block = 1; // The fetched block. + repeated AnyChainBlock block = 1; // List of fetched blocks. } // Request to dump the block history. diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs index 25a51e7bdb..bdd7419f5f 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs @@ -45,27 +45,32 @@ import Network.GRPC.Spec ) -- | Handle the @FetchBlock@ SyncService RPC method. --- Fetches a block from ChainDB by slot and header hash. +-- Fetches blocks from ChainDB by slot and header hash. -- Byron-era transactions carry no fee: Byron fees are implicit (inputs minus -- outputs) and computing them needs UTxO lookups this handler does not do. --- Returns @NOT_FOUND@ if the requested block is missing. --- Returns @INVALID_ARGUMENT@ if the block reference has an invalid hash. +-- Returns @NOT_FOUND@ if any requested block is missing. +-- Returns @INVALID_ARGUMENT@ if a block reference has an invalid hash. fetchBlockMethod :: MonadRpc e m => Proto U5c.FetchBlockRequest - -- ^ Request containing a block reference (slot + hash) + -- ^ Request containing block references (slot + hash) -> m (Proto U5c.FetchBlockResponse) - -- ^ Response containing the fetched block with raw CBOR and cardano header + -- ^ Response containing the fetched blocks with raw CBOR and cardano header fetchBlockMethod request = do nodeKernelAccess@NodeKernelAccess{systemStart, readEraHistory} <- grabNodeKernelAccess - (slot, headerHash) <- blockRefToPoint (request ^. U5c.ref) - let throwNotFound = - throwGrpcErrorWithMessage GrpcNotFound $ - "block not found at slot " <> tshow (unSlotNo slot) - (rawBytes, blockInMode) <- - fetchBlock nodeKernelAccess slot headerHash >>= maybe throwNotFound pure - timestamp <- slotTimestampOrThrow systemStart readEraHistory slot - pure $ defMessage & U5c.block .~ mkAnyChainBlock rawBytes blockInMode timestamp + blocks <- forM (request ^. U5c.ref) $ \blockRef -> do + (slot, headerHash) <- blockRefToPoint blockRef + let throwNotFound = + throwGrpcErrorWithMessage GrpcNotFound $ + "block not found at slot " + <> tshow (unSlotNo slot) + <> ", header hash " + <> serialiseToRawBytesHexText headerHash + (rawBytes, blockInMode) <- + fetchBlock nodeKernelAccess slot headerHash >>= maybe throwNotFound pure + timestamp <- slotTimestampOrThrow systemStart readEraHistory slot + pure $ mkAnyChainBlock rawBytes blockInMode timestamp + pure $ defMessage & U5c.block .~ blocks -- | Handle the @ReadTip@ SyncService RPC method. -- Reads the current chain tip from ChainDB and returns it as slot, block From e792d146216397912c797b9f357085205630aecc Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Thu, 20 Aug 2026 16:42:00 +0200 Subject: [PATCH 35/62] cardano-rpc: Mark indexer-dependent methods in the README ReadData and ReadTx need a whole-chain index (datum by hash, transaction by hash) that cardano-node does not maintain, so they cannot be implemented without building an external chain indexer into the node. Distinguish them from the methods that are merely not yet implemented. --- cardano-rpc/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cardano-rpc/README.md b/cardano-rpc/README.md index 513e32e379..f3e0f61c62 100644 --- a/cardano-rpc/README.md +++ b/cardano-rpc/README.md @@ -7,7 +7,9 @@ It implements [UTxO RPC](https://utxorpc.org/introduction) protobuf communicatio ## UTxO RPC v1beta spec coverage -Methods marked as not supported are exposed by the server but respond with the `UNIMPLEMENTED` gRPC status. +Methods marked ⬜ or ❌ are exposed by the server but respond with the `UNIMPLEMENTED` gRPC status. +Methods marked ❌ cannot be served by `cardano-node` at all: they need a whole-chain index (transaction by hash, datum by hash) that the node does not maintain, and supporting them would mean building an external chain indexer into the node. +Use a dedicated chain indexing service for those. ### [QueryService](https://utxorpc.org/query/spec/) @@ -16,8 +18,8 @@ Methods marked as not supported are exposed by the server but respond with the ` | [ReadParams](https://utxorpc.org/query/spec/#readparamsrequest) | ✅ Supported | | [ReadUtxos](https://utxorpc.org/query/spec/#readutxosrequest) | ✅ Supported | | [SearchUtxos](https://utxorpc.org/query/spec/#searchutxosrequest) | ✅ Supported | -| [ReadData](https://utxorpc.org/query/spec/#readdatarequest) | ⬜ Not supported | -| [ReadTx](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | +| [ReadData](https://utxorpc.org/query/spec/#readdatarequest) | ❌ Not supported, needs a chain indexer | +| [ReadTx](https://utxorpc.org/query/spec/#queryservice) | ❌ Not supported, needs a chain indexer | | [ReadGenesis](https://utxorpc.org/query/spec/#queryservice) | ✅ Supported | | [ReadEraSummary](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | | [ReadState](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | From 565d088739414f99b6fffcd50b31b0721d7ac688 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Thu, 27 Aug 2026 16:47:37 +0200 Subject: [PATCH 36/62] cardano-rpc: Add changelog fragment for the UTxO RPC spec update --- ...0000_cardano-rpc_carbolymer_utxorpc_spec_update.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml diff --git a/.changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml b/.changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml new file mode 100644 index 0000000000..addaaf9f59 --- /dev/null +++ b/.changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml @@ -0,0 +1,10 @@ +project: cardano-rpc + +pr: 1303 + +kind: + - feature + - breaking + +description: | + Update the vendored UTxO RPC v1beta proto definitions to the latest upstream utxorpc/spec (v0.19.2 plus the unreleased EvalReport optional-field flags from [utxorpc/spec#203](https://github.com/utxorpc/spec/pull/203), a wire-compatible change), including resetting FetchBlock to the upstream repeated request/response shape (the single-item variant moved to the upcoming utxorpc v1). Expose all v1beta service methods: the unimplemented ones (ReadData, ReadTx, ReadEraSummary, ReadState, ReadMempool, WaitForTx, WatchMempool, DumpHistory) respond with the UNIMPLEMENTED gRPC status. Populate the new `Tx.votes` field (governance votes, Conway onwards) and the new `TxOutput.original_cbor` field (canonical re-encoding of the output; the ledger does not retain the original on-chain TxOut bytes). From 08b5d4e8a92df0f92c4931dfc096209f54b9994a Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Fri, 28 Aug 2026 14:47:34 +0200 Subject: [PATCH 37/62] Add TCP listening support to the gRPC server Replace the rpcSocketPath field of RpcConfigF with an RpcEndpoint sum type: the server listens either on a unix domain socket (default, rpc.sock next to the node socket) or on plaintext TCP (HTTP/2 without TLS) when a listen port is configured. The TCP listen address defaults to 127.0.0.1. Trace the resolved endpoint on server start. --- ...20260828_cardano_rpc_grpc_tcp_listener.yml | 7 ++++ cardano-rpc/cardano-rpc.cabal | 1 + cardano-rpc/src/Cardano/Rpc/Server.hs | 16 +++++++-- cardano-rpc/src/Cardano/Rpc/Server/Config.hs | 36 ++++++++++++++----- .../Cardano/Rpc/Server/Internal/Tracing.hs | 9 ++++- 5 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 .changes/20260828_cardano_rpc_grpc_tcp_listener.yml diff --git a/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml b/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml new file mode 100644 index 0000000000..79a2189bd9 --- /dev/null +++ b/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml @@ -0,0 +1,7 @@ +project: cardano-rpc +pr: 0 +kind: + - feature + - breaking +description: | + The cardano-rpc gRPC server can now listen on a plain TCP endpoint (HTTP/2 without TLS) instead of a unix domain socket, configured via the node configuration keys `RpcListenAddress`/`RpcListenPort` or the `--grpc-listen-address`/`--grpc-listen-port` CLI flags; the listen address defaults to `127.0.0.1`, and configuring both a socket path and a listen port is rejected at configuration parsing time. As part of this, `RpcConfigF`'s `rpcSocketPath` field was replaced by `rpcEndpoint`, a new `RpcEndpoint` sum type with `RpcEndpointUnixSocket` and `RpcEndpointTcp` constructors, and `TraceRpc` gained a new `TraceRpcServerListening` constructor. diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index 354c8864d9..fcd250ae3f 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -123,6 +123,7 @@ library memory, mempack, microlens, + network, proto-lens >=0.7.1.7, proto-lens-protobuf-types, random, diff --git a/cardano-rpc/src/Cardano/Rpc/Server.hs b/cardano-rpc/src/Cardano/Rpc/Server.hs index 7f43cc00c8..23445d9262 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server.hs @@ -46,6 +46,7 @@ import Cardano.Rpc.Server.NodeKernelAccess import RIO import Control.Tracer +import Data.Text qualified as Text import Network.GRPC.Common import Network.GRPC.Server import Network.GRPC.Server.Protobuf @@ -121,12 +122,20 @@ runRpcServer runRpcServer tracer rpcConfig networkMagic nodeKernelAccessRef = handleFatalExceptions $ do let RpcConfig { isEnabled = Identity isEnabled - , rpcSocketPath = Identity (File rpcSocketPathFp) + , rpcEndpoint = Identity rpcEndpoint , nodeSocketPath = Identity nodeSocketPath } = rpcConfig + insecureConfig :: InsecureConfig + insecureConfig = case rpcEndpoint of + RpcEndpointUnixSocket (File socketPath) -> InsecureUnix socketPath + RpcEndpointTcp host port -> + InsecureConfig + { insecureHost = Just $ Text.unpack host + , insecurePort = port + } config = ServerConfig - { serverInsecure = Just $ InsecureUnix rpcSocketPathFp + { serverInsecure = Just insecureConfig , serverSecure = Nothing } rpcEnv = @@ -137,7 +146,8 @@ runRpcServer tracer rpcConfig networkMagic nodeKernelAccessRef = handleFatalExce , rpcNodeKernelAccess = nodeKernelAccessRef } - when isEnabled $ + when isEnabled $ do + traceWith tracer $ TraceRpcServerListening rpcEndpoint runRIO rpcEnv $ withRunInIO $ \runInIO -> runServerWithHandlers serverParams config . fmap (hoistSomeRpcHandler runInIO) $ diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Config.hs b/cardano-rpc/src/Cardano/Rpc/Server/Config.hs index add0cf8a72..99e62b279a 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Config.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Config.hs @@ -9,6 +9,8 @@ module Cardano.Rpc.Server.Config ( RpcConfig , PartialRpcConfig , RpcConfigF (..) + , RpcEndpoint (..) + , defaultRpcListenAddress , makeRpcConfig , nodeSocketPathToRpcSocketPath ) @@ -19,6 +21,7 @@ import Cardano.Api import RIO import Data.Monoid +import Network.Socket (PortNumber) import System.FilePath (takeDirectory, ()) import Generic.Data (gmappend, gmempty) @@ -27,12 +30,26 @@ type PartialRpcConfig = RpcConfigF Last type RpcConfig = RpcConfigF Identity +-- | Endpoint the RPC server listens on. Exactly one listener is active at a +-- time. Future transports (for example TLS) are added as new constructors. +data RpcEndpoint + = RpcEndpointUnixSocket !SocketPath + | -- | host and port of the TCP listener, HTTP/2 without TLS. The host is + -- always concrete: config parsers apply 'defaultRpcListenAddress' when + -- only a port was provided. Port 0 makes the operating system choose. + RpcEndpointTcp !Text !PortNumber + deriving (Eq, Show) + +-- | Default host the TCP listener binds to when only a port is configured. +defaultRpcListenAddress :: Text +defaultRpcListenAddress = "127.0.0.1" + -- | RPC server configuration, which is a part of cardano-node configuration. data RpcConfigF m = RpcConfig { isEnabled :: !(m Bool) -- ^ whether the RPC server is enabled - , rpcSocketPath :: !(m SocketPath) - -- ^ path to the socket file where the RPC server listens + , rpcEndpoint :: !(m RpcEndpoint) + -- ^ endpoint where the RPC server listens , nodeSocketPath :: !(m SocketPath) -- ^ cardano-node socket path. Only valid if RPC endpoint is enabled. } @@ -57,7 +74,7 @@ instance Monoid (RpcConfigF Last) where -- -- Uses the following defaults if the values are not provided -- * RPC is disabled --- * @rpc.sock@ is placed in the same path as the node socket +-- * the endpoint is a unix socket, @rpc.sock@, placed in the same path as the node socket -- -- Validates if the node socket is enabled if RPC is enabled. makeRpcConfig @@ -67,21 +84,22 @@ makeRpcConfig makeRpcConfig RpcConfig { isEnabled = Last mIsEnabled - , rpcSocketPath = Last mRpcSocketPath + , rpcEndpoint = Last mRpcEndpoint , nodeSocketPath = Last mNodeSocketPath } = do let isEnabled = fromMaybe False mIsEnabled -- default to a some non-existing path. Does not matter if the gRPC endpoint is disabled nodeSocketPath = fromMaybe "./node.socket" mNodeSocketPath - rpcSocketPath = fromMaybe (nodeSocketPathToRpcSocketPath nodeSocketPath) mRpcSocketPath + rpcEndpoint = fromMaybe (RpcEndpointUnixSocket $ nodeSocketPathToRpcSocketPath nodeSocketPath) mRpcEndpoint when (isEnabled && isNothing mNodeSocketPath) $ throwError "Configuration error: gRPC endpoint was enabled but node socket file was not specified. Cannot run gRPC server without node socket." - pure $ + pure RpcConfig - (pure isEnabled) - (pure rpcSocketPath) - (pure nodeSocketPath) + { isEnabled = pure isEnabled + , rpcEndpoint = pure rpcEndpoint + , nodeSocketPath = pure nodeSocketPath + } -- | Convert node socket path to a default rpc socket path. -- By default it's @rpc.sock@ in the same directory as node socket path. diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs index 1aae342493..423e41382b 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs @@ -4,7 +4,7 @@ -- | Provides datatypes used in tracing module Cardano.Rpc.Server.Internal.Tracing where -import Cardano.Api (SlotNo) +import Cardano.Api (File (..), SlotNo) import Cardano.Api.Consensus (TxValidationErrorInCardanoMode) import Cardano.Api.Era (Inject (..)) import Cardano.Api.Error @@ -12,6 +12,7 @@ import Cardano.Api.Pretty import Cardano.Api.Serialise.Cbor (DecoderError) import Cardano.Api.Serialise.Raw (SerialiseAsRawBytesError) import Cardano.Api.Serialise.SerialiseUsing +import Cardano.Rpc.Server.Config (RpcEndpoint (..)) import Control.Exception import Data.Word (Word64) @@ -24,6 +25,8 @@ data TraceRpc | TraceRpcNodeKernelAccess TraceRpcNodeKernelAccess | TraceRpcError SomeException | TraceRpcFatalError SomeException + | -- | Emitted just before the server starts listening on the endpoint. + TraceRpcServerListening !RpcEndpoint -- | Traces used in Query service data TraceRpcQuery @@ -45,6 +48,10 @@ instance Pretty TraceRpc where TraceRpcNodeKernelAccess t -> pretty t TraceRpcError e -> "Exception when processing RPC request:\n" <> prettyException e TraceRpcFatalError e -> "RPC server fatal error: " <> prettyException e + TraceRpcServerListening (RpcEndpointUnixSocket (File socketPath)) -> + "RPC server starting, listening on unix socket " <> pretty socketPath + TraceRpcServerListening (RpcEndpointTcp host port) -> + "RPC server starting, listening on " <> pretty host <> ":" <> pshow port -- | Span type data TraceSpanEvent From 726931a4ea9fb2aa004df259cb8cce986db080d5 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Fri, 28 Aug 2026 15:10:03 +0200 Subject: [PATCH 38/62] Add TLS listening support to the gRPC server Add an RpcEndpointTcpTls endpoint: when TLS certificate and private key files are configured, the server listens with TLS on the configured host and port. Grapesy's default of honouring the SSLKEYLOGFILE environment variable is explicitly disabled so the node never silently logs TLS session keys. --- ...20260828_cardano_rpc_grpc_tcp_listener.yml | 4 +- cardano-rpc/cardano-rpc.cabal | 1 + cardano-rpc/src/Cardano/Rpc/Server.hs | 43 ++++++++++---- cardano-rpc/src/Cardano/Rpc/Server/Config.hs | 59 ++++++++++++++----- .../Cardano/Rpc/Server/Internal/Tracing.hs | 12 ++-- 5 files changed, 81 insertions(+), 38 deletions(-) diff --git a/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml b/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml index 79a2189bd9..f97d058ceb 100644 --- a/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml +++ b/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml @@ -1,7 +1,7 @@ project: cardano-rpc -pr: 0 +pr: 1322 kind: - feature - breaking description: | - The cardano-rpc gRPC server can now listen on a plain TCP endpoint (HTTP/2 without TLS) instead of a unix domain socket, configured via the node configuration keys `RpcListenAddress`/`RpcListenPort` or the `--grpc-listen-address`/`--grpc-listen-port` CLI flags; the listen address defaults to `127.0.0.1`, and configuring both a socket path and a listen port is rejected at configuration parsing time. As part of this, `RpcConfigF`'s `rpcSocketPath` field was replaced by `rpcEndpoint`, a new `RpcEndpoint` sum type with `RpcEndpointUnixSocket` and `RpcEndpointTcp` constructors, and `TraceRpc` gained a new `TraceRpcServerListening` constructor. + The cardano-rpc gRPC server can now listen on HTTP/2 (h2c) or HTTP/2 over TLS on a configured IP address and port instead of only a unix domain socket, configured via new cardano-node options such as `--grpc-listen-port` and `--grpc-tls-certificate`. `RpcConfigF`'s `rpcSocketPath` field was replaced by the new `RpcEndpoint` sum type. diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index fcd250ae3f..64cdf67930 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -120,6 +120,7 @@ library generic-data, grapesy, grpc-spec, + iproute, memory, mempack, microlens, diff --git a/cardano-rpc/src/Cardano/Rpc/Server.hs b/cardano-rpc/src/Cardano/Rpc/Server.hs index 23445d9262..909c609b5f 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server.hs @@ -46,7 +46,6 @@ import Cardano.Rpc.Server.NodeKernelAccess import RIO import Control.Tracer -import Data.Text qualified as Text import Network.GRPC.Common import Network.GRPC.Server import Network.GRPC.Server.Protobuf @@ -125,19 +124,37 @@ runRpcServer tracer rpcConfig networkMagic nodeKernelAccessRef = handleFatalExce , rpcEndpoint = Identity rpcEndpoint , nodeSocketPath = Identity nodeSocketPath } = rpcConfig - insecureConfig :: InsecureConfig - insecureConfig = case rpcEndpoint of - RpcEndpointUnixSocket (File socketPath) -> InsecureUnix socketPath - RpcEndpointTcp host port -> - InsecureConfig - { insecureHost = Just $ Text.unpack host - , insecurePort = port + config :: ServerConfig + config = case rpcEndpoint of + RpcEndpointUnixSocket (File socketPath) -> + ServerConfig + { serverInsecure = Just $ InsecureUnix socketPath + , serverSecure = Nothing + } + RpcEndpointHttp host port -> + ServerConfig + { serverInsecure = + Just + InsecureConfig + { insecureHost = Just $ show host + , insecurePort = port + } + , serverSecure = Nothing + } + RpcEndpointHttps host port (RpcTlsFiles certificateFile privateKeyFile chainCertificateFiles) -> + ServerConfig + { serverInsecure = Nothing + , serverSecure = + Just + SecureConfig + { secureHost = show host + , securePort = port + , securePubCert = unFile certificateFile + , secureChainCerts = unFile <$> chainCertificateFiles + , securePrivKey = unFile privateKeyFile + , secureSslKeyLog = def + } } - config = - ServerConfig - { serverInsecure = Just insecureConfig - , serverSecure = Nothing - } rpcEnv = RpcEnv { config = rpcConfig diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Config.hs b/cardano-rpc/src/Cardano/Rpc/Server/Config.hs index 99e62b279a..620c9cdbcc 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Config.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Config.hs @@ -2,6 +2,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE NoFieldSelectors #-} @@ -10,6 +11,9 @@ module Cardano.Rpc.Server.Config , PartialRpcConfig , RpcConfigF (..) , RpcEndpoint (..) + , RpcTlsFiles (..) + , TlsCertificate + , TlsPrivateKey , defaultRpcListenAddress , makeRpcConfig , nodeSocketPathToRpcSocketPath @@ -20,6 +24,7 @@ import Cardano.Api import RIO +import Data.IP (IP) import Data.Monoid import Network.Socket (PortNumber) import System.FilePath (takeDirectory, ()) @@ -30,20 +35,6 @@ type PartialRpcConfig = RpcConfigF Last type RpcConfig = RpcConfigF Identity --- | Endpoint the RPC server listens on. Exactly one listener is active at a --- time. Future transports (for example TLS) are added as new constructors. -data RpcEndpoint - = RpcEndpointUnixSocket !SocketPath - | -- | host and port of the TCP listener, HTTP/2 without TLS. The host is - -- always concrete: config parsers apply 'defaultRpcListenAddress' when - -- only a port was provided. Port 0 makes the operating system choose. - RpcEndpointTcp !Text !PortNumber - deriving (Eq, Show) - --- | Default host the TCP listener binds to when only a port is configured. -defaultRpcListenAddress :: Text -defaultRpcListenAddress = "127.0.0.1" - -- | RPC server configuration, which is a part of cardano-node configuration. data RpcConfigF m = RpcConfig { isEnabled :: !(m Bool) @@ -70,6 +61,44 @@ instance Semigroup (RpcConfigF Last) where instance Monoid (RpcConfigF Last) where mempty = gmempty +-- | Endpoint the RPC server listens on. Exactly one listener is active at a +-- time. +data RpcEndpoint + = RpcEndpointUnixSocket !SocketPath + | -- | IP address and port of the HTTP/2 without TLS (h2c) listener. + RpcEndpointHttp !IP !PortNumber + | -- | IP address, port and TLS credential files of the HTTP/2 over TLS + -- listener. + RpcEndpointHttps !IP !PortNumber !RpcTlsFiles + deriving (Eq, Show) + +instance Pretty RpcEndpoint where + pretty = \case + RpcEndpointUnixSocket (File socketPath) -> pretty socketPath + RpcEndpointHttp host port -> pshow host <> ":" <> pshow port + RpcEndpointHttps host port _ -> pshow host <> ":" <> pshow port <> " (TLS)" + +-- | TLS credential files for the RPC server, PEM format. +data RpcTlsFiles = RpcTlsFiles + { certificateFile :: !(File TlsCertificate In) + -- ^ server X.509 certificate + , privateKeyFile :: !(File TlsPrivateKey In) + -- ^ private key matching the certificate + , chainCertificateFiles :: ![File TlsCertificate In] + -- ^ intermediate chain certificates, if any + } + deriving (Eq, Show) + +-- | Empty content tag for 'File' identifying a TLS certificate file. +data TlsCertificate + +-- | Empty content tag for 'File' identifying a TLS private key file. +data TlsPrivateKey + +-- | Default IP address the HTTP/2 listener binds to when only a port is configured. +defaultRpcListenAddress :: IP +defaultRpcListenAddress = "127.0.0.1" + -- | Build RPC Config -- -- Uses the following defaults if the values are not provided @@ -88,7 +117,7 @@ makeRpcConfig , nodeSocketPath = Last mNodeSocketPath } = do let isEnabled = fromMaybe False mIsEnabled - -- default to a some non-existing path. Does not matter if the gRPC endpoint is disabled + -- Default to a non-existing path. Irrelevant when the RPC server is disabled; when enabled, the validation below requires an explicit node socket path. nodeSocketPath = fromMaybe "./node.socket" mNodeSocketPath rpcEndpoint = fromMaybe (RpcEndpointUnixSocket $ nodeSocketPathToRpcSocketPath nodeSocketPath) mRpcEndpoint when (isEnabled && isNothing mNodeSocketPath) $ diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs index 423e41382b..94a554e370 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs @@ -4,7 +4,7 @@ -- | Provides datatypes used in tracing module Cardano.Rpc.Server.Internal.Tracing where -import Cardano.Api (File (..), SlotNo) +import Cardano.Api (SlotNo) import Cardano.Api.Consensus (TxValidationErrorInCardanoMode) import Cardano.Api.Era (Inject (..)) import Cardano.Api.Error @@ -12,7 +12,7 @@ import Cardano.Api.Pretty import Cardano.Api.Serialise.Cbor (DecoderError) import Cardano.Api.Serialise.Raw (SerialiseAsRawBytesError) import Cardano.Api.Serialise.SerialiseUsing -import Cardano.Rpc.Server.Config (RpcEndpoint (..)) +import Cardano.Rpc.Server.Config (RpcEndpoint) import Control.Exception import Data.Word (Word64) @@ -25,8 +25,7 @@ data TraceRpc | TraceRpcNodeKernelAccess TraceRpcNodeKernelAccess | TraceRpcError SomeException | TraceRpcFatalError SomeException - | -- | Emitted just before the server starts listening on the endpoint. - TraceRpcServerListening !RpcEndpoint + | TraceRpcServerListening !RpcEndpoint -- | Traces used in Query service data TraceRpcQuery @@ -48,10 +47,7 @@ instance Pretty TraceRpc where TraceRpcNodeKernelAccess t -> pretty t TraceRpcError e -> "Exception when processing RPC request:\n" <> prettyException e TraceRpcFatalError e -> "RPC server fatal error: " <> prettyException e - TraceRpcServerListening (RpcEndpointUnixSocket (File socketPath)) -> - "RPC server starting, listening on unix socket " <> pretty socketPath - TraceRpcServerListening (RpcEndpointTcp host port) -> - "RPC server starting, listening on " <> pretty host <> ":" <> pshow port + TraceRpcServerListening endpoint -> "RPC server starting on " <> pretty endpoint -- | Span type data TraceSpanEvent From 79c2bd459b9c98952d405416ec8fde24fb8b3b79 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Mon, 31 Aug 2026 16:52:20 +0200 Subject: [PATCH 39/62] Bound per-connection RPC parallelism via explicit HTTP/2 settings Build the gRPC server with mkGrpcServer and runServer instead of the runServerWithHandlers convenience wrapper, so the HTTP/2 settings are explicit at the call site. Halve the maximum concurrent streams per connection to 64; all other settings keep grapesy defaults, including the HTTP/2 flood-protection rate limits and flow-control windows. --- cardano-rpc/src/Cardano/Rpc/Server.hs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cardano-rpc/src/Cardano/Rpc/Server.hs b/cardano-rpc/src/Cardano/Rpc/Server.hs index 909c609b5f..05940a2bf2 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server.hs @@ -167,7 +167,7 @@ runRpcServer tracer rpcConfig networkMagic nodeKernelAccessRef = handleFatalExce traceWith tracer $ TraceRpcServerListening rpcEndpoint runRIO rpcEnv $ withRunInIO $ \runInIO -> - runServerWithHandlers serverParams config . fmap (hoistSomeRpcHandler runInIO) $ + runServer http2Settings config <=< mkGrpcServer serverParams . fmap (hoistSomeRpcHandler runInIO) $ mconcat [ fromMethods methodsNodeRpc , fromMethods methodsUtxoRpc @@ -178,6 +178,13 @@ runRpcServer tracer rpcConfig networkMagic nodeKernelAccessRef = handleFatalExce serverParams :: ServerParams serverParams = def{serverTopLevel = topLevelHandler} + -- Halve grapesy's default of 128: bounds per-connection RPC parallelism. + -- Remaining fields keep grapesy defaults, including the HTTP/2 flood-protection + -- rate limits and the 256 KiB / 2 MiB flow-control windows that cap buffered + -- inbound request data per stream / connection. + http2Settings :: HTTP2Settings + http2Settings = def{http2MaxConcurrentStreams = 64} + -- Top level hook for request handlers, handle exceptions topLevelHandler :: RequestHandler () -> RequestHandler () topLevelHandler h unmask req resp = catchAny (h unmask req resp) $ \e -> From f97ee89afb8058cf24c09decf4ba2b24c2fc20b1 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Wed, 2 Sep 2026 15:41:46 +0200 Subject: [PATCH 40/62] Harden the gRPC server against abuse of the network endpoints Redact handler exceptions sent to clients: the response carries the error message only, never call stacks or internal detail; full detail is still traced server-side. Bound script evaluation requests by a 64 KiB pre-decode size cap, the protocol maximum transaction size and a limit of 100 redeemers. Limit UTxO reads to 20000 keys and block fetches to 500 references per request. Document the security posture in the package README. --- ...20260828_cardano_rpc_grpc_tcp_listener.yml | 2 +- cardano-rpc/README.md | 15 ++++++ cardano-rpc/src/Cardano/Rpc/Server.hs | 15 +++++- .../src/Cardano/Rpc/Server/Internal/Error.hs | 6 +++ .../Rpc/Server/Internal/UtxoRpc/Eval.hs | 46 ++++++++++++++++++- .../Rpc/Server/Internal/UtxoRpc/Query.hs | 14 ++++++ .../Rpc/Server/Internal/UtxoRpc/Sync.hs | 13 ++++++ 7 files changed, 108 insertions(+), 3 deletions(-) diff --git a/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml b/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml index f97d058ceb..cede1ff0c3 100644 --- a/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml +++ b/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml @@ -4,4 +4,4 @@ kind: - feature - breaking description: | - The cardano-rpc gRPC server can now listen on HTTP/2 (h2c) or HTTP/2 over TLS on a configured IP address and port instead of only a unix domain socket, configured via new cardano-node options such as `--grpc-listen-port` and `--grpc-tls-certificate`. `RpcConfigF`'s `rpcSocketPath` field was replaced by the new `RpcEndpoint` sum type. + The cardano-rpc gRPC server can now listen on HTTP/2 (h2c) or HTTP/2 over TLS on a configured IP address and port instead of only a unix domain socket, configured via new cardano-node options such as `--grpc-listen-port` and `--grpc-tls-certificate`. `RpcConfigF`'s `rpcSocketPath` field was replaced by the new `RpcEndpoint` sum type. Error responses no longer include internal diagnostic detail such as call stacks. Script evaluation requests are rejected when the transaction exceeds the protocol maximum size or carries more than 100 redeemers. UTxO reads are limited to 20000 keys and block fetches to 500 references per request. diff --git a/cardano-rpc/README.md b/cardano-rpc/README.md index f3e0f61c62..2a894b2bc9 100644 --- a/cardano-rpc/README.md +++ b/cardano-rpc/README.md @@ -80,3 +80,18 @@ To build the package use the following command: cabal build cardano-rpc ``` +## Security + +The RPC server has no authentication or authorisation: every method is open to anyone who can reach the listener, including transaction submission and script evaluation. +Everything served is public chain data, so the concern is resource consumption and node exposure rather than confidentiality. + +Defaults are conservative: the server is off unless `--grpc-enable` is given, it listens on a unix socket by default, and `--grpc-listen-port` binds `127.0.0.1` unless another address is given. +The node warns at startup when RPC is enabled on a block-producing node. + +TLS encrypts the connection and lets clients verify the node; it does not restrict who may call, since there is no client-certificate support. +A TLS listener on a public address is as open as a cleartext one. + +For deployment, keep the listener on loopback or a trusted network segment. +Anywhere else, front it with a reverse proxy that terminates TLS and handles authentication and rate limiting, the pattern recommended in ADR-018. + +The server writes TLS key-log material if `SSLKEYLOGFILE` is set in its environment. diff --git a/cardano-rpc/src/Cardano/Rpc/Server.hs b/cardano-rpc/src/Cardano/Rpc/Server.hs index 05940a2bf2..0a224d493c 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server.hs @@ -30,6 +30,7 @@ import Cardano.Rpc.Proto.Api.UtxoRpc.Submit qualified as UtxoRpc import Cardano.Rpc.Proto.Api.UtxoRpc.Sync qualified as UtxoRpc import Cardano.Rpc.Server.Config import Cardano.Rpc.Server.Internal.Env +import Cardano.Rpc.Server.Internal.Error (renderRpcExceptionForClient) import Cardano.Rpc.Server.Internal.Monad import Cardano.Rpc.Server.Internal.Node import Cardano.Rpc.Server.Internal.Orphans () @@ -176,7 +177,19 @@ runRpcServer tracer rpcConfig networkMagic nodeKernelAccessRef = handleFatalExce ] where serverParams :: ServerParams - serverParams = def{serverTopLevel = topLevelHandler} + serverParams = + def + { serverTopLevel = topLevelHandler + , serverExceptionToClient = exceptionToClient + } + + -- Clients must never see internal error detail or call stacks; full detail is + -- still traced server-side by 'topLevelHandler'. + exceptionToClient :: SomeException -> IO (Maybe Text) + exceptionToClient e = + pure . Just $ maybe genericErrorMessage renderRpcExceptionForClient $ fromException e + where + genericErrorMessage = "Internal error while processing the request." -- Halve grapesy's default of 128: bounds per-connection RPC parallelism. -- Remaining fields keep grapesy defaults, including the HTTP/2 flood-protection diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Error.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Error.hs index 0bf86a7bef..b8fab23e8b 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Error.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Error.hs @@ -14,6 +14,7 @@ module Cardano.Rpc.Server.Internal.Error , throwExceptT , throwGrpcErrorWithMessage , RpcException (..) + , renderRpcExceptionForClient ) where @@ -42,6 +43,11 @@ instance Exception RpcException where , prettyCallStack callStack ] +-- | Render an 'RpcException' for an RPC client, without the call stack. +-- The call stack is internal detail (module names, source lines) and must stay server-side only. +renderRpcExceptionForClient :: RpcException -> Text +renderRpcExceptionForClient (RpcException e) = tshow (prettyError e) + -- | Throw a 'GrpcException' with the given error code and message. -- grapesy converts this to proper gRPC trailers before it reaches 'serverTopLevel'. throwGrpcErrorWithMessage :: MonadIO m => GrpcError -> Text -> m a diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Eval.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Eval.hs index 667bd64dd9..bd08a5e610 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Eval.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Eval.hs @@ -25,6 +25,7 @@ import Cardano.Ledger.Api qualified as L import RIO hiding (toList) +import Data.ByteString qualified as BS import Data.Default import Data.Map.Strict qualified as Map import Data.ProtoLens (defMessage) @@ -48,11 +49,33 @@ evalTxMethod request = do AnyCardanoEra (era :: CardanoEra era) <- liftIO . throwExceptT $ determineEra nodeConnInfo (eon :: Era era) <- forEraInEon @Era era (error "Minimum Conway era required") pure + let rawTx = request ^. U5c.tx . U5c.raw + + -- A tx's inputs live inside its raw bytes, so this also bounds the input set the + -- query batch below resolves. The exact protocol limit is enforced further down, + -- once protocol parameters are available. + when (BS.length rawTx > maxEvalTxSizeBytes) $ + throwGrpcErrorWithMessage GrpcInvalidArgument $ + "transaction size " + <> tshow (BS.length rawTx) + <> " exceeds the evaluation limit " + <> tshow maxEvalTxSizeBytes + (Exp.SignedTx ledgerTx :: Exp.SignedTx era) <- putTraceThrowEither . first TraceRpcEvalTxDecodingError . obtainCommonConstraints eon (deserialiseFromRawBytes asType) - $ request ^. U5c.tx . U5c.raw + $ rawTx + + -- Each redeemer gets the full per-tx execution budget during evaluation, so an + -- unbounded redeemer count lets an unauthenticated caller multiply evaluation cost. + let redeemerCount = + obtainCommonConstraints eon $ + Map.size . L.unRedeemers $ + ledgerTx ^. L.witsTxL . L.rdmrsTxWitsL + when (redeemerCount > maxEvalRedeemers) $ + throwGrpcErrorWithMessage GrpcInvalidArgument $ + "too many redeemers: " <> tshow redeemerCount <> ", maximum " <> tshow maxEvalRedeemers let allInputs = obtainCommonConstraints eon $ @@ -78,6 +101,16 @@ evalTxMethod request = do pure (protocolParams, utxo, systemStart, eraHistory, stakeDelegDeposits, registeredPools) + -- A tx that only needs to decode, not be valid, could otherwise be submitted for + -- evaluation regardless of size; bound it to what could plausibly be submitted. + let maxTxSize = fromIntegral $ protocolParams ^. L.ppMaxTxSizeL + when (BS.length rawTx > maxTxSize) $ + throwGrpcErrorWithMessage GrpcInvalidArgument $ + "transaction size " + <> tshow (BS.length rawTx) + <> " exceeds the protocol maximum " + <> tshow maxTxSize + obtainCommonConstraints eon $ do let ledgerUtxo = toLedgerUTxO (convert eon) utxo epochInfo = toLedgerEpochInfo eraHistory @@ -119,6 +152,17 @@ evalTxMethod request = do either putTrace (const $ pure ()) value throwEither value +-- | Coarse pre-decode bound (~4x the current mainnet maxTxSize): caps decode and +-- UTxO-query work for oversized requests. The exact protocol limit is enforced +-- after protocol parameters are fetched. +maxEvalTxSizeBytes :: Int +maxEvalTxSizeBytes = 65536 + +-- | Bounds attacker-controlled script evaluations per request: each redeemer may +-- consume the full per-tx execution budget. +maxEvalRedeemers :: Int +maxEvalRedeemers = 100 + -- | Extract the credentials and pool IDs needed for balance check queries from -- the transaction body certificates. extractBalanceCheckCreds diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs index dc3cc70598..b89d860df1 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs @@ -94,6 +94,15 @@ readUtxosMethod readUtxosMethod req | null $ req ^. U5c.keys = pure defMessage | otherwise = do + let keyCount = length $ req ^. U5c.keys + when (keyCount > maxReadUtxosKeys) $ + throwGrpcErrorWithMessage GrpcInvalidArgument $ + "too many keys: " + <> tshow keyCount + <> ", maximum " + <> tshow maxReadUtxosKeys + <> "; batch your requests" + utxoFilter <- QueryUTxOByTxIn . fromList <$> mapM txoRefToTxIn (req ^. U5c.keys) nodeConnInfo <- grab @@ -121,6 +130,11 @@ readUtxosMethod req txId' <- throwEither $ deserialiseFromRawBytes AsTxId $ r ^. U5c.hash pure $ TxIn txId' (TxIx . fromIntegral $ r ^. U5c.index) +-- | Bounds per-request UTxO lookups the node performs; SearchUtxos pagination +-- caps at 10_000 per page. +maxReadUtxosKeys :: Int +maxReadUtxosKeys = 20_000 + -- | Handle the @SearchUtxos@ RPC method. -- Filters the UTxO set by a predicate and returns a paginated result. -- The predicate must contain exact address matches so the query can be diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs index bdd7419f5f..6c28b6d3cc 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs @@ -57,6 +57,15 @@ fetchBlockMethod -> m (Proto U5c.FetchBlockResponse) -- ^ Response containing the fetched blocks with raw CBOR and cardano header fetchBlockMethod request = do + let refCount = length $ request ^. U5c.ref + when (refCount > maxFetchBlockRefs) $ + throwGrpcErrorWithMessage GrpcInvalidArgument $ + "too many block references: " + <> tshow refCount + <> ", maximum " + <> tshow maxFetchBlockRefs + <> "; batch your requests" + nodeKernelAccess@NodeKernelAccess{systemStart, readEraHistory} <- grabNodeKernelAccess blocks <- forM (request ^. U5c.ref) $ \blockRef -> do (slot, headerHash) <- blockRefToPoint blockRef @@ -72,6 +81,10 @@ fetchBlockMethod request = do pure $ mkAnyChainBlock rawBytes blockInMode timestamp pure $ defMessage & U5c.block .~ blocks +-- | Each ref is a ChainDB read and a full block in the non-streaming response. +maxFetchBlockRefs :: Int +maxFetchBlockRefs = 500 + -- | Handle the @ReadTip@ SyncService RPC method. -- Reads the current chain tip from ChainDB and returns it as slot, block -- header hash, block height and slot timestamp. From 7062407be5f01ad9aa2044163eb304033c4f5a3d Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Thu, 3 Sep 2026 16:55:45 +0200 Subject: [PATCH 41/62] Bump `ouroboros-consensus-4.2.1.0` --- ...15_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml | 6 ++++++ cabal.project | 2 +- cardano-api/cardano-api.cabal | 2 +- flake.lock | 6 +++--- 4 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 .changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml diff --git a/.changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml b/.changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml new file mode 100644 index 0000000000..336339b9ff --- /dev/null +++ b/.changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml @@ -0,0 +1,6 @@ +description: Bumped ouroboros-consensus to address issue that affected queries `kes-period-info` + and `tip`. +kind: +- bugfix +pr: 1327 +project: cardano-api diff --git a/cabal.project b/cabal.project index de118ade25..5088d490d3 100644 --- a/cabal.project +++ b/cabal.project @@ -14,7 +14,7 @@ repository cardano-haskell-packages -- you need to run if you change them index-state: , hackage.haskell.org 2026-08-02T17:21:34Z - , cardano-haskell-packages 2026-08-11T14:53:43Z + , cardano-haskell-packages 2026-09-03T10:20:53Z packages: cardano-api diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 54b27bff3c..839d12a662 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -178,7 +178,7 @@ library network-mux, nothunks, ordered-containers, - ouroboros-consensus:{cardano, diffusion, ouroboros-consensus, protocol} ^>=4.1, + ouroboros-consensus:{cardano, diffusion, ouroboros-consensus, protocol} ^>=4.2.1.0, ouroboros-network:{api, framework, ouroboros-network, protocols} ^>=1.2, parsec, plutus-core ^>=1.65, diff --git a/flake.lock b/flake.lock index 986aad6f0e..1ca971dc76 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "CHaP": { "flake": false, "locked": { - "lastModified": 1786489982, - "narHash": "sha256-T0r6CvdSEDxszlb7uK7mxEVZcCtFNbk8tlr8B1bRKqM=", + "lastModified": 1788439818, + "narHash": "sha256-+sjKSr1tFhiLrxhplOOToCjXMyWZV4ZbvYOdkqwHzBg=", "owner": "intersectmbo", "repo": "cardano-haskell-packages", - "rev": "13d0f23cf6af9ea55194b91f6947c0a2aeb522d9", + "rev": "95889113a879bc92976bba48cf743bd78f99710f", "type": "github" }, "original": { From 59f9df95aecacf55c282123e0243ec89c16668eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 4 Sep 2026 06:55:45 +0000 Subject: [PATCH 42/62] Release cardano-api-11.7.0.0 --- ..._canonical_inline_datum_json_roundtrip.yml | 6 ----- ..._cardano_api_redeemer_pointer_indexing.yml | 8 ------- ...thub-actions[bot]_cardano_api_11_6_0_0.yml | 5 ----- ...o-api_palas_dijkstra_hard_fork_trigger.yml | 6 ----- ..._pablo.lamela_bump_ouroboros_consensus.yml | 6 ----- .changes/reexport-txauxdata-accessors.yml | 6 ----- cardano-api/CHANGELOG.md | 22 +++++++++++++++++++ cardano-api/cardano-api.cabal | 2 +- 8 files changed, 23 insertions(+), 38 deletions(-) delete mode 100644 .changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml delete mode 100644 .changes/20260811_cardano_api_redeemer_pointer_indexing.yml delete mode 100644 .changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml delete mode 100644 .changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml delete mode 100644 .changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml delete mode 100644 .changes/reexport-txauxdata-accessors.yml diff --git a/.changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml b/.changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml deleted file mode 100644 index 56ce8bc2e4..0000000000 --- a/.changes/20260625_fix_non_canonical_inline_datum_json_roundtrip.yml +++ /dev/null @@ -1,6 +0,0 @@ -project: cardano-api -pr: 1238 -kind: - - bugfix -description: | - FromJSON (TxOut) no longer crashes when parsing a TxOut whose inline datum was encoded with non-canonical CBOR bytes (e.g. definite-length arrays instead of the indefinite-length form Plutus normally emits). diff --git a/.changes/20260811_cardano_api_redeemer_pointer_indexing.yml b/.changes/20260811_cardano_api_redeemer_pointer_indexing.yml deleted file mode 100644 index 89427890e9..0000000000 --- a/.changes/20260811_cardano_api_redeemer_pointer_indexing.yml +++ /dev/null @@ -1,8 +0,0 @@ -project: cardano-api -pr: 1288 -kind: - - bugfix - - breaking - - test -description: | - Fix plutus redeemer pointer indexing: proposal pointers now follow the transaction's insertion order and certificate pointers count unwitnessed certificates, in both the experimental and the deprecated transaction builders. Remove the unused StakeCredential field from the WitTxCert constructor. Add property tests checking every redeemer pointer against the ledger's own resolution. diff --git a/.changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml b/.changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml deleted file mode 100644 index 49ed5b4866..0000000000 --- a/.changes/20260825_135837_cardano-api_github-actions[bot]_cardano_api_11_6_0_0.yml +++ /dev/null @@ -1,5 +0,0 @@ -description: Release cardano-api 11.6.0.0 -kind: -- release -pr: 1319 -project: cardano-api diff --git a/.changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml b/.changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml deleted file mode 100644 index d617debb85..0000000000 --- a/.changes/20260825_161536_cardano-api_palas_dijkstra_hard_fork_trigger.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: | - `foldBlocks` and the rest of the ledger-state machinery now honour `TestDijkstraHardForkAtEpoch` in the node configuration file, so they can follow a chain into the Dijkstra era. -kind: - - bugfix -pr: 1321 -project: cardano-api diff --git a/.changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml b/.changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml deleted file mode 100644 index 336339b9ff..0000000000 --- a/.changes/20260903_165615_cardano-api_pablo.lamela_bump_ouroboros_consensus.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: Bumped ouroboros-consensus to address issue that affected queries `kes-period-info` - and `tip`. -kind: -- bugfix -pr: 1327 -project: cardano-api diff --git a/.changes/reexport-txauxdata-accessors.yml b/.changes/reexport-txauxdata-accessors.yml deleted file mode 100644 index ed504331ac..0000000000 --- a/.changes/reexport-txauxdata-accessors.yml +++ /dev/null @@ -1,6 +0,0 @@ -project: cardano-api -pr: 1262 -kind: - - compatible -description: | - Re-export additional ledger accessors from `Cardano.Api.Ledger` so downstream code can read a transaction and its outputs through the ledger lenses without depending on `cardano-ledger` directly: `auxDataTxL` (via `EraTx`), `metadataTxAuxDataL` (via `EraTxAuxData`), `addrTxOutL` / `valueTxOutL` (via `EraTxOut`), `datumTxOutF` (via `AlonzoEraTxOut`), plus `Datum (..)`, `hashBinaryData`, and `hashScript`. diff --git a/cardano-api/CHANGELOG.md b/cardano-api/CHANGELOG.md index acf7e03b71..ef6cd4343b 100644 --- a/cardano-api/CHANGELOG.md +++ b/cardano-api/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog for cardano-api +## 11.7.0.0 -- 2026-09-04 + +- Bumped ouroboros-consensus to address issue that affected queries `kes-period-info` and `tip`. + (bugfix) + [PR 1327](https://github.com/intersectmbo/cardano-api/pull/1327) + +- `foldBlocks` and the rest of the ledger-state machinery now honour `TestDijkstraHardForkAtEpoch` in the node configuration file, so they can follow a chain into the Dijkstra era. + (bugfix) + [PR 1321](https://github.com/intersectmbo/cardano-api/pull/1321) + +- Fix plutus redeemer pointer indexing: proposal pointers now follow the transaction's insertion order and certificate pointers count unwitnessed certificates, in both the experimental and the deprecated transaction builders. Remove the unused StakeCredential field from the WitTxCert constructor. Add property tests checking every redeemer pointer against the ledger's own resolution. + (bugfix, breaking, test) + [PR 1288](https://github.com/intersectmbo/cardano-api/pull/1288) + +- Re-export additional ledger accessors from `Cardano.Api.Ledger` so downstream code can read a transaction and its outputs through the ledger lenses without depending on `cardano-ledger` directly: `auxDataTxL` (via `EraTx`), `metadataTxAuxDataL` (via `EraTxAuxData`), `addrTxOutL` / `valueTxOutL` (via `EraTxOut`), `datumTxOutF` (via `AlonzoEraTxOut`), plus `Datum (..)`, `hashBinaryData`, and `hashScript`. + (compatible) + [PR 1262](https://github.com/intersectmbo/cardano-api/pull/1262) + +- FromJSON (TxOut) no longer crashes when parsing a TxOut whose inline datum was encoded with non-canonical CBOR bytes (e.g. definite-length arrays instead of the indefinite-length form Plutus normally emits). + (bugfix) + [PR 1238](https://github.com/intersectmbo/cardano-api/pull/1238) + ## 11.6.0.0 -- 2026-08-25 - The Dijkstra era can now be selected and enumerated like the other eras: `maxBound` and `[minBound .. maxBound]` for `AnyCardanoEra`, `AnyShelleyBasedEra` and the experimental `Some Era` include it, and the era-name parsers (`anyCardanoEraFromStringLike` and the JSON instances) accept "Dijkstra". diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 839d12a662..e7ed538ab6 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -1,6 +1,6 @@ cabal-version: 3.8 name: cardano-api -version: 11.6.0.0 +version: 11.7.0.0 synopsis: The cardano API description: The cardano API. category: From 545506d4279c6b7ec4a1ae53c6fe3673bb4109d1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 4 Sep 2026 06:55:51 +0000 Subject: [PATCH 43/62] Add release changelog fragment for cardano-api 11.7.0.0 --- ..._cardano-api_github-actions[bot]_cardano_api_11_7_0_0.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/20260904_065551_cardano-api_github-actions[bot]_cardano_api_11_7_0_0.yml diff --git a/.changes/20260904_065551_cardano-api_github-actions[bot]_cardano_api_11_7_0_0.yml b/.changes/20260904_065551_cardano-api_github-actions[bot]_cardano_api_11_7_0_0.yml new file mode 100644 index 0000000000..d66414862a --- /dev/null +++ b/.changes/20260904_065551_cardano-api_github-actions[bot]_cardano_api_11_7_0_0.yml @@ -0,0 +1,5 @@ +description: Release cardano-api 11.7.0.0 +kind: +- release +pr: 1329 +project: cardano-api From c97c8a14366514c404f4b8eac4e98d046481feac Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 4 Sep 2026 07:53:45 +0000 Subject: [PATCH 44/62] Release cardano-rpc-11.3.0.0 --- ...0000_cardano-rpc_carbolymer_utxorpc_spec_update.yml | 10 ---------- ...no-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml | 5 ----- .changes/20260828_cardano_rpc_grpc_tcp_listener.yml | 7 ------- cardano-rpc/CHANGELOG.md | 10 ++++++++++ cardano-rpc/cardano-rpc.cabal | 2 +- 5 files changed, 11 insertions(+), 23 deletions(-) delete mode 100644 .changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml delete mode 100644 .changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml delete mode 100644 .changes/20260828_cardano_rpc_grpc_tcp_listener.yml diff --git a/.changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml b/.changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml deleted file mode 100644 index addaaf9f59..0000000000 --- a/.changes/20260819_160000_cardano-rpc_carbolymer_utxorpc_spec_update.yml +++ /dev/null @@ -1,10 +0,0 @@ -project: cardano-rpc - -pr: 1303 - -kind: - - feature - - breaking - -description: | - Update the vendored UTxO RPC v1beta proto definitions to the latest upstream utxorpc/spec (v0.19.2 plus the unreleased EvalReport optional-field flags from [utxorpc/spec#203](https://github.com/utxorpc/spec/pull/203), a wire-compatible change), including resetting FetchBlock to the upstream repeated request/response shape (the single-item variant moved to the upcoming utxorpc v1). Expose all v1beta service methods: the unimplemented ones (ReadData, ReadTx, ReadEraSummary, ReadState, ReadMempool, WaitForTx, WatchMempool, DumpHistory) respond with the UNIMPLEMENTED gRPC status. Populate the new `Tx.votes` field (governance votes, Conway onwards) and the new `TxOutput.original_cbor` field (canonical re-encoding of the output; the ledger does not retain the original on-chain TxOut bytes). diff --git a/.changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml b/.changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml deleted file mode 100644 index 03c3831aee..0000000000 --- a/.changes/20260825_142437_cardano-rpc_github-actions[bot]_cardano_rpc_11_2_0_0.yml +++ /dev/null @@ -1,5 +0,0 @@ -description: Release cardano-rpc 11.2.0.0 -kind: -- release -pr: 1320 -project: cardano-rpc diff --git a/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml b/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml deleted file mode 100644 index cede1ff0c3..0000000000 --- a/.changes/20260828_cardano_rpc_grpc_tcp_listener.yml +++ /dev/null @@ -1,7 +0,0 @@ -project: cardano-rpc -pr: 1322 -kind: - - feature - - breaking -description: | - The cardano-rpc gRPC server can now listen on HTTP/2 (h2c) or HTTP/2 over TLS on a configured IP address and port instead of only a unix domain socket, configured via new cardano-node options such as `--grpc-listen-port` and `--grpc-tls-certificate`. `RpcConfigF`'s `rpcSocketPath` field was replaced by the new `RpcEndpoint` sum type. Error responses no longer include internal diagnostic detail such as call stacks. Script evaluation requests are rejected when the transaction exceeds the protocol maximum size or carries more than 100 redeemers. UTxO reads are limited to 20000 keys and block fetches to 500 references per request. diff --git a/cardano-rpc/CHANGELOG.md b/cardano-rpc/CHANGELOG.md index e097de98f0..6b74f47012 100644 --- a/cardano-rpc/CHANGELOG.md +++ b/cardano-rpc/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog for cardano-rpc +## 11.3.0.0 -- 2026-09-04 + +- The cardano-rpc gRPC server can now listen on HTTP/2 (h2c) or HTTP/2 over TLS on a configured IP address and port instead of only a unix domain socket, configured via new cardano-node options such as `--grpc-listen-port` and `--grpc-tls-certificate`. `RpcConfigF`'s `rpcSocketPath` field was replaced by the new `RpcEndpoint` sum type. Error responses no longer include internal diagnostic detail such as call stacks. Script evaluation requests are rejected when the transaction exceeds the protocol maximum size or carries more than 100 redeemers. UTxO reads are limited to 20000 keys and block fetches to 500 references per request. + (feature, breaking) + [PR 1322](https://github.com/intersectmbo/cardano-api/pull/1322) + +- Update the vendored UTxO RPC v1beta proto definitions to the latest upstream utxorpc/spec (v0.19.2 plus the unreleased EvalReport optional-field flags from [utxorpc/spec#203](https://github.com/utxorpc/spec/pull/203), a wire-compatible change), including resetting FetchBlock to the upstream repeated request/response shape (the single-item variant moved to the upcoming utxorpc v1). Expose all v1beta service methods: the unimplemented ones (ReadData, ReadTx, ReadEraSummary, ReadState, ReadMempool, WaitForTx, WatchMempool, DumpHistory) respond with the UNIMPLEMENTED gRPC status. Populate the new `Tx.votes` field (governance votes, Conway onwards) and the new `TxOutput.original_cbor` field (canonical re-encoding of the output; the ledger does not retain the original on-chain TxOut bytes). + (feature, breaking) + [PR 1303](https://github.com/intersectmbo/cardano-api/pull/1303) + ## 11.2.0.0 -- 2026-08-25 - Fixed the UTxO RPC `ReadGenesis` response reporting no initial funds for networks created with `cardano-cli create-testnet-data`, and stopped the node retaining the parsed genesis in memory for its whole lifetime. The Shelley genesis is now read from disk when `ReadGenesis` is served, verified against the genesis hash computed at node startup, and kept for five minutes after the last request; a genesis file that changed since startup fails the request with `FAILED_PRECONDITION`. Breaking change: `mkNodeKernelAccess` no longer takes `ProtocolInfoArgs` and takes the Shelley genesis file path instead. diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index 64cdf67930..9b33d6ea22 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -1,6 +1,6 @@ cabal-version: 3.8 name: cardano-rpc -version: 11.2.0.0 +version: 11.3.0.0 synopsis: A gRPC server and client for interacting with the Cardano node description: A Haskell library providing a gRPC-based RPC interface for the Cardano node, From 7f58483d57d68b5963f69bb721427e3c863c5452 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 4 Sep 2026 07:53:51 +0000 Subject: [PATCH 45/62] Add release changelog fragment for cardano-rpc 11.3.0.0 --- ..._cardano-rpc_github-actions[bot]_cardano_rpc_11_3_0_0.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/20260904_075351_cardano-rpc_github-actions[bot]_cardano_rpc_11_3_0_0.yml diff --git a/.changes/20260904_075351_cardano-rpc_github-actions[bot]_cardano_rpc_11_3_0_0.yml b/.changes/20260904_075351_cardano-rpc_github-actions[bot]_cardano_rpc_11_3_0_0.yml new file mode 100644 index 0000000000..29760d53ba --- /dev/null +++ b/.changes/20260904_075351_cardano-rpc_github-actions[bot]_cardano_rpc_11_3_0_0.yml @@ -0,0 +1,5 @@ +description: Release cardano-rpc 11.3.0.0 +kind: +- release +pr: 1330 +project: cardano-rpc From 018b6065b73cc435cec702f4d54670a673f384e6 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 3 Sep 2026 11:26:46 -0400 Subject: [PATCH 46/62] Remove caseShelleyEraOnlyOrAllegraEraOnwards Two of the three call sites discarded the `ShelleyEraOnly` witness entirely, so they are expressed directly with `inEonForShelleyBasedEra` and an `AllegraEraOnwards` default. `invalidHereAfterTxBodyL` needs the `ShelleyEraOnly` witness in the Shelley branch to reach `ttlAsInvalidHereAfterTxBodyL`, which `inEonForShelleyBasedEra` cannot supply, so it now matches on the `ShelleyBasedEra` constructors directly. --- .../src/Cardano/Api/Era/Internal/Case.hs | 20 ------------------ .../src/Cardano/Api/Tx/Internal/Body.hs | 8 +++---- .../src/Cardano/Api/Tx/Internal/Body/Lens.hs | 21 ++++++++++++++----- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs b/cardano-api/src/Cardano/Api/Era/Internal/Case.hs index d8dd947ed0..59783cd240 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Case.hs @@ -7,16 +7,13 @@ module Cardano.Api.Era.Internal.Case ( -- Case on CardanoEra caseByronOrShelleyBasedEra -- Case on ShelleyBasedEra - , caseShelleyEraOnlyOrAllegraEraOnwards , caseShelleyToBabbageOrConwayEraOnwards ) where import Cardano.Api.Era.Internal.Core -import Cardano.Api.Era.Internal.Eon.AllegraEraOnwards import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra -import Cardano.Api.Era.Internal.Eon.ShelleyEraOnly import Cardano.Api.Era.Internal.Eon.ShelleyToBabbageEra -- | @caseByronOrShelleyBasedEra f g era@ returns @f@ in Byron and applies @g@ to Shelley-based eras. @@ -38,23 +35,6 @@ caseByronOrShelleyBasedEra l r = \case ConwayEra -> r ShelleyBasedEraConway DijkstraEra -> r ShelleyBasedEraDijkstra --- | @caseShelleyEraOnlyOrAllegraEraOnwards f g era@ applies @f@ to shelley; --- and applies @g@ to allegra and later eras. -caseShelleyEraOnlyOrAllegraEraOnwards - :: () - => (ShelleyEraOnlyConstraints era => ShelleyEraOnly era -> a) - -> (AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a) - -> ShelleyBasedEra era - -> a -caseShelleyEraOnlyOrAllegraEraOnwards l r = \case - ShelleyBasedEraShelley -> l ShelleyEraOnlyShelley - ShelleyBasedEraAllegra -> r AllegraEraOnwardsAllegra - ShelleyBasedEraMary -> r AllegraEraOnwardsMary - ShelleyBasedEraAlonzo -> r AllegraEraOnwardsAlonzo - ShelleyBasedEraBabbage -> r AllegraEraOnwardsBabbage - ShelleyBasedEraConway -> r AllegraEraOnwardsConway - ShelleyBasedEraDijkstra -> r AllegraEraOnwardsDijkstra - -- | @caseShelleyToBabbageOrConwayEraOnwards f g era@ applies @f@ to eras before conway; -- and applies @g@ to conway and later eras. caseShelleyToBabbageOrConwayEraOnwards diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index 829c376f85..618348d15c 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -1656,8 +1656,8 @@ fromLedgerTxValidityLowerBound -> A.LedgerTxBody era -> TxValidityLowerBound era fromLedgerTxValidityLowerBound sbe body = - caseShelleyEraOnlyOrAllegraEraOnwards - (const TxValidityNoLowerBound) + inEonForShelleyBasedEra + TxValidityNoLowerBound ( \w -> let mInvalidBefore = body ^. A.invalidBeforeTxBodyL w in case mInvalidBefore of @@ -1719,8 +1719,8 @@ fromLedgerTxAuxiliaryData sbe (Just auxData) = metadata = if null ms then TxMetadataNone else TxMetadataInEra sbe $ TxMetadata ms auxdata = - caseShelleyEraOnlyOrAllegraEraOnwards - (const TxAuxScriptsNone) + inEonForShelleyBasedEra + TxAuxScriptsNone ( \w -> case ss of [] -> TxAuxScriptsNone diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs index 9092c64403..f5e993d0cd 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body/Lens.hs @@ -1,5 +1,7 @@ {-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} {- HLINT ignore "Eta reduce" -} @@ -45,7 +47,6 @@ module Cardano.Api.Tx.Internal.Body.Lens ) where -import Cardano.Api.Era.Internal.Case import Cardano.Api.Era.Internal.Eon.AllegraEraOnwards import Cardano.Api.Era.Internal.Eon.AlonzoEraOnwards import Cardano.Api.Era.Internal.Eon.BabbageEraOnwards @@ -109,10 +110,20 @@ invalidBeforeTxBodyL w = allegraEraOnwardsConstraints w $ txBodyL . L.vldtTxBody -- 'invalidHereAfterTxBodyL' lens over both with a 'Maybe SlotNo' type representation. Withing the -- Shelley era, setting Nothing will set the ttl to 'maxBound' in the underlying ledger type. invalidHereAfterTxBodyL :: ShelleyBasedEra era -> Lens' (LedgerTxBody era) (Maybe SlotNo) -invalidHereAfterTxBodyL = - caseShelleyEraOnlyOrAllegraEraOnwards - ttlAsInvalidHereAfterTxBodyL - (const $ txBodyL . L.vldtTxBodyL . L.invalidHereAfterL . strictMaybeL) +invalidHereAfterTxBodyL = \case + ShelleyBasedEraShelley -> ttlAsInvalidHereAfterTxBodyL ShelleyEraOnlyShelley + ShelleyBasedEraAllegra -> vldtAsInvalidHereAfterTxBodyL + ShelleyBasedEraMary -> vldtAsInvalidHereAfterTxBodyL + ShelleyBasedEraAlonzo -> vldtAsInvalidHereAfterTxBodyL + ShelleyBasedEraBabbage -> vldtAsInvalidHereAfterTxBodyL + ShelleyBasedEraConway -> vldtAsInvalidHereAfterTxBodyL + ShelleyBasedEraDijkstra -> vldtAsInvalidHereAfterTxBodyL + where + vldtAsInvalidHereAfterTxBodyL + :: L.AllegraEraTxBody (ShelleyLedgerEra era') + => Lens' (LedgerTxBody era') (Maybe SlotNo) + vldtAsInvalidHereAfterTxBodyL = + txBodyL . L.vldtTxBodyL . L.invalidHereAfterL . strictMaybeL -- | Compatibility lens over 'ttlTxBodyL' which represents 'maxBound' as Nothing and all other values as 'Just'. ttlAsInvalidHereAfterTxBodyL :: ShelleyEraOnly era -> Lens' (LedgerTxBody era) (Maybe SlotNo) From c0b5072e180e55dba1df30dd3c4d3a9a1b113c01 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 3 Sep 2026 11:38:07 -0400 Subject: [PATCH 47/62] Remove caseByronOrShelleyBasedEra It had no call sites left, and its own comment marked it for deletion once `build-raw --byron-era` was deprecated in cardano-cli. Callers needing the same split can use `inEonForEra` with `ShelleyBasedEra`, which is what the `Cardano.Api.Network.IPC` haddock example now shows. --- cardano-api/src/Cardano/Api/Era.hs | 3 --- .../src/Cardano/Api/Era/Internal/Case.hs | 25 +------------------ cardano-api/src/Cardano/Api/Network/IPC.hs | 2 +- 3 files changed, 2 insertions(+), 28 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Era.hs b/cardano-api/src/Cardano/Api/Era.hs index 8dd13e9c8b..48c5cc5b24 100644 --- a/cardano-api/src/Cardano/Api/Era.hs +++ b/cardano-api/src/Cardano/Api/Era.hs @@ -61,9 +61,6 @@ module Cardano.Api.Era -- * Era case handling - -- ** Case on CardanoEra - , caseByronOrShelleyBasedEra - -- ** Case on ShelleyBasedEra , caseShelleyToBabbageOrConwayEraOnwards ) diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs b/cardano-api/src/Cardano/Api/Era/Internal/Case.hs index 59783cd240..8a686c9a79 100644 --- a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs +++ b/cardano-api/src/Cardano/Api/Era/Internal/Case.hs @@ -4,37 +4,14 @@ {-# LANGUAGE RankNTypes #-} module Cardano.Api.Era.Internal.Case - ( -- Case on CardanoEra - caseByronOrShelleyBasedEra - -- Case on ShelleyBasedEra - , caseShelleyToBabbageOrConwayEraOnwards + ( caseShelleyToBabbageOrConwayEraOnwards ) where -import Cardano.Api.Era.Internal.Core import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra import Cardano.Api.Era.Internal.Eon.ShelleyToBabbageEra --- | @caseByronOrShelleyBasedEra f g era@ returns @f@ in Byron and applies @g@ to Shelley-based eras. -caseByronOrShelleyBasedEra - :: () - => a - -> (ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a) - -> CardanoEra era - -> a -caseByronOrShelleyBasedEra l r = \case - ByronEra -> l -- We no longer provide the witness because Byron is isolated. - -- This function will be deleted shortly after build-raw --byron-era is - -- deprecated in cardano-cli - ShelleyEra -> r ShelleyBasedEraShelley - AllegraEra -> r ShelleyBasedEraAllegra - MaryEra -> r ShelleyBasedEraMary - AlonzoEra -> r ShelleyBasedEraAlonzo - BabbageEra -> r ShelleyBasedEraBabbage - ConwayEra -> r ShelleyBasedEraConway - DijkstraEra -> r ShelleyBasedEraDijkstra - -- | @caseShelleyToBabbageOrConwayEraOnwards f g era@ applies @f@ to eras before conway; -- and applies @g@ to conway and later eras. caseShelleyToBabbageOrConwayEraOnwards diff --git a/cardano-api/src/Cardano/Api/Network/IPC.hs b/cardano-api/src/Cardano/Api/Network/IPC.hs index c27d42d09b..275f414eeb 100644 --- a/cardano-api/src/Cardano/Api/Network/IPC.hs +++ b/cardano-api/src/Cardano/Api/Network/IPC.hs @@ -107,7 +107,7 @@ module Cardano.Api.Network.IPC -- @ -- Api.AnyShelleyBasedEra sbe :: Api.AnyShelleyBasedEra <- case eEra of -- Right (Api.AnyCardanoEra era) -> - -- Api.caseByronOrShelleyBasedEra + -- Api.inEonForEra -- (error "Error, we are in Byron era") -- (return . Api.AnyShelleyBasedEra) -- era From 9cf58c4ec36bd6d8e480a8637f3a21a1a68ce0e5 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 3 Sep 2026 11:48:45 -0400 Subject: [PATCH 48/62] Prefer inEonForShelleyBasedEra over caseShelleyToBabbageOrConwayEraOnwards Sixteen of the nineteen call sites ignored one of the two witnesses, so they are expressed with `inEonForShelleyBasedEra` and a default for the eras outside the eon. Unlike the case combinator, `inEonForShelleyBasedEra` hands the callback a witness but no constraints, so `maybeFromLedgerTxUpdateProposal` now calls `shelleyToBabbageEraConstraints` itself. In `toConsensusQueryShelleyBased` the eleven Conway-onwards queries go through a local `conwayOnwards` witness which matches on `ShelleyBasedEra` exhaustively instead of using an eon, so adding or retiring an era is a compile error at that match rather than a silent fall through to the unsupported branch. The witness is `ConwayEraOnwards` and the constraints come from `conwayEraOnwardsConstraints`, so these queries no longer depend on the experimental `Era`, whose constructors only cover the currently supported eras. `nextEpochEligibleLeadershipSlots` needs a visible type application because neither branch mentions the witness. --- cardano-api/src/Cardano/Api/LedgerState.hs | 4 +- .../Cardano/Api/Query/Internal/Convenience.hs | 4 +- .../Api/Query/Internal/Type/QueryInMode.hs | 162 +++++------------- .../src/Cardano/Api/Tx/Internal/Body.hs | 22 ++- 4 files changed, 59 insertions(+), 133 deletions(-) diff --git a/cardano-api/src/Cardano/Api/LedgerState.hs b/cardano-api/src/Cardano/Api/LedgerState.hs index 6e3c3b6c1b..8007f148b1 100644 --- a/cardano-api/src/Cardano/Api/LedgerState.hs +++ b/cardano-api/src/Cardano/Api/LedgerState.hs @@ -110,9 +110,9 @@ import Cardano.Api.Byron.Internal.Proposal as Byron import Cardano.Api.Certificate.Internal import Cardano.Api.Consensus.Internal.Mode import Cardano.Api.Consensus.Internal.Mode qualified as Api -import Cardano.Api.Era.Internal.Case import Cardano.Api.Era.Internal.Core (forEraInEon, forEraMaybeEon, toCardanoEra) import Cardano.Api.Era.Internal.Eon.BabbageEraOnwards +import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards (ConwayEraOnwards) import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra import Cardano.Api.Error as Api import Cardano.Api.Genesis.Internal @@ -2119,7 +2119,7 @@ nextEpochEligibleLeadershipSlots sbe sGen serCurrEpochState ptclState poolid (Vr stabilityWindowSlots :: SlotNo stabilityWindowSlots = fromIntegral @Word64 $ floor $ fromRational @Double stabilityWindowR stableStakeDistribSlot = currentEpochLastSlot - stabilityWindowSlots - stabilityWindowConst = caseShelleyToBabbageOrConwayEraOnwards (const 3) (const 4) sbe + stabilityWindowConst = inEonForShelleyBasedEra @ConwayEraOnwards 3 (const 4) sbe case cTip of ChainTipAtGenesis -> Left LeaderErrGenesisSlot diff --git a/cardano-api/src/Cardano/Api/Query/Internal/Convenience.hs b/cardano-api/src/Cardano/Api/Query/Internal/Convenience.hs index 59c19a63ad..d6a74be61e 100644 --- a/cardano-api/src/Cardano/Api/Query/Internal/Convenience.hs +++ b/cardano-api/src/Cardano/Api/Query/Internal/Convenience.hs @@ -169,8 +169,8 @@ queryStateForBalancedTx era allTxIns certs = runExceptT $ do ) featuredTxTreasuryValueM <- - caseShelleyToBabbageOrConwayEraOnwards - (const $ pure Nothing) + inEonForShelleyBasedEra + (pure Nothing) ( \cOnwards -> do ChainAccountState{casTreasury} <- lift (queryAccountState cOnwards) diff --git a/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs b/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs index 671a787d3b..c7c714b765 100644 --- a/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs +++ b/cardano-api/src/Cardano/Api/Query/Internal/Type/QueryInMode.hs @@ -71,12 +71,12 @@ import Cardano.Api.Address import Cardano.Api.Block import Cardano.Api.Certificate.Internal import Cardano.Api.Consensus.Internal.Mode -import Cardano.Api.Era.Internal.Case import Cardano.Api.Era.Internal.Core -import Cardano.Api.Era.Internal.Eon.Convert (Convert (convert)) -import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards () +import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards + ( ConwayEraOnwards (..) + , conwayEraOnwardsConstraints + ) import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra -import Cardano.Api.Experimental.Era (obtainCommonConstraints) import Cardano.Api.Genesis.Internal.Parameters import Cardano.Api.HasTypeProxy (HasTypeProxy (..)) import Cardano.Api.Key.Internal @@ -586,15 +586,8 @@ toConsensusQueryShelleyBased sbe = \case QueryEpoch -> Some (consensusQueryInEraInMode era Consensus.GetEpochNo) QueryConstitution -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: QueryConstitution is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ Some (consensusQueryInEraInMode era Consensus.GetConstitution) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryConstitution") $ + Some (consensusQueryInEraInMode era Consensus.GetConstitution) QueryGenesisParameters -> Some (consensusQueryInEraInMode era Consensus.GetGenesisConfig) QueryProtocolParameters -> @@ -662,128 +655,63 @@ toConsensusQueryShelleyBased sbe = \case QueryGovState -> Some (consensusQueryInEraInMode era Consensus.GetGovState) QueryRatifyState -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error "toConsensusQueryShelleyBased: QueryRatifyState is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ Some (consensusQueryInEraInMode era Consensus.GetRatifyState) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryRatifyState") $ + Some (consensusQueryInEraInMode era Consensus.GetRatifyState) QueryFuturePParams -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: QueryFuturePParams is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some (consensusQueryInEraInMode era Consensus.GetFuturePParams) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryFuturePParams") $ + Some (consensusQueryInEraInMode era Consensus.GetFuturePParams) QueryDRepState creds -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error "toConsensusQueryShelleyBased: QueryDRepState is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some (consensusQueryInEraInMode era (Consensus.GetDRepState creds)) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryDRepState") $ + Some (consensusQueryInEraInMode era (Consensus.GetDRepState creds)) QueryDRepStakeDistr dreps -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: QueryDRepStakeDistr is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some (consensusQueryInEraInMode era (Consensus.GetDRepStakeDistr dreps)) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryDRepStakeDistr") $ + Some (consensusQueryInEraInMode era (Consensus.GetDRepStakeDistr dreps)) QuerySPOStakeDistr spos -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: QuerySPOStakeDistr is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some (consensusQueryInEraInMode era (Consensus.GetSPOStakeDistr spos)) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QuerySPOStakeDistr") $ + Some (consensusQueryInEraInMode era (Consensus.GetSPOStakeDistr spos)) QueryCommitteeMembersState coldCreds hotCreds statuses -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: QueryCommitteeMembersState is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some - (consensusQueryInEraInMode era (Consensus.GetCommitteeMembersState coldCreds hotCreds statuses)) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryCommitteeMembersState") $ + Some + (consensusQueryInEraInMode era (Consensus.GetCommitteeMembersState coldCreds hotCreds statuses)) QueryStakeVoteDelegatees creds -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: QueryStakeVoteDelegatees is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some - ( consensusQueryInEraInMode - era - (Consensus.GetFilteredVoteDelegatees creds') - ) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryStakeVoteDelegatees") $ + Some (consensusQueryInEraInMode era (Consensus.GetFilteredVoteDelegatees creds')) where creds' :: Set (Shelley.Credential Shelley.Staking) creds' = Set.map toShelleyStakeCredential creds QueryProposals govActs -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error "toConsensusQueryShelleyBased: QueryProposals is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some - (consensusQueryInEraInMode era (Consensus.GetProposals govActs)) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryProposals") $ + Some (consensusQueryInEraInMode era (Consensus.GetProposals govActs)) QueryLedgerPeerSnapshot peerKind -> Some (consensusQueryInEraInMode era (Consensus.GetLedgerPeerSnapshot peerKind)) QueryStakePoolDefaultVote govActs -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: QueryStakePoolDefaultVote is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some - (consensusQueryInEraInMode era (Consensus.QueryStakePoolDefaultVote govActs)) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "QueryStakePoolDefaultVote") $ + Some (consensusQueryInEraInMode era (Consensus.QueryStakePoolDefaultVote govActs)) GetDRepDelegations dreps -> - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - error - "toConsensusQueryShelleyBased: GetDRepDelegations is only available from the Conway era onwards" - ) - ( \w -> - obtainCommonConstraints (convert w) $ - Some - (consensusQueryInEraInMode era (Consensus.GetDRepDelegations dreps)) - ) - sbe + conwayEraOnwardsConstraints (conwayOnwards "GetDRepDelegations") $ + Some (consensusQueryInEraInMode era (Consensus.GetDRepDelegations dreps)) where era = toCardanoEra sbe + -- Witness that @era@ is Conway or later. Matched on 'ShelleyBasedEra', + -- totally: adding or retiring an era is then a compile error here rather + -- than a silent fall through to 'unsupported'. + conwayOnwards :: String -> ConwayEraOnwards era + conwayOnwards q = case sbe of + ShelleyBasedEraShelley -> unsupported + ShelleyBasedEraAllegra -> unsupported + ShelleyBasedEraMary -> unsupported + ShelleyBasedEraAlonzo -> unsupported + ShelleyBasedEraBabbage -> unsupported + ShelleyBasedEraConway -> ConwayEraOnwardsConway + ShelleyBasedEraDijkstra -> ConwayEraOnwardsDijkstra + where + unsupported :: forall a. a + unsupported = + error $ + "toConsensusQueryShelleyBased: " <> q <> " is only available from the Conway era onwards" + consensusQueryInEraInMode :: forall era erablock modeblock result result' fp xs . ConsensusBlockForEra era ~ erablock diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs index 618348d15c..0d82849b54 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Body.hs @@ -238,7 +238,6 @@ where import Cardano.Api.Address import Cardano.Api.Byron.Internal.Key -import Cardano.Api.Era.Internal.Case import Cardano.Api.Era.Internal.Core import Cardano.Api.Era.Internal.Eon.AllegraEraOnwards import Cardano.Api.Era.Internal.Eon.AlonzoEraOnwards @@ -1780,13 +1779,14 @@ maybeFromLedgerTxUpdateProposal -> Ledger.TxBody Ledger.TopTx (ShelleyLedgerEra era) -> TxUpdateProposal era maybeFromLedgerTxUpdateProposal sbe body = - caseShelleyToBabbageOrConwayEraOnwards + inEonForShelleyBasedEra + TxUpdateProposalNone ( \w -> - case body ^. L.updateTxBodyL of - SNothing -> TxUpdateProposalNone - SJust p -> TxUpdateProposal w (fromLedgerUpdate sbe p) + shelleyToBabbageEraConstraints w $ + case body ^. L.updateTxBodyL of + SNothing -> TxUpdateProposalNone + SJust p -> TxUpdateProposal w (fromLedgerUpdate sbe p) ) - (const TxUpdateProposalNone) sbe fromLedgerTxMintValue @@ -2384,10 +2384,8 @@ collectTxBodyScriptWitnessRequirements extractWitnessableMints aEon txMintValue txVotingWits <- - caseShelleyToBabbageOrConwayEraOnwards - ( \w -> - shelleyToBabbageEraConstraints w $ Right $ TxScriptWitnessRequirements mempty mempty mempty mempty - ) + inEonForShelleyBasedEra + (Right $ TxScriptWitnessRequirements mempty mempty mempty mempty) ( \eon -> first TxBodyPlutusScriptDecodeError $ legacyWitnessToScriptRequirements aEon $ @@ -2395,8 +2393,8 @@ collectTxBodyScriptWitnessRequirements ) sbe txProposalWits <- - caseShelleyToBabbageOrConwayEraOnwards - (const $ Right $ TxScriptWitnessRequirements mempty mempty mempty mempty) + inEonForShelleyBasedEra + (Right $ TxScriptWitnessRequirements mempty mempty mempty mempty) ( \eon -> first TxBodyPlutusScriptDecodeError $ legacyWitnessToScriptRequirements aEon $ From 7cb19631e5fcf5fe5138461f921576366a4111e2 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 3 Sep 2026 11:57:09 -0400 Subject: [PATCH 49/62] Remove caseShelleyToBabbageOrConwayEraOnwards The three remaining call sites are certificate generators whose pre-Conway branch needs `ShelleyEraTxCert` and whose Conway branch needs `ConwayEraTxCert`. `inEonForShelleyBasedEra` supplies a witness but no constraints, and its default argument has no witness at all, so these match on the `ShelleyBasedEra` constructors and obtain the constraints from the witness in each branch. That empties `Cardano.Api.Era.Internal.Case`, so the module goes too. --- cardano-api/cardano-api.cabal | 1 - cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs | 111 ++++++++++-------- cardano-api/src/Cardano/Api/Era.hs | 6 - .../src/Cardano/Api/Era/Internal/Case.hs | 30 ----- 4 files changed, 65 insertions(+), 83 deletions(-) delete mode 100644 cardano-api/src/Cardano/Api/Era/Internal/Case.hs diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index e7ed538ab6..48b34e6263 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -217,7 +217,6 @@ library Cardano.Api.Consensus.Internal.Mode Cardano.Api.Consensus.Internal.Protocol Cardano.Api.Consensus.Internal.Reexport - Cardano.Api.Era.Internal.Case Cardano.Api.Era.Internal.Core Cardano.Api.Era.Internal.Eon.AllegraEraOnwards Cardano.Api.Era.Internal.Eon.AlonzoEraOnwards diff --git a/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs b/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs index 63130f4b53..e2671ef83c 100644 --- a/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs +++ b/cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs @@ -2,6 +2,7 @@ {-# LANGUAGE EmptyCase #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} @@ -849,58 +850,76 @@ genCertificate sbe = genStakeAddressRegistrationCertificate :: ShelleyBasedEra era -> Gen (Exp.Certificate (ShelleyLedgerEra era)) -genStakeAddressRegistrationCertificate = - caseShelleyToBabbageOrConwayEraOnwards - ( \w -> - shelleyToBabbageEraConstraints w $ - Exp.Certificate . L.mkRegTxCert . toShelleyStakeCredential <$> genStakeCredential - ) - ( \w -> - conwayEraOnwardsConstraints w $ - Exp.Certificate - <$> ( L.mkRegDepositTxCert . toShelleyStakeCredential - <$> genStakeCredential - <*> genLovelace - ) - ) +genStakeAddressRegistrationCertificate = \case + ShelleyBasedEraShelley -> preConway + ShelleyBasedEraAllegra -> preConway + ShelleyBasedEraMary -> preConway + ShelleyBasedEraAlonzo -> preConway + ShelleyBasedEraBabbage -> preConway + ShelleyBasedEraConway -> postConway + ShelleyBasedEraDijkstra -> postConway + where + preConway :: L.ShelleyEraTxCert ledgerera => Gen (Exp.Certificate ledgerera) + preConway = + Exp.Certificate . L.mkRegTxCert . toShelleyStakeCredential <$> genStakeCredential + + postConway :: L.ConwayEraTxCert ledgerera => Gen (Exp.Certificate ledgerera) + postConway = + Exp.Certificate + <$> ( L.mkRegDepositTxCert . toShelleyStakeCredential + <$> genStakeCredential + <*> genLovelace + ) genStakeAddressUnregistrationCertificate :: ShelleyBasedEra era -> Gen (Exp.Certificate (ShelleyLedgerEra era)) -genStakeAddressUnregistrationCertificate = - caseShelleyToBabbageOrConwayEraOnwards - ( \w -> - shelleyToBabbageEraConstraints w $ - Exp.Certificate . L.mkUnRegTxCert . toShelleyStakeCredential <$> genStakeCredential - ) - ( \w -> - conwayEraOnwardsConstraints w $ - Exp.Certificate - <$> ( L.mkUnRegDepositTxCert . toShelleyStakeCredential - <$> genStakeCredential - <*> genLovelace - ) - ) +genStakeAddressUnregistrationCertificate = \case + ShelleyBasedEraShelley -> preConway + ShelleyBasedEraAllegra -> preConway + ShelleyBasedEraMary -> preConway + ShelleyBasedEraAlonzo -> preConway + ShelleyBasedEraBabbage -> preConway + ShelleyBasedEraConway -> postConway + ShelleyBasedEraDijkstra -> postConway + where + preConway :: L.ShelleyEraTxCert ledgerera => Gen (Exp.Certificate ledgerera) + preConway = + Exp.Certificate . L.mkUnRegTxCert . toShelleyStakeCredential <$> genStakeCredential + + postConway :: L.ConwayEraTxCert ledgerera => Gen (Exp.Certificate ledgerera) + postConway = + Exp.Certificate + <$> ( L.mkUnRegDepositTxCert . toShelleyStakeCredential + <$> genStakeCredential + <*> genLovelace + ) genStakeAddressDelegationCertificate :: ShelleyBasedEra era -> Gen (Exp.Certificate (ShelleyLedgerEra era)) -genStakeAddressDelegationCertificate = - caseShelleyToBabbageOrConwayEraOnwards - ( \w -> - shelleyToBabbageEraConstraints w $ - Exp.Certificate - <$> ( L.mkDelegStakeTxCert . toShelleyStakeCredential - <$> genStakeCredential - <*> (unStakePoolKeyHash <$> genVerificationKeyHash AsStakePoolKey) - ) - ) - ( \w -> - conwayEraOnwardsConstraints w $ - Exp.Certificate - <$> ( L.mkDelegTxCert . toShelleyStakeCredential - <$> genStakeCredential - <*> Q.arbitrary - ) - ) +genStakeAddressDelegationCertificate = \case + ShelleyBasedEraShelley -> preConway + ShelleyBasedEraAllegra -> preConway + ShelleyBasedEraMary -> preConway + ShelleyBasedEraAlonzo -> preConway + ShelleyBasedEraBabbage -> preConway + ShelleyBasedEraConway -> postConway + ShelleyBasedEraDijkstra -> postConway + where + preConway :: L.ShelleyEraTxCert ledgerera => Gen (Exp.Certificate ledgerera) + preConway = + Exp.Certificate + <$> ( L.mkDelegStakeTxCert . toShelleyStakeCredential + <$> genStakeCredential + <*> (unStakePoolKeyHash <$> genVerificationKeyHash AsStakePoolKey) + ) + + postConway :: L.ConwayEraTxCert ledgerera => Gen (Exp.Certificate ledgerera) + postConway = + Exp.Certificate + <$> ( L.mkDelegTxCert . toShelleyStakeCredential + <$> genStakeCredential + <*> Q.arbitrary + ) genStakePoolRegistrationCertificate :: ShelleyBasedEra era -> Gen (Exp.Certificate (ShelleyLedgerEra era)) diff --git a/cardano-api/src/Cardano/Api/Era.hs b/cardano-api/src/Cardano/Api/Era.hs index 48c5cc5b24..b37a52e917 100644 --- a/cardano-api/src/Cardano/Api/Era.hs +++ b/cardano-api/src/Cardano/Api/Era.hs @@ -58,15 +58,9 @@ module Cardano.Api.Era , AsConwayEra , AsDijkstraEra ) - - -- * Era case handling - - -- ** Case on ShelleyBasedEra - , caseShelleyToBabbageOrConwayEraOnwards ) where -import Cardano.Api.Era.Internal.Case import Cardano.Api.Era.Internal.Core import Cardano.Api.Era.Internal.Eon.AllegraEraOnwards import Cardano.Api.Era.Internal.Eon.AlonzoEraOnwards diff --git a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs b/cardano-api/src/Cardano/Api/Era/Internal/Case.hs deleted file mode 100644 index 8a686c9a79..0000000000 --- a/cardano-api/src/Cardano/Api/Era/Internal/Case.hs +++ /dev/null @@ -1,30 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE RankNTypes #-} - -module Cardano.Api.Era.Internal.Case - ( caseShelleyToBabbageOrConwayEraOnwards - ) -where - -import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards -import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra -import Cardano.Api.Era.Internal.Eon.ShelleyToBabbageEra - --- | @caseShelleyToBabbageOrConwayEraOnwards f g era@ applies @f@ to eras before conway; --- and applies @g@ to conway and later eras. -caseShelleyToBabbageOrConwayEraOnwards - :: () - => (ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a) - -> (ConwayEraOnwardsConstraints era => ConwayEraOnwards era -> a) - -> ShelleyBasedEra era - -> a -caseShelleyToBabbageOrConwayEraOnwards l r = \case - ShelleyBasedEraShelley -> l ShelleyToBabbageEraShelley - ShelleyBasedEraAllegra -> l ShelleyToBabbageEraAllegra - ShelleyBasedEraMary -> l ShelleyToBabbageEraMary - ShelleyBasedEraAlonzo -> l ShelleyToBabbageEraAlonzo - ShelleyBasedEraBabbage -> l ShelleyToBabbageEraBabbage - ShelleyBasedEraConway -> r ConwayEraOnwardsConway - ShelleyBasedEraDijkstra -> r ConwayEraOnwardsDijkstra From 78b9abc5e769560209440bee06af899ea2b2ed1e Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Thu, 3 Sep 2026 11:57:10 -0400 Subject: [PATCH 50/62] Add changelog fragment --- ...remove-case-shelley-era-only-or-allegra-era-onwards.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/remove-case-shelley-era-only-or-allegra-era-onwards.yml diff --git a/.changes/remove-case-shelley-era-only-or-allegra-era-onwards.yml b/.changes/remove-case-shelley-era-only-or-allegra-era-onwards.yml new file mode 100644 index 0000000000..bac242c345 --- /dev/null +++ b/.changes/remove-case-shelley-era-only-or-allegra-era-onwards.yml @@ -0,0 +1,7 @@ +project: cardano-api +pr: 1326 +kind: + - breaking + - refactoring +description: | + Removed the era case combinators `caseByronOrShelleyBasedEra` and `caseShelleyToBabbageOrConwayEraOnwards`, along with the internal `caseShelleyEraOnlyOrAllegraEraOnwards`, and the now-empty `Cardano.Api.Era.Internal.Case` module. Use `inEonForEra` / `inEonForShelleyBasedEra` with the appropriate eon, or match on the era constructors where both branches need era constraints. From 3f476c6da90901f19549719d2d35cd71dd96935e Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Thu, 3 Sep 2026 14:08:25 +0200 Subject: [PATCH 51/62] cardano-rpc: Encapsulate NodeKernelAccess internals Stop exporting the NodeKernelAccess record's fields. The node kernel state is reachable only through Cardano.Rpc.Server.NodeKernelAccess's functions (nodeKernelSystemStart, securityParam, genesisConfig, readEraHistory, readChainTipHeader), so that module is the single place that reads the record directly. The record itself lives in the unexposed Cardano.Rpc.Server.NodeKernelAccess.Internal.Type module (per ADR-009), which only the environment wiring imports. --- cardano-rpc/cardano-rpc.cabal | 4 +- .../src/Cardano/Rpc/Server/Internal/Env.hs | 2 +- .../src/Cardano/Rpc/Server/Internal/Monad.hs | 2 +- .../Rpc/Server/Internal/UtxoRpc/Query.hs | 9 +- .../Rpc/Server/Internal/UtxoRpc/Sync.hs | 37 ++++---- .../Server/Internal/UtxoRpc/Type/Genesis.hs | 2 +- .../Cardano/Rpc/Server/NodeKernelAccess.hs | 87 +++++++++++++++---- .../NodeKernelAccess/{ => Internal}/Type.hs | 18 ++-- 8 files changed, 111 insertions(+), 50 deletions(-) rename cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/{ => Internal}/Type.hs (87%) diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index 9b33d6ea22..25444753ae 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -81,10 +81,10 @@ library Cardano.Rpc.Server.Internal.UtxoRpc.Type.TxEval Cardano.Rpc.Server.Internal.UtxoRpc.Type.TxOutput Cardano.Rpc.Server.NodeKernelAccess - Cardano.Rpc.Server.NodeKernelAccess.Type other-modules: Cardano.Rpc.Server.Internal.Orphans + Cardano.Rpc.Server.NodeKernelAccess.Internal.Type Paths_cardano_rpc autogen-modules: @@ -125,6 +125,8 @@ library mempack, microlens, network, + ouroboros-consensus, + ouroboros-consensus:cardano, proto-lens >=0.7.1.7, proto-lens-protobuf-types, random, diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Env.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Env.hs index 78387ab824..10a762a0e3 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Env.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Env.hs @@ -10,7 +10,7 @@ where import Cardano.Api import Cardano.Rpc.Server.Config import Cardano.Rpc.Server.Internal.Tracing -import Cardano.Rpc.Server.NodeKernelAccess.Type (NodeKernelAccess) +import Cardano.Rpc.Server.NodeKernelAccess.Internal.Type (NodeKernelAccess) import Control.Tracer (Tracer) import Data.IORef diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Monad.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Monad.hs index 2cfd85e897..30d82694a7 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Monad.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Monad.hs @@ -24,7 +24,7 @@ where import Cardano.Api import Cardano.Rpc.Server.Internal.Env import Cardano.Rpc.Server.Internal.Tracing -import Cardano.Rpc.Server.NodeKernelAccess.Type (NodeKernelAccess) +import Cardano.Rpc.Server.NodeKernelAccess.Internal.Type (NodeKernelAccess) import RIO diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs index b89d860df1..3fd061e36f 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs @@ -201,14 +201,11 @@ readGenesisMethod -> m (Proto UtxoRpc.ReadGenesisResponse) readGenesisMethod _req = do -- TODO: field masks are ignored for now (same as readParamsMethod) - NodeKernelAccess - { genesisConfig = - genesisBundle@GenesisBundle + nodeKernelAccess <- grabNodeKernelAccess + let genesisBundle@GenesisBundle { shelleyGenesisHash , shelleyGenesis = (shelleyGenesisFile, shelleyGenesisCache) - } - } <- - grabNodeKernelAccess + } = genesisConfig nodeKernelAccess shelleyGenesis <- readThroughCache shelleyGenesisCache $ readShelleyGenesisWithInitialFunds shelleyGenesisFile shelleyGenesisHash diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs index 6c28b6d3cc..df19393fd5 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs @@ -66,7 +66,7 @@ fetchBlockMethod request = do <> tshow maxFetchBlockRefs <> "; batch your requests" - nodeKernelAccess@NodeKernelAccess{systemStart, readEraHistory} <- grabNodeKernelAccess + nodeKernelAccess <- grabNodeKernelAccess blocks <- forM (request ^. U5c.ref) $ \blockRef -> do (slot, headerHash) <- blockRefToPoint blockRef let throwNotFound = @@ -77,7 +77,8 @@ fetchBlockMethod request = do <> serialiseToRawBytesHexText headerHash (rawBytes, blockInMode) <- fetchBlock nodeKernelAccess slot headerHash >>= maybe throwNotFound pure - timestamp <- slotTimestampOrThrow systemStart readEraHistory slot + timestamp <- + slotTimestampOrThrow (nodeKernelSystemStart nodeKernelAccess) (readEraHistory nodeKernelAccess) slot pure $ mkAnyChainBlock rawBytes blockInMode timestamp pure $ defMessage & U5c.block .~ blocks @@ -94,8 +95,11 @@ readTipMethod => Proto U5c.ReadTipRequest -> m (Proto U5c.ReadTipResponse) readTipMethod _request = do - NodeKernelAccess{chainDb, systemStart, readEraHistory} <- grabNodeKernelAccess - tip <- readTipBlockRef chainDb (slotTimestampOrThrow systemStart readEraHistory) + nodeKernelAccess <- grabNodeKernelAccess + tip <- + readTipBlockRef + nodeKernelAccess + (slotTimestampOrThrow (nodeKernelSystemStart nodeKernelAccess) (readEraHistory nodeKernelAccess)) pure $ defMessage & U5c.maybe'tip .~ tip -- | Handle the @FollowTip@ SyncService RPC method: stream fully parsed @@ -115,7 +119,7 @@ readTipMethod _request = do -- slot and hash only, like ChainSync's @MsgRollBackward@. The tracked -- window is sized to the node's security parameter /k/, so no rollback -- consensus can produce falls outside it (see --- 'Cardano.Rpc.Server.NodeKernelAccess.Type.NodeKernelAccess'). +-- 'Cardano.Rpc.Server.NodeKernelAccess.securityParam'). -- Every response also carries the current chain tip. -- -- Errors: @INVALID_ARGUMENT@ if an intersection block ref has an invalid @@ -131,8 +135,7 @@ followTipMethod -- ^ Callback used to send each streamed response -> m () followTipMethod request send = do - nodeKernelAccess@NodeKernelAccess{chainDb, systemStart, readEraHistory, securityParam} <- - grabNodeKernelAccess + nodeKernelAccess <- grabNodeKernelAccess requestedPoints <- traverse blockRefToIntersectPoint (request ^. U5c.intersect) withFollower nodeKernelAccess $ \follower -> do -- an empty intersect list follows from the current tip; resolving it @@ -140,19 +143,19 @@ followTipMethod request send = do -- for "the current tip point"), so this step stays here rather than -- moving into 'followTipStream', which only takes an already-resolved, -- non-empty point list - let slotTimestamp = slotTimestampOrThrow systemStart readEraHistory + let slotTimestamp = slotTimestampOrThrow (nodeKernelSystemStart nodeKernelAccess) (readEraHistory nodeKernelAccess) startPoints <- if null requestedPoints then do - tipHeader <- liftIO $ Consensus.getTipHeader chainDb + tipHeader <- readChainTipHeader nodeKernelAccess pure [maybe ChainPointAtGenesis tipHeaderPoint tipHeader] else pure requestedPoints followTipStream follower - (readTipBlockRef chainDb slotTimestamp) + (readTipBlockRef nodeKernelAccess slotTimestamp) slotTimestamp (fetchBlockByChainPoint nodeKernelAccess) - (fromIntegral . L.unNonZero $ Consensus.maxRollbacks securityParam) + (fromIntegral . L.unNonZero $ Consensus.maxRollbacks (securityParam nodeKernelAccess)) send startPoints @@ -262,7 +265,7 @@ followTipStream -> Int -- ^ How many applied points to track for undo re-fetch. In production -- this is the node's security parameter /k/ - -- ('Cardano.Rpc.Server.NodeKernelAccess.Type.securityParam'). Consensus + -- ('Cardano.Rpc.Server.NodeKernelAccess.securityParam'). Consensus -- never rolls back more than /k/ blocks, so tracking /k/ points covers -- every rollback the protocol can produce, on any network. An entry -- costs roughly 40 bytes, so the window costs about @40 * k@ bytes per @@ -378,12 +381,12 @@ followTipStream ChainFollower{nextChange, findIntersect} readTip slotTimestamp f -- 'mkTipBlockRef', or 'Nothing' at origin. readTipBlockRef :: MonadIO m - => Consensus.ChainDB IO (Consensus.CardanoBlock Consensus.StandardCrypto) + => NodeKernelAccess -> (SlotNo -> m UTCTime) -- ^ Convert a slot to its wall-clock timestamp -> m (Maybe (Proto U5c.BlockRef)) -readTipBlockRef chainDb slotTimestamp = do - tipHeader <- liftIO $ Consensus.getTipHeader chainDb +readTipBlockRef nodeKernelAccess slotTimestamp = do + tipHeader <- readChainTipHeader nodeKernelAccess forM tipHeader $ \header -> mkTipBlockRef header <$> slotTimestamp (Consensus.blockSlot header) @@ -396,8 +399,8 @@ slotTimestampOrThrow -- ^ Read current era history from the ledger state -> SlotNo -> m UTCTime -slotTimestampOrThrow systemStart readEraHistory slot = do - eraHistory <- readEraHistory +slotTimestampOrThrow systemStart readEraHistoryAction slot = do + eraHistory <- readEraHistoryAction slotToUTCTime systemStart eraHistory slot & either (const throwPastHorizon) pure where diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs index cbaa534d92..3dbbad14d3 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs @@ -35,7 +35,7 @@ import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Certificate , keyHashToBytes , scriptHashToBytes ) -import Cardano.Rpc.Server.NodeKernelAccess.Type (GenesisBundle (..)) +import Cardano.Rpc.Server.NodeKernelAccess.Internal.Type (GenesisBundle (..)) import Cardano.Chain.Common qualified as Byron ( KeyHash diff --git a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs index 51223ccc39..caa0ea0c74 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs @@ -7,7 +7,12 @@ {-# LANGUAGE NoFieldSelectors #-} module Cardano.Rpc.Server.NodeKernelAccess - ( NodeKernelAccess (..) + ( Type.NodeKernelAccess + , nodeKernelSystemStart + , securityParam + , genesisConfig + , readEraHistory + , readChainTipHeader , GenesisBundle (..) , mkNodeKernelAccess , fetchBlock @@ -23,7 +28,11 @@ import Cardano.Api.Consensus qualified as Consensus import Cardano.Rpc.Server.Internal.Monad (MonadRpc, grab) import Cardano.Rpc.Server.Internal.TimedCache (newTimedCache) import Cardano.Rpc.Server.Internal.Tracing -import Cardano.Rpc.Server.NodeKernelAccess.Type +import Cardano.Rpc.Server.NodeKernelAccess.Internal.Type (GenesisBundle (..)) +import Cardano.Rpc.Server.NodeKernelAccess.Internal.Type qualified as Type + +import Ouroboros.Consensus.Cardano.Block (CardanoEras) +import Ouroboros.Consensus.HardFork.History qualified as History import RIO (MonadUnliftIO, atomically, bracket, throwIO, withRunInIO) @@ -52,27 +61,38 @@ mkNodeKernelAccess -- ^ Block type witness -> Consensus.NodeKernel IO addrNTN addrNTC blk -- ^ Consensus node kernel - -> m (Maybe NodeKernelAccess) + -> m (Maybe Type.NodeKernelAccess) mkNodeKernelAccess tracer shelleyGenesisHash shelleyGenesisFile blockType kernel = case blockType of Consensus.CardanoBlockType -> do - genesisConfig <- readGenesisBundle shelleyGenesisHash shelleyGenesisFile topLevelConfig - pure $ Just NodeKernelAccess{chainDb, systemStart, readEraHistory, securityParam, genesisConfig} + genesisBundle <- readGenesisBundle shelleyGenesisHash shelleyGenesisFile topLevelConfig + pure $ + Just + Type.NodeKernelAccess + { Type.chainDb = chainDb + , Type.systemStart = Consensus.nodeSystemStart topLevelConfig + , Type.readHardForkSummary = readHardForkSummary' + , Type.securityParam = Consensus.configSecurityParam topLevelConfig + , Type.genesisConfig = genesisBundle + } where chainDb = Consensus.getChainDB kernel topLevelConfig = Consensus.getTopLevelConfig kernel ledgerConfig = Consensus.configLedger topLevelConfig - systemStart = Consensus.nodeSystemStart topLevelConfig - securityParam = Consensus.configSecurityParam topLevelConfig + -- Primed because 'Cardano.Rpc.Server.NodeKernelAccess' also exports an + -- accessor of the same name; this is the local action that feeds the + -- corresponding record field above. + -- -- Read the current ledger state (cheap STM TVar read) and recompute -- the era summary on every call - O(number_of_eras). -- This is the same approach consensus uses for GetInterpreter queries -- (interpretQueryHardFork); neither path caches the summary. -- RunWithCachedSummary exists but is private to the blockchain time thread. - readEraHistory :: MonadIO n => n EraHistory - readEraHistory = liftIO $ do + readHardForkSummary' + :: MonadIO n + => n (History.Summary (CardanoEras Consensus.StandardCrypto)) + readHardForkSummary' = liftIO $ do extLedger <- atomically $ Consensus.getCurrentLedger chainDb - pure . EraHistory . Consensus.mkInterpreter $ - Consensus.hardForkSummary ledgerConfig (Consensus.ledgerState extLedger) + pure $ Consensus.hardForkSummary ledgerConfig (Consensus.ledgerState extLedger) _ -> do -- unsupported block type traceWith tracer . inject . TraceRpcUnsupportedBlockType . pack $ show blockType @@ -134,7 +154,7 @@ readGenesisBundle shelleyGenesisHash shelleyGenesisFile topLevelConfig = -- gRPC UNAVAILABLE if the node kernel has not yet initialised. grabNodeKernelAccess :: MonadRpc e m - => m NodeKernelAccess + => m Type.NodeKernelAccess grabNodeKernelAccess = grab >>= liftIO . readIORef >>= \case Nothing -> @@ -148,11 +168,46 @@ grabNodeKernelAccess = Just nodeKernelAccess -> pure nodeKernelAccess +-- | The network's system start time, extracted from genesis config. +-- Used together with 'readEraHistory' to convert slots to wall-clock time. +nodeKernelSystemStart :: Type.NodeKernelAccess -> SystemStart +nodeKernelSystemStart Type.NodeKernelAccess{Type.systemStart = value} = value + +-- | The protocol security parameter /k/: consensus never rolls back more +-- than /k/ blocks. +securityParam :: Type.NodeKernelAccess -> Consensus.SecurityParam +securityParam Type.NodeKernelAccess{Type.securityParam = value} = value + +-- | The network's genesis configuration. +genesisConfig :: Type.NodeKernelAccess -> GenesisBundle +genesisConfig Type.NodeKernelAccess{Type.genesisConfig = value} = value + +-- | Read the raw hard-fork era summary from the current ledger state, with +-- the era boundaries directly accessible. +readHardForkSummary + :: MonadIO m + => Type.NodeKernelAccess + -> m (History.Summary (CardanoEras Consensus.StandardCrypto)) +readHardForkSummary Type.NodeKernelAccess{Type.readHardForkSummary = action} = action + +-- | Read current era history from the ledger state: the hard-fork era +-- summary wrapped into the opaque interpreter used for slot/time conversion +-- queries. +readEraHistory :: MonadIO m => Type.NodeKernelAccess -> m EraHistory +readEraHistory access = EraHistory . Consensus.mkInterpreter <$> readHardForkSummary access + +-- | Read the current chain tip header from ChainDB, or 'Nothing' at origin. +readChainTipHeader + :: MonadIO m + => Type.NodeKernelAccess + -> m (Maybe (Consensus.Header (Consensus.CardanoBlock Consensus.StandardCrypto))) +readChainTipHeader Type.NodeKernelAccess{Type.chainDb = chainDb} = liftIO $ Consensus.getTipHeader chainDb + -- | Fetch a raw block and its parsed era-contextualised form from ChainDB -- by slot and header hash. fetchBlock :: MonadIO m - => NodeKernelAccess + => Type.NodeKernelAccess -- ^ Node kernel access handle -> SlotNo -- ^ Block slot number @@ -160,7 +215,7 @@ fetchBlock -- ^ Block header hash -> m (Maybe (ByteString, BlockInMode)) -- ^ Raw CBOR bytes and the block in era context, or 'Nothing' if not found -fetchBlock NodeKernelAccess{chainDb} slot (HeaderHash shortHash) = do +fetchBlock Type.NodeKernelAccess{Type.chainDb = chainDb} slot (HeaderHash shortHash) = do let point = Consensus.RealPoint slot (Consensus.OneEraHash shortHash) component = (,) <$> fmap BSL.toStrict Consensus.GetRawBlock <*> fmap fromConsensusBlock Consensus.GetBlock liftIO $ Consensus.getBlockComponent chainDb component point @@ -201,10 +256,10 @@ data ChainFollower = ChainFollower -- ChainSync client, so one follower per stream scales the same way. withFollower :: MonadUnliftIO m - => NodeKernelAccess + => Type.NodeKernelAccess -> (ChainFollower -> m a) -> m a -withFollower NodeKernelAccess{chainDb} action = +withFollower Type.NodeKernelAccess{Type.chainDb = chainDb} action = withRunInIO $ \runInIO -> Consensus.withRegistry $ \registry -> bracket diff --git a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Internal/Type.hs similarity index 87% rename from cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs rename to cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Internal/Type.hs index 1e035a7d95..2213e45a92 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Internal/Type.hs @@ -2,15 +2,14 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE NoFieldSelectors #-} -module Cardano.Rpc.Server.NodeKernelAccess.Type +module Cardano.Rpc.Server.NodeKernelAccess.Internal.Type ( NodeKernelAccess (..) , GenesisBundle (..) ) where import Cardano.Api - ( EraHistory - , FileDirection (In) + ( FileDirection (In) , GenesisHashShelley , ShelleyGenesisFile , SystemStart @@ -22,6 +21,8 @@ import Cardano.Chain.Genesis qualified as Byron (Config) import Cardano.Ledger.Alonzo.Genesis qualified as L (AlonzoGenesis) import Cardano.Ledger.Conway.Genesis qualified as L (ConwayGenesis) import Cardano.Ledger.Shelley.Genesis qualified as L (ShelleyGenesis) +import Ouroboros.Consensus.Cardano.Block (CardanoEras) +import Ouroboros.Consensus.HardFork.History qualified as History import Control.Monad.IO.Class (MonadIO) @@ -32,12 +33,15 @@ data NodeKernelAccess = NodeKernelAccess -- ^ Handle to the consensus chain database , systemStart :: SystemStart -- ^ Network system start time, extracted from genesis config. - -- Used together with 'readEraHistory' to convert slots to wall-clock time. - , readEraHistory :: forall m. MonadIO m => m EraHistory - -- ^ Read current era history from the ledger state. + -- Used together with the era history to convert slots to wall-clock time. + , readHardForkSummary + :: forall m + . MonadIO m + => m (History.Summary (CardanoEras Consensus.StandardCrypto)) + -- ^ Read the hard-fork era summary from the current ledger state. -- This is a separate read from 'chainDb', but the inconsistency is -- always safe: the ledger state is at or ahead of any block in ChainDB, - -- and era summaries only grow, so the returned history always covers the + -- and era summaries only grow, so the summary always covers the -- slot of any block fetched from ChainDB. , securityParam :: Consensus.SecurityParam -- ^ The protocol security parameter /k/: consensus never rolls back more From fcfe27a54e1501c558ce34b75d10b36972693a02 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Thu, 3 Sep 2026 13:34:36 +0200 Subject: [PATCH 52/62] cardano-rpc: Implement ReadEraSummary gRPC method Serve era summaries from the node kernel's hard-fork history: era name, start and end boundaries (Unix-epoch milliseconds, slot, epoch). The current era's end is left unset (no well-defined ending yet) and per-era protocol parameters are left unset (the node keeps no historical parameters; use ReadParams instead). --- .../20260903_cardano_rpc_read_era_summary.yml | 7 ++ cardano-rpc/README.md | 2 +- cardano-rpc/cardano-rpc.cabal | 7 ++ cardano-rpc/src/Cardano/Rpc/Server.hs | 2 +- .../Cardano/Rpc/Server/Internal/Tracing.hs | 4 + .../Rpc/Server/Internal/UtxoRpc/Query.hs | 16 +++ .../Rpc/Server/Internal/UtxoRpc/Type.hs | 2 + .../Internal/UtxoRpc/Type/EraSummary.hs | 87 +++++++++++++ .../Cardano/Rpc/Server/NodeKernelAccess.hs | 1 + .../Test/Cardano/Rpc/EraSummary.hs | 115 ++++++++++++++++++ 10 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 .changes/20260903_cardano_rpc_read_era_summary.yml create mode 100644 cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/EraSummary.hs create mode 100644 cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/EraSummary.hs diff --git a/.changes/20260903_cardano_rpc_read_era_summary.yml b/.changes/20260903_cardano_rpc_read_era_summary.yml new file mode 100644 index 0000000000..4d299ca307 --- /dev/null +++ b/.changes/20260903_cardano_rpc_read_era_summary.yml @@ -0,0 +1,7 @@ +project: cardano-rpc +pr: 1325 +kind: + - feature + - breaking +description: | + Implement the `ReadEraSummary` gRPC method, returning the era name and the start and end boundaries (Unix-epoch milliseconds, slot, epoch) of every era in the chain's history. The `NodeKernelAccess` type is now abstract; use the functions of `Cardano.Rpc.Server.NodeKernelAccess` instead of its record fields. diff --git a/cardano-rpc/README.md b/cardano-rpc/README.md index 2a894b2bc9..ea7f110aad 100644 --- a/cardano-rpc/README.md +++ b/cardano-rpc/README.md @@ -21,7 +21,7 @@ Use a dedicated chain indexing service for those. | [ReadData](https://utxorpc.org/query/spec/#readdatarequest) | ❌ Not supported, needs a chain indexer | | [ReadTx](https://utxorpc.org/query/spec/#queryservice) | ❌ Not supported, needs a chain indexer | | [ReadGenesis](https://utxorpc.org/query/spec/#queryservice) | ✅ Supported | -| [ReadEraSummary](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | +| [ReadEraSummary](https://utxorpc.org/query/spec/#queryservice) | ✅ Supported | | [ReadState](https://utxorpc.org/query/spec/#queryservice) | ⬜ Not supported | ### [SubmitService](https://utxorpc.org/submit/spec/) diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index 25444753ae..cb37193147 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -71,6 +71,7 @@ library Cardano.Rpc.Server.Internal.UtxoRpc.Type.Byron Cardano.Rpc.Server.Internal.UtxoRpc.Type.Certificate Cardano.Rpc.Server.Internal.UtxoRpc.Type.ChainPoint + Cardano.Rpc.Server.Internal.UtxoRpc.Type.EraSummary Cardano.Rpc.Server.Internal.UtxoRpc.Type.Genesis Cardano.Rpc.Server.Internal.UtxoRpc.Type.Governance Cardano.Rpc.Server.Internal.UtxoRpc.Type.PlutusData @@ -110,6 +111,7 @@ library cardano-ledger-dijkstra, cardano-ledger-shelley, cardano-rpc:gen, + cardano-slotting, containers, contra-tracer, data-default, @@ -131,6 +133,7 @@ library proto-lens-protobuf-types, random, rio, + sop-extras, strict-sop-core, text, time, @@ -185,6 +188,7 @@ test-suite cardano-rpc-test cardano-ledger-shelley, cardano-ledger-shelley:testlib, cardano-rpc, + cardano-slotting, containers, formatting, grpc-spec, @@ -193,10 +197,12 @@ test-suite cardano-rpc-test hedgehog-quickcheck, memory, mtl, + ouroboros-consensus, ouroboros-consensus:cardano, proto-lens, rio, scientific, + sop-extras, tasty, tasty-hedgehog, text, @@ -211,6 +217,7 @@ test-suite cardano-rpc-test build-tool-depends: tasty-discover:tasty-discover other-modules: Test.Cardano.Rpc.ByronTx + Test.Cardano.Rpc.EraSummary Test.Cardano.Rpc.Eval Test.Cardano.Rpc.FetchBlockTx Test.Cardano.Rpc.FollowTipStream diff --git a/cardano-rpc/src/Cardano/Rpc/Server.hs b/cardano-rpc/src/Cardano/Rpc/Server.hs index 0a224d493c..4fa6c51ef5 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server.hs @@ -71,7 +71,7 @@ methodsUtxoRpc => Methods m (ProtobufMethodsOf UtxoRpc.QueryService) methodsUtxoRpc = UnsupportedMethod -- readData - . UnsupportedMethod -- readEraSummary + . Method (mkNonStreaming $ wrapInSpan TraceRpcQueryReadEraSummarySpan . readEraSummaryMethod) . Method (mkNonStreaming $ wrapInSpan TraceRpcQueryReadGenesisSpan . readGenesisMethod) . Method (mkNonStreaming $ wrapInSpan TraceRpcQueryParamsSpan . readParamsMethod) . UnsupportedMethod -- readState diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs index 94a554e370..f35c97b1eb 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs @@ -37,6 +37,8 @@ data TraceRpcQuery TraceRpcQuerySearchUtxosSpan TraceSpanEvent | -- | Span trace marking ReadGenesis query TraceRpcQueryReadGenesisSpan TraceSpanEvent + | -- | Span trace marking ReadEraSummary query + TraceRpcQueryReadEraSummarySpan TraceSpanEvent deriving Show instance Pretty TraceRpc where @@ -70,6 +72,8 @@ instance Pretty TraceRpcQuery where TraceRpcQuerySearchUtxosSpan (SpanEnd _) -> "Finished query search UTXO method" TraceRpcQueryReadGenesisSpan (SpanBegin _) -> "Started query read genesis method" TraceRpcQueryReadGenesisSpan (SpanEnd _) -> "Finished query read genesis method" + TraceRpcQueryReadEraSummarySpan (SpanBegin _) -> "Started query read era summary method" + TraceRpcQueryReadEraSummarySpan (SpanEnd _) -> "Finished query read era summary method" instance Error TraceRpcQuery where prettyError = pretty diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs index 3fd061e36f..14d87c8350 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs @@ -16,6 +16,7 @@ module Cardano.Rpc.Server.Internal.UtxoRpc.Query , readUtxosMethod , searchUtxosMethod , readGenesisMethod + , readEraSummaryMethod , paginateByTxIn ) where @@ -264,6 +265,21 @@ readShelleyGenesisWithInitialFunds shelleyGenesisFile@(File path) bootGenesisHas <> ": " <> Text.pack reason +-- | Handle the @ReadEraSummary@ RPC method. +-- Returns the node's hard-fork era summary: one entry per era the node's +-- ledger state has seen so far, with name and start/end boundaries. See +-- 'eraSummariesToProto' for exactly which fields are populated. +readEraSummaryMethod + :: MonadRpc e m + => Proto UtxoRpc.ReadEraSummaryRequest + -> m (Proto UtxoRpc.ReadEraSummaryResponse) +readEraSummaryMethod _req = do + -- TODO: field masks are ignored for now (same as readParamsMethod) + nodeKernelAccess <- grabNodeKernelAccess + summary <- readHardForkSummary nodeKernelAccess + pure $ + defMessage & U5c.cardano .~ eraSummariesToProto (nodeKernelSystemStart nodeKernelAccess) summary + -- | The CAIP-2 chain identifier for a Cardano network, keyed on the Shelley -- network magic. -- This follows Dolos, the reference UTxO RPC implementation: the three diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type.hs index 4657fcdf71..0e8cbc8242 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type.hs @@ -5,6 +5,7 @@ module Cardano.Rpc.Server.Internal.UtxoRpc.Type ( utxoRpcPParamsToProtocolParams , genesisBundleToProto + , eraSummariesToProto , utxoToUtxoRpcAnyUtxoData , txInTxOutToAnyUtxoData , anyUtxoDataUtxoRpcToUtxo @@ -31,6 +32,7 @@ where import Cardano.Rpc.Server.Internal.UtxoRpc.Type.BigInt import Cardano.Rpc.Server.Internal.UtxoRpc.Type.ChainPoint +import Cardano.Rpc.Server.Internal.UtxoRpc.Type.EraSummary import Cardano.Rpc.Server.Internal.UtxoRpc.Type.Genesis import Cardano.Rpc.Server.Internal.UtxoRpc.Type.PlutusData import Cardano.Rpc.Server.Internal.UtxoRpc.Type.ProtocolParameters diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/EraSummary.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/EraSummary.hs new file mode 100644 index 0000000000..9cdf206845 --- /dev/null +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/EraSummary.hs @@ -0,0 +1,87 @@ +{-# LANGUAGE LambdaCase #-} + +-- | Conversion of the node's hard-fork era summary to the UTxO RPC +-- 'U5c.EraSummaries' message. +module Cardano.Rpc.Server.Internal.UtxoRpc.Type.EraSummary + ( eraSummariesToProto + ) +where + +import Cardano.Api (AnyCardanoEra (..), SystemStart, docToText, pretty, unEpochNo, unSlotNo) +import Cardano.Api.Consensus qualified as Consensus +import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as U5c +import Cardano.Rpc.Server.Internal.UtxoRpc.Type.ChainPoint (utcTimeToMs) + +import Cardano.Slotting.Time (fromRelativeTime) +import Ouroboros.Consensus.Cardano.Block (CardanoEras) +import Ouroboros.Consensus.HardFork.History qualified as History + +import RIO + +import Data.ProtoLens (defMessage) +import Data.SOP.NonEmpty (nonEmptyToList) +import Data.Text qualified as Text +import Network.GRPC.Spec + +-- | Convert the node's hard-fork era summary to the UTxO RPC +-- 'U5c.EraSummaries' message. +-- +-- Every era except the last gets its 'U5c.maybe''end' populated from the +-- confirmed era transition. The last era's end is always left unset, even +-- when consensus already supplies a bound for it: consensus cannot +-- distinguish a confirmed transition from the safe-zone forecast horizon, so +-- the spec's "if the era has a well-defined ending" only ever holds for +-- non-final eras here. 'History.EraUnbounded' likewise maps to unset. +-- +-- 'U5c.protocolParams' is left unset for every era: the node does not keep +-- historical per-era protocol parameters. Use @ReadParams@ for the current +-- era's parameters. +eraSummariesToProto + :: SystemStart + -> History.Summary (CardanoEras Consensus.StandardCrypto) + -> Proto U5c.EraSummaries +eraSummariesToProto systemStart summary = + defMessage & U5c.summaries .~ zipWith3 mkEraSummary eraNames isLastEra eraEntries + where + -- All eras in chronological order, i.e. the same order as the summary's + -- entries: 'History.Summary' has no era name field, an entry's era is its + -- position, so the names are zipped in positionally. + eraNames :: [Text] + eraNames = + [ Text.toLower . docToText $ pretty era + | AnyCardanoEra era <- [minBound .. maxBound] + ] + + eraEntries :: [History.EraSummary] + eraEntries = nonEmptyToList (History.getSummary summary) + + -- 'eraEntries' is always non-empty ('Summary' wraps a non-empty list), so + -- this always ends in exactly one 'True'. + isLastEra :: [Bool] + isLastEra = replicate (length eraEntries - 1) False <> [True] + + mkEraSummary :: Text -> Bool -> History.EraSummary -> Proto U5c.EraSummary + mkEraSummary name isLast entry = + defMessage + & U5c.name .~ name + & U5c.start .~ boundToProto (History.eraStart entry) + & U5c.maybe'end .~ if isLast then Nothing else endToProto (History.eraEnd entry) + + endToProto :: History.EraEnd -> Maybe (Proto U5c.EraBoundary) + endToProto = \case + History.EraEnd bound -> Just (boundToProto bound) + History.EraUnbounded -> Nothing + + boundToProto :: History.Bound -> Proto U5c.EraBoundary + boundToProto bound = + defMessage + & U5c.time .~ boundTimeMs bound + & U5c.slot .~ unSlotNo (History.boundSlot bound) + & U5c.epoch .~ unEpochNo (History.boundEpoch bound) + + -- Reuses 'utcTimeToMs', the same millisecond conversion 'mkChainPointMsg' + -- and 'mkTipBlockRef' use for their proto timestamps, for consistency + -- across the API. 'fromRelativeTime' adds the boundary's 'RelativeTime' to + -- the system start with 'Pico'-precision arithmetic throughout. + boundTimeMs :: History.Bound -> Word64 + boundTimeMs bound = utcTimeToMs (fromRelativeTime systemStart (History.boundTime bound)) diff --git a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs index caa0ea0c74..f06f6d4ae5 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs @@ -12,6 +12,7 @@ module Cardano.Rpc.Server.NodeKernelAccess , securityParam , genesisConfig , readEraHistory + , readHardForkSummary , readChainTipHeader , GenesisBundle (..) , mkNodeKernelAccess diff --git a/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/EraSummary.hs b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/EraSummary.hs new file mode 100644 index 0000000000..f2dc07af17 --- /dev/null +++ b/cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/EraSummary.hs @@ -0,0 +1,115 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeApplications #-} + +module Test.Cardano.Rpc.EraSummary where + +import Cardano.Api (EpochNo (..), SlotNo (..), SystemStart (..)) +import Cardano.Api.Consensus qualified as Consensus +import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as U5c +import Cardano.Rpc.Server.Internal.UtxoRpc.Type (eraSummariesToProto) + +import Cardano.Ledger.BaseTypes (knownNonZeroBounded) +import Cardano.Slotting.Time (RelativeTime (..)) +import Ouroboros.Consensus.BlockchainTime.WallClock.Types (slotLengthFromSec) +import Ouroboros.Consensus.Cardano.Block (CardanoEras) +import Ouroboros.Consensus.HardFork.History qualified as History + +import RIO + +import Data.SOP.NonEmpty (NonEmpty (..)) +import Data.Time.Clock.POSIX (posixSecondsToUTCTime) + +import Hedgehog as H +import Hedgehog.Extras qualified as H + +-- | Placeholder era parameters: 'eraSummariesToProto' never reads them, but +-- an 'History.EraSummary' fixture still needs one. +dummyEraParams :: History.EraParams +dummyEraParams = + History.defaultEraParams + (Consensus.SecurityParam (knownNonZeroBounded @2160)) + (slotLengthFromSec 1) + +mkBound :: SlotNo -> EpochNo -> RelativeTime -> History.Bound +mkBound slot epoch time = + History.Bound + { History.boundTime = time + , History.boundSlot = slot + , History.boundEpoch = epoch + , History.boundPerasRound = History.NoPerasEnabled + } + +mkEraSummary :: History.Bound -> History.EraEnd -> History.EraSummary +mkEraSummary start end = + History.EraSummary + { History.eraStart = start + , History.eraEnd = end + , History.eraParams = dummyEraParams + } + +-- | Two eras: the boundary between them uses a fractional-second +-- 'RelativeTime' to prove the millisecond conversion is exact (rounded to +-- the nearest millisecond, never routed through 'Double'). The second era is +-- last and carries a real 'History.EraEnd' bound, but its end must still +-- come out unset. +hprop_era_summary_multi_era :: Property +hprop_era_summary_multi_era = H.propertyOnce $ do + let systemStart = SystemStart (posixSecondsToUTCTime 0) + + byronStart = mkBound (SlotNo 0) (EpochNo 0) (RelativeTime 0) + -- 172800.6789s proves the ms conversion is exact fixed-point via the + -- shared 'utcTimeToMs' (nearest-ms rounding): .6789s -> 679ms. A + -- Double-based path, or a floor instead of a round, would give 678. + transition = mkBound (SlotNo 21600) (EpochNo 1) (RelativeTime 172800.6789) + shelleyEnd = mkBound (SlotNo 43200) (EpochNo 2) (RelativeTime 259200) + + byronSummary = mkEraSummary byronStart (History.EraEnd transition) + shelleySummary = mkEraSummary transition (History.EraEnd shelleyEnd) + + summary :: History.Summary (CardanoEras Consensus.StandardCrypto) + summary = History.Summary (NonEmptyCons byronSummary (NonEmptyOne shelleySummary)) + + proto = eraSummariesToProto systemStart summary + entries = proto ^. U5c.summaries + + length entries === 2 + + byronEntry <- H.nothingFail $ listToMaybe entries + shelleyEntry <- H.nothingFail . listToMaybe $ drop 1 entries + + byronEntry ^. U5c.name === "byron" + byronEntry ^. U5c.start . U5c.time === 0 + byronEntry ^. U5c.start . U5c.slot === 0 + byronEntry ^. U5c.start . U5c.epoch === 0 + H.assertWith (byronEntry ^. U5c.maybe'end) isJust + byronEntry ^. U5c.end . U5c.time === 172800679 + byronEntry ^. U5c.end . U5c.slot === 21600 + byronEntry ^. U5c.end . U5c.epoch === 1 + + shelleyEntry ^. U5c.name === "shelley" + shelleyEntry ^. U5c.start . U5c.time === 172800679 + shelleyEntry ^. U5c.start . U5c.slot === 21600 + shelleyEntry ^. U5c.start . U5c.epoch === 1 + -- Last era: end must be unset even though the fixture supplies a real bound. + H.assertWith (shelleyEntry ^. U5c.maybe'end) isNothing + +-- | A single-era summary (only Byron) has exactly one entry, and that entry +-- has no end, whether or not consensus reports the era as unbounded. +hprop_era_summary_single_era_no_end :: Property +hprop_era_summary_single_era_no_end = H.propertyOnce $ do + let systemStart = SystemStart (posixSecondsToUTCTime 0) + byronStart = mkBound (SlotNo 0) (EpochNo 0) (RelativeTime 0) + byronSummary = mkEraSummary byronStart History.EraUnbounded + + summary :: History.Summary (CardanoEras Consensus.StandardCrypto) + summary = History.Summary (NonEmptyOne byronSummary) + + proto = eraSummariesToProto systemStart summary + entries = proto ^. U5c.summaries + + length entries === 1 + + byronEntry <- H.nothingFail $ listToMaybe entries + byronEntry ^. U5c.name === "byron" + H.assertWith (byronEntry ^. U5c.maybe'end) isNothing From 17201a7adcf8cae69e92707a45c2f775b1150812 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 13 Aug 2026 13:59:03 +1000 Subject: [PATCH 53/62] Updates for crypton/memory/ram changes The package `crypton < 1.1` depends on `memory` and `>= 1.1` depends on `ram`. By dropping the dependency on `memory` and adding the dependency on `ram` we are effectively changing to `crypton >= 1.1`. --- cardano-api/cardano-api.cabal | 2 +- cardano-rpc/cardano-rpc.cabal | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 48b34e6263..a422b83024 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -169,7 +169,6 @@ library fs-api ^>=0.4, io-classes, iproute, - memory, mempack, microlens <0.6, mono-traversable, @@ -187,6 +186,7 @@ library prettyprinter, prettyprinter-ansi-terminal, prettyprinter-configurable ^>=1.36, + ram, random, resource-registry ^>=0.3, safe-exceptions, diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index cb37193147..9a13aa658e 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -123,7 +123,6 @@ library grapesy, grpc-spec, iproute, - memory, mempack, microlens, network, @@ -131,6 +130,7 @@ library ouroboros-consensus:cardano, proto-lens >=0.7.1.7, proto-lens-protobuf-types, + ram, random, rio, sop-extras, @@ -195,11 +195,11 @@ test-suite cardano-rpc-test hedgehog, hedgehog-extras, hedgehog-quickcheck, - memory, mtl, ouroboros-consensus, ouroboros-consensus:cardano, proto-lens, + ram, rio, scientific, sop-extras, From b69b0e552eacc1d5ed363f5e341028039e996db9 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 13 Aug 2026 15:03:03 +1000 Subject: [PATCH 54/62] Use SRPs to pull in dependencies that use crypton >= 1.1 --- cabal.project | 99 +++++++++++++++++++++++++++++++++-- cardano-api/cardano-api.cabal | 10 ++-- 2 files changed, 99 insertions(+), 10 deletions(-) diff --git a/cabal.project b/cabal.project index 5088d490d3..441958eaed 100644 --- a/cabal.project +++ b/cabal.project @@ -48,11 +48,6 @@ jobs: $ncpus semaphore: True -constraints: - -- haskell.nix patch does not work for 1.6.8 - , any.crypton-x509-system < 1.6.8 - - -- WASM compilation specific if arch(wasm32) @@ -166,3 +161,97 @@ if impl(ghc >=9.14) , time-locale-compat:time , with-utf8:base -- cabal-allow-newer end + +-- TEMPORARY: switching to crypton >= 1.1 (which depends on `ram` instead of +-- `memory`) needs cardano-crypto-class-2.6.0.0 (the first version depending +-- on crypton ^>=1.1 and `ram`), but the released ouroboros-consensus-3.0.1.0 +-- pins `cardano-crypto-class ^>=2.3`, which excludes it. The blocks below +-- replicate the (draft, do-not-merge) upstream fix in +-- https://github.com/IntersectMBO/ouroboros-consensus/pull/2213, which widens +-- ouroboros-consensus's bound to also allow cardano-crypto-class-2.6.0.0 and +-- pulls in the handful of other packages that need to move in lockstep with +-- it. Remove all of this once these land upstream and a release picks them up. +allow-newer: + cardano-ledger-mary:cardano-crypto-class, + cardano-ledger-shelley:cardano-crypto-class, + cardano-ledger-binary:cardano-crypto-class, + cardano-ledger-core:cardano-crypto-class, + cardano-protocol:cardano-crypto-class, + cardano-protocol-tpraos:cardano-crypto-class, + kes-agent:cardano-crypto-class, + kes-agent-crypto:cardano-crypto-class, + +source-repository-package + type: git + location: https://github.com/IntersectMBO/ouroboros-consensus + tag: 4da82e0afed5dabbe930d5f5cad5de687428e07b + +-- TEMPORARY: pulls in cardano-base PR #694 (erikd/contra-tracer, not yet +-- merged) https://github.com/IntersectMBO/cardano-base/pull/694, which widens +-- cardano-crypto-class:testlib's contra-tracer bound so it builds against the +-- same contra-tracer version as everything else here. Needed by the +-- ouroboros-consensus pin above. Remove once this PR (or an equivalent fix) +-- is released. +source-repository-package + type: git + location: https://github.com/IntersectMBO/cardano-base + tag: ad3afec8113872652ec8edf19ae1280552ce2a20 + subdir: cardano-crypto-class + +-- TEMPORARY: pulls in kes-agent PR #105 (erikd/contra-tracer, not yet merged) +-- https://github.com/input-output-hk/kes-agent/pull/105, which widens the +-- same contra-tracer bound for kes-agent/kes-agent-crypto, on top of the +-- FixedSizeCodec migration cardano-crypto-class-2.6.0.0 needs. Needed by the +-- ouroboros-consensus pin above. Remove once this PR (or an equivalent fix) +-- is released. +source-repository-package + type: git + location: https://github.com/input-output-hk/kes-agent + tag: 0e9a16c61ecc6b5cc747ae0ebdb718a02eae8ddc + subdir: + kes-agent + kes-agent-crypto + +-- TEMPORARY: pulls in cardano-ledger PR #5999 (erikd/ram, not yet merged) +-- https://github.com/IntersectMBO/cardano-ledger/pull/5999, which switches +-- cardano-crypto-wrapper from `memory` to `ram` so it builds against crypton +-- >=1.1. Needed by the ouroboros-consensus pin above. Remove once this PR (or +-- an equivalent fix) is released. +source-repository-package + type: git + location: https://github.com/IntersectMBO/cardano-ledger + tag: 6def84b5ae0033053feda72f32b1dac41c812e0e + subdir: eras/byron/crypto + +-- TEMPORARY: cardano-addresses-4.0.2 (the latest released on CHaP) still pins +-- `crypton >=0.32 && <1.1` and depends on the standalone `cardano-crypto` +-- package (capped at <1.4.0, i.e. before its own `memory`->`ram` switch). +-- master (unreleased, 4.0.7) has already moved to `crypton >=1.1 && <1.2` / +-- `ram` and dropped the `cardano-crypto` dependency entirely. Remove once a +-- release picks this up. +source-repository-package + type: git + location: https://github.com/IntersectMBO/cardano-addresses + tag: 63c2497f965e96610c6e3df1127dbd0b9481228f + +-- TEMPORARY: grapesy-1.1.1 (the latest released on Hackage) pins +-- `tls >=1.7 && <2.2`, which excludes tls-2.4.3 (needed for crypton >=1.1, +-- since older tls versions pull in crypton-x509-validation <1.7, which caps +-- crypton <1.1). well-typed/grapesy's master widens that to +-- `tls >=1.7 && <2.5`, still version 1.1.1 (unreleased bump). Remove once a +-- release picks this up. +source-repository-package + type: git + location: https://github.com/well-typed/grapesy + tag: bd6af64f69ff89e3a8fc02e2c81262e648f4715d + subdir: + grapesy + grpc-spec + +-- TEMPORARY: this pin (working around a haskell.nix patch that doesn't apply +-- to crypton-x509-system-1.6.8) forces an old crypton-x509-system, which +-- conflicts with the crypton >=1.1 migration above (that needs +-- crypton-x509-system-1.9.0). Dropped for now; revisit once the crypton +-- migration lands and re-check whether the haskell.nix issue still applies. +-- constraints: +-- , any.crypton-x509-system < 1.6.8 diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index a422b83024..1a82e50c71 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -135,8 +135,8 @@ library cardano-base ^>=0.1, cardano-binary, cardano-crypto, - cardano-crypto-class ^>=2.5, - cardano-crypto-wrapper ^>=1.7, + cardano-crypto-class ^>=2.5 || ^>=2.6, + cardano-crypto-wrapper ^>=1.7 || ^>=1.8, cardano-data >=1.0, cardano-diffusion:{api, cardano-diffusion} ^>=1.1, cardano-ledger-allegra >=1.7, @@ -329,8 +329,8 @@ library gen bytestring, cardano-api, cardano-binary >=1.6 && <1.10, - cardano-crypto-class ^>=2.5, - cardano-crypto-wrapper:testlib ^>=1.7, + cardano-crypto-class ^>=2.5 || ^>=2.6, + cardano-crypto-wrapper:testlib ^>=1.7 || ^>=1.8, cardano-ledger-alonzo:{cardano-ledger-alonzo, testlib}, cardano-ledger-byron:testlib, cardano-ledger-conway:testlib, @@ -373,7 +373,7 @@ test-suite cardano-api-test cardano-api:gen, cardano-binary, cardano-crypto, - cardano-crypto-class:{cardano-crypto-class, testlib} ^>=2.5, + cardano-crypto-class:{cardano-crypto-class, testlib} ^>=2.5 || ^>=2.6, cardano-crypto-wrapper:testlib, cardano-data >=1.0, cardano-ledger-alonzo, From 45b4fb879408c0f6ee6ca08c4e8bb60aeadb031c Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 13 Aug 2026 15:18:11 +1000 Subject: [PATCH 55/62] Update all DSIGN operations to FixedSizeCodec ops This change required due to dependence on cardano-crypto-class which in turn was required to support crypton >= 1.1. --- cardano-api/cardano-api.cabal | 11 ++++++++ .../src/Cardano/Api/Crypto/Ed25519Bip32.hs | 25 +++++++++++-------- cardano-rpc/cardano-rpc.cabal | 3 ++- .../Rpc/Server/Internal/UtxoRpc/Type/Byron.hs | 4 +-- .../Rpc/Server/Internal/UtxoRpc/Type/Tx.hs | 16 ++++++------ 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 1a82e50c71..cd96975295 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -132,10 +132,16 @@ library bytestring, bytestring-trie, cardano-addresses ^>=4.0.0, +<<<<<<< HEAD cardano-base ^>=0.1, cardano-binary, cardano-crypto, cardano-crypto-class ^>=2.5 || ^>=2.6, +======= + cardano-binary >=1.9.1, + cardano-crypto, + cardano-crypto-class ^>=2.6, +>>>>>>> e9b8beea3 (Update all DSIGN operations to FixedSizeCodec ops) cardano-crypto-wrapper ^>=1.7 || ^>=1.8, cardano-data >=1.0, cardano-diffusion:{api, cardano-diffusion} ^>=1.1, @@ -328,8 +334,13 @@ library gen base16-bytestring, bytestring, cardano-api, +<<<<<<< HEAD cardano-binary >=1.6 && <1.10, cardano-crypto-class ^>=2.5 || ^>=2.6, +======= + cardano-binary >=1.9.1 && <1.10, + cardano-crypto-class ^>=2.6, +>>>>>>> e9b8beea3 (Update all DSIGN operations to FixedSizeCodec ops) cardano-crypto-wrapper:testlib ^>=1.7 || ^>=1.8, cardano-ledger-alonzo:{cardano-ledger-alonzo, testlib}, cardano-ledger-byron:testlib, diff --git a/cardano-api/src/Cardano/Api/Crypto/Ed25519Bip32.hs b/cardano-api/src/Cardano/Api/Crypto/Ed25519Bip32.hs index 4cf0685b01..fc0a8c7d03 100644 --- a/cardano-api/src/Cardano/Api/Crypto/Ed25519Bip32.hs +++ b/cardano-api/src/Cardano/Api/Crypto/Ed25519Bip32.hs @@ -40,15 +40,6 @@ data Ed25519Bip32DSIGN instance DSIGNAlgorithm Ed25519Bip32DSIGN where type SeedSizeDSIGN Ed25519Bip32DSIGN = 32 - -- \| BIP32-Ed25519 extended verification key size is 64 octets. - type VerKeySizeDSIGN Ed25519Bip32DSIGN = 64 - - -- \| BIP32-Ed25519 extended signing key size is 96 octets. - type SignKeySizeDSIGN Ed25519Bip32DSIGN = 96 - - -- \| BIP32-Ed25519 extended signature size is 64 octets. - type SigSizeDSIGN Ed25519Bip32DSIGN = 64 - -- -- Key and signature types -- @@ -102,21 +93,33 @@ instance DSIGNAlgorithm Ed25519Bip32DSIGN where (mempty :: ScrubbedBytes) (mempty :: ScrubbedBytes) +-- +-- raw serialise/deserialise, in fixed-size raw format +-- + instance FixedSizeCodec (VerKeyDSIGN Ed25519Bip32DSIGN) where + -- \| BIP32-Ed25519 extended verification key size is 64 octets. type FixedSize (VerKeyDSIGN Ed25519Bip32DSIGN) = 64 + rawEncodeFixedSized (VerKeyEd25519Bip32DSIGN vk) = CC.unXPub vk rawDecodeFixedSized bs = either fail (pure . VerKeyEd25519Bip32DSIGN) (CC.xpub bs) instance FixedSizeCodec (SignKeyDSIGN Ed25519Bip32DSIGN) where + -- \| BIP32-Ed25519 extended signing key size is 96 octets. type FixedSize (SignKeyDSIGN Ed25519Bip32DSIGN) = 96 + rawEncodeFixedSized (SignKeyEd25519Bip32DSIGN sk) = xPrvToBytes sk rawDecodeFixedSized bs = - maybe (fail "invalid Ed25519Bip32DSIGN signing key") (pure . SignKeyEd25519Bip32DSIGN) $ - xPrvFromBytes bs + maybe + (fail "Ed25519Bip32DSIGN: invalid SignKeyDSIGN") + (pure . SignKeyEd25519Bip32DSIGN) + (xPrvFromBytes bs) instance FixedSizeCodec (SigDSIGN Ed25519Bip32DSIGN) where + -- \| BIP32-Ed25519 extended signature size is 64 octets. type FixedSize (SigDSIGN Ed25519Bip32DSIGN) = 64 + rawEncodeFixedSized = BA.convert rawDecodeFixedSized bs = either fail (pure . SigEd25519Bip32DSIGN) (CC.xsignature bs) diff --git a/cardano-rpc/cardano-rpc.cabal b/cardano-rpc/cardano-rpc.cabal index 9a13aa658e..4522e3c99e 100644 --- a/cardano-rpc/cardano-rpc.cabal +++ b/cardano-rpc/cardano-rpc.cabal @@ -98,8 +98,9 @@ library bytestring, cardano-api >=11.5, cardano-binary, + cardano-binary >=1.9.1, cardano-crypto, - cardano-crypto-class, + cardano-crypto-class ^>=2.6, cardano-crypto-wrapper, cardano-ledger-allegra, cardano-ledger-alonzo, diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Byron.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Byron.hs index d210b94bd4..3db2468e5a 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Byron.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Byron.hs @@ -15,7 +15,7 @@ import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as U5c import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as UtxoRpc import Cardano.Rpc.Server.Internal.Orphans () -import Cardano.Binary.FixedSizeCodec (rawEncodeFixedSized) +import Cardano.Binary.FixedSizeCodec qualified as DSIGN import Cardano.Chain.Block qualified as Byron (ABlockOrBoundary (..), blockTxPayload) import Cardano.Chain.Common (lovelaceToInteger) import Cardano.Chain.UTxO @@ -99,7 +99,7 @@ byronTxToUtxoRpcTx txAux = do bootstrapWitnesses :: [Proto UtxoRpc.BootstrapWitness] bootstrapWitnesses = [ defMessage - & U5c.vkey .~ rawEncodeFixedSized vkey + & U5c.vkey .~ DSIGN.rawEncodeFixedSized vkey & U5c.signature .~ WC.unXSignature xSignature & U5c.chainCode .~ SBS.fromShort (byteArrayToShortByteString (L.unChainCode chainCode)) | VKWitness verificationKey (Byron.Signature xSignature) <- witnesses diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs index 21be2fa74c..66b9b7c305 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs @@ -43,7 +43,7 @@ import Cardano.Rpc.Server.Internal.UtxoRpc.Type.TxOutput , txOutToUtxoRpcTxOutput ) -import Cardano.Binary.FixedSizeCodec (rawEncodeFixedSized) +import Cardano.Binary.FixedSizeCodec qualified as DSIGN import Cardano.Crypto.DSIGN.Class qualified as DSIGN import Cardano.Ledger.Api qualified as L import Cardano.Ledger.BaseTypes qualified as L @@ -131,20 +131,18 @@ txToUtxoRpcTx ledgerTx = anyEraTxConstraints sbe $ do vkeyWitnesses = toList (wits ^. L.addrTxWitsL) <&> \(L.WitVKey (L.VKey vkey) (DSIGN.SignedDSIGN signature)) -> defMessage - & U5c.vkey .~ rawEncodeFixedSized vkey - & U5c.signature .~ rawEncodeFixedSized signature + & U5c.vkey .~ DSIGN.rawEncodeFixedSized vkey + & U5c.signature .~ DSIGN.rawEncodeFixedSized signature bootstrapWitnesses :: [Proto UtxoRpc.BootstrapWitness] bootstrapWitnesses = toList (wits ^. L.bootAddrTxWitsL) <&> \bootstrapWitness -> do let L.VKey bootstrapKey = L.bwKey bootstrapWitness DSIGN.SignedDSIGN bootstrapSignature = L.bwSignature bootstrapWitness defMessage - & U5c.vkey .~ rawEncodeFixedSized bootstrapKey - & U5c.signature .~ rawEncodeFixedSized bootstrapSignature - & U5c.chainCode - .~ SBS.fromShort (byteArrayToShortByteString (L.unChainCode (L.bwChainCode bootstrapWitness))) - & U5c.attributes - .~ SBS.fromShort (byteArrayToShortByteString (L.bwAttributes bootstrapWitness)) + & U5c.vkey .~ DSIGN.rawEncodeFixedSized bootstrapKey + & U5c.signature .~ DSIGN.rawEncodeFixedSized bootstrapSignature + & U5c.chainCode .~ L.unChainCode (L.bwChainCode bootstrapWitness) + & U5c.attributes .~ L.bwAttributes bootstrapWitness scriptWitnesses :: [Proto UtxoRpc.Script] scriptWitnesses = M.elems (wits ^. L.scriptTxWitsL) <&> ledgerScriptToUtxoRpcScript sbe From 6f06938d4b2d5e39015dec957aa566496588920a Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 13 Aug 2026 16:06:50 +1000 Subject: [PATCH 56/62] Fix cardano-api for the validation package's 1.1 -> 1.2 breaking rewrite validation had no version bound in cardano-api.cabal. Its 1.2.2 release (uploaded between the two Hackage index-states this crypton migration spans) is a complete rewrite to a lens/profunctor-optics based API, which dropped Valid.toEither/Valid.liftError used by Cardano.Api.Tx.Internal.Sign.decodeShelleyBasedWitness. Capping validation to <1.2 to keep that old API is not an option: the ouroboros-consensus changes pulled in by the cabal.project SRP had already migrated Ouroboros.Consensus.Shelley.Ledger.Mempool to the new validation >=1.2 API (view Data.Validation.either) themselves, and validation is a single globally-resolved package across the whole build plan, so pinning it down for cardano-api's sake breaks ouroboros-consensus-cardano instead. Rewrite decodeShelleyBasedWitness to use only the primitives that are stable across both API generations (the Valid.Failure/Valid.Success constructors and the Semigroup/Monoid instances), and pin validation ^>=1.2 to reflect what the build already requires transitively. --- cardano-api/cardano-api.cabal | 14 +------- .../src/Cardano/Api/Tx/Internal/Sign.hs | 32 +++++++++++-------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index cd96975295..55db5639c6 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -132,16 +132,9 @@ library bytestring, bytestring-trie, cardano-addresses ^>=4.0.0, -<<<<<<< HEAD - cardano-base ^>=0.1, - cardano-binary, - cardano-crypto, - cardano-crypto-class ^>=2.5 || ^>=2.6, -======= cardano-binary >=1.9.1, cardano-crypto, cardano-crypto-class ^>=2.6, ->>>>>>> e9b8beea3 (Update all DSIGN operations to FixedSizeCodec ops) cardano-crypto-wrapper ^>=1.7 || ^>=1.8, cardano-data >=1.0, cardano-diffusion:{api, cardano-diffusion} ^>=1.1, @@ -208,7 +201,7 @@ library transformers, transformers-except ^>=0.1.3, typed-protocols ^>=1.2, - validation, + validation ^>=1.2, vector, yaml, @@ -334,13 +327,8 @@ library gen base16-bytestring, bytestring, cardano-api, -<<<<<<< HEAD cardano-binary >=1.6 && <1.10, cardano-crypto-class ^>=2.5 || ^>=2.6, -======= - cardano-binary >=1.9.1 && <1.10, - cardano-crypto-class ^>=2.6, ->>>>>>> e9b8beea3 (Update all DSIGN operations to FixedSizeCodec ops) cardano-crypto-wrapper:testlib ^>=1.7 || ^>=1.8, cardano-ledger-alonzo:{cardano-ledger-alonzo, testlib}, cardano-ledger-byron:testlib, diff --git a/cardano-api/src/Cardano/Api/Tx/Internal/Sign.hs b/cardano-api/src/Cardano/Api/Tx/Internal/Sign.hs index 2ac9770d75..791fd22adc 100644 --- a/cardano-api/src/Cardano/Api/Tx/Internal/Sign.hs +++ b/cardano-api/src/Cardano/Api/Tx/Internal/Sign.hs @@ -782,20 +782,24 @@ decodeShelleyBasedWitness -> ByteString -> Either CBOR.DecoderError (KeyWitness era) decodeShelleyBasedWitness sbe bs = - let e = - Valid.foldValidation Left Right $ - mconcat $ - map - (either (Valid.Failure . (: [])) Valid.Success) - [ bootstrapWitnessDecoder bs - , shelleyKeyWitnessDecoder bs - , legacyKeyWitnessDecoder bs - ] - in case e of - Left errs -> - let allErrs = Text.unlines $ map renderBuildable errs - in Left $ CBOR.DecoderErrorCustom "Failed to deserialise key witness" allErrs - Right res -> return res + -- NB: built directly from 'Valid.Failure'/'Valid.Success' (rather than via + -- 'Valid.liftError'/'Valid.toEither') since those convenience functions were + -- removed from the "validation" package's newer, lens-based API; the + -- constructors and the 'Semigroup'/'Monoid' instances used here are stable + -- across both APIs. + case + mconcat $ + map + (either (Valid.Failure . return) Valid.Success) + [ bootstrapWitnessDecoder bs + , shelleyKeyWitnessDecoder bs + , legacyKeyWitnessDecoder bs + ] + of + Valid.Failure errs -> + let allErrs = Text.unlines $ map renderBuildable errs + in Left $ CBOR.DecoderErrorCustom "Failed to deserialise key witness" allErrs + Valid.Success res -> return res where shelleyKeyWitnessDecoder b = ShelleyKeyWitness sbe From 134c9505071b8a39c57a515fa662c478725ef8f9 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 13 Aug 2026 16:08:23 +1000 Subject: [PATCH 57/62] Adapt to cardano-crypto-class-2.5.0.0's BLS12381SignContext/testlib changes cardano-crypto-class-2.5.0.0 removed BLS12381SignContext's constructors from export in favour of the pre-built minSigPoPDST/minVerKeyPoPDST values, which broke Leios.hs's provisional reconstruction of that context (already flagged there with a TODO anticipating this exact change). Use Crypto.minSigPoPDST directly now that it's available. The same version bump renamed cardano-crypto-class:testlib's prop_cbor_with -> prop_cbor_fixed_sized, prop_cbor_direct_vs_class -> prop_cbor_fixed_sized_vs_class, and added _fixed_sized variants of prop_raw_serialise/prop_size_serialise built on FixedSizeCodec directly. Switch Test.Cardano.Api.Crypto to the new names/variants, following on from "Update all DSIGN operations to FixedSizeCodec ops". --- cardano-api/src/Cardano/Api/Key/Internal/Leios.hs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs b/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs index dd7cc93f48..94ff2377a1 100644 --- a/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs +++ b/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs @@ -191,6 +191,17 @@ blsPossessionProof hexBs = Left e -> error $ "blsPossessionProof: " ++ show e Right p -> p +-- | Signing context including the Domain Separation Tag (DST) for the proofs-of-possession of +-- BLS keys using the minimal-signature-size BLS12-381 variant. +-- +-- A Domain Separation Tag is a unique tag (like a magic number) that we add to ensure that +-- the signature is used only in the context that it was intended for. +-- This is because BLS keys and signatures can be used for multiple purposes, and +-- we don't want a proof of possession for one purpose to be interpreted as something different +-- in a different context. +minSigPoPContext :: Crypto.BLS12381SignContext +minSigPoPContext = Crypto.minSigPoPDST + -- | Create a proof of possession for a BLS signing key. -- -- This proof demonstrates that the holder of a BLS verification key knows the corresponding From f0686e17a1f1b01e2c36345dc25fe591c78bbce1 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 13 Aug 2026 16:08:34 +1000 Subject: [PATCH 58/62] Bridge cardano-addresses' vendored XPrv to cardano-crypto's in Mnemonic.hs cardano-addresses' master (pulled in by the cabal.project SRP, needed for its own crypton >=1.1/ram migration) vendored its own copy of Cardano.Crypto.Wallet to drop the cardano-crypto/memory dependency, rather than re-exporting cardano-crypto's module as before. Its XPrv is now a distinct type from the Crypto.HD.XPrv ("Cardano.Crypto.Wallet", from the standalone cardano-crypto package) that SigningKey constructors expect. Bridge the two via the same 96-byte compact raw format both sides already implement (Cardano.Address.Derivation.xprvToBytes round-tripped through Cardano.Api.Crypto.Ed25519Bip32.xPrvFromBytes) rather than changing what type SigningKey wraps, so the on-disk/wire key format is unaffected. --- .../src/Cardano/Api/Key/Internal/Mnemonic.hs | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Key/Internal/Mnemonic.hs b/cardano-api/src/Cardano/Api/Key/Internal/Mnemonic.hs index acab90c299..da37d444b6 100644 --- a/cardano-api/src/Cardano/Api/Key/Internal/Mnemonic.hs +++ b/cardano-api/src/Cardano/Api/Key/Internal/Mnemonic.hs @@ -15,6 +15,7 @@ module Cardano.Api.Key.Internal.Mnemonic ) where +import Cardano.Api.Crypto.Ed25519Bip32 (xPrvFromBytes) import Cardano.Api.Error (Error (..)) import Cardano.Api.Key.Internal ( AsType @@ -35,6 +36,7 @@ import Cardano.Address.Derivation , XPrv , genMasterKeyFromMnemonic , indexFromWord32 + , xprvToBytes ) import Cardano.Address.Style.Shelley ( Role (..) @@ -44,6 +46,7 @@ import Cardano.Address.Style.Shelley , deriveDRepPrivateKey ) import Cardano.Crypto.Encoding.BIP39 (Dictionary (dictionaryIndexToWord)) +import Cardano.Crypto.Wallet qualified as Crypto.HD import Cardano.Mnemonic ( MkSomeMnemonic (mkSomeMnemonic) , MkSomeMnemonicError (..) @@ -59,6 +62,7 @@ import Data.ByteString qualified as BS import Data.Either.Combinators (mapLeft, maybeToRight) import Data.Either.Extra (maybeToEither) import Data.Foldable (toList) +import Data.Maybe (fromMaybe) import Data.Text (Text) import Data.Text qualified as Text import Data.Text.Encoding (decodeUtf8, encodeUtf8) @@ -146,6 +150,23 @@ class IndexedSigningKeyFromRootKey keyrole where -> Either Word32 (SigningKey keyrole) -- ^ The derived extended signing key or the 'indexType' if it is invalid. +-- | cardano-addresses' own 'XPrv' (from key derivation) and the 'Crypto.HD.XPrv' +-- ("Cardano.Crypto.Wallet", from the standalone @cardano-crypto@ package) that +-- 'SigningKey' constructors expect used to be the same type: cardano-addresses +-- re-exported cardano-crypto's. Since cardano-addresses vendored its own copy of +-- "Cardano.Crypto.Wallet" (to drop the @cardano-crypto@/@memory@ dependency in +-- favour of @crypton@/@ram@), the two are now distinct types, so bridge between +-- them via the same 96-byte compact raw format both sides already use (compare +-- 'Cardano.Address.Derivation.xprvToBytes' with +-- 'Cardano.Api.Crypto.Ed25519Bip32.xPrvToBytes'/'xPrvFromBytes'). Both are +-- implementations of the same BIP32-Ed25519 extended-key format, so this +-- round-trip is lossless. +toCryptoXPrv :: XPrv -> Crypto.HD.XPrv +toCryptoXPrv = + fromMaybe (error "toCryptoXPrv: impossible: cardano-addresses' XPrv is always 96 bytes") + . xPrvFromBytes + . xprvToBytes + instance IndexedSigningKeyFromRootKey PaymentExtendedKey where deriveSigningKeyFromAccountWithPaymentKeyIndex :: AsType PaymentExtendedKey @@ -154,7 +175,11 @@ instance IndexedSigningKeyFromRootKey PaymentExtendedKey where -> Either Word32 (SigningKey PaymentExtendedKey) deriveSigningKeyFromAccountWithPaymentKeyIndex _ accK idx = do payKeyIx <- maybeToEither idx $ indexFromWord32 @(Index 'Soft 'PaymentK) idx - return $ PaymentExtendedSigningKey $ getKey $ deriveAddressPrivateKey accK UTxOExternal payKeyIx + return $ + PaymentExtendedSigningKey $ + toCryptoXPrv $ + getKey $ + deriveAddressPrivateKey accK UTxOExternal payKeyIx instance IndexedSigningKeyFromRootKey StakeExtendedKey where deriveSigningKeyFromAccountWithPaymentKeyIndex @@ -164,7 +189,11 @@ instance IndexedSigningKeyFromRootKey StakeExtendedKey where -> Either Word32 (SigningKey StakeExtendedKey) deriveSigningKeyFromAccountWithPaymentKeyIndex _ accK idx = do payKeyIx <- maybeToEither idx $ indexFromWord32 @(Index 'Soft 'PaymentK) idx - return $ StakeExtendedSigningKey $ getKey $ deriveAddressPrivateKey accK Stake payKeyIx + return $ + StakeExtendedSigningKey $ + toCryptoXPrv $ + getKey $ + deriveAddressPrivateKey accK Stake payKeyIx instance SigningKeyFromRootKey DRepExtendedKey where deriveSigningKeyFromAccount @@ -172,7 +201,7 @@ instance SigningKeyFromRootKey DRepExtendedKey where -> Shelley 'AccountK XPrv -> SigningKey DRepExtendedKey deriveSigningKeyFromAccount _ accK = - DRepExtendedSigningKey $ getKey $ deriveDRepPrivateKey accK + DRepExtendedSigningKey $ toCryptoXPrv $ getKey $ deriveDRepPrivateKey accK instance SigningKeyFromRootKey CommitteeColdExtendedKey where deriveSigningKeyFromAccount @@ -180,7 +209,7 @@ instance SigningKeyFromRootKey CommitteeColdExtendedKey where -> Shelley 'AccountK XPrv -> SigningKey CommitteeColdExtendedKey deriveSigningKeyFromAccount _ accK = - CommitteeColdExtendedSigningKey $ getKey $ deriveCCColdPrivateKey accK + CommitteeColdExtendedSigningKey $ toCryptoXPrv $ getKey $ deriveCCColdPrivateKey accK instance SigningKeyFromRootKey CommitteeHotExtendedKey where deriveSigningKeyFromAccount @@ -188,7 +217,7 @@ instance SigningKeyFromRootKey CommitteeHotExtendedKey where -> Shelley 'AccountK XPrv -> SigningKey CommitteeHotExtendedKey deriveSigningKeyFromAccount _ accK = - CommitteeHotExtendedSigningKey $ getKey $ deriveCCHotPrivateKey accK + CommitteeHotExtendedSigningKey $ toCryptoXPrv $ getKey $ deriveCCHotPrivateKey accK -- | Generate a signing key from a mnemonic sentence given a function that -- derives a key from an account extended key. From f5ff45212e70273b51bf4ac2dfb1f53a07da4773 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 20 Aug 2026 15:19:56 +1000 Subject: [PATCH 59/62] Update cardano-ledger SRP --- cabal.project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal.project b/cabal.project index 441958eaed..2110d7f52b 100644 --- a/cabal.project +++ b/cabal.project @@ -220,7 +220,7 @@ source-repository-package source-repository-package type: git location: https://github.com/IntersectMBO/cardano-ledger - tag: 6def84b5ae0033053feda72f32b1dac41c812e0e + tag: 407b27ad62459cccf346145f97f63a259ae7ec75 subdir: eras/byron/crypto -- TEMPORARY: cardano-addresses-4.0.2 (the latest released on CHaP) still pins From 9b62c533318745fd38de4433f3654c8d0d904460 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 20 Aug 2026 21:15:35 +1000 Subject: [PATCH 60/62] Update SRPs --- cabal.project | 6 +++--- cardano-api/cardano-api.cabal | 1 + cardano-api/src/Cardano/Api/Key/Internal/Leios.hs | 2 +- .../src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cabal.project b/cabal.project index 2110d7f52b..d72797a1ae 100644 --- a/cabal.project +++ b/cabal.project @@ -164,8 +164,8 @@ if impl(ghc >=9.14) -- TEMPORARY: switching to crypton >= 1.1 (which depends on `ram` instead of -- `memory`) needs cardano-crypto-class-2.6.0.0 (the first version depending --- on crypton ^>=1.1 and `ram`), but the released ouroboros-consensus-3.0.1.0 --- pins `cardano-crypto-class ^>=2.3`, which excludes it. The blocks below +-- on crypton ^>=1.1 and `ram`), but the released ouroboros-consensus-4.1.0.0 +-- pins `cardano-crypto-class ^>=2.5`, which excludes it. The blocks below -- replicate the (draft, do-not-merge) upstream fix in -- https://github.com/IntersectMBO/ouroboros-consensus/pull/2213, which widens -- ouroboros-consensus's bound to also allow cardano-crypto-class-2.6.0.0 and @@ -184,7 +184,7 @@ allow-newer: source-repository-package type: git location: https://github.com/IntersectMBO/ouroboros-consensus - tag: 4da82e0afed5dabbe930d5f5cad5de687428e07b + tag: 206dffef96e76e42e15a1fb9fd6796394aef3409 -- TEMPORARY: pulls in cardano-base PR #694 (erikd/contra-tracer, not yet -- merged) https://github.com/IntersectMBO/cardano-base/pull/694, which widens diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 55db5639c6..f6f0804d4a 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -132,6 +132,7 @@ library bytestring, bytestring-trie, cardano-addresses ^>=4.0.0, + cardano-base ^>=0.1, cardano-binary >=1.9.1, cardano-crypto, cardano-crypto-class ^>=2.6, diff --git a/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs b/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs index 94ff2377a1..443ff7d8bd 100644 --- a/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs +++ b/cardano-api/src/Cardano/Api/Key/Internal/Leios.hs @@ -210,7 +210,7 @@ minSigPoPContext = Crypto.minSigPoPDST -- honest participants' keys during aggregation (a rogue key attack). createBlsPossessionProof :: SigningKey BlsKey -> BlsPossessionProof createBlsPossessionProof (BlsSigningKey sk) = - BlsPossessionProof (Crypto.createPossessionProofDSIGN Crypto.minSigPoPDST sk) + BlsPossessionProof (Crypto.createPossessionProofDSIGN minSigPoPContext sk) instance HasTypeProxy BlsPossessionProof where data AsType BlsPossessionProof = AsBlsPossessionProof diff --git a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs index 66b9b7c305..70c2794c8f 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs @@ -141,8 +141,8 @@ txToUtxoRpcTx ledgerTx = anyEraTxConstraints sbe $ do defMessage & U5c.vkey .~ DSIGN.rawEncodeFixedSized bootstrapKey & U5c.signature .~ DSIGN.rawEncodeFixedSized bootstrapSignature - & U5c.chainCode .~ L.unChainCode (L.bwChainCode bootstrapWitness) - & U5c.attributes .~ L.bwAttributes bootstrapWitness + & U5c.chainCode .~ SBS.fromShort (byteArrayToShortByteString (L.unChainCode (L.bwChainCode bootstrapWitness))) + & U5c.attributes .~ SBS.fromShort (byteArrayToShortByteString (L.bwAttributes bootstrapWitness)) scriptWitnesses :: [Proto UtxoRpc.Script] scriptWitnesses = M.elems (wits ^. L.scriptTxWitsL) <&> ledgerScriptToUtxoRpcScript sbe From 4d379fbea8bdddcc4c523adba54e7f6f15812756 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Wed, 2 Sep 2026 08:12:05 +1000 Subject: [PATCH 61/62] cabal.project: Update index-states --- cabal.project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal.project b/cabal.project index d72797a1ae..f94f42924e 100644 --- a/cabal.project +++ b/cabal.project @@ -13,7 +13,7 @@ repository cardano-haskell-packages -- See CONTRIBUTING for information about these, including some Nix commands -- you need to run if you change them index-state: - , hackage.haskell.org 2026-08-02T17:21:34Z + , hackage.haskell.org 2026-09-01T20:29:07Z , cardano-haskell-packages 2026-09-03T10:20:53Z packages: From 3db5a0310a3df10952ef1954122e2557816b5021 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Thu, 10 Sep 2026 07:34:31 +1000 Subject: [PATCH 62/62] cardano-rpc: fix serverExceptionToClient for grapesy-1.2.0's ExactException grapesy changed serverExceptionToClient's field type from SomeException to ExactException (a newtype wrapper) between 1.1.1 and 1.2.0. This repo's own pinned Hackage index-state (2026-08-02) predates that release, so CI still resolves an older grapesy with the old signature; a newer index-state (as used downstream by cardano-node) resolves 1.2.0 and this commit's serverExceptionToClient assignment fails to typecheck. Unwrap via the ExactException pattern before using fromException, as grapesy's own Server.Call/Context modules do internally. --- cardano-rpc/src/Cardano/Rpc/Server.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cardano-rpc/src/Cardano/Rpc/Server.hs b/cardano-rpc/src/Cardano/Rpc/Server.hs index 4fa6c51ef5..ca9cf42d53 100644 --- a/cardano-rpc/src/Cardano/Rpc/Server.hs +++ b/cardano-rpc/src/Cardano/Rpc/Server.hs @@ -48,6 +48,7 @@ import RIO import Control.Tracer import Network.GRPC.Common +import Network.GRPC.Common.Exception (ExactException (..)) import Network.GRPC.Server import Network.GRPC.Server.Protobuf import Network.GRPC.Server.Run @@ -185,8 +186,8 @@ runRpcServer tracer rpcConfig networkMagic nodeKernelAccessRef = handleFatalExce -- Clients must never see internal error detail or call stacks; full detail is -- still traced server-side by 'topLevelHandler'. - exceptionToClient :: SomeException -> IO (Maybe Text) - exceptionToClient e = + exceptionToClient :: ExactException -> IO (Maybe Text) + exceptionToClient (WrapExactException e) = pure . Just $ maybe genericErrorMessage renderRpcExceptionForClient $ fromException e where genericErrorMessage = "Internal error while processing the request."