Skip to content

Commit d56ef7e

Browse files
iohk-bors[bot]Denis Shevchenko
andauthored
Merge #330
330: Transaction generator: specify target nodes without topology. r=CodiePP a=denisshevchenko #329 Since #318 is going to eliminate `TopologyInfo` type, tx generator has to avoid such a dependency. Currently tx generator uses `--target-node-id`s only for extracting corresponding IPs/ports from topology file, so now it should receive `--target-node` CLI parameter with not `NodeId`, but with explicit IP/port, for example: `--target-node ("127.0.0.1",3002)`. Co-authored-by: Denis Shevchenko <denis.shevchenko@iohk.io>
2 parents 4cf223d + 2210cf0 commit d56ef7e

File tree

5 files changed

+52
-72
lines changed

5 files changed

+52
-72
lines changed

cardano-node/app/cardano-cli.hs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
13
import Cardano.Prelude hiding (option)
24
import Prelude (String, error, id)
35

@@ -7,12 +9,14 @@ import qualified Data.List.NonEmpty as NE
79
import Data.Text
810
import Data.Time (UTCTime)
911
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
12+
import Network.Socket (PortNumber)
1013
import qualified Options.Applicative as Opt
1114
import Options.Applicative (Parser, ParserInfo, ParserPrefs, auto,
1215
commandGroup, flag, flag', help, long,
1316
metavar, option, showHelpOnEmpty,
1417
strOption, subparser, value)
1518
import System.Exit (exitFailure)
19+
import Text.Read (readMaybe)
1620

