diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml
index 3b45526f2..b93a511c8 100644
--- a/.github/workflows/continuous-integration.yaml
+++ b/.github/workflows/continuous-integration.yaml
@@ -227,7 +227,7 @@ jobs:
os: [ linux ]
arch: [ x86_64 ]
network: [ preview ]
- cardano-node: [ 9.1.0 ]
+ cardano-node: [ 9.1.1 ]
runs-on: ${{ matrix.os == 'linux' && 'ubuntu-22.04' }}
steps:
@@ -404,8 +404,8 @@ jobs:
os: [ linux ]
target: [ cardano-node-ogmios ]
network: [ mainnet, preprod, preview, sanchonet ]
- cardano-node: [ 9.1.0 ]
- cardano-node-latest: [ 9.1.0 ]
+ cardano-node: [ 9.1.1 ]
+ cardano-node-latest: [ 9.1.1 ]
arch: [ x86_64 ]
steps:
- name: 📥 Checkout repository
diff --git a/.github/workflows/network-synchronization.yaml b/.github/workflows/network-synchronization.yaml
index 197bcb487..77807d3df 100644
--- a/.github/workflows/network-synchronization.yaml
+++ b/.github/workflows/network-synchronization.yaml
@@ -16,8 +16,8 @@ jobs:
strategy:
matrix:
network: [ preview ]
- ogmios_version: [ v6.6.0 ]
- cardano_node_version: [ 9.1.0 ]
+ ogmios_version: [ v6.6.2 ]
+ cardano_node_version: [ 9.1.1 ]
runs-on: ubuntu-latest
steps:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77cc2e944..8ffe9a3fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,20 @@ pre: "6. "
math: true
---
+### [6.7.0] - 2024-09-13
+
+#### Added
+
+- Automatically upgrade transactions from previous era (up until Alonzo) on submission.
+
+#### Changed
+
+- N/A
+
+#### Removed
+
+- N/A
+
### [6.6.2] - 2024-09-10
#### Added
diff --git a/Dockerfile b/Dockerfile
index 1667aabd8..e886d415f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-ARG CARDANO_NODE_IMAGE=ghcr.io/intersectmbo/cardano-node:9.0.0
+ARG CARDANO_NODE_IMAGE=ghcr.io/intersectmbo/cardano-node:9.1.1
# #
# --------------------------- BUILD (ogmios) --------------------------------- #
diff --git a/clients/TypeScript/package.json b/clients/TypeScript/package.json
index 21b6fbf2f..ce53bd5d6 100644
--- a/clients/TypeScript/package.json
+++ b/clients/TypeScript/package.json
@@ -1,6 +1,6 @@
{
"name": "cardano-ogmios",
- "version": "6.6.2",
+ "version": "6.7.0",
"private": true,
"description": "TypeScript monorepo with client libraries for Cardano Ogmios",
"engines": {
diff --git a/clients/TypeScript/packages/client/package.json b/clients/TypeScript/packages/client/package.json
index 98069f4fe..436bf64ad 100644
--- a/clients/TypeScript/packages/client/package.json
+++ b/clients/TypeScript/packages/client/package.json
@@ -1,6 +1,6 @@
{
"name": "@cardano-ogmios/client",
- "version": "6.6.2",
+ "version": "6.7.0",
"description": "TypeScript client library for Cardano Ogmios",
"engines": {
"node": ">=14"
@@ -47,7 +47,7 @@
"typescript": "^4.2.3"
},
"dependencies": {
- "@cardano-ogmios/schema": "6.6.2",
+ "@cardano-ogmios/schema": "6.7.0",
"@cardanosolutions/json-bigint": "^1.0.1",
"@types/json-bigint": "^1.0.1",
"bech32": "^2.0.0",
diff --git a/clients/TypeScript/packages/repl/package.json b/clients/TypeScript/packages/repl/package.json
index 5589a9f4e..061b7cede 100644
--- a/clients/TypeScript/packages/repl/package.json
+++ b/clients/TypeScript/packages/repl/package.json
@@ -1,6 +1,6 @@
{
"name": "@cardano-ogmios/repl",
- "version": "6.6.2",
+ "version": "6.7.0",
"description": "REPL for Cardano Ogmios",
"engines": {
"node": ">=14"
@@ -39,7 +39,7 @@
"typescript": "^4.2.3"
},
"dependencies": {
- "@cardano-ogmios/client": "6.6.2",
+ "@cardano-ogmios/client": "6.7.0",
"yargs-parser": "^20.2.7"
},
"files": [
diff --git a/clients/TypeScript/packages/schema/package.json b/clients/TypeScript/packages/schema/package.json
index 748d904d2..995c15cc0 100644
--- a/clients/TypeScript/packages/schema/package.json
+++ b/clients/TypeScript/packages/schema/package.json
@@ -1,6 +1,6 @@
{
"name": "@cardano-ogmios/schema",
- "version": "6.6.2",
+ "version": "6.7.0",
"description": "Generated TypeScript from the Cardano Ogmios schema",
"engines": {
"node": ">=14"
diff --git a/docker-compose.yml b/docker-compose.yml
index 8b774d35d..76644d4a0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
cardano-node:
- image: ghcr.io/intersectmbo/cardano-node:9.1.0
+ image: ghcr.io/intersectmbo/cardano-node:9.1.1
command: [
"run",
"--config", "/config/config.json",
diff --git a/docs/content/api/_index.md b/docs/content/api/_index.md
index ec5937d6b..608eb90ce 100644
--- a/docs/content/api/_index.md
+++ b/docs/content/api/_index.md
@@ -1,5 +1,5 @@
+++
-title = "WebSocket API Reference (v6.6.*)"
+title = "WebSocket API Reference (v6.7.*)"
weight = 4
chapter = false
pre = "4. "
diff --git a/docs/static/api/specification.yaml b/docs/static/api/specification.yaml
index ca543fdf0..722ee4efb 100644
--- a/docs/static/api/specification.yaml
+++ b/docs/static/api/specification.yaml
@@ -1,7 +1,7 @@
asyncapi: '2.4.0'
info:
title: Ogmios
- version: '6.6.*'
+ version: '6.7.*'
description: |
### Protocols
diff --git a/server/src/Ogmios/App/Protocol/TxSubmission.hs b/server/src/Ogmios/App/Protocol/TxSubmission.hs
index aa33ed62f..1bbdae030 100644
--- a/server/src/Ogmios/App/Protocol/TxSubmission.hs
+++ b/server/src/Ogmios/App/Protocol/TxSubmission.hs
@@ -53,6 +53,7 @@ import Cardano.Ledger.BaseTypes
import Cardano.Ledger.Core
( EraTx (..)
, EraTxBody (..)
+ , eraName
)
import Control.Monad.Trans.Except
( Except
@@ -85,8 +86,10 @@ import Ogmios.Control.MonadSTM
, takeTMVar
)
import Ogmios.Data.EraTranslation
- ( MultiEraUTxO (..)
+ ( MostRecentEra
+ , MultiEraUTxO (..)
, Upgrade (..)
+ , upgradeGenTx
)
import Ogmios.Data.Json
( Json
@@ -128,10 +131,14 @@ import Ouroboros.Consensus.Cardano.Block
, CardanoBlock
, CardanoQueryResult
, GenTx (..)
+ , HardForkApplyTxErr (..)
)
import Ouroboros.Consensus.HardFork.Combinator
( HardForkBlock
)
+import Ouroboros.Consensus.HardFork.Combinator.AcrossEras
+ ( EraMismatch (..)
+ )
import Ouroboros.Consensus.HardFork.Combinator.Ledger.Query
( QueryHardFork (..)
)
@@ -180,6 +187,7 @@ import Type.Reflection
import qualified Codec.Json.Rpc as Rpc
import qualified Data.Aeson as Json
import qualified Data.Map.Strict as Map
+import qualified Data.Text as T
import qualified Ouroboros.Consensus.HardFork.Combinator as HF
import qualified Ouroboros.Consensus.Ledger.Query as Ledger
import qualified Ouroboros.Network.Protocol.LocalStateQuery.Client as LSQ
@@ -212,6 +220,16 @@ mkTxSubmissionClient tr defaultWithInternalError TxSubmissionCodecs{..} Executio
await :: m (TxSubmissionMessage block)
await = atomically (readTQueue queue)
+ isMostRecentEra era =
+ T.toLower (toText era) == T.toLower (toText (eraName @(MostRecentEra block)))
+
+ -- NOTE: On successful submission, clear our cached
+ -- mempool to ensure we always use the latest available
+ -- mempool snapshot during evaluation.
+ clearMempoolOnSuccess = \case
+ SubmitSuccess -> clearMempoolM
+ _ -> pure ()
+
clientStIdle
:: m (LocalTxClientStIdle (SerializedTransaction block) (SubmitTransactionError block) m ())
clientStIdle = await >>= \case
@@ -219,17 +237,34 @@ mkTxSubmissionClient tr defaultWithInternalError TxSubmissionCodecs{..} Executio
defaultWithInternalError clientStIdle yield toResponse $ case request of
MultiEraDecoderSuccess transaction -> do
pure $ SendMsgSubmitTx transaction $ \result -> do
- -- NOTE: On successful submission, clear our cached
- -- mempool to ensure we always use the latest available
- -- mempool snapshot during evaluation.
case result of
- SubmitSuccess -> clearMempoolM
- SubmitFail{} -> pure ()
- mkSubmitTransactionResponse transaction result
- & toResponse
- & encodeSubmitTransactionResponse
- & yield
- clientStIdle
+ SubmitFail (ApplyTxErrWrongEra eraMismatch) | isMostRecentEra (ledgerEraName eraMismatch) -> do
+ case upgradeGenTx transaction of
+ Left hint -> do
+ SubmitTransactionFailedToUpgrade hint
+ & toResponse
+ & encodeSubmitTransactionResponse
+ & yield
+ clientStIdle
+ Right upgradedTx ->
+ pure $ SendMsgSubmitTx upgradedTx $ \result' -> do
+ clearMempoolOnSuccess result'
+ mkSubmitTransactionResponse transaction result'
+ & toResponse
+ & encodeSubmitTransactionResponse
+ & yield
+ clientStIdle
+ _ -> do
+ -- NOTE: On successful submission, clear our cached
+ -- mempool to ensure we always use the latest available
+ -- mempool snapshot during evaluation.
+ clearMempoolOnSuccess result
+ mkSubmitTransactionResponse transaction result
+ & toResponse
+ & encodeSubmitTransactionResponse
+ & yield
+ clientStIdle
+
MultiEraDecoderErrors errs -> do
SubmitTransactionDeserialisationFailure errs
& toResponse
diff --git a/server/src/Ogmios/Data/EraTranslation.hs b/server/src/Ogmios/Data/EraTranslation.hs
index 1af9e44fd..fafa1afa1 100644
--- a/server/src/Ogmios/Data/EraTranslation.hs
+++ b/server/src/Ogmios/Data/EraTranslation.hs
@@ -16,6 +16,7 @@ module Ogmios.Data.EraTranslation
-- * Translations
, Upgrade (..)
+ , upgradeGenTx
) where
import Ogmios.Prelude
@@ -51,13 +52,20 @@ import Data.Maybe.Strict
import Ouroboros.Consensus.Cardano
( CardanoBlock
)
+import Ouroboros.Consensus.Cardano.Block
+ ( GenTx (..)
+ )
import Ouroboros.Consensus.Shelley.Ledger
( ShelleyBlock
)
+import Ouroboros.Consensus.Shelley.Ledger.Mempool
+ ( GenTx (..)
+ )
import qualified Cardano.Ledger.Alonzo.Tx as Alonzo
import qualified Cardano.Ledger.Babbage.TxBody as Babbage
import qualified Cardano.Ledger.Conway.Core as Conway
+import qualified Cardano.Ledger.Core as Core
import qualified Cardano.Ledger.Crypto as Ledger
type family MostRecentEra block :: Type where
@@ -106,6 +114,35 @@ instance
let isValid = Alonzo.isValid tx
pure $ AlonzoTx{body,wits,auxiliaryData,isValid}
+----------
+-- GenTx
+----------
+
+upgradeGenTx
+ :: forall crypto.
+ ( Crypto crypto
+ )
+ => GenTx (CardanoBlock crypto)
+ -> Either Text (GenTx (CardanoBlock crypto))
+upgradeGenTx = \case
+ GenTxByron _ ->
+ Left "cannot upgrade from Byron transaction: too old, use a more recent transaction builder."
+ GenTxShelley _ ->
+ Left "cannot upgrade from Shelley transaction: too old, use a more recent transaction builder."
+ GenTxAllegra _ ->
+ Left "cannot upgrade from Allegra transaction: too old, use a more recent transaction builder."
+ GenTxMary _ ->
+ Left "cannot upgrade from Mary transaction: too old, use a more recent transaction builder."
+ GenTxAlonzo (ShelleyTx hash txInAlonzo) -> do
+ txInBabbage <- left show $ Core.upgradeTx @(BabbageEra crypto) txInAlonzo
+ txInConway <- left show $ Core.upgradeTx @(ConwayEra crypto) txInBabbage
+ pure $ GenTxConway $ ShelleyTx hash txInConway
+ GenTxBabbage (ShelleyTx hash txInBabbage) -> do
+ txInConway <- left show $ Core.upgradeTx @(ConwayEra crypto) txInBabbage
+ pure $ GenTxConway $ ShelleyTx hash txInConway
+ latest@(GenTxConway(_))->
+ Right latest
+
unsafeFromRight :: (HasCallStack) => Either Text a -> a
unsafeFromRight = either error id
diff --git a/server/src/Ogmios/Data/Protocol/TxSubmission.hs b/server/src/Ogmios/Data/Protocol/TxSubmission.hs
index 33b36b211..75b8dee26 100644
--- a/server/src/Ogmios/Data/Protocol/TxSubmission.hs
+++ b/server/src/Ogmios/Data/Protocol/TxSubmission.hs
@@ -254,6 +254,7 @@ _decodeSubmitTransaction =
data SubmitTransactionResponse block
= SubmitTransactionSuccess (GenTxId block)
| SubmitTransactionFailure (SubmitTransactionError block)
+ | SubmitTransactionFailedToUpgrade Text
| SubmitTransactionDeserialisationFailure [(SomeShelleyEra, Binary.DecoderError, Word)]
deriving (Generic)
deriving instance
@@ -281,6 +282,16 @@ _encodeSubmitTransactionResponse _proxy
resolve $ encodeObject ("transaction" .= encodeTransactionId i)
SubmitTransactionFailure e ->
encodeSubmitTransactionError reject e
+ SubmitTransactionFailedToUpgrade hint ->
+ reject Rpc.FaultInvalidParams
+ "Non-upgradable transaction; it seems that you're trying to submit a \
+ \transaction in a format that presents incompatibility with the current \
+ \ledger era. The field \"data.hint\" contains possible useful information \
+ \about what went wrong."
+ (pure $ encodeObject
+ ( "hint" .= encodeText hint
+ )
+ )
SubmitTransactionDeserialisationFailure errs ->
encodeDeserialisationFailure reject errs