@@ -9,6 +9,7 @@ module Populate (
99 runCmd ,
1010 flg ,
1111 opt ,
12+ raw ,
1213 drain ,
1314 getPolicyId ,
1415 Wallet (.. ),
@@ -26,6 +27,7 @@ module Populate (
2627 -- Main
2728 testScriptTrigger ,
2829 escrow ,
30+ runFanout ,
2931) where
3032
3133-------------------------------------------------------------------------------
@@ -35,6 +37,8 @@ module Populate (
3537import Control.Concurrent (threadDelay )
3638import Control.Monad (void )
3739import Data.Function ((&) )
40+ import Data.List (isPrefixOf )
41+ import Data.Maybe (fromJust )
3842import Data.Word (Word8 )
3943import Streamly.Data.Array (Array )
4044import Streamly.Data.Fold qualified as Fold
@@ -142,15 +146,22 @@ env_TX_SIGNED = env_POPULATE_WORK_DIR </> "tx.signed"
142146-------------------------------------------------------------------------------
143147
144148type Command = String
145- type CmdOption = (String , Maybe String )
149+
150+ data CmdOption
151+ = CoOpt String String
152+ | CoFlg String
153+ | CoRaw String
146154
147155opt :: (Show b ) => String -> b -> CmdOption
148- opt a b = (a, Just (quoted b) )
156+ opt a b = CoOpt a (quoted b)
149157 where
150158 quoted = show
151159
152160flg :: String -> CmdOption
153- flg a = (a, Nothing )
161+ flg = CoFlg
162+
163+ raw :: String -> CmdOption
164+ raw = CoRaw
154165
155166optNetwork :: CmdOption
156167optNetwork = opt " testnet-magic" env_CARDANO_TESTNET_MAGIC
@@ -167,7 +178,11 @@ runCmd :: Command -> [CmdOption] -> Stream IO (Array Word8)
167178runCmd cmd args =
168179 Stream. before (putStrLn [str |> #{cmdStr}|]) (Cmd. toChunks cmdStr)
169180 where
170- cmdList = cmd : concatMap (\ (k, v) -> [" --" ++ k, maybe " " id v]) args
181+ cmdOptStr (CoOpt k v) = [str |--#{k} #{v}|]
182+ cmdOptStr (CoFlg k) = [str |--#{k}|]
183+ cmdOptStr (CoRaw v) = v
184+
185+ cmdList = cmd : map cmdOptStr args
171186 cmdStr = unwords cmdList
172187
173188getPolicyId :: FilePath -> IO String
@@ -554,6 +569,100 @@ testScriptTrigger = do
554569 testScriptTriggerWith =<< makeAppEnv " tracing-plutus-v2"
555570 testScriptTriggerWith =<< makeAppEnv " tracing-plutus-v3"
556571
572+ --------------------------------------------------------------------------------
573+ -- Fanout
574+ --------------------------------------------------------------------------------
575+
576+ data FanoutConfig = FanoutConfig
577+ { fcValidatorAddr :: String
578+ , fcValidatorFilePath :: String
579+ , fcFaucetAddr :: String
580+ }
581+
582+ makeFanoutConfig :: FilePath -> IO FanoutConfig
583+ makeFanoutConfig alwaysTrueScriptPath = do
584+ let fcValidatorFilePath = alwaysTrueScriptPath
585+ fcFaucetAddr <- env_FAUCET_WALLET_ADDR
586+ fcValidatorAddr <- getScriptAddress fcValidatorFilePath
587+
588+ printVar " fcFaucetAddr" fcFaucetAddr
589+ printVar " fcValidatorAddr" fcValidatorAddr
590+
591+ pure $
592+ FanoutConfig
593+ { fcValidatorAddr
594+ , fcValidatorFilePath
595+ , fcFaucetAddr
596+ }
597+
598+ type UtxoRef = String
599+
600+ fanout :: FanoutConfig -> Int -> [UtxoRef ] -> IO [UtxoRef ]
601+ fanout FanoutConfig {.. } spread inpUtxos = do
602+ ensureBlankWorkDir
603+
604+ faucetUtxo <- getFirstUtxoAt fcFaucetAddr
605+ printVar " faucetUtxo" faucetUtxo
606+
607+ let optTxInAdditional =
608+ [ opt " tx-in-script-file" fcValidatorFilePath
609+ , opt " tx-in-redeemer-value" (10 :: Int )
610+ , opt " tx-in-collateral" faucetUtxo
611+ ]
612+
613+ txInList = (: optTxInAdditional) . opt " tx-in" <$> inpUtxos
614+ txOutList =
615+ opt " tx-out"
616+ <$> replicate spread [str |#{fcValidatorAddr} + 1000000|]
617+
618+ printStep " fanout"
619+ buildTransaction $
620+ concat
621+ [
622+ [ opt " tx-in" faucetUtxo
623+ , opt " change-address" fcFaucetAddr
624+ , opt " out-file" env_TX_UNSIGNED
625+ ]
626+ , concat txInList
627+ , txOutList
628+ ]
629+ finalizeCurrentTransaction
630+ txId <- getTransactionId env_TX_SIGNED
631+ printVar " txId" txId
632+ waitTillExists $ fstOutput txId
633+ let mkUtxoRef i = txId ++ " #" ++ show i
634+ pure $ map mkUtxoRef [0 .. (spread - 1 )]
635+
636+ -- NOTE: The port (8090) and the tag (max_internal_utxo_map_size) is hard coded
637+ -- here.
638+ getInternalMapSize :: IO String
639+ getInternalMapSize = do
640+ runCmd " curl" [flg " silent" , raw " http://localhost:8090/metrics" ]
641+ & nonEmptyLines
642+ & Stream. filter (" max_internal_utxo_map_size" `isPrefixOf` )
643+ & Stream. fold Fold. one
644+ & fmap (maybe " " id )
645+
646+ runFanout :: IO ()
647+ runFanout = do
648+ let alwaysTrueScriptPath =
649+ env_LOCAL_CONFIG_DIR </> " tracing-plutus-v3/validator.plutus"
650+ fc <- makeFanoutConfig alwaysTrueScriptPath
651+ (nextSpread, utxos) <-
652+ Stream. iterateM (iterFunc fc (+ 1 )) (pure (1 , [] ))
653+ & Stream. take 10
654+ & Stream. fold Fold. latest
655+ & fmap fromJust
656+ Stream. iterateM (iterFunc fc (\ x -> x - 1 )) (pure (nextSpread - 1 , utxos))
657+ & Stream. take 10
658+ & Stream. fold Fold. drain
659+ where
660+ iterFunc fc incF (spread, inp) = do
661+ outs <- fanout fc spread inp
662+ ist <- getInternalMapSize
663+ printStep $ " Spread: " ++ show spread ++ " [" ++ ist ++ " ]"
664+ pure (incF spread, outs)
665+
557666--------------------------------------------------------------------------------
558667-- Escrow
559668--------------------------------------------------------------------------------
0 commit comments