Skip to content

Commit 446a135

Browse files
committed
Add a golden test for the localTxSubmissionServer.
1 parent 7eba954 commit 446a135

File tree

4 files changed

+211
-9
lines changed

4 files changed

+211
-9
lines changed

ouroboros-consensus-cardano/ouroboros-consensus-cardano.cabal

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ test-suite cardano-test
414414
other-modules:
415415
Test.Consensus.Cardano.ByronCompatibility
416416
Test.Consensus.Cardano.Golden
417+
Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.ByteStringTxParser
418+
Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.Server
417419
Test.Consensus.Cardano.Serialisation
418420
Test.ThreadNet.AllegraMary
419421
Test.ThreadNet.Cardano
@@ -422,6 +424,7 @@ test-suite cardano-test
422424

423425
build-depends:
424426
, base
427+
, base16-bytestring
425428
, byron-testlib
426429
, bytestring
427430
, cardano-crypto-class
@@ -434,18 +437,23 @@ test-suite cardano-test
434437
, cardano-testlib
435438
, cborg
436439
, containers
440+
, contra-tracer
437441
, filepath
438442
, microlens
439-
, ouroboros-consensus-cardano
443+
, ouroboros-consensus-cardano:{ouroboros-consensus-cardano, cardano-testlib}
440444
, ouroboros-consensus-diffusion:diffusion-testlib
441445
, ouroboros-consensus-protocol
442-
, ouroboros-consensus:{ouroboros-consensus, consensus-testlib}
446+
, ouroboros-consensus:{ouroboros-consensus, consensus-testlib, mempool-test-utils}
443447
, ouroboros-network-api
448+
, ouroboros-network-protocols:{ouroboros-network-protocols, testlib}
449+
, pretty-simple
444450
, QuickCheck
445451
, shelley-testlib
446452
, sop-core
447453
, tasty
454+
, tasty-hunit
448455
, tasty-quickcheck
456+
, typed-protocols
449457

450458
library cardano-tools
451459
import: common-lib

ouroboros-consensus-cardano/test/cardano-test/Main.hs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ module Main (main) where
22

33
import System.IO (BufferMode (LineBuffering), hSetBuffering,
44
hSetEncoding, stdout, utf8)
5-
import qualified Test.Consensus.Cardano.ByronCompatibility (tests)
6-
import qualified Test.Consensus.Cardano.Golden (tests)
7-
import qualified Test.Consensus.Cardano.Serialisation (tests)
5+
import qualified Test.Consensus.Cardano.ByronCompatibility
6+
import qualified Test.Consensus.Cardano.Golden
7+
import qualified Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.Server
8+
import qualified Test.Consensus.Cardano.Serialisation
89
import Test.Tasty
9-
import qualified Test.ThreadNet.AllegraMary (tests)
10-
import qualified Test.ThreadNet.Cardano (tests)
11-
import qualified Test.ThreadNet.MaryAlonzo (tests)
12-
import qualified Test.ThreadNet.ShelleyAllegra (tests)
10+
import qualified Test.ThreadNet.AllegraMary
11+
import qualified Test.ThreadNet.Cardano
12+
import qualified Test.ThreadNet.MaryAlonzo
13+
import qualified Test.ThreadNet.ShelleyAllegra
1314
import Test.Util.TestEnv (defaultMainWithTestEnv,
1415
defaultTestEnvConfig)
1516

