Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test that Consensus emits valid CBOR #3099

Closed
nfrisby opened this issue Apr 28, 2021 · 17 comments · Fixed by IntersectMBO/ouroboros-consensus#323 or IntersectMBO/ouroboros-consensus#479
Assignees
Labels
consensus issues related to ouroboros-consensus good first issue Good for newcomers

Comments

@nfrisby
Copy link
Contributor

nfrisby commented Apr 28, 2021

This is related to issue #1090, but the resolution there only implemented round-trip tests, not specific validity tests.

EG The Network team is invoking validFlatTerm from https://hackage.haskell.org/package/cborg-0.2.5.0/docs/Codec-CBOR-FlatTerm.html#v:validFlatTerm

This Issue is to determine whether our existing round-trip tests supplant that, and if not to add such tests.

@nfrisby nfrisby added good first issue Good for newcomers consensus issues related to ouroboros-consensus labels Apr 28, 2021
@KtorZ
Copy link
Contributor

KtorZ commented Jul 23, 2021

Seems like there's an issue with the MsgRollForward decoder in the ChainSync protocol. Here's a minimal reproduction case, using arbitrary generators from Test.Consensus.Cardano.Generators

forAll ((,) <$> genBlock <*> genTip) $ \(blk, tip) ->
    let
        codec = codecs (EpochSlots 432000) NodeToClientV_9 & cChainSyncCodec
        msg = MsgRollForward blk tip
        agency = ServerAgency TokNext{}
     in
        monadicIO $ do
            decoder <- run $ decode codec agency
            run (runDecoder [encode codec agency msg] decoder) >>= assert . isRight

If we exclude the Alonzo blocks, it passes. There's no shrinker defined for the associated generator so the exact error is hard to locate... All I can say is that it used to work fine in: e50613562d6d4a0f933741fcf590b0f69a1eda67, doing some bisection between here and master would probably help identifying the issue.

Note: the issue is likely in one of the cardano-ledger-specs CBOR instance I imagine.

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 23, 2021

Thanks @KtorZ -- can you point me at a self-contained module that runs that test? I tried adding the necessary imports, but I'm (at least) stumped on where you're getting codecs from. Thanks!

@KtorZ
Copy link
Contributor

KtorZ commented Jul 23, 2021

Whoops, that one was internal indeed. Here's a self-contained module:

ouroboros-network's revision: e338f2cf8e1078fbda9555dd2b169c6737ef6774

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeApplications #-}

module TmpSpec
    ( spec
    ) where

import Prelude

import Data.Function
    ( (&) )
import Data.Proxy
    ( Proxy (..) )

import Control.Monad.Class.MonadST
    ( MonadST )
import Network.TypedProtocol.Codec
    ( Codec (..), PeerHasAgency (..), runDecoder )
import Ouroboros.Consensus.Byron.Ledger.Config
    ( CodecConfig (..) )
import Ouroboros.Consensus.Cardano
    ( CardanoBlock )
import Ouroboros.Consensus.Cardano.Block
    ( CodecConfig (..), HardForkBlock (..) )
