Skip to content

Commit b6cdd56

Browse files
committed
tx-generator: remove fund-set / ix-set
1 parent f90ce2f commit b6cdd56

File tree

7 files changed

+42
-269
lines changed

7 files changed

+42
-269
lines changed

bench/tx-generator/src/Cardano/Benchmarking/FundSet.hs

+6-179
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ module Cardano.Benchmarking.FundSet
1212
where
1313
import Prelude
1414

15-
import Data.IxSet.Typed as IxSet
16-
import Data.Proxy
17-
18-
import Control.Applicative ((<|>))
1915
import Cardano.Api as Api
2016

2117
-- Outputs that are available for spending.
@@ -26,50 +22,29 @@ data FundInEra era = FundInEra {
2622
, _fundWitness :: Witness WitCtxTxIn era
2723
, _fundVal :: !(TxOutValue era)
2824
, _fundSigningKey :: !(Maybe (SigningKey PaymentKey))
29-
, _fundVariant :: !Variant
30-
, _fundValidity :: !Validity
3125
} deriving (Show)
3226

33-
data Variant
34-
= PlainOldFund
35-
-- maybe better use the script itself instead of the filePath
36-
| PlutusScriptFund
37-
-- A collateralFund is just a regular (PlainOldFund) on the chain,
38-
-- but tagged in the wallet so that it is not selected for spending.
39-
| CollateralFund
40-
deriving (Show, Eq, Ord)
27+
newtype Fund = Fund {unFund :: InAnyCardanoEra FundInEra}
4128

42-
data Validity
43-
= Confirmed
44-
| InFlight !Target !SeqNumber
45-
deriving (Show, Eq, Ord)
29+
type FundSet = [ Fund ]
4630

47-
newtype Target = Target String
48-
deriving (Show, Eq, Ord)
31+
type FundSource m = m (Either String [Fund])
32+
type FundToStore m = [Fund] -> m ()
4933

5034
newtype SeqNumber = SeqNumber Int
5135
deriving (Show, Eq, Ord, Enum)
5236

53-
newtype Fund = Fund {unFund :: InAnyCardanoEra FundInEra}
54-
55-
getFundVariant :: Fund -> Variant
56-
getFundVariant (Fund (InAnyCardanoEra _ a)) = _fundVariant a
57-
5837
getFundTxIn :: Fund -> TxIn
5938
getFundTxIn (Fund (InAnyCardanoEra _ a)) = _fundTxIn a
6039

6140
getFundKey :: Fund -> Maybe (SigningKey PaymentKey)
6241
getFundKey (Fund (InAnyCardanoEra _ a)) = _fundSigningKey a
6342

64-
getFundValidity :: Fund -> Validity
65-
getFundValidity (Fund (InAnyCardanoEra _ a)) = _fundValidity a
66-
6743
getFundLovelace :: Fund -> Lovelace
6844
getFundLovelace (Fund (InAnyCardanoEra _ a)) = case _fundVal a of
6945
TxOutAdaOnly _era l -> l
7046
TxOutValue _era v -> selectLovelace v
7147

72-
7348
-- This effectively rules out era-transitions for transactions !
7449
-- This is not what we want !!
7550
getFundWitness :: forall era. IsShelleyBasedEra era => Fund -> Witness WitCtxTxIn era
@@ -85,14 +60,6 @@ getFundWitness fund = case (cardanoEra @ era, fund) of
8560
-- It should be possible to cast KeyWitnesses from one era to an other !
8661
(_ , _) -> error "getFundWitness: era mismatch"
8762

88-
data IsConfirmed = IsConfirmed | IsNotConfirmed
89-
deriving (Show, Eq, Ord)
90-
91-
isConfirmed :: Fund -> IsConfirmed
92-
isConfirmed f = case getFundValidity f of
93-
Confirmed -> IsConfirmed
94-
InFlight _ _ -> IsNotConfirmed
95-
9663
instance Show Fund where
9764
show (Fund (InAnyCardanoEra _ f)) = show f
9865

@@ -105,32 +72,12 @@ instance Eq Fund where
10572
instance Ord Fund where
10673
compare a b = compare (getFundTxIn a) (getFundTxIn b)
10774

108-
type FundIndices = '[ TxIn, IsConfirmed, Target, SeqNumber, Lovelace, Variant ]
109-
type FundSet = IxSet FundIndices Fund
110-
111-
instance Indexable FundIndices Fund where
112-
indices = ixList
113-
(ixFun $ \f -> [ getFundTxIn f ])
114-
(ixFun $ \f -> [ isConfirmed f ])
115-
(ixFun $ \f -> case getFundValidity f of
116-
Confirmed -> []
117-
InFlight t _ -> [t]
118-
)
119-
(ixFun $ \f -> case getFundValidity f of
120-
Confirmed -> [SeqNumber (-1) ] -- Confirmed Txs get SeqNumber -1
121-
InFlight _ n -> [ n ]
122-
)
123-
(ixFun $ \f -> [ getFundLovelace f ])
124-
(ixFun $ \f -> [ getFundVariant f ])
12575

