From 0aef8a9cd01d70e5676eabefa5d0e80664b56ba3 Mon Sep 17 00:00:00 2001 From: Sebastian Nagel Date: Thu, 16 Jan 2025 22:06:39 +0100 Subject: [PATCH 1/2] Map and debug PlutusFailure cases of ApplyTx When submitting transactions which spend from scripts to the L2 cardano ledger, we can use debugPlutus to re-evaluate the script and dump debug information. This does not fix the formatting though (newlines in Text). --- CHANGELOG.md | 2 ++ hydra-node/hydra-node.cabal | 1 + hydra-node/src/Hydra/Ledger/Cardano.hs | 22 +++++++++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2b71ecd885..c03c39d103a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ changes. - Overall this results in transactions still to be submitted once per client, but requires signifanctly less book-keeping on the client-side. +- Auto-debug and provide more information on `PlutusFailure` when validating transactions on L2 ledger. + - Bump docusaurus version - Add blockfrost support to `hydra-chain-observer`, to follow the chain via Blockfrost API. diff --git a/hydra-node/hydra-node.cabal b/hydra-node/hydra-node.cabal index 30e014f13b7..d9bb0ae0fda 100644 --- a/hydra-node/hydra-node.cabal +++ b/hydra-node/hydra-node.cabal @@ -109,6 +109,7 @@ library , cardano-ledger-api , cardano-ledger-babbage , cardano-ledger-babbage:testlib + , cardano-ledger-conway , cardano-ledger-conway:testlib , cardano-ledger-core , cardano-ledger-core:testlib diff --git a/hydra-node/src/Hydra/Ledger/Cardano.hs b/hydra-node/src/Hydra/Ledger/Cardano.hs index 5b03ee33921..f9456ba5f74 100644 --- a/hydra-node/src/Hydra/Ledger/Cardano.hs +++ b/hydra-node/src/Hydra/Ledger/Cardano.hs @@ -16,7 +16,18 @@ import Hydra.Ledger.Cardano.Builder import Cardano.Api.UTxO (fromPairs, pairs) import Cardano.Api.UTxO qualified as UTxO +import Cardano.Ledger.Alonzo.Rules ( + FailureDescription (..), + TagMismatchDescription (FailedUnexpectedly), + ) import Cardano.Ledger.BaseTypes qualified as Ledger +import Cardano.Ledger.Conway.Rules ( + ConwayLedgerPredFailure (ConwayUtxowFailure), + ConwayUtxoPredFailure (UtxosFailure), + ConwayUtxosPredFailure (ValidationTagMismatch), + ConwayUtxowPredFailure (UtxoFailure), + ) +import Cardano.Ledger.Plutus (debugPlutus) import Cardano.Ledger.Shelley.API.Mempool qualified as Ledger import Cardano.Ledger.Shelley.Genesis qualified as Ledger import Cardano.Ledger.Shelley.LedgerState qualified as Ledger @@ -68,7 +79,16 @@ cardanoLedger globals ledgerEnv = Right (Ledger.LedgerState{Ledger.lsUTxOState = us}, _validatedTx) -> Right . fromLedgerUTxO $ Ledger.utxosUtxo us where - toValidationError = ValidationError . show + -- As we use applyTx we only expect one ledger rule to run and one tx to + -- fail validation, hence using the heads of non empty lists is fine. + toValidationError (Ledger.ApplyTxError (e :| _)) = case e of + (ConwayUtxowFailure (UtxoFailure (UtxosFailure (ValidationTagMismatch _ (FailedUnexpectedly (PlutusFailure msg ctx :| _)))))) -> + ValidationError $ + "Plutus validation failed: " + <> msg + <> "Debug info: " + <> show (debugPlutus @StandardCrypto (decodeUtf8 ctx)) + _ -> ValidationError $ show e env' = ledgerEnv{Ledger.ledgerSlotNo = fromIntegral slot} From 36d631464926be60a938c09c43bde28eb1a663ec Mon Sep 17 00:00:00 2001 From: Sebastian Nagel Date: Mon, 20 Jan 2025 20:43:11 +0100 Subject: [PATCH 2/2] Use unsafeDupablePerformIO to debugPlutus It's not clear why debugPlutus would need to be an IO action, it does not have any side effects. See also https://github.com/IntersectMBO/cardano-ledger/commit/8b5fa4a26a69e4089ca1dc61e73d09116a9c4edc --- hydra-node/src/Hydra/Ledger/Cardano.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hydra-node/src/Hydra/Ledger/Cardano.hs b/hydra-node/src/Hydra/Ledger/Cardano.hs index f9456ba5f74..3c47ef99cb5 100644 --- a/hydra-node/src/Hydra/Ledger/Cardano.hs +++ b/hydra-node/src/Hydra/Ledger/Cardano.hs @@ -38,6 +38,7 @@ import Data.Default (def) import Hydra.Chain.ChainState (ChainSlot (..)) import Hydra.Ledger (Ledger (..), ValidationError (..)) import Hydra.Tx (IsTx (..)) +import System.IO.Unsafe (unsafeDupablePerformIO) import Test.Cardano.Ledger.Babbage.Arbitrary () import Test.Cardano.Ledger.Conway.Arbitrary () import Test.Hydra.Tx.Gen (genKeyPair, genOneUTxOFor) @@ -87,7 +88,10 @@ cardanoLedger globals ledgerEnv = "Plutus validation failed: " <> msg <> "Debug info: " - <> show (debugPlutus @StandardCrypto (decodeUtf8 ctx)) + -- NOTE: There is not a clear reason why 'debugPlutus' is an IO + -- action. It only re-evaluates the script and does not have any + -- side-effects. + <> show (unsafeDupablePerformIO $ debugPlutus @StandardCrypto (decodeUtf8 ctx)) _ -> ValidationError $ show e env' = ledgerEnv{Ledger.ledgerSlotNo = fromIntegral slot}