1721
import Cardano.Binary (Annotated (..))
1822
import Cardano.Chain.Common
@@ -30,6 +34,7 @@ import Cardano.Config.Partial (PartialCardanoConfiguration (..),
3034
mkCardanoConfiguration)
3135
import Cardano.Config.Presets (mainnetConfiguration)
3236
import Cardano.Config.Protocol (Protocol)
37+
import Cardano.Config.Topology (NodeAddress (..), NodeHostAddress (..))
3338
import Cardano.Config.Types (CardanoEnvironment (..), GenesisFile(..),
3439
RequireNetworkMagic)
3540
import Cardano.Crypto ( AProtocolMagic(..)
@@ -334,9 +339,12 @@ parseTxRelatedValues =
334339
"generate-txs"
335340
"Launch transactions generator."
336341
$ GenerateTxs
337-
<$> parseTargetNodeIds
338-
"target-node-id"
339-
"Identifiers of nodes transactions will be sent to."
342+
<$> (NE.fromList <$> some (
343+
parseTargetNodeAddress
344+
"target-node"
345+
"host and port of the node transactions will be sent to."
346+
)
347+
)
340348
<*> parseNumberOfTxs
341349
"num-of-txs"
342350
"Number of transactions generator will create."
@@ -461,6 +469,19 @@ parseFlag def active optname desc =
461469
flag def active $ long optname <> help desc
462470

463471

472+
parseTargetNodeAddress :: String -> String -> Parser NodeAddress
473+
parseTargetNodeAddress optname desc =
474+
option
475+
( uncurry NodeAddress
476+
. Control.Arrow.first cliParseHostAddress
477+
. Control.Arrow.second cliParsePort
478+
<$> auto
479+
)
480+
$ long optname
481+
<> metavar "(HOST,PORT)"
482+
<> help desc
483+
484+
464485
-- | Here, we hope to get away with the usage of 'error' in a pure expression,
465486
-- because the CLI-originated values are either used, in which case the error is
466487
-- unavoidable rather early in the CLI tooling scenario (and especially so, if
@@ -485,6 +506,13 @@ cliParseTxId =
485506
either (error . ("Bad Lovelace value: " <>) . show) id
486507
. decodeHash . pack
487508

509+
cliParseHostAddress :: String -> NodeHostAddress
510+
cliParseHostAddress = NodeHostAddress . Just .
511+
maybe (error "Bad host of target node") id . readMaybe
512+
513+
cliParsePort :: Word16 -> PortNumber
514+
cliParsePort = fromIntegral
515+
488516
parseAddress :: String -> String -> Parser Address
489517
parseAddress opt desc =
490518
option (cliParseBase58Address <$> auto)
@@ -557,9 +585,6 @@ parseNewTxFile opt =
557585
NewTxFile
558586
<$> parseFilePath opt "Non-existent file to write the signed transaction to."
559587

560-
parseTargetNodeIds :: String -> String -> Parser [TargetNodeId]
561-
parseTargetNodeIds opt desc = many $ TargetNodeId <$> parseIntegral opt desc
562-
563588
parseNumberOfTxs :: String -> String -> Parser NumberOfTxs
564589
parseNumberOfTxs opt desc = NumberOfTxs <$> parseIntegral opt desc
565590

@@ -579,4 +604,4 @@ parseTxAdditionalSize :: String -> String -> Parser TxAdditionalSize
579604
parseTxAdditionalSize opt desc = TxAdditionalSize <$> parseIntegral opt desc
580605

581606
parseSigningKeysFiles :: String -> String -> Parser [SigningKeyFile]
582-
parseSigningKeysFiles opt desc = many $ SigningKeyFile <$> parseFilePath opt desc
607+
parseSigningKeysFiles opt desc = some $ SigningKeyFile <$> parseFilePath opt desc

cardano-node/cardano-node.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ executable cardano-cli
243243
, cardano-ledger
244244
, cardano-prelude
245245
, cardano-node
246+
, iproute
247+
, network
246248
, optparse-applicative
247249
, ouroboros-consensus
248250
, safe-exceptions

cardano-node/src/Cardano/CLI/Run.hs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ module Cardano.CLI.Run (
3030
, NewCertificateFile(..)
3131
, TxFile(..)
3232
, NewTxFile(..)
33-
, TargetNodeId(..)
3433
, NumberOfTxs(..)
3534
, NumberOfInputsPerTx(..)
3635
, NumberOfOutputsPerTx(..)
@@ -71,8 +70,7 @@ import Cardano.CLI.Genesis
7170
import Cardano.CLI.Key
7271
import Cardano.CLI.Ops
7372
import Cardano.CLI.Tx
74-
import Cardano.CLI.Tx.Generation (TargetNodeId (..),
75-
NumberOfTxs (..),
73+
import Cardano.CLI.Tx.Generation (NumberOfTxs (..),
7674
NumberOfInputsPerTx (..),
7775
NumberOfOutputsPerTx (..),
7876
FeePerTx (..), TPSRate (..),
@@ -86,7 +84,7 @@ import Cardano.Config.Types (CardanoConfiguration(..), ConfigYamlFileP
8684
SigningKeyFile(..), TopologyFile(..),
8785
parseNodeConfiguration)
8886
import Cardano.Config.Logging (LoggingLayer (..))
89-
import Cardano.Config.Topology (TopologyInfo(..))
87+
import Cardano.Config.Topology (NodeAddress(..), TopologyInfo(..))
9088

9189
-- | Sub-commands of 'cardano-cli'.
9290
data ClientCommand
@@ -162,7 +160,7 @@ data ClientCommand
162160
--- Tx Generator Command ----------
163161

164162
| GenerateTxs
165-
[TargetNodeId]
163+
(NonEmpty NodeAddress)
166164
NumberOfTxs
167165
NumberOfInputsPerTx
168166
NumberOfOutputsPerTx
@@ -247,7 +245,7 @@ runCommand _ _ (SpendUTxO (NewTxFile ctTx) ctKey ins outs nCli) = do
247245
liftIO . ensureNewFileLBS ctTx $ serialise gTx
248246

249247
runCommand _ loggingLayer
250-
(GenerateTxs targetNodeIds
248+
(GenerateTxs targetNodeAddresses
251249
numOfTxs
252250
numOfInsPerTx
253251
numOfOutsPerTx
@@ -260,13 +258,11 @@ runCommand _ loggingLayer
260258

261259
liftIO $ withRealPBFT nc nCli $
262260
\protocol@(Consensus.ProtocolRealPBFT _ _ _ _ _) -> do
263-
let topologyFp = unTopology . topFile $ mscFp nCli
264261
res <- runExceptT $ genesisBenchmarkRunner
265262
loggingLayer
266263
nCli
267264
protocol
268-
(TopologyInfo (ncNodeId nc) topologyFp)
269-
targetNodeIds
265+
targetNodeAddresses
270266
numOfTxs
271267
numOfInsPerTx
272268
numOfOutsPerTx

cardano-node/src/Cardano/CLI/Tx/Generation.hs

Lines changed: 11 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
{-# OPTIONS_GHC -Wno-missed-specialisations #-}
1111

1212
module Cardano.CLI.Tx.Generation
13-
( TargetNodeId(..)
14-
, NumberOfTxs(..)
13+
( NumberOfTxs(..)
1514
, NumberOfInputsPerTx(..)
1615
, NumberOfOutputsPerTx(..)
1716
, FeePerTx(..)
@@ -31,10 +30,7 @@ import qualified Control.Exception as Exception
3130
import Control.Monad (forM, forM_, mapM, when)
3231
import qualified Control.Monad.Class.MonadSTM as MSTM
3332
import Control.Monad.Trans.Except (ExceptT)
34-
import Control.Monad.Trans.Except.Extra (firstExceptT,
35-
hoistEither,
36-
left, newExceptT,
37-
right)
33+
import Control.Monad.Trans.Except.Extra (left, right)
3834
import Data.Bifunctor (bimap)
3935
import qualified Data.ByteString.Lazy as LB
4036
import Data.Either (isLeft)
@@ -69,11 +65,7 @@ import Cardano.Config.Logging (LoggingLayer (..), Trace)
6965
import Cardano.Config.Types (NodeCLI(..))
7066
import qualified Cardano.Crypto as Crypto
7167
import Cardano.Config.Topology (NodeAddress (..),
72-
NodeHostAddress(..),
73-
TopologyError(..),
74-
TopologyInfo (..),
75-
createNodeAddress,
76-
readTopologyFile)
68+
NodeHostAddress(..))
7769
import Cardano.CLI.Tx (txSpendGenesisUTxOByronPBFT)
7870
import Cardano.CLI.Tx.BenchmarkingTxSubmission (ROEnv (..),
7971
TraceBenchTxSubmit (..),
@@ -91,19 +83,15 @@ import Ouroboros.Consensus.Block(BlockProtocol)
9183
import Ouroboros.Consensus.Ledger.Byron.Config (pbftProtocolMagic)
9284
import Ouroboros.Consensus.Node.ProtocolInfo (ProtocolInfo (..),
9385
protocolInfo)
94-
import Ouroboros.Consensus.NodeId (NodeId (..))
9586
import qualified Ouroboros.Consensus.Protocol as Consensus
9687
import Ouroboros.Consensus.Ledger.Byron (ByronBlock (..),
9788
GenTx (..),
9889
ByronConsensusProtocol)
9990
import qualified Ouroboros.Consensus.Ledger.Byron as Byron
91+
import Ouroboros.Consensus.NodeId (NodeId (..))
10092
import Ouroboros.Consensus.Protocol.Abstract (NodeConfig)
10193
import Ouroboros.Consensus.Protocol.PBFT (pbftExtConfig)
10294

103-
newtype TargetNodeId =
104-
TargetNodeId Int
105-
deriving (Eq, Ord, Show)
106-
10795
newtype NumberOfTxs =
10896
NumberOfTxs Word64
10997
deriving (Eq, Ord, Show)
@@ -140,11 +128,7 @@ newtype TxAdditionalSize =
140128
data TxGenError = CurrentlyCannotSendTxToRelayNode FilePath
141129
-- ^ Relay nodes cannot currently be transaction recipients.
142130
| InsufficientFundsForRecipientTx
143-
| TargetNodeAddressError TopologyError
144131
-- ^ Error occurred while creating the target node address.
145-
| TopologyFileReadError String
146-
| NeedMinimumOneTargetNodeId [TargetNodeId]
147-
-- ^ Need at least 1 target node id.
148132
| NeedMinimumThreeSigningKeyFiles [FilePath]
149133
-- ^ Need at least 3 signing key files.
150134
| SecretKeyDeserialiseError String
@@ -160,8 +144,7 @@ genesisBenchmarkRunner
160144
:: LoggingLayer
161145
-> NodeCLI
162146
-> Consensus.Protocol ByronBlock
163-
-> TopologyInfo
164-
-> [TargetNodeId]
147+
-> NonEmpty NodeAddress
165148
-> NumberOfTxs
166149
-> NumberOfInputsPerTx
167150
-> NumberOfOutputsPerTx
@@ -173,8 +156,7 @@ genesisBenchmarkRunner
173156
genesisBenchmarkRunner loggingLayer
174157
nCli
175158
protocol@(Consensus.ProtocolRealPBFT genesisConfig _ _ _ _)
176-
topologyInfo
177-
targetNodeIds
159+
targetNodeAddresses
178160
numOfTxs@(NumberOfTxs rawNumOfTxs)
179161
numOfInsPerTx
180162
numOfOutsPerTx
@@ -185,29 +167,11 @@ genesisBenchmarkRunner loggingLayer
185167
when (length signingKeyFiles < 3) $
186168
left $ NeedMinimumThreeSigningKeyFiles signingKeyFiles
187169

188-
when (null targetNodeIds) $
189-
left $ NeedMinimumOneTargetNodeId targetNodeIds
190-
191170
let (benchTracer, connectTracer, submitTracer, lowLevelSubmitTracer) = createTracers loggingLayer
192171

193172
liftIO . traceWith benchTracer . TraceBenchTxSubDebug
194173
$ "******* Tx generator, tracers are ready *******"
195174

196-
liftIO . traceWith benchTracer . TraceBenchTxSubDebug
197-
$ "******* Tx generator, protocol info and topology are ready *******"
198-
199-
-- We have to extract host and port of the nodes we want to talk with
200-
-- (based on values of `--target-node-id` CLI argument) from the topology file.
201-
topology <- firstExceptT TopologyFileReadError . newExceptT $
202-
readTopologyFile (topologyFile topologyInfo)
203-
targetNodeAddresses <- forM targetNodeIds $ \(TargetNodeId targetNodeId) -> do
204-
let eitherNodeAddress = createNodeAddress (CoreId targetNodeId) topology (topologyFile topologyInfo)
205-
targetNodeAddress <- firstExceptT TargetNodeAddressError . hoistEither $ eitherNodeAddress
206-
return targetNodeAddress
207-
208-
liftIO . traceWith benchTracer . TraceBenchTxSubDebug
209-
$ "******* Tx generator, target node's address is ready *******"
210-
211175
-- 'genesisKey' is for genesis address with initial amount of money (1.4 billion ADA for now).
212176
-- 'sourceKey' is for source address that we'll use as a source of money for next transactions.
213177
-- 'recepientKey' is for recipient address that we'll use as an output for next transactions.
@@ -236,7 +200,6 @@ genesisBenchmarkRunner loggingLayer
236200
nCli
237201
genesisConfig
238202
pInfoConfig
239-
topologyInfo
240203
genesisUtxo
241204
genesisAddress
242205
sourceAddress
@@ -255,7 +218,6 @@ genesisBenchmarkRunner loggingLayer
255218
pInfoConfig
256219
sourceKey
257220
recipientAddress
258-
topologyInfo
259221
targetNodeAddresses
260222
numOfTxs
261223
numOfInsPerTx
@@ -430,7 +392,6 @@ prepareInitialFunds
430392
-> NodeCLI
431393
-> CC.Genesis.Config
432394
-> NodeConfig ByronConsensusProtocol
433-
-> TopologyInfo
434395
-> Map Int ((CC.UTxO.TxIn, CC.UTxO.TxOut), Crypto.SigningKey)
435396
-> CC.Common.Address
436397
-> CC.Common.Address
@@ -440,7 +401,6 @@ prepareInitialFunds llTracer
440401
nCli
441402
genesisConfig
442403
pInfoConfig
443-
topologyInfo
444404
genesisUtxo
445405
genesisAddress
446406
targetAddress
@@ -459,7 +419,7 @@ prepareInitialFunds llTracer
459419
genesisAddress
460420
(NE.fromList [outForBig])
461421

462-
submitTx nCli pInfoConfig (node topologyInfo) genesisTx llTracer
422+
submitTx nCli pInfoConfig (CoreId 0) genesisTx llTracer
463423
-- Done, the first transaction 'initGenTx' is submitted, now 'sourceAddress' has a lot of money.
464424

465425
let txIn = CC.UTxO.TxInUtxo (getTxIdFromGenTx genesisTx) 0
@@ -686,8 +646,7 @@ runBenchmark
686646
-> NodeConfig ByronConsensusProtocol
687647
-> Crypto.SigningKey
688648
-> CC.Common.Address
689-
-> TopologyInfo
690-
-> [NodeAddress]
649+
-> NonEmpty NodeAddress
691650
-> NumberOfTxs
692651
-> NumberOfInputsPerTx
693652
-> NumberOfOutputsPerTx
@@ -703,7 +662,6 @@ runBenchmark benchTracer
703662
pInfoConfig
704663
sourceKey
705664
recipientAddress
706-
topologyInfo
707665
targetNodeAddresses
708666
numOfTxs
709667
numOfInsPerTx
@@ -719,7 +677,6 @@ runBenchmark benchTracer
719677
pInfoConfig
720678
sourceKey
721679
txFee
722-
topologyInfo
723680
numOfTxs
724681
numOfInsPerTx
725682

@@ -769,7 +726,7 @@ runBenchmark benchTracer
769726
recipientAddress
770727
sourceKey
771728
txFee
772-
(length targetNodeAddresses)
729+
(NE.length targetNodeAddresses)
773730
numOfTxs
774731
numOfInsPerTx
775732
numOfOutsPerTx
@@ -780,7 +737,7 @@ runBenchmark benchTracer
780737

781738
liftIO $ do
782739
txsLists <- STM.atomically $ STM.takeTMVar txsListsForTargetNodes
783-
let targetNodesAddrsAndTxsLists = zip remoteAddresses txsLists
740+
let targetNodesAddrsAndTxsLists = zip (NE.toList remoteAddresses) txsLists
784741
allAsyncs <- forM targetNodesAddrsAndTxsLists $ \(remoteAddr, txsList) -> do
785742
-- Launch connection and submission threads for a peer
786743
-- (corresponding to one target node).
@@ -807,7 +764,6 @@ createMoreFundCoins
807764
-> NodeConfig ByronConsensusProtocol
808765
-> Crypto.SigningKey
809766
-> FeePerTx
810-
-> TopologyInfo
811767
-> NumberOfTxs
812768
-> NumberOfInputsPerTx
813769
-> ExceptT TxGenError IO ()
@@ -816,7 +772,6 @@ createMoreFundCoins llTracer
816772
pInfoConfig
817773
sourceKey
818774
(FeePerTx txFee)
819-
topologyInfo
820775
(NumberOfTxs numOfTxs)
821776
(NumberOfInputsPerTx numOfInsPerTx) = do
822777
let feePerTx = assumeBound . CC.Common.mkLovelace $ txFee
@@ -854,7 +809,7 @@ createMoreFundCoins llTracer
854809
txOut
855810
[]
856811
liftIO $ forM_ splittingTxs $ \(tx, txDetailsList) -> do
857-
submitTx nCli pInfoConfig (node topologyInfo) tx llTracer
812+
submitTx nCli pInfoConfig (CoreId 0) tx llTracer
858813
-- Update available fundValueStatus to reuse the numSplittingTxOuts TxOuts.
859814
forM_ txDetailsList addToAvailableFunds
860815
where

0 commit comments

Comments
 (0)