12676
emptyFunds :: FundSet
127-
emptyFunds = IxSet.empty
77+
emptyFunds = [ ]
12878

12979
insertFund :: FundSet -> Fund -> FundSet
130-
insertFund s f = updateIx (getFundTxIn f) f s
131-
132-
deleteFund :: FundSet -> Fund -> FundSet
133-
deleteFund s f = deleteIx (getFundTxIn f) s
80+
insertFund s f = f : s
13481

13582
liftAnyEra :: ( forall era. IsCardanoEra era => f1 era -> f2 era ) -> InAnyCardanoEra f1 -> InAnyCardanoEra f2
13683
liftAnyEra f x = case x of
@@ -141,126 +88,6 @@ liftAnyEra f x = case x of
14188
InAnyCardanoEra AlonzoEra a -> InAnyCardanoEra AlonzoEra $ f a
14289
InAnyCardanoEra BabbageEra a -> InAnyCardanoEra BabbageEra $ f a
14390

144-
type FundSelector = FundSet -> Either String [Fund]
145-
type FundSource m = m (Either String [Fund])
146-
type FundToStore m = [Fund] -> m ()
147-
148-
-- Select Funds to cover a minimum value.
149-
-- TODO:
150-
-- This fails unless there is a single fund with the required value
151-
-- Extend this to really return a list of funds.
152-
selectMinValue :: Lovelace -> FundSet -> Either String [Fund]
153-
selectMinValue minValue fs = case coins of
154-
[] -> Left $ "findSufficientCoin: no single coin with min value >= " ++ show minValue
155-
(c:_) -> Right [c]
156-
where coins = toAscList ( Proxy :: Proxy Lovelace) (fs @=PlainOldFund @= IsConfirmed @>= minValue)
157-
158-
selectCollateral :: FundSet -> Either String [Fund]
159-
selectCollateral fs = case coins of
160-
[] -> Left "no matching none-Plutus fund found"
161-
(c:_) -> Right [c]
162-
where
163-
coins = toAscList ( Proxy :: Proxy Lovelace) (fs @=CollateralFund @= IsConfirmed )
164-
165-
data AllowRecycle
166-
= UseConfirmedOnly
167-
| ReuseSameTarget
168-
-- ReuseAny can cause none-deterministic runtime errors !
169-
-- The problematic case is the reuse of an UTxO/Tx that is not yet confirmed
170-
-- and still waits in the mempool of an other target-node.
171-
| ReuseAny
172-
| ConfirmedBeforeReuse -- useful for testing
173-
deriving (Eq, Ord, Enum, Show)
174-
175-
-- There are many possible heuristics to implement the selectInputs function.
176-
-- TODO: Check that the complexity of selectInputs is good enough.
177-
selectInputs ::
178-
AllowRecycle
179-
-> Int
180-
-> Lovelace
181-
-> Variant
182-
-> Target
183-
-> FundSet
184-
-> Either String [Fund]
185-
selectInputs allowRecycle count minTotalValue variant targetNode fs
186-
= case allowRecycle of
187-
UseConfirmedOnly -> selectConfirmed
188-
ReuseSameTarget -> reuseSameTarget <|> selectConfirmed
189-
ReuseAny -> reuseSameTarget <|> selectConfirmed <|> reuseAnyCoin
190-
ConfirmedBeforeReuse -> selectConfirmed <|> reuseSameTarget
191-
where
192-
selectConfirmed = selectConfirmedSmallValue <|> selectConfirmedBigValue
193-
194-
isSufficientCoins coins = length coins == count && sum (map getFundLovelace coins) >= minTotalValue
195-
196-
checkCoins :: String -> [Fund] -> Either String [Fund]
197-
checkCoins err coins
198-
= if isSufficientCoins coins then Right coins else Left err
199-
200-
-- Share intermediate results for variantIxSet confirmedIxSet and targetIxSet
201-
-- TODO: it unclear if this helps on the complexity or it it is even harmful.
202-
variantIxSet = fs @= variant
203-
confirmedIxSet = variantIxSet @= IsConfirmed
204-
targetIxSet = variantIxSet @= targetNode
205-
206-
confirmedBigValueList = toDescList (Proxy :: Proxy Lovelace) confirmedIxSet
207-
sameTargetList = toAscList (Proxy :: Proxy SeqNumber) targetIxSet
208-
209-
selectConfirmedSmallValue
210-
= checkCoins
211-
"selectConfirmedSmall: not enough coins available"
212-
(take count $ toAscList (Proxy :: Proxy Lovelace) confirmedIxSet)
213-
214-
selectConfirmedBigValue
215-
= checkCoins
216-
"selectConfirmedSmall: not enough coins available"
217-
(take count confirmedBigValueList)
218-
219-
-- reuseSameTargetStrict is problematic: It fails if the coins in the queues are too small. But it will never consume the small coins.
220-
-- therefore: (reuseSameTargetStrict <|> reuseSameTargetWithBackup)
221-
reuseSameTargetStrict
222-
= checkCoins
223-
"reuseSameTargetStrict: not enough coins available"
224-
(take count sameTargetList)
225-
226-
-- reuseSameTargetWithBackup can collect some dust.
227-
-- reuseSameTargetWithBackup works fine if there is at least one sufficient confirmed UTxO available.
228-
reuseSameTargetWithBackup = checkCoins "reuseSameTargetWithBackup: not enough coins available" (backupCoin ++ targetCoins)
229-
where
230-
-- targetCoins and backupCoins must be disjoint.
231-
-- This is case because IsConfirmed \= InFlight target.
232-
backupCoin = take 1 $ toAscList (Proxy :: Proxy Lovelace) (confirmedIxSet @> minTotalValue)
233-
targetCoins = take (count - 1) sameTargetList
234-
235-
reuseSameTarget = reuseSameTargetStrict <|> reuseSameTargetWithBackup
236-
237-
-- reuseAnyCoin is the last resort !
238-
reuseAnyCoin
239-
= checkCoins
240-
"reuseAnyTarget: not enough coins available"
241-
(take count $ confirmedBigValueList ++ inFlightCoins)
242-
where
243-
-- inFlightCoins and confirmedCoins are disjoint
244-
inFlightCoins = toAscList (Proxy :: Proxy SeqNumber) (variantIxSet @=IsNotConfirmed)
245-
246-
selectToBuffer ::
247-
Int
248-
-> Lovelace
249-
-> Maybe Variant
250-
-> FundSet
251-
-> Either String [Fund]
252-
selectToBuffer count minValue variant fs
253-
= if length coins < count
254-
then Left $ concat
255-
[ "selectToBuffer: not enough coins found: count: ", show count
256-
, " minValue: ", show minValue
257-
, " variant: ", show variant
258-
]
259-
else Right coins
260-
where
261-
coins = case variant of
262-
Just v -> take count $ toAscList ( Proxy :: Proxy Lovelace) (fs @=v @= IsConfirmed @>= minValue)
263-
Nothing -> take count $ toAscList ( Proxy :: Proxy Lovelace) (fs @= IsConfirmed @>= minValue)
26491
-- Todo: check sufficient funds and minimumValuePerUtxo
26592
inputsToOutputsWithFee :: Lovelace -> Int -> [Lovelace] -> [Lovelace]
26693
inputsToOutputsWithFee fee count inputs = map (quantityToLovelace . Quantity) outputs