@@ -29,4 +30,5 @@ tests =
2930
, Test.ThreadNet.Cardano.tests
3031
, Test.ThreadNet.MaryAlonzo.tests
3132
, Test.ThreadNet.ShelleyAllegra.tests
33+
, Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.Server.tests
3234
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
-- | Utility functions to deserialize the hexadecimal representation of a CBOR
3+
-- encoded Cardano transaction.
4+
--
5+
-- To use from the repl run:
6+
--
7+
-- > cabal repl ouroboros-consensus-cardano:test:cardano-test
8+
-- > import Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.ByteStringTxParser
9+
--
10+
module Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.ByteStringTxParser (
11+
cardanoCodecCfg
12+
, deserialiseTx
13+
, printDeserializedTx
14+
) where
15+
16+
17+
import Cardano.Chain.Slotting (EpochSlots (..))
18+
import Codec.CBOR.Read (DeserialiseFailure, deserialiseFromBytes)
19+
import Data.ByteString.Base16.Lazy (decodeLenient)
20+
import qualified Data.ByteString.Lazy as BL
21+
import Ouroboros.Consensus.Byron.Ledger
22+
import Ouroboros.Consensus.Cardano.Block
23+
import Ouroboros.Consensus.Cardano.Node
24+
import Ouroboros.Consensus.Node.Serialisation
25+
(SerialiseNodeToClient (decodeNodeToClient))
26+
import Ouroboros.Consensus.Protocol.Praos.Translate ()
27+
import Ouroboros.Consensus.Shelley.Ledger
28+
(CodecConfig (ShelleyCodecConfig))
29+
import Ouroboros.Consensus.Shelley.Ledger.SupportsProtocol ()
30+
import Text.Pretty.Simple (pPrint)
31+
32+
cardanoCodecCfg :: CodecConfig (CardanoBlock StandardCrypto)
33+
cardanoCodecCfg =
34+
CardanoCodecConfig
35+
(ByronCodecConfig (EpochSlots 21600))
36+
ShelleyCodecConfig
37+
ShelleyCodecConfig
38+
ShelleyCodecConfig
39+
ShelleyCodecConfig
40+
ShelleyCodecConfig
41+
ShelleyCodecConfig
42+
43+
deserialiseTx ::
44+
BL.ByteString
45+
-> Either DeserialiseFailure (BL.ByteString, GenTx (CardanoBlock StandardCrypto))
46+
deserialiseTx = deserialiseFromBytes cborDecoder . decodeLenient
47+
where
48+
cborDecoder = decodeNodeToClient cardanoCodecCfg CardanoNodeToClientVersion11
49+
50+
printDeserializedTx :: BL.ByteString -> IO ()
51+
printDeserializedTx bs =
52+
case deserialiseTx bs of
53+
Left err -> pPrint err
54+
Right (_rest, result) -> pPrint result
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{-# LANGUAGE FlexibleContexts #-}
2+
{-# LANGUAGE NumericUnderscores #-}
3+
{-# LANGUAGE OverloadedStrings #-}
4+
5+
-- TODO: remove once we hook 'should_process_and_return' up
6+
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
7+
-- TODO: remove once we find out why GHC is reporting 'Redundant constraint: Show (LedgerSupportsMempool.ApplyTxErr blk)' in 'should_process_and_return'
8+
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
9+
-- | Test that we can submit transactions to the mempool using the local
10+
-- submission server, in different Cardano eras.
11+
--
12+
module Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.Server (tests) where
13+
14+
import Control.Monad (void)
15+
import Control.Tracer (Tracer, nullTracer, stdoutTracer)
16+
import Data.Functor.Contravariant ((>$<))
17+
import Data.SOP.Strict (index_NS)
18+
import qualified Data.SOP.Telescope as Telescope
19+
import Network.TypedProtocol.Proofs (connect)
20+
import Ouroboros.Consensus.Cardano.Block
21+
import Ouroboros.Consensus.Config (topLevelConfigLedger)
22+
import qualified Ouroboros.Consensus.Config as Consensus
23+
import Ouroboros.Consensus.HardFork.Combinator (getHardForkState,
24+
hardForkLedgerStatePerEra)
25+
import Ouroboros.Consensus.Ledger.Extended (ledgerState)
26+
import qualified Ouroboros.Consensus.Ledger.SupportsMempool as Ledger
27+
import qualified Ouroboros.Consensus.Ledger.SupportsMempool as LedgerSupportsMempool
28+
import qualified Ouroboros.Consensus.Mempool.Capacity as Mempool
29+
import Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server
30+
(TraceLocalTxSubmissionServerEvent,
31+
localTxSubmissionServer)
32+
import Ouroboros.Consensus.Node.ProtocolInfo
33+
import Ouroboros.Network.Protocol.LocalTxSubmission.Client
34+
(SubmitResult, localTxSubmissionClientPeer)
35+
import Ouroboros.Network.Protocol.LocalTxSubmission.Examples
36+
(localTxSubmissionClient)
37+
import Ouroboros.Network.Protocol.LocalTxSubmission.Server
38+
(localTxSubmissionServerPeer)
39+
import Test.Consensus.Cardano.MiniProtocol.LocalTxSubmission.ByteStringTxParser
40+
(deserialiseTx)
41+
import Test.Consensus.Cardano.ProtocolInfo
42+
(ByronSlotLengthInSeconds (..), Era (..),
43+
ShelleySlotLengthInSeconds (..), hardForkInto,
44+
mkSimpleTestProtocolInfo, stayInByron)
45+
import qualified Test.Consensus.Mempool.Mocked as Mocked
46+
import Test.Consensus.Mempool.Mocked (MockedMempool)
47+
import Test.Tasty (TestTree, testGroup)
48+
import Test.Tasty.HUnit (testCase, (@=?))
49+
import qualified Test.ThreadNet.Infra.Shelley as Shelley
50+
51+
tests :: TestTree
52+
tests = testGroup "LocalTxSubmissionServer"
53+
[ localServerCanProcessGoldenTransactions (stayInByron , 0)
54+
, localServerCanProcessGoldenTransactions (hardForkInto Shelley, 1)
55+
, localServerCanProcessGoldenTransactions (hardForkInto Allegra, 2)
56+
, localServerCanProcessGoldenTransactions (hardForkInto Mary , 3)
57+
, localServerCanProcessGoldenTransactions (hardForkInto Alonzo , 4)
58+
, localServerCanProcessGoldenTransactions (hardForkInto Babbage, 5)
59+
, localServerCanProcessGoldenTransactions (hardForkInto Conway, 6)
60+
]
61+
where
62+
era 0 = "Byron"
63+
era 1 = "Shelley"
64+
era 2 = "Allegra"
65+
era 3 = "Mary"
66+
era 4 = "Alonzo"
67+
era 5 = "Babbage"
68+
era 6 = "Conway"
69+
era i = error $ "Unknown era index: " ++ show i
70+
71+
localServerCanProcessGoldenTransactions (hardForkSpec, i) =
72+
testCase ("Can process golden transactions (" ++ era i ++ ")") $ do
73+
let
74+
pInfo :: ProtocolInfo (CardanoBlock StandardCrypto)
75+
pInfo = mkSimpleTestProtocolInfo
76+
(Shelley.DecentralizationParam 1)
77+
(Consensus.SecurityParam 10)
78+
(ByronSlotLengthInSeconds 1)
79+
(ShelleySlotLengthInSeconds 1)
80+
hardForkSpec
81+
eraIndex = index_NS
82+
. Telescope.tip
83+
. getHardForkState
84+
. hardForkLedgerStatePerEra
85+
. ledgerState
86+
$ pInfoInitLedger pInfo
87+
88+
eraIndex @=? i
89+
90+
mempool <- Mocked.openMockedMempool (Mempool.mkCapacityBytesOverride 100_000) -- We don't want the mempool to fill up during these tests.
91+
nullTracer -- Use 'show >$< stdoutTracer' for debugging.
92+
LedgerSupportsMempool.txInBlockSize
93+
(ledgerState $ pInfoInitLedger pInfo)
94+
(topLevelConfigLedger $ pInfoConfig pInfo)
95+
mempool `should_process` [ _137 ]
96+
where
97+
-- Reported in https://github.com/input-output-hk/ouroboros-consensus/issues/137
98+
_137 :: GenTx (CardanoBlock StandardCrypto)
99+
_137 = either (error . show) snd (deserialiseTx _137_bs)
100+
where
101+
_137_bs = "8205d818590210" <> "84a400828258203a79a6a834e7779c67b0b3cbd3b7271883bbbeac15b1a89d78f057edc25e000b008258203a79a6a834e7779c67b0b3cbd3b7271883bbbeac15b1a89d78f057edc25e000b010182825839007d5a2560d23c3443b98d84c57b0c491311da4b3098de1945c7bcfc4c63ea8c5404f9ed9ae80d95b5544857b2011e3f26b63ddc3be1abd42d1a001e84808258390009ecea977429fa7a4993bc045ea618f3697e6b8eac9d5ea68bba7e4b63ea8c5404f9ed9ae80d95b5544857b2011e3f26b63ddc3be1abd42d821a560ea01ca4581c47be64fcc8a7fe5321b976282ce4e43e4d29015f6613cfabcea28eaba244546573741a3b97c0aa51576f52456d706972654c696368303037391a3443f4a0581c4cd2ea369880853541c5f446725f3e4ecaf141635f0c56c43104923ba14574464c41431b0de0b6b346d4b018581c85ef026c7da6a91f7acc1e662c50301bcce79eb401a3217690aa7044a14574464c41431b000000022eaca140581c92bd3be92d6a6eadd7c01ce9ff485809f3f2eb36845cd7a25c9177bfa14b546f20746865206d6f6f6e01021a0002b9b5031a05a18ef7a100818258202726733baa5c15d8d856c8d94e7d83bcfc7f5661ec7f952f052f311a2443feb258405f9d3d8a703baf700a3015994a3e8702fd7fe2e25d640487944b32ea999f36b314be9674be09b8b8f2c678976ecf994c83086180e854120d81243476c2b89e05f5f6"
102+
103+
-- | Check that the given transactions can be processed, irrespective of whether
104+
-- they were sucessfully validated.
105+
should_process :: MockedMempool IO blk -> [Ledger.GenTx blk] -> IO ()
106+
should_process mockedMempool txs = do
107+
void $ processTxs nullTracer mockedMempool txs
108+
109+
processTxs ::
110+
Tracer IO (TraceLocalTxSubmissionServerEvent blk)
111+
-> MockedMempool IO blk
112+
-> [Ledger.GenTx blk]
113+
-> IO [(GenTx blk, SubmitResult (LedgerSupportsMempool.ApplyTxErr blk))]
114+
processTxs tracer mockedMempool txs =
115+
(\(a, _, _) -> a) <$>
116+
connect (localTxSubmissionClientPeer client) (localTxSubmissionServerPeer mServer)
117+
where
118+
mServer = pure $ localTxSubmissionServer tracer
119+
(Mocked.getMempool mockedMempool)
120+
client = localTxSubmissionClient txs
121+
122+
-- TODO: this function is unused at the moment. We will use it once we add tests
123+
-- for Cardano transactions that are supposed to succeed.
124+
should_process_and_return ::
125+
( Show (Ledger.GenTx blk)
126+
, Eq (Ledger.ApplyTxErr blk)
127+
, Show (Ledger.ApplyTxErr blk)
128+
, Show (SubmitResult (LedgerSupportsMempool.ApplyTxErr blk))
129+
)
130+
=> MockedMempool IO blk -> [(Ledger.GenTx blk, SubmitResult (LedgerSupportsMempool.ApplyTxErr blk))] -> IO ()
131+
should_process_and_return mockedMempool txs_ress = do
132+
processResult <- processTxs (show >$< stdoutTracer) mockedMempool (fmap fst txs_ress)
133+
let
134+
actualResults = fmap snd processResult
135+
expectedResults = fmap snd txs_ress
136+
length actualResults @=? length expectedResults
137+
mapM_ (uncurry (@=?)) $ zip expectedResults actualResults
138+
pure ()

0 commit comments

Comments
 (0)