import Ouroboros.Consensus.Network.NodeToClient
    ( ClientCodecs, Codecs' (..), clientCodecs )
import Ouroboros.Consensus.Node.NetworkProtocolVersion
    ( SupportedNetworkProtocolVersion (..) )
import Ouroboros.Consensus.Shelley.Ledger.Config
    ( CodecConfig (..) )
import Ouroboros.Consensus.Shelley.Protocol
    ( StandardCrypto )
import Ouroboros.Network.Block
    ( Tip (..) )
import Ouroboros.Network.NodeToClient
    ( NodeToClientVersion (..) )
import Ouroboros.Network.Protocol.ChainSync.Type
    ( Message (..), ServerHasAgency (..) )
import Test.Consensus.Cardano.Generators
    ()

-- cardano-ledger-byron
import Cardano.Chain.Slotting
    ( EpochSlots (..) )

-- containers
import Data.Map.Strict
    ( (!) )

-- hspec
import Test.Hspec
    ( Spec )
import Test.Hspec.QuickCheck
    ( prop )

-- QuickCheck
import Test.QuickCheck
    ( Arbitrary (..), Gen, counterexample, forAll, frequency )
import Test.QuickCheck.Monadic
    ( assert, monadicIO, monitor, run )

spec :: Spec
spec = do
    prop "RollForward roundtrip error" $ do
        forAll ((,) <$> genBlock <*> genTip) $ \(blk, tip) ->
            let
                codec = codecs (EpochSlots 432000) NodeToClientV_9 & cChainSyncCodec
                msg = MsgRollForward blk tip
                agency = ServerAgency TokNext{}
             in
                monadicIO $ do
                    decoder <- run $ decode codec agency
                    run (runDecoder [encode codec agency msg] decoder) >>= \case
                        Right{} -> assert True
                        Left e  -> monitor (counterexample (show e)) >> assert False

type Block = CardanoBlock StandardCrypto

codecs
    :: forall m. (MonadST m)
    => EpochSlots
    -> NodeToClientVersion
    -> ClientCodecs Block m
codecs epochSlots nodeToClientV =
    clientCodecs cfg (supportedVersions ! nodeToClientV) nodeToClientV
  where
    supportedVersions = supportedNodeToClientVersions (Proxy @Block)
    cfg = CardanoCodecConfig byron shelley allegra mary alonzo
      where
        byron   = ByronCodecConfig epochSlots
        shelley = ShelleyCodecConfig
        allegra = ShelleyCodecConfig
        mary    = ShelleyCodecConfig
        alonzo  = ShelleyCodecConfig

genBlock :: Gen Block
genBlock =
    BlockAlonzo <$> arbitrary

genTip :: Gen (Tip Block)
genTip = frequency
    [ (1, pure TipGenesis)
    , (10, Tip <$> arbitrary <*> arbitrary <*> arbitrary)
    ]

Running this gives the following error:

DeserialiseFailure 3102 "expected word"

with, a counter-example:

(HardForkBlock {getHardForkBlock = S (S (S (S (Z (I (ShelleyBlock {shelleyBlockRaw = Block' (BHeader' {bHeaderBody' = BHBody {bheaderBlockNo = BlockNo 39, bheaderSlotNo = SlotNo 1, bheaderPrev = BlockHash (HashHeader {unHashHeader = "ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25"}), bheaderVk = VKey (VerKeyEd25519DSIGN (PublicKey "`3zdek\242dof\201\n\180\165F\187\243\195\245\248\240\v\240o\204\GS\159}\SOH\217$\246")), bheaderVrfVk = VerKeyPraosVRF "\156\132mD\180\DC4\196M\a\217\158T\208;\196\247\134\n\137=\200H\229\&3[\202\SOH>_!\218P", bheaderEta = CertifiedVRF {certifiedOutput = OutputVRF {getOutputVRFBytes = "\135\190\SI\DC1\188\254\ACKlo\226k\251pf\SUB\189\NAKu\221M\197\184\183\193\173\205\&0\154\239\DC2\vpwd!:\138\ESC\233\179\r\DC2;\139\222\129\243\214\174\162\190=fODY\187XE\222\148&LH"}, certifiedProof = CertPraosVRF "\221\ETX\165:+\151W\161Iq>9\US\b\219\160=\205\151\170M'\238j\254Q\215\220D\184\ESCy\209\235\180\131\200\190)\147ca\161A\STX\129\247W\142\209'\219\&7k\198~\255:\ETX7\228:\167\229\209D\196\&1\209\235\222a\218|\147\ENQ*\246\164\ACK"}, bheaderL = CertifiedVRF {certifiedOutput = OutputVRF {getOutputVRFBytes = "\135\187\214\230\135\231r\179\225g\155\SOH\ETX$(\187\DEL\151\147\247J\DC2\209-\167\185e\GS7\ETX\fz\214\176\141\189\228I\141\227?O\182\&7\183.\231\138\DC1\189>s\178)\251\139\238\233\152\DLE\224T_\163"}, certifiedProof = CertPraosVRF "2P$Q:L\248\DLE\244\FS\196\238\DC3F\SI\DC3`Y\GS\215\238`\202\nn\164\215\EOT\231\224\b<\140\156*\165q)\202\215%\139\&9\129\210\243M\ACK\164*\196\209*j\152\215\n\206\210l\188\135\131\DEL?\240pD\239TU4\171\146g\233\DC4\229\135\v"}, bsize = 777, bhash = "ae85d245a3d00bfde01f59f3c4fe0b4bfae1cb37e9cf91929eadcea4985711de", bheaderOCert = OCert {ocertVkHot = VerKeySumKES "944f1f5a20a5195206906bf2e88ab15219ea14f73926486cafe18d35a2617bb9", ocertN = 1, ocertKESPeriod = KESPeriod 1, ocertSigma = SignedDSIGN (SigEd25519DSIGN (Signature "zd\b\194\EMM\243y\173\149\218\216#j+\134I:\t,\206\239\218!\CAN\194(fWA9+\246Y\158\236\185\rr{)\144^\249\ESCv;&B\155W\253-\160H\213\205\160\187z\NULX\FS\t"))}, bprotver = ProtVer {pvMajor = 0, pvMinor = 0}}, bHeaderSig' = SignedKES {getSig = SigSumKES (SigSumKES (SigSumKES (SigSumKES (SigSumKES (SigSumKES (SigSingleKES (SigEd25519DSIGN (Signature "K\137\NUL2\211\223\&9\DLE\234t\148\170\160-\ESC0s_%\149\206\178\162\DC2\221\138 \238\211b9\160L\NULrPI\130\FS\178M\140\163\&9\218\247M\228\157\212\176\DC4\n|z\190!Iw#\DC3\STX\249\SOH"))) (VerKeySingleKES (VerKeyEd25519DSIGN (PublicKey "+m4GP\ACK\201\210\239G\149\222\225\214\177\216(!\182\190\165(\DLE(\214\169\247\197\245\v\248k"))) (VerKeySingleKES (VerKeyEd25519DSIGN (PublicKey "V\163\133K\255U\197y/dT2\211G\a\137p\128\165\184\228\175?5\134f\255\141\nT^\192")))) (VerKeySumKES "18eaf3a3f8c69fc245a878fb2e1e87b3e96bc574b80f1fef357fa3b29e3ed130") (VerKeySumKES "8eb9db10c2685523ac70258222c1cf71e51be6e59acda91ab47eb4f2af96798c")) (VerKeySumKES "a4f7a1ce425387f34a80264a0112112dfcf1a38f2904a4bb2bf4675ce8b03d5e") (VerKeySumKES "d13a8242d1a179a235924f777130fe00a13b89a93f391c097fc2771ed2383d67")) (VerKeySumKES "601be59a48689e21abe49637c23116fc158360b700337ad1f43eddf4794bce07") (VerKeySumKES "eabadf4d0923279b6bee4182060257e6c815182aa382a4db986342a7c3e23c0f")) (VerKeySumKES "ad597b7f251812322c3f445cd5ab46de8bc8c6cf5dcc4f67ccdd2e55cf80df82") (VerKeySumKES "50c4013398b66d9b07aebe9f2dd78b626a7c3bcb88878d30797b2868644c9be8")) (VerKeySumKES "197a73750075f41cc1b21bc6da0f9ed13f567fe408ad9d7549c7da5688bbbd0f") (VerKeySumKES "ca8e58c1c59860ad6270c47fc7598ae2d892b6c05db2ed3ee34e530447ca6719")}, bHeaderBytes = "\130\143\CAN'\SOHX \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%X `3zdek\242dof\201\n\180\165F\187\243\195\245\248\240\v\240o\204\GS\159}\SOH\217$\246X \156\132mD\180\DC4\196M\a\217\158T\208;\196\247\134\n\137=\200H\229\&3[\202\SOH>_!\218P\130X@\135\190\SI\DC1\188\254\ACKlo\226k\251pf\SUB\189\NAKu\221M\197\184\183\193\173\205\&0\154\239\DC2\vpwd!:\138\ESC\233\179\r\DC2;\139\222\129\243\214\174\162\190=fODY\187XE\222\148&LHXP\221\ETX\165:+\151W\161Iq>9\US\b\219\160=\205\151\170M'\238j\254Q\215\220D\184\ESCy\209\235\180\131\200\190)\147ca\161A\STX\129\247W\142\209'\219\&7k\198~\255:\ETX7\228:\167\229\209D\196\&1\209\235\222a\218|\147\ENQ*\246\164\ACK\130X@\135\187\214\230\135\231r\179\225g\155\SOH\ETX$(\187\DEL\151\147\247J\DC2\209-\167\185e\GS7\ETX\fz\214\176\141\189\228I\141\227?O\182\&7\183.\231\138\DC1\189>s\178)\251\139\238\233\152\DLE\224T_\163XP2P$Q:L\248\DLE\244\FS\196\238\DC3F\SI\DC3`Y\GS\215\238`\202\nn\164\215\EOT\231\224\b<\140\156*\165q)\202\215%\139\&9\129\210\243M\ACK\164*\196\209*j\152\215\n\206\210l\188\135\131\DEL?\240pD\239TU4\171\146g\233\DC4\229\135\v\EM\ETX\tX \174\133\210E\163\208\v\253\224\USY\243\196\254\vK\250\225\203\&7\233\207\145\146\158\173\206\164\152W\DC1\222X \148O\USZ \165\EMR\ACK\144k\242\232\138\177R\EM\234\DC4\247\&9&Hl\175\225\141\&5\162a{\185\SOH\SOHX@zd\b\194\EMM\243y\173\149\218\216#j+\134I:\t,\206\239\218!\CAN\194(fWA9+\246Y\158\236\185\rr{)\144^\249\ESCv;&B\155W\253-\160H\213\205\160\187z\NULX\FS\t\NUL\NULY\SOH\192K\137\NUL2\211\223\&9\DLE\234t\148\170\160-\ESC0s_%\149\206\178\162\DC2\221\138 \238\211b9\160L\NULrPI\130\FS\178M\140\163\&9\218\247M\228\157\212\176\DC4\n|z\190!Iw#\DC3\STX\249\SOH+m4GP\ACK\201\210\239G\149\222\225\214\177\216(!\182\190\165(\DLE(\214\169\247\197\245\v\248kV\163\133K\255U\197y/dT2\211G\a\137p\128\165\184\228\175?5\134f\255\141\nT^\192\CAN\234\243\163\248\198\159\194E\168x\251.\RS\135\179\233k\197t\184\SI\US\239\&5\DEL\163\178\158>\209\&0\142\185\219\DLE\194hU#\172p%\130\"\193\207q\229\ESC\230\229\154\205\169\SUB\180~\180\242\175\150y\140\164\247\161\206BS\135\243J\128&J\SOH\DC2\DC1-\252\241\163\143)\EOT\164\187+\244g\\\232\176=^\209:\130B\209\161y\162\&5\146Owq0\254\NUL\161;\137\169?9\FS\t\DEL\194w\RS\210\&8=g`\ESC\229\154Hh\158!\171\228\150\&7\194\&1\SYN\252\NAK\131`\183\NUL3z\209\244>\221\244yK\206\a\234\186\223M\t#'\155k\238A\130\ACK\STXW\230\200\NAK\CAN*\163\130\164\219\152cB\167\195\226<\SI\173Y{\DEL%\CAN\DC22,?D\\\213\171F\222\139\200\198\207]\204Og\204\221.U\207\128\223\130P\196\SOH3\152\182m\155\a\174\190\159-\215\139bj|;\203\136\135\141\&0y{(hdL\155\232\EMzsu\NULu\244\FS\193\178\ESC\198\218\SI\158\209?V\DEL\228\b\173\157uI\199\218V\136\187\189\SI\202\142X\193\197\152`\173bp\196\DEL\199Y\138\226\216\146\182\192]\178\237>\227NS\EOTG\202g\EM"}) (TxSeq' {txSeqTxns = StrictSeq {fromStrict = fromList [ValidatedTx {body = TxBodyConstr TxBodyRaw {_inputs = fromList [], _collateral = fromList [TxInCompact (TxId {_unTxId = SafeHash "ae85d245a3d00bfde01f59f3c4fe0b4bfae1cb37e9cf91929eadcea4985711de"}) 176,TxInCompact (TxId {_unTxId = SafeHash "e88bd757ad5b9bedf372d8d3f0cf6c962a469db61a265f6418e1ffed86da29ec"}) 579,TxInCompact (TxId {_unTxId = SafeHash "ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25"}) 125], _outputs = StrictSeq {fromStrict = fromList [(Addr Mainnet (ScriptHashObj (ScriptHash "0d94e174732ef9aae73f395ab44507bfa983d65023c11a951f0c32e4")) (StakeRefPtr (Ptr (SlotNo 14412) 0 0)),Value 3 (fromList [(PolicyID {policyID = ScriptHash "4acf2773917c7b547c576a7ff110d2ba5733c1f1ca9cdc659aea3a56"},fromList [("\SOH",2)]),(PolicyID {policyID = ScriptHash "b5ae663aaea8e500157bdf4baafd6f5ba0ce5759f7cd4101fc132f54"},fromList [("\DC3",1)]),(PolicyID {policyID = ScriptHash "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541"},fromList [("\151",1)])]),SJust (SafeHash "bb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa"))]}, _certs = StrictSeq {fromStrict = fromList [DCertGenesis (GenesisDelegCert (KeyHash "b5ae663aaea8e500157bdf4baafd6f5ba0ce5759f7cd4101fc132f54") (KeyHash "4acf2773917c7b547c576a7ff110d2ba5733c1f1ca9cdc659aea3a56") "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314"),DCertDeleg (DeRegKey (KeyHashObj (KeyHash "4acf2773917c7b547c576a7ff110d2ba5733c1f1ca9cdc659aea3a56")))]}, _wdrls = Wdrl {unWdrl = fromList [(RewardAcnt {getRwdNetwork = Mainnet, getRwdCred = KeyHashObj (KeyHash "b16b56f5ec064be6ac3cab6035efae86b366cc3dc4a0d571603d70e5")},Coin 958)]}, _txfee = Coin 521, _vldt = ValidityInterval {invalidBefore = SJust (SlotNo 82903), invalidHereafter = SNothing}, _update = SJust (Update (ProposedPPUpdates (fromList [])) (EpochNo 78667)), _reqSignerHashes = fromList [], _mint = Value 0 (fromList []), _wppHash = SNothing, _adHash = SNothing, _txnetworkid = SNothing}, wits = TxWitnessRaw {_txwitsVKey = fromList [WitVKey' {wvkKey' = VKey (VerKeyEd25519DSIGN (PublicKey "\186\192\154q\v^\207\242\201MF\236\145\184:\250gd\199`\237Q\162\&0\170\196\EMj_\187\DC4\a")), wvkSig' = SignedDSIGN (SigEd25519DSIGN (Signature "\139Q\ETXz\145/e\252\213b\226\190\203\185\be\175\245\181\236\&9\STXF;\181 ca\244\212\CAN\130\251\EM\155\DC3\224\t\154\241\237\143\165\176\141\247\GS\128\128\190\214\EOTaERe0\bE\EOTK\242\190\208")), wvkKeyHash = KeyHash "4458eb67338a1116bc648c9d8f6102cf48e73478ad28730dfade4577", wvkBytes = "\130X \186\192\154q\v^\207\242\201MF\236\145\184:\250gd\199`\237Q\162\&0\170\196\EMj_\187\DC4\aX@\139Q\ETXz\145/e\252\213b\226\190\203\185\be\175\245\181\236\&9\STXF;\181 ca\244\212\CAN\130\251\EM\155\DC3\224\t\154\241\237\143\165\176\141\247\GS\128\128\190\214\EOTaERe0\bE\EOTK\242\190\208"},WitVKey' {wvkKey' = VKey (VerKeyEd25519DSIGN (PublicKey "cs\187\204\ESC0\130\159V\142\242\225\215\238\144\192\219\&2\140Mh\f\208\&7\149\156\US,|\211\NUL\v")), wvkSig' = SignedDSIGN (SigEd25519DSIGN (Signature " \228P:\216vJ\GS\198Gsy\243l`\207\238\&7I\202\174.\v.\r0\240<]~\142\140\b\RS\197\182\DC3\166\DC4\222\228\240\218\ENQq\RS\170G\200eU\195h\194W\185\151\188E\213\215\ENQg\157")), wvkKeyHash = KeyHash "640e694b4a2a981d1a9549f62bda890d960dde606f8d4807e09170ce", wvkBytes = "\130X cs\187\204\ESC0\130\159V\142\242\225\215\238\144\192\219\&2\140Mh\f\208\&7\149\156\US,|\211\NUL\vX@ \228P:\216vJ\GS\198Gsy\243l`\207\238\&7I\202\174.\v.\r0\240<]~\142\140\b\RS\197\182\DC3\166\DC4\222\228\240\218\ENQq\RS\170G\200eU\195h\194W\185\151\188E\213\215\ENQg\157"},WitVKey' {wvkKey' = VKey (VerKeyEd25519DSIGN (PublicKey "\169\242\200~1\189\&5\144\128\DC3\195\183u\fE\158\205\218}\205\145\237\187_w-?\242\208\159\SO\244")), wvkSig' = SignedDSIGN (SigEd25519DSIGN (Signature "\159\196\196\204\149\ETX$\217i\ENQ\244\191\&2\DC1\129[\ESC=\166\155\164R\214U\207\198\135\&7\215\197\DC4\228\251\150\&8\STX\DLE\RS\SI\141\167\252%>|O\225y\215M&\243\229\148\&2\171\232{\146\250\243~%\139")), wvkKeyHash = KeyHash "6efe01e62870ddc1f738d1a169f5385110c7b906d8191678ff96fbc7", wvkBytes = "\130X \169\242\200~1\189\&5\144\128\DC3\195\183u\fE\158\205\218}\205\145\237\187_w-?\242\208\159\SO\244X@\159\196\196\204\149\ETX$\217i\ENQ\244\191\&2\DC1\129[\ESC=\166\155\164R\214U\207\198\135\&7\215\197\DC4\228\251\150\&8\STX\DLE\RS\SI\141\167\252%>|O\225y\215M&\243\229\148\&2\171\232{\146\250\243~%\139"}], _txwitsBoot = fromList [BootstrapWitness' {bwKey' = VKey (VerKeyEd25519DSIGN (PublicKey "\241\253\251\150\247~\244b\t\139AY\169\154\&80{\168xO\142\184\135|\159=\184m\174n\DLE\189")), bwSig' = SignedDSIGN (SigEd25519DSIGN (Signature "amkvoumqqqeaztgvdqjpyiqkjgemadygupfnyaiabsvvoejlwoizebbljswjihvj")), bwChainCode' = ChainCode "tW", bwAttributes' = "\213\&2", bwBytes = "\132X \241\253\251\150\247~\244b\t\139AY\169\154\&80{\168xO\142\184\135|\159=\184m\174n\DLE\189X@amkvoumqqqeaztgvdqjpyiqkjgemadygupfnyaiabsvvoejlwoizebbljswjihvjBtWB\213\&2"},BootstrapWitness' {bwKey' = VKey (VerKeyEd25519DSIGN (PublicKey "\155A\138[\200A\SUB\210\231\140M\228\202\225\&4\195\151\149!\131\132=\EM\218\&8`\210\&6\250\178\149\206")), bwSig' = SignedDSIGN (SigEd25519DSIGN (Signature "ztnlfycoxaeiyflvwkrxrmcoiuzccwoljfxvmuxhrvodtsnlxzwkiycmaumsbbnt")), bwChainCode' = ChainCode "", bwAttributes' = "\DC1\253", bwBytes = "\132X \155A\138[\200A\SUB\210\231\140M\228\202\225\&4\195\151\149!\131\132=\EM\218\&8`\210\&6\250\178\149\206X@ztnlfycoxaeiyflvwkrxrmcoiuzccwoljfxvmuxhrvodtsnlxzwkiycmaumsbbnt@B\DC1\253"}], _txscripts = fromList [(ScriptHash "4509cdddad21412c22c9164e10bc6071340ba235562f1575a35ded4d",PlutusScript ScriptHash "4509cdddad21412c22c9164e10bc6071340ba235562f1575a35ded4d")], _txdats = TxDatsRaw (fromList [(SafeHash "5973d59655c379515965eb3087f0496c2bc5d4c91d2d9831c148d899adaddd6d",DataConstr B ">\140\SUB\194"),(SafeHash "642206314f534b29ad297d82440a5f9f210e30ca5ced805a587ca402de927342",DataConstr I 4),(SafeHash "ae85d245a3d00bfde01f59f3c4fe0b4bfae1cb37e9cf91929eadcea4985711de",DataConstr I (-1))]), _txrdmrs = RedeemersRaw (fromList [(RdmrPtr Rewrd 0,(DataConstr B "\133",ExUnits {exUnitsMem = 3, exUnitsSteps = 0}))])}, isValidating = IsValidating True, auxiliaryData = SNothing},ValidatedTx {body = TxBodyConstr TxBodyRaw {_inputs = fromList [TxInCompact (TxId {_unTxId = SafeHash "95c3003a78585e0db8c9496f6deef4de0ff000994b8534cd66d4fe96bb21ddd3"}) 741,TxInCompact (TxId {_unTxId = SafeHash "bb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa"}) 741,TxInCompact (TxId {_unTxId = SafeHash "ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25"}) 974], _collateral = fromList [TxInCompact (TxId {_unTxId = SafeHash "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314"}) 192,TxInCompact (TxId {_unTxId = SafeHash "e88bd757ad5b9bedf372d8d3f0cf6c962a469db61a265f6418e1ffed86da29ec"}) 985], _outputs = StrictSeq {fromStrict = fromList [(Addr Mainnet (ScriptHashObj (ScriptHash "4acf2773917c7b547c576a7ff110d2ba5733c1f1ca9cdc659aea3a56")) StakeRefNull,Value 0 (fromList []),SJust (SafeHash "ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25")),(AddrBootstrap (BootstrapAddress (Address {addrRoot = f56bf80fbb8e11c46c0b01e14e17f3874821b4f2e91f66a9d02beb8a, addrAttributes = Attributes { data: AddrAttributes {aaVKDerivationPath = Just (HDAddressPayload {getHDAddressPayload = "hzagaipgsqqhjonftvchtdcfezspbual"}), aaNetworkMagic = NetworkTestnet 2952834267} }, addrType = ATRedeem})),Value 2 (fromList []),SNothing),(AddrBootstrap (BootstrapAddress (Address {addrRoot = c65e19fa420194f791fc666b2239511a54cc1263314193e8bb45c002, addrAttributes = Attributes { data: AddrAttributes {aaVKDerivationPath = Nothing, aaNetworkMagic = NetworkMainOrStage} }, addrType = ATVerKey})),Value 2 (fromList [(PolicyID {policyID = ScriptHash "3542acb3a64d80c29302260d62c3b87a742ad14abf855ebc6733081e"},fromList [("\NULA",2)]),(PolicyID {policyID = ScriptHash "a646474b8f5431261506b6c273d307c7569a4eb6c96b42dd4a29520a"},fromList [("\233(",4)]),(PolicyID {policyID = ScriptHash "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541"},fromList [("",3)])]),SNothing)]}, _certs = StrictSeq {fromStrict = fromList [DCertDeleg (DeRegKey (KeyHashObj (KeyHash "b5ae663aaea8e500157bdf4baafd6f5ba0ce5759f7cd4101fc132f54")))]}, _wdrls = Wdrl {unWdrl = fromList [(RewardAcnt {getRwdNetwork = Testnet, getRwdCred = ScriptHashObj (ScriptHash "b5ae663aaea8e500157bdf4baafd6f5ba0ce5759f7cd4101fc132f54")},Coin 870),(RewardAcnt {getRwdNetwork = Testnet, getRwdCred = KeyHashObj (KeyHash "0d94e174732ef9aae73f395ab44507bfa983d65023c11a951f0c32e4")},Coin 250)]}, _txfee = Coin 313, _vldt = ValidityInterval {invalidBefore = SJust (SlotNo 89275), invalidHereafter = SJust (SlotNo 59752)}, _update = SJust (Update (ProposedPPUpdates (fromList [])) (EpochNo 41320)), _reqSignerHashes = fromList [], _mint = Value 0 (fromList []), _wppHash = SNothing, _adHash = SJust (AuxiliaryDataHash {unsafeAuxiliaryDataHash = SafeHash "0268be9dbd0446eaa217e1dec8f399249305e551d7fc1437dd84521f74aa621c"}), _txnetworkid = SJust Testnet}, wits = TxWitnessRaw {_txwitsVKey = fromList [WitVKey' {wvkKey' = VKey (VerKeyEd25519DSIGN (PublicKey "\155\165\178\196\142\DC2H\132\185\180y\189\163\145\185\&2\135\174\231\193+v\ENQ\230\236\DC3Y\ETX-;\141\195")), wvkSig' = SignedDSIGN (SigEd25519DSIGN (Signature "|\226\150\170\GSK\222\222\252\216\194\194F!\EM\206\236\247\197\146\247'\234\ENQ&u\156\169\f\t^x\181\217\188\DC2p*\255\164\166\144\246m\a\158\231i\179\156%O\ACKEF\188\232\FS\174\180\&4_\\\202")), wvkKeyHash = KeyHash "1addc04b5f1a3eed41713d8ec0acc236e7196855d3f84e32dec0ae87", wvkBytes = "\130X \155\165\178\196\142\DC2H\132\185\180y\189\163\145\185\&2\135\174\231\193+v\ENQ\230\236\DC3Y\ETX-;\141\195X@|\226\150\170\GSK\222\222\252\216\194\194F!\EM\206\236\247\197\146\247'\234\ENQ&u\156\169\f\t^x\181\217\188\DC2p*\255\164\166\144\246m\a\158\231i\179\156%O\ACKEF\188\232\FS\174\180\&4_\\\202"}], _txwitsBoot = fromList [], _txscripts = fromList [(ScriptHash "3f93bd2290d6e242cb212fba32b2a013f1f4ba764a5d152646cebc51",TimelockScript TimelockConstr AnyOf (StrictSeq {fromStrict = fromList [TimelockConstr TimeStart (SlotNo 81396),TimelockConstr TimeStart (SlotNo 28749),TimelockConstr TimeStart (SlotNo 31553),TimelockConstr AnyOf (StrictSeq {fromStrict = fromList [TimelockConstr Signature (KeyHash "b16b56f5ec064be6ac3cab6035efae86b366cc3dc4a0d571603d70e5"),TimelockConstr TimeStart (SlotNo 67335),TimelockConstr AnyOf (StrictSeq {fromStrict = fromList [TimelockConstr Signature (KeyHash "0d94e174732ef9aae73f395ab44507bfa983d65023c11a951f0c32e4"),TimelockConstr Signature (KeyHash "bd039f956f4b302f3ab6fc7c4bac3350a540f44af81a8492194dd2c2"),TimelockConstr Signature (KeyHash "3542acb3a64d80c29302260d62c3b87a742ad14abf855ebc6733081e")]}),TimelockConstr TimeExpire (SlotNo 65101),TimelockConstr TimeExpire (SlotNo 96958)]}),TimelockConstr TimeExpire (SlotNo 86871)]})),(ScriptHash "7e20f09e0a507214b59564da404ac7eda335bbdd815c9cf73aa8b369",TimelockScript TimelockConstr TimeExpire (SlotNo 55602)),(ScriptHash "e8b0c20ca7081d2b58572d63bd9408dfb4c85f95a610369c747d16af",TimelockScript TimelockConstr Signature (KeyHash "3542acb3a64d80c29302260d62c3b87a742ad14abf855ebc6733081e"))], _txdats = TxDatsRaw (fromList []), _txrdmrs = RedeemersRaw (fromList [(RdmrPtr Spend 2,(DataConstr Map [(B "\EOT",B "\204a")],ExUnits {exUnitsMem = 4, exUnitsSteps = 1})),(RdmrPtr Cert 3,(DataConstr Constr 1 [I (-5),B "\239\247\150{",List [Map [(I (-3),B "r\185\162g"),(I (-2),B "\CAN\231"),(B "n",B ""),(I 1,B "\235\aT"),(I (-2),I 4)],I (-4),Constr (-4) [I 4,I 1,I (-3)]]],ExUnits {exUnitsMem = 1, exUnitsSteps = 3})),(RdmrPtr Rewrd 0,(DataConstr B "\201",ExUnits {exUnitsMem = 0, exUnitsSteps = 2}))])}, isValidating = IsValidating False, auxiliaryData = SNothing}]}, txSeqBodyBytes = "\130\169\NUL\128\r\131\130X \174\133\210E\163\208\v\253\224\USY\243\196\254\vK\250\225\203\&7\233\207\145\146\158\173\206\164\152W\DC1\222\CAN\176\130X \232\139\215W\173[\155\237\243r\216\211\240\207l\150*F\157\182\SUB&_d\CAN\225\255\237\134\218)\236\EM\STXC\130X \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%\CAN}\SOH\129\131X!Q\r\148\225ts.\249\170\231?9Z\180E\a\191\169\131\214P#\193\SUB\149\US\f2\228\240L\NUL\NUL\130\ETX\163X\FSJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:V\161A\SOH\STXX\FS\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/T\161A\DC3\SOHX\FS\224\167\DC41\152\DC2\195\247s\186\EOT\236]k?\252\213\170\216P\ACK\128[\EOT{\b%A\161A\151\SOHX \187\&0\164,\RSb\240\175\218_\nN\138V/z\DC3\162L\234\NUL\238\129\145{\134\184\158\128\DC3\DC4\170\STX\EM\STX\t\EOT\130\132\ENQX\FS\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/TX\FSJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:VX \ETX\ETB\n.u\151\183\183\227\216L\ENQ9\GS\DC3\154b\177W\231\135\134\216\192\130\242\157\207L\DC1\DC3\DC4\130\SOH\130\NULX\FSJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:V\ENQ\161X\GS\225\177kV\245\236\ACKK\230\172<\171`5\239\174\134\179f\204=\196\160\213q`=p\229\EM\ETX\190\ACK\130\160\SUB\NUL\SOH3K\b\SUB\NUL\SOHC\215\SO\128\172\NUL\131\130X \149\195\NUL:xX^\r\184\201Iom\238\244\222\SI\240\NUL\153K\133\&4\205f\212\254\150\187!\221\211\EM\STX\229\130X \187\&0\164,\RSb\240\175\218_\nN\138V/z\DC3\162L\234\NUL\238\129\145{\134\184\158\128\DC3\DC4\170\EM\STX\229\130X \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%\EM\ETX\206\r\130\130X \ETX\ETB\n.u\151\183\183\227\216L\ENQ9\GS\DC3\154b\177W\231\135\134\216\192\130\242\157\207L\DC1\DC3\DC4\CAN\192\130X \232\139\215W\173[\155\237\243r\216\211\240\207l\150*F\157\182\SUB&_d\CAN\225\255\237\134\218)\236\EM\ETX\217\SOH\131\131X\GSqJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:V\NULX \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%\130XW\130\216\CANXM\131X\FS\245k\248\SI\187\142\DC1\196l\v\SOH\225N\ETB\243\135H!\180\242\233\USf\169\208+\235\138\162\SOHX\"X hzagaipgsqqhjonftvchtdcfezspbual\STXE\SUB\176\NUL\172\219\STX\SUB\182\179\199+\STX\130X+\130\216\CANX!\131X\FS\198^\EM\250B\SOH\148\247\145\252fk\"9Q\SUBT\204\DC2c1A\147\232\187E\192\STX\160\NUL\SUB\SUB\234\&6\139\130\STX\163X\FS5B\172\179\166M\128\194\147\STX&\rb\195\184zt*\209J\191\133^\188g3\b\RS\161B\NULA\STXX\FS\166FGK\143T1&\NAK\ACK\182\194s\211\a\199V\154N\182\201kB\221J)R\n\161B\233(\EOTX\FS\224\167\DC41\152\DC2\195\247s\186\EOT\236]k?\252\213\170\216P\ACK\128[\EOT{\b%A\161@\ETX\STX\EM\SOH9\ETX\EM\233h\EOT\129\130\SOH\130\NULX\FS\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/T\ENQ\162X\GS\240\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/T\EM\ETXfX\GS\224\r\148\225ts.\249\170\231?9Z\180E\a\191\169\131\214P#\193\SUB\149\US\f2\228\CAN\250\ACK\130\160\EM\161h\b\SUB\NUL\SOH\\\187\SO\128\aX \STXh\190\157\189\EOTF\234\162\ETB\225\222\200\243\153$\147\ENQ\229Q\215\252\DC47\221\132R\USt\170b\FS\SI\NUL", txSeqWitsBytes = "\130\165\NUL\131\130X \186\192\154q\v^\207\242\201MF\236\145\184:\250gd\199`\237Q\162\&0\170\196\EMj_\187\DC4\aX@\139Q\ETXz\145/e\252\213b\226\190\203\185\be\175\245\181\236\&9\STXF;\181 ca\244\212\CAN\130\251\EM\155\DC3\224\t\154\241\237\143\165\176\141\247\GS\128\128\190\214\EOTaERe0\bE\EOTK\242\190\208\130X cs\187\204\ESC0\130\159V\142\242\225\215\238\144\192\219\&2\140Mh\f\208\&7\149\156\US,|\211\NUL\vX@ \228P:\216vJ\GS\198Gsy\243l`\207\238\&7I\202\174.\v.\r0\240<]~\142\140\b\RS\197\182\DC3\166\DC4\222\228\240\218\ENQq\RS\170G\200eU\195h\194W\185\151\188E\213\215\ENQg\157\130X \169\242\200~1\189\&5\144\128\DC3\195\183u\fE\158\205\218}\205\145\237\187_w-?\242\208\159\SO\244X@\159\196\196\204\149\ETX$\217i\ENQ\244\191\&2\DC1\129[\ESC=\166\155\164R\214U\207\198\135\&7\215\197\DC4\228\251\150\&8\STX\DLE\RS\SI\141\167\252%>|O\225y\215M&\243\229\148\&2\171\232{\146\250\243~%\139\STX\130\132X \241\253\251\150\247~\244b\t\139AY\169\154\&80{\168xO\142\184\135|\159=\184m\174n\DLE\189X@amkvoumqqqeaztgvdqjpyiqkjgemadygupfnyaiabsvvoejlwoizebbljswjihvjBtWB\213\&2\132X \155A\138[\200A\SUB\210\231\140M\228\202\225\&4\195\151\149!\131\132=\EM\218\&8`\210\&6\250\178\149\206X@ztnlfycoxaeiyflvwkrxrmcoiuzccwoljfxvmuxhrvodtsnlxzwkiycmaumsbbnt@B\DC1\253\ETX\129FE\SOH\NUL\NUL&\SOH\EOT\131D>\140\SUB\194\EOT \ENQ\129\132\ETX\NULA\133\130\ETX\NUL\163\NUL\129\130X \155\165\178\196\142\DC2H\132\185\180y\189\163\145\185\&2\135\174\231\193+v\ENQ\230\236\DC3Y\ETX-;\141\195X@|\226\150\170\GSK\222\222\252\216\194\194F!\EM\206\236\247\197\146\247'\234\ENQ&u\156\169\f\t^x\181\217\188\DC2p*\255\164\166\144\246m\a\158\231i\179\156%O\ACKEF\188\232\FS\174\180\&4_\\\202\SOH\131\130\STX\133\130\EOT\SUB\NUL\SOH=\244\130\EOT\EMpM\130\EOT\EM{A\130\STX\133\130\NULX\FS\177kV\245\236\ACKK\230\172<\171`5\239\174\134\179f\204=\196\160\213q`=p\229\130\EOT\SUB\NUL\SOH\a\a\130\STX\131\130\NULX\FS\r\148\225ts.\249\170\231?9Z\180E\a\191\169\131\214P#\193\SUB\149\US\f2\228\130\NULX\FS\189\ETX\159\149oK0/:\182\252|K\172\&3P\165@\244J\248\SUB\132\146\EMM\210\194\130\NULX\FS5B\172\179\166M\128\194\147\STX&\rb\195\184zt*\209J\191\133^\188g3\b\RS\130\ENQ\EM\254M\130\ENQ\SUB\NUL\SOHz\190\130\ENQ\SUB\NUL\SOHSW\130\ENQ\EM\217\&2\130\NULX\FS5B\172\179\166M\128\194\147\STX&\rb\195\184zt*\209J\191\133^\188g3\b\RS\ENQ\131\132\NUL\STX\161A\EOTB\204a\130\EOT\SOH\132\STX\ETX\216z\131$D\239\247\150{\131\165\"Dr\185\162g!B\CAN\231An@\SOHC\235\aT!\EOT#\216f\132#\EOT\SOH\"\130\SOH\ETX\132\ETX\NULA\201\130\NUL\STX", txSeqMetadataBytes = "\160", txSeqIsValidatingBytes = "\129\SOH"}) "\133\130\143\CAN'\SOHX \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%X `3zdek\242dof\201\n\180\165F\187\243\195\245\248\240\v\240o\204\GS\159}\SOH\217$\246X \156\132mD\180\DC4\196M\a\217\158T\208;\196\247\134\n\137=\200H\229\&3[\202\SOH>_!\218P\130X@\135\190\SI\DC1\188\254\ACKlo\226k\251pf\SUB\189\NAKu\221M\197\184\183\193\173\205\&0\154\239\DC2\vpwd!:\138\ESC\233\179\r\DC2;\139\222\129\243\214\174\162\190=fODY\187XE\222\148&LHXP\221\ETX\165:+\151W\161Iq>9\US\b\219\160=\205\151\170M'\238j\254Q\215\220D\184\ESCy\209\235\180\131\200\190)\147ca\161A\STX\129\247W\142\209'\219\&7k\198~\255:\ETX7\228:\167\229\209D\196\&1\209\235\222a\218|\147\ENQ*\246\164\ACK\130X@\135\187\214\230\135\231r\179\225g\155\SOH\ETX$(\187\DEL\151\147\247J\DC2\209-\167\185e\GS7\ETX\fz\214\176\141\189\228I\141\227?O\182\&7\183.\231\138\DC1\189>s\178)\251\139\238\233\152\DLE\224T_\163XP2P$Q:L\248\DLE\244\FS\196\238\DC3F\SI\DC3`Y\GS\215\238`\202\nn\164\215\EOT\231\224\b<\140\156*\165q)\202\215%\139\&9\129\210\243M\ACK\164*\196\209*j\152\215\n\206\210l\188\135\131\DEL?\240pD\239TU4\171\146g\233\DC4\229\135\v\EM\ETX\tX \174\133\210E\163\208\v\253\224\USY\243\196\254\vK\250\225\203\&7\233\207\145\146\158\173\206\164\152W\DC1\222X \148O\USZ \165\EMR\ACK\144k\242\232\138\177R\EM\234\DC4\247\&9&Hl\175\225\141\&5\162a{\185\SOH\SOHX@zd\b\194\EMM\243y\173\149\218\216#j+\134I:\t,\206\239\218!\CAN\194(fWA9+\246Y\158\236\185\rr{)\144^\249\ESCv;&B\155W\253-\160H\213\205\160\187z\NULX\FS\t\NUL\NULY\SOH\192K\137\NUL2\211\223\&9\DLE\234t\148\170\160-\ESC0s_%\149\206\178\162\DC2\221\138 \238\211b9\160L\NULrPI\130\FS\178M\140\163\&9\218\247M\228\157\212\176\DC4\n|z\190!Iw#\DC3\STX\249\SOH+m4GP\ACK\201\210\239G\149\222\225\214\177\216(!\182\190\165(\DLE(\214\169\247\197\245\v\248kV\163\133K\255U\197y/dT2\211G\a\137p\128\165\184\228\175?5\134f\255\141\nT^\192\CAN\234\243\163\248\198\159\194E\168x\251.\RS\135\179\233k\197t\184\SI\US\239\&5\DEL\163\178\158>\209\&0\142\185\219\DLE\194hU#\172p%\130\"\193\207q\229\ESC\230\229\154\205\169\SUB\180~\180\242\175\150y\140\164\247\161\206BS\135\243J\128&J\SOH\DC2\DC1-\252\241\163\143)\EOT\164\187+\244g\\\232\176=^\209:\130B\209\161y\162\&5\146Owq0\254\NUL\161;\137\169?9\FS\t\DEL\194w\RS\210\&8=g`\ESC\229\154Hh\158!\171\228\150\&7\194\&1\SYN\252\NAK\131`\183\NUL3z\209\244>\221\244yK\206\a\234\186\223M\t#'\155k\238A\130\ACK\STXW\230\200\NAK\CAN*\163\130\164\219\152cB\167\195\226<\SI\173Y{\DEL%\CAN\DC22,?D\\\213\171F\222\139\200\198\207]\204Og\204\221.U\207\128\223\130P\196\SOH3\152\182m\155\a\174\190\159-\215\139bj|;\203\136\135\141\&0y{(hdL\155\232\EMzsu\NULu\244\FS\193\178\ESC\198\218\SI\158\209?V\DEL\228\b\173\157uI\199\218V\136\187\189\SI\202\142X\193\197\152`\173bp\196\DEL\199Y\138\226\216\146\182\192]\178\237>\227NS\EOTG\202g\EM\130\169\NUL\128\r\131\130X \174\133\210E\163\208\v\253\224\USY\243\196\254\vK\250\225\203\&7\233\207\145\146\158\173\206\164\152W\DC1\222\CAN\176\130X \232\139\215W\173[\155\237\243r\216\211\240\207l\150*F\157\182\SUB&_d\CAN\225\255\237\134\218)\236\EM\STXC\130X \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%\CAN}\SOH\129\131X!Q\r\148\225ts.\249\170\231?9Z\180E\a\191\169\131\214P#\193\SUB\149\US\f2\228\240L\NUL\NUL\130\ETX\163X\FSJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:V\161A\SOH\STXX\FS\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/T\161A\DC3\SOHX\FS\224\167\DC41\152\DC2\195\247s\186\EOT\236]k?\252\213\170\216P\ACK\128[\EOT{\b%A\161A\151\SOHX \187\&0\164,\RSb\240\175\218_\nN\138V/z\DC3\162L\234\NUL\238\129\145{\134\184\158\128\DC3\DC4\170\STX\EM\STX\t\EOT\130\132\ENQX\FS\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/TX\FSJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:VX \ETX\ETB\n.u\151\183\183\227\216L\ENQ9\GS\DC3\154b\177W\231\135\134\216\192\130\242\157\207L\DC1\DC3\DC4\130\SOH\130\NULX\FSJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:V\ENQ\161X\GS\225\177kV\245\236\ACKK\230\172<\171`5\239\174\134\179f\204=\196\160\213q`=p\229\EM\ETX\190\ACK\130\160\SUB\NUL\SOH3K\b\SUB\NUL\SOHC\215\SO\128\172\NUL\131\130X \149\195\NUL:xX^\r\184\201Iom\238\244\222\SI\240\NUL\153K\133\&4\205f\212\254\150\187!\221\211\EM\STX\229\130X \187\&0\164,\RSb\240\175\218_\nN\138V/z\DC3\162L\234\NUL\238\129\145{\134\184\158\128\DC3\DC4\170\EM\STX\229\130X \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%\EM\ETX\206\r\130\130X \ETX\ETB\n.u\151\183\183\227\216L\ENQ9\GS\DC3\154b\177W\231\135\134\216\192\130\242\157\207L\DC1\DC3\DC4\CAN\192\130X \232\139\215W\173[\155\237\243r\216\211\240\207l\150*F\157\182\SUB&_d\CAN\225\255\237\134\218)\236\EM\ETX\217\SOH\131\131X\GSqJ\207's\145|{T|Wj\DEL\241\DLE\210\186W3\193\241\202\156\220e\154\234:V\NULX \238\NAKZ\206\156@) t\203j\255\140\156\205\210s\200\SYNH\255\DC1I\239\&6\188\234n\187\138>%\130XW\130\216\CANXM\131X\FS\245k\248\SI\187\142\DC1\196l\v\SOH\225N\ETB\243\135H!\180\242\233\USf\169\208+\235\138\162\SOHX\"X hzagaipgsqqhjonftvchtdcfezspbual\STXE\SUB\176\NUL\172\219\STX\SUB\182\179\199+\STX\130X+\130\216\CANX!\131X\FS\198^\EM\250B\SOH\148\247\145\252fk\"9Q\SUBT\204\DC2c1A\147\232\187E\192\STX\160\NUL\SUB\SUB\234\&6\139\130\STX\163X\FS5B\172\179\166M\128\194\147\STX&\rb\195\184zt*\209J\191\133^\188g3\b\RS\161B\NULA\STXX\FS\166FGK\143T1&\NAK\ACK\182\194s\211\a\199V\154N\182\201kB\221J)R\n\161B\233(\EOTX\FS\224\167\DC41\152\DC2\195\247s\186\EOT\236]k?\252\213\170\216P\ACK\128[\EOT{\b%A\161@\ETX\STX\EM\SOH9\ETX\EM\233h\EOT\129\130\SOH\130\NULX\FS\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/T\ENQ\162X\GS\240\181\174f:\174\168\229\NUL\NAK{\223K\170\253o[\160\206WY\247\205A\SOH\252\DC3/T\EM\ETXfX\GS\224\r\148\225ts.\249\170\231?9Z\180E\a\191\169\131\214P#\193\SUB\149\US\f2\228\CAN\250\ACK\130\160\EM\161h\b\SUB\NUL\SOH\\\187\SO\128\aX \STXh\190\157\189\EOTF\234\162\ETB\225\222\200\243\153$\147\ENQ\229Q\215\252\DC47\221\132R\USt\170b\FS\SI\NUL\130\165\NUL\131\130X \186\192\154q\v^\207\242\201MF\236\145\184:\250gd\199`\237Q\162\&0\170\196\EMj_\187\DC4\aX@\139Q\ETXz\145/e\252\213b\226\190\203\185\be\175\245\181\236\&9\STXF;\181 ca\244\212\CAN\130\251\EM\155\DC3\224\t\154\241\237\143\165\176\141\247\GS\128\128\190\214\EOTaERe0\bE\EOTK\242\190\208\130X cs\187\204\ESC0\130\159V\142\242\225\215\238\144\192\219\&2\140Mh\f\208\&7\149\156\US,|\211\NUL\vX@ \228P:\216vJ\GS\198Gsy\243l`\207\238\&7I\202\174.\v.\r0\240<]~\142\140\b\RS\197\182\DC3\166\DC4\222\228\240\218\ENQq\RS\170G\200eU\195h\194W\185\151\188E\213\215\ENQg\157\130X \169\242\200~1\189\&5\144\128\DC3\195\183u\fE\158\205\218}\205\145\237\187_w-?\242\208\159\SO\244X@\159\196\196\204\149\ETX$\217i\ENQ\244\191\&2\DC1\129[\ESC=\166\155\164R\214U\207\198\135\&7\215\197\DC4\228\251\150\&8\STX\DLE\RS\SI\141\167\252%>|O\225y\215M&\243\229\148\&2\171\232{\146\250\243~%\139\STX\130\132X \241\253\251\150\247~\244b\t\139AY\169\154\&80{\168xO\142\184\135|\159=\184m\174n\DLE\189X@amkvoumqqqeaztgvdqjpyiqkjgemadygupfnyaiabsvvoejlwoizebbljswjihvjBtWB\213\&2\132X \155A\138[\200A\SUB\210\231\140M\228\202\225\&4\195\151\149!\131\132=\EM\218\&8`\210\&6\250\178\149\206X@ztnlfycoxaeiyflvwkrxrmcoiuzccwoljfxvmuxhrvodtsnlxzwkiycmaumsbbnt@B\DC1\253\ETX\129FE\SOH\NUL\NUL&\SOH\EOT\131D>\140\SUB\194\EOT \ENQ\129\132\ETX\NULA\133\130\ETX\NUL\163\NUL\129\130X \155\165\178\196\142\DC2H\132\185\180y\189\163\145\185\&2\135\174\231\193+v\ENQ\230\236\DC3Y\ETX-;\141\195X@|\226\150\170\GSK\222\222\252\216\194\194F!\EM\206\236\247\197\146\247'\234\ENQ&u\156\169\f\t^x\181\217\188\DC2p*\255\164\166\144\246m\a\158\231i\179\156%O\ACKEF\188\232\FS\174\180\&4_\\\202\SOH\131\130\STX\133\130\EOT\SUB\NUL\SOH=\244\130\EOT\EMpM\130\EOT\EM{A\130\STX\133\130\NULX\FS\177kV\245\236\ACKK\230\172<\171`5\239\174\134\179f\204=\196\160\213q`=p\229\130\EOT\SUB\NUL\SOH\a\a\130\STX\131\130\NULX\FS\r\148\225ts.\249\170\231?9Z\180E\a\191\169\131\214P#\193\SUB\149\US\f2\228\130\NULX\FS\189\ETX\159\149oK0/:\182\252|K\172\&3P\165@\244J\248\SUB\132\146\EMM\210\194\130\NULX\FS5B\172\179\166M\128\194\147\STX&\rb\195\184zt*\209J\191\133^\188g3\b\RS\130\ENQ\EM\254M\130\ENQ\SUB\NUL\SOHz\190\130\ENQ\SUB\NUL\SOHSW\130\ENQ\EM\217\&2\130\NULX\FS5B\172\179\166M\128\194\147\STX&\rb\195\184zt*\209J\191\133^\188g3\b\RS\ENQ\131\132\NUL\STX\161A\EOTB\204a\130\EOT\SOH\132\STX\ETX\216z\131$D\239\247\150{\131\165\"Dr\185\162g!B\CAN\231An@\SOHC\235\aT!\EOT#\216f\132#\EOT\SOH\"\130\SOH\ETX\132\ETX\NULA\201\130\NUL\STX\160\129\SOH", shelleyBlockHeaderHash = ShelleyHash {unShelleyHash = HashHeader {unHashHeader = "3aab0cf29afeaaa354c712f1a20e2153b36cb0363ee828aa125ba7c1b8d0d823"}}}))))))},Tip (SlotNo 10216) 95c3003a78585e0db8c9496f6deef4de0ff000994b8534cd66d4fe96bb21ddd3 (BlockNo 4))

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 23, 2021

With this diff, the ouroboros-consensus-cardano-test:test:test exe from (an innocuous extension of) 36cb0b9 passes with -p 'roundtrip blk' --quickcheck-tests=1000.

$ git diff -- '*hs'
diff --git a/ouroboros-consensus-test/src/Test/Util/Serialisation/Roundtrip.hs b/ouroboros-consensus-test/src/Test/Util/Serialisation/Roundtrip.hs
index bdf4bdc72..854962fa4 100644
--- a/ouroboros-consensus-test/src/Test/Util/Serialisation/Roundtrip.hs
+++ b/ouroboros-consensus-test/src/Test/Util/Serialisation/Roundtrip.hs
@@ -32,6 +32,7 @@ module Test.Util.Serialisation.Roundtrip (
 
 import           Codec.CBOR.Decoding (Decoder)
 import           Codec.CBOR.Encoding (Encoding)
+import qualified Codec.CBOR.FlatTerm as FT
 import           Codec.CBOR.Read (deserialiseFromBytes)
 import           Codec.CBOR.Write (toLazyByteString)
 import qualified Data.ByteString.Base16.Lazy as Base16
@@ -93,6 +94,10 @@ roundtrip' :: (Eq a, Show a)
            -> Property
 roundtrip' enc dec a = case deserialiseFromBytes dec bs of
     Right (bs', a')
+      | not (FT.validFlatTerm flatTerm)
+      ->
+          counterexample ("invalid flat term " <> show flatTerm)
+        $ property False
       | Lazy.null bs'
       -> a === a' bs
       | otherwise
@@ -106,6 +111,9 @@ roundtrip' enc dec a = case deserialiseFromBytes dec bs of
     toBase16 :: Lazy.ByteString -> String
     toBase16 = Char8.unpack . Base16.encode
 
+    flatTerm :: FT.FlatTerm
+    flatTerm = FT.toFlatTerm (enc a)
+
 {------------------------------------------------------------------------------
   Test skeleton
 ------------------------------------------------------------------------------}

So, on to brainstorming differences. Can you share here with commits of ouroboros-network and cardano-ledger-specs your latest repro involves?

I think these tests are using a dummy value for epochSlots = 100. That's the only difference I'm yet aware of.

I'm rerunning them now with additional patches to force all the tests to use NodeToClientV_9.

@KtorZ
Copy link
Contributor

KtorZ commented Jul 23, 2021

ouroboros-network: e338f2cf8e1078fbda9555dd2b169c6737ef6774
cardano-ledger-specs: ec9c77edbf5700a4b2ece8f97a1e313df06abc97

These are the same as cardano-node uses in 1.28.0

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 23, 2021

The code you shared passes 1000 tests when I build it against an extension of this ouroboros-network commit.

36cb0b970 - (origin/master, origin/bors/staging, origin/HEAD) Merge #3230 (16 hours ago) <iohk-bors[bot]>

The extension commits change:

 source-repository-package
   type: git
   location: https://github.com/input-output-hk/cardano-base
-  tag: eb58eebc16ee898980c83bc325ab37a2c77b2414
-  --sha256: 1v5algrsa3g6lphl1nfih54xkc2xa5q1yfa3kgclcp6sxj1yjnnl
+  tag: 8c732560b201b5da8e3bdf175c6eda73a32d64bc
+  --sha256: 0nwy03wyd2ks4qxg47py7lm18karjz6vs7p8knmn3zy72i3n9rfi

and

 source-repository-package
   type: git
   location: https://github.com/input-output-hk/cardano-ledger-specs
-  tag: 136967cd3700f34c57cd70be7aceca8a5efca485
-  --sha256: 020sm2wsmc9qhkpmjz0qi8wl6w95lq5g0m1gvlivb0kc78w3lmhd
+  tag: 51561fcb13170e3849873eef82e634c1041ee1d6
+  --sha256: 1699hbz1i92hbjjzv9ym43qzji5xiz7gqbd0y8m2ylc353c0sxzn

So, in summary, if I use very recent tips of cardano-ledger-specs and ouroboros-network, I don't see a failure using your repro.

@KtorZ
Copy link
Contributor

KtorZ commented Jul 23, 2021

Let me try locally with those revisions.

I guess it'll solve the issue on my hand, but we certainly need to patch cardano-node@1.28.0 🤔
I wonder how this went through though; I had a look at the roundtrip tests you showed above in the codebase, but it seems to me that they are only testing encoding/decoding of types used inside mini-protocols messages, but not the codec themselves?

@KtorZ
Copy link
Contributor

KtorZ commented Jul 23, 2021

Arg. Testing it locally is going to be harder... as I also depend on cardano-node & cardano-api for a few things, which require a different / incompatible version of plutus than the bumped cardano-ledger-specs...

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 23, 2021

Arg. Testing it locally is going to be harder... as I also depend on cardano-node & cardano-api for a few things, which require a different / incompatible version of plutus than the bumped cardano-ledger-specs...

Oof. I hear you.

I'm out of my phone calls now; I'll try now to repro within my dev environment using the revisions you shared.

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 23, 2021

Hmm. Your code is not failing for me on the commits you specified.

$ git status -suno
$ git lg -2
abcb87df2 - (HEAD -> nfrisby/ktorz-codec-error-repro, origin/nfrisby/ktorz-codec-error-repro) TEMP KtorZ codec error repro (5 minutes ago) <Nicolas Frisby>
e338f2cf8 - Merge #3243 (2 weeks ago) <iohk-bors[bot]>
$ grep -C2 -e ledger-specs cabal.project
source-repository-package
  type: git
  location: https://github.com/input-output-hk/cardano-ledger-specs
  tag: ec9c77edbf5700a4b2ece8f97a1e313df06abc97
  --sha256: 1ia8x9dnw36y0xazg7xg263ax9mamw9w4sg460cmibj3wv49im4w
$ nix-shell -j4
$ cabal run -j4 ouroboros-consensus-cardano-test:test:test -- -p adhoc --quickcheck-tests=1000 
...
cardano
  adhoc: OK (503.74s)
    +++ OK, passed 1000 tests.

All 1 tests passed (503.74s)

Please take no offense, but now I'm wondering if there is some confusion in your build process about which versions of upstream components are being used when you're seeing this test fail. (I've double-checked this on my end, eg: I think a clean git status and exiting and re-entering the nix-shell is strong evidence.)

But maybe you can check my nfrisby/ktorz-codec-error-repro branch to make sure I copy-pasted your repro correctly, eg?

@KtorZ
Copy link
Contributor

KtorZ commented Jul 23, 2021

@nfrisby it does not fail on your branch with this dependencies set indeed. I am quite sure about the versions of upstream components I use, as far as one can be sure with stack -- though I also tried on a clean installation with the same results.

So, out of paranoia I also aligned the other dependencies which I'd suspect to be good candidates for introducing an issue; namely: cardano-base, plutus and cardano-prelude. And.. it fails in one test similarly to what I experience on my setup. To be clear, I am not using any "fancy" dependency set, but the same on as defined in cardano-node for the 1.28.0 tag (that is: https://github.com/input-output-hk/cardano-node/blob/48429531f0d3d71fadce9a5971bf56a6df396f2d/cabal.project)

Here's the diff from your branch.

(edit I pushed the diff to your branch, since I can. Feel free to try and let me know 🙏)

diff --git a/cabal.project b/cabal.project
index 1e751eef6..fab37e786 100644
--- a/cabal.project
+++ b/cabal.project
@@ -1,4 +1,4 @@
-index-state: 2021-02-15T00:00:00Z
+index-state: 2021-04-30T00:00:00Z
 
 packages: ./typed-protocols
           ./typed-protocols-examples
@@ -177,8 +177,8 @@ source-repository-package
 source-repository-package
   type: git
   location: https://github.com/input-output-hk/cardano-prelude
-  tag: bb4ed71ba8e587f672d06edf9d2e376f4b055555
-  --sha256: 00h10l5mmiza9819p9v5q5749nb9pzgi20vpzpy1d34zmh6gf1cj
+  tag: fd773f7a58412131512b9f694ab95653ac430852
+  --sha256: 02jddik1yw0222wd6q0vv10f7y8rdgrlqaiy83ph002f9kjx7mh6
   subdir:
     cardano-prelude
     cardano-prelude-test
@@ -186,8 +186,8 @@ source-repository-package
 source-repository-package
   type: git
   location: https://github.com/input-output-hk/cardano-base
-  tag: 0f409343c3655c4bacd7fab385d392ec5d5cca98
-  --sha256: 0js76inb7avg8c39c9k2zsr77sycg2vadylgvsswdsba808p6hr9
+  tag: b6a215c42a28dc8b71b42946fe30256a333d34af
+  --sha256: 1l9nqsg6kfkfadlbvyl4afdf8v408zf0fn6dkihqf56g2mnk4i04
   subdir:
     binary
     binary/test
@@ -222,13 +222,20 @@ source-repository-package
 source-repository-package
   type: git
   location: https://github.com/input-output-hk/plutus
-  tag: c89e13e66c5bef628a1f7ea3a3732951be8be8ba
-  --sha256: 0hdck39i4yv656phxjy5ppqgzrq7x3q4b5rf8vj7hrzcs0aggl8r
+  tag: 523f349f3d68db07c98150734793ed7003d1f562
+  --sha256: 0vp6wiv1fz5bzvw90pdwv96nck78m5s91xiwjhkksq06l1yqr3ps
   subdir:
     plutus-ledger-api
     plutus-tx
     plutus-core
     prettyprinter-configurable
+    word-array
+
+source-repository-package
+  type: git
+  location: https://github.com/Quid2/flat.git
+  tag: 95e5d7488451e43062ca84d5376b3adcc465f1cd
+  --sha256: 06l31x3y93rjpryvlxnpsyq2zyxvb0z6lik6yq2fvh36i5zwvwa3
 
 source-repository-package
   type: git
@@ -239,5 +246,5 @@ source-repository-package
 source-repository-package
   type: git
   location: https://github.com/input-output-hk/cardano-crypto
-  tag: f73079303f663e028288f9f4a9e08bcca39a923e
-  --sha256: 1n87i15x54s0cjkh3nsxs4r1x016cdw1fypwmr68936n3xxsjn6q
+  tag: ce8f1934e4b6252084710975bd9bbc0a4648ece4
+  --sha256: 1v2laq04piyj511b2m77hxjh9l1yd6k9kc7g6bjala4w3zdwa4ni

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 24, 2021

Hmm. Ah, yes, Plutus script serialization changed "recently", so I could imagine the plutus version makes the difference.

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 26, 2021

cardano-prelude adds

d773f7 - (origin/master, origin/HEAD) Merge pull request #159 from input-output-hk/upgrade-to-cabal-3.4.0.0 (4 months ago) <John Ky>

cardano-base adds

b6a215c - Merge pull request #222 from input-output-hk/utctime_serialisation (3 weeks ago) <Duncan Coutts>
27f93e6 - Merge pull request #217 from input-output-hk/dcoutts/fromcbor-ratio (7 weeks ago) <Duncan Coutts>
a715c7f - Merge pull request #216 from input-output-hk/upgrade-to-cabal-3.4.0.0 (2 months ago) <John Ky>

cardano-crypto is also minor.

ce8f193 - (HEAD -> master, origin/master, origin/HEAD) Merge pull request #70 from newhoggy/use-cabal-3.4.0.0-rc (6 months ago) <Eduardo Morais>

The plutus change adds tens of PRs; several weeks worth. And the current target doesn't even seem to be from the master branch. Merging that was probably an oversight.


I could imagine the cardano-base and the plutus diffs being relevant somehow.

@nfrisby
Copy link
Contributor Author

nfrisby commented Jul 27, 2021

I opened Issue IntersectMBO/cardano-ledger#2397 for what I think is causing this failure, @KtorZ

Edit: Jared resolved that issue 👍

@dnadales dnadales self-assigned this Aug 21, 2023
github-merge-queue bot pushed a commit to IntersectMBO/ouroboros-consensus that referenced this issue Sep 20, 2023
- Check that the encoders used in the serialization roundtrip are valid.
- Add a unit test to check that the encoders used to encode the Cardano
examples are valid.

Needs: well-typed/cborg#324.

Closes IntersectMBO/ouroboros-network#3099.
@dnadales
Copy link
Member

I re-introduced the commit that adds valid-CBOR tests in this branch. The tests are still failing. This is currently blocked on:

@dnadales
Copy link
Member

It turns out that this error occurs due to the use of legacy encoders. I'll discuss with @amesgen how to exclude the legacy encoders from the tests.

github-merge-queue bot pushed a commit to IntersectMBO/ouroboros-consensus that referenced this issue Nov 13, 2023
Fixes IntersectMBO/ouroboros-network#3099

Sadly some CBOR validity tests need to be skipped due to:

- IntersectMBO/cardano-ledger#3800
- IntersectMBO/cardano-ledger#3741
- IntersectMBO/cardano-ledger#3740

This patch introduces an ad-hoc filtering mechanism to fix problems with
legacy encoders.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consensus issues related to ouroboros-consensus good first issue Good for newcomers
Projects
None yet
3 participants