bench/tx-generator/src/Cardano/Benchmarking/GeneratorTx.hs

+2-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import Ouroboros.Consensus.Shelley.Eras (StandardShelley)
3939

4040
import Cardano.Api hiding (txFee)
4141

42-
import qualified Cardano.Benchmarking.FundSet as FundSet
4342
import Cardano.Benchmarking.GeneratorTx.Error
4443
import Cardano.Benchmarking.GeneratorTx.Genesis
4544
import Cardano.Benchmarking.GeneratorTx.NodeToNode
@@ -152,7 +151,7 @@ walletBenchmark :: forall era. IsShelleyBasedEra era
152151
-> SubmissionErrorPolicy
153152
-> AsType era
154153
-> NumberOfTxs
155-
-> (FundSet.Target -> WalletScript era)
154+
-> WalletScript era
156155
-> ExceptT TxGenError IO AsyncBenchmarkControl
157156
walletBenchmark
158157
traceSubmit
@@ -184,7 +183,7 @@ walletBenchmark
184183
client = txSubmissionClient
185184
traceN2N
186185
traceSubmit
187-
(walletTxSource (walletScript (FundSet.Target $ show remoteAddr)) tpsThrottle)
186+
(walletTxSource walletScript tpsThrottle)
188187
(submitSubmissionThreadStats reportRef)
189188
async $ handle errorHandler (connectClient remoteAddr client)
190189

bench/tx-generator/src/Cardano/Benchmarking/ListBufferedSelector.hs

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{-# LANGUAGE LambdaCase #-}
1+
-- todo: remove
22
module Cardano.Benchmarking.ListBufferedSelector
33
(
44
mkBufferedSource
@@ -7,24 +7,18 @@ where
77
import Prelude
88

99
import Control.Concurrent.MVar
10-
import Cardano.Api
1110

1211
import Cardano.Benchmarking.FundSet as FundSet
1312
import Cardano.Benchmarking.Wallet as Wallet
1413

1514
mkBufferedSource ::
1615
WalletRef
1716
-> Int
18-
-> Lovelace
19-
-> Maybe Variant
20-
-> Int
21-
-> IO (Either String (FundSource IO))
22-
mkBufferedSource walletRef count minValue variant munch
23-
= mkWalletFundSource walletRef (selectToBuffer count minValue variant) >>= \case
24-
Left err -> return $ Left err
25-
Right funds -> do
26-
buffer <- newMVar funds
27-
return $ Right $ listSource buffer munch
17+
-> IO (FundSource IO)
18+
mkBufferedSource walletRef munch = do
19+
funds <- askWalletRef walletRef walletFunds
20+
buffer <- newMVar funds
21+
return $ listSource buffer munch
2822

2923
listSource :: MVar [Fund] -> Int -> IO (Either String [Fund])
3024
listSource mvar count = modifyMVarMasked mvar popFunds

0 commit comments

Comments
 (0)