module Cooked.MockChain.Runnable where
import Cooked.MockChain.Error
import Cooked.MockChain.Journal
import Cooked.MockChain.State
import Cooked.MockChain.Write
import Cooked.Skeleton.Output
import Cooked.Wallet
import Data.Default
import Data.List (foldl')
import Data.Map (Map)
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V3 qualified as Api
import Polysemy
type InitialDistribution = [TxSkelOut]
initialDistributionTemplate :: InitialDistribution
initialDistributionTemplate :: InitialDistribution
initialDistributionTemplate =
[(Wallet, [Value])] -> InitialDistribution
forall owner.
IsTxSkelOutAllowedOwner owner =>
[(owner, [Value])] -> InitialDistribution
distributionFromList
([(Wallet, [Value])] -> InitialDistribution)
-> (Value -> [(Wallet, [Value])]) -> Value -> InitialDistribution
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Wallet] -> [[Value]] -> [(Wallet, [Value])]
forall a b. [a] -> [b] -> [(a, b)]
zip (Int -> [Wallet] -> [Wallet]
forall a. Int -> [a] -> [a]
take Int
4 [Wallet]
knownWallets)
([[Value]] -> [(Wallet, [Value])])
-> (Value -> [[Value]]) -> Value -> [(Wallet, [Value])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Value] -> [[Value]]
forall a. a -> [a]
repeat
([Value] -> [[Value]]) -> (Value -> [Value]) -> Value -> [[Value]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Value -> [Value]
forall a. Int -> a -> [a]
replicate Int
4
(Value -> InitialDistribution) -> Value -> InitialDistribution
forall a b. (a -> b) -> a -> b
$ Integer -> Value
Script.ada Integer
100
distributionFromList :: (IsTxSkelOutAllowedOwner owner) => [(owner, [Api.Value])] -> InitialDistribution
distributionFromList :: forall owner.
IsTxSkelOutAllowedOwner owner =>
[(owner, [Value])] -> InitialDistribution
distributionFromList = (InitialDistribution -> (owner, [Value]) -> InitialDistribution)
-> InitialDistribution -> [(owner, [Value])] -> InitialDistribution
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\InitialDistribution
x (owner
user, [Value]
values) -> InitialDistribution
x InitialDistribution -> InitialDistribution -> InitialDistribution
forall a. Semigroup a => a -> a -> a
<> (Value -> TxSkelOut) -> [Value] -> InitialDistribution
forall a b. (a -> b) -> [a] -> [b]
map (owner -> Payable '[ 'IsValue] -> TxSkelOut
forall owner (els :: [PayableKind]).
IsTxSkelOutAllowedOwner owner =>
owner -> Payable els -> TxSkelOut
receives owner
user (Payable '[ 'IsValue] -> TxSkelOut)
-> (Value -> Payable '[ 'IsValue]) -> Value -> TxSkelOut
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Payable '[ 'IsValue]
forall a1. ToValue a1 => a1 -> Payable '[ 'IsValue]
Value) [Value]
values) []
type RawMockChainReturn a =
(MockChainJournal, (MockChainState, Either MockChainError a))
data MockChainReturn a where
MockChainReturn ::
{
forall a. MockChainReturn a -> Either MockChainError a
mcrValue :: Either MockChainError a,
forall a. MockChainReturn a -> Map TxOutRef (TxSkelOut, Bool)
mcrOutputs :: Map Api.TxOutRef (TxSkelOut, Bool),
forall a. MockChainReturn a -> UtxoState
mcrUtxoState :: UtxoState,
forall a. MockChainReturn a -> MockChainJournal
mcrJournal :: MockChainJournal
} ->
MockChainReturn a
deriving ((forall a b. (a -> b) -> MockChainReturn a -> MockChainReturn b)
-> (forall a b. a -> MockChainReturn b -> MockChainReturn a)
-> Functor MockChainReturn
forall a b. a -> MockChainReturn b -> MockChainReturn a
forall a b. (a -> b) -> MockChainReturn a -> MockChainReturn b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> MockChainReturn a -> MockChainReturn b
fmap :: forall a b. (a -> b) -> MockChainReturn a -> MockChainReturn b
$c<$ :: forall a b. a -> MockChainReturn b -> MockChainReturn a
<$ :: forall a b. a -> MockChainReturn b -> MockChainReturn a
Functor)
type FunOnMockChainResult a b = RawMockChainReturn a -> b
unRawMockChainReturn :: FunOnMockChainResult a (MockChainReturn a)
unRawMockChainReturn :: forall a. FunOnMockChainResult a (MockChainReturn a)
unRawMockChainReturn (MockChainJournal
journal, (MockChainState
st, Either MockChainError a
val)) =
Either MockChainError a
-> Map TxOutRef (TxSkelOut, Bool)
-> UtxoState
-> MockChainJournal
-> MockChainReturn a
forall a.
Either MockChainError a
-> Map TxOutRef (TxSkelOut, Bool)
-> UtxoState
-> MockChainJournal
-> MockChainReturn a
MockChainReturn Either MockChainError a
val (MockChainState -> Map TxOutRef (TxSkelOut, Bool)
mcstOutputs MockChainState
st) (MockChainState -> UtxoState
mcstToUtxoState MockChainState
st) MockChainJournal
journal
data MockChainConf a b where
MockChainConf ::
{
forall a b. MockChainConf a b -> MockChainState
mccInitialState :: MockChainState,
forall a b. MockChainConf a b -> InitialDistribution
mccInitialDistribution :: InitialDistribution,
forall a b. MockChainConf a b -> FunOnMockChainResult a b
mccFunOnResult :: FunOnMockChainResult a b
} ->
MockChainConf a b
mockChainConfTemplate :: MockChainConf a (MockChainReturn a)
mockChainConfTemplate :: forall a. MockChainConf a (MockChainReturn a)
mockChainConfTemplate = MockChainState
-> InitialDistribution
-> FunOnMockChainResult a (MockChainReturn a)
-> MockChainConf a (MockChainReturn a)
forall a b.
MockChainState
-> InitialDistribution
-> FunOnMockChainResult a b
-> MockChainConf a b
MockChainConf MockChainState
forall a. Default a => a
def InitialDistribution
forall a. Default a => a
def FunOnMockChainResult a (MockChainReturn a)
forall a. FunOnMockChainResult a (MockChainReturn a)
unRawMockChainReturn
class RunnableMockChain effs where
runMockChain :: MockChainState -> Sem effs a -> [RawMockChainReturn a]
runMockChainFromConf ::
( RunnableMockChain effs,
Member MockChainWrite effs
) =>
MockChainConf a b ->
Sem effs a ->
[b]
runMockChainFromConf :: forall (effs :: EffectRow) a b.
(RunnableMockChain effs, Member MockChainWrite effs) =>
MockChainConf a b -> Sem effs a -> [b]
runMockChainFromConf (MockChainConf MockChainState
initState InitialDistribution
initDist FunOnMockChainResult a b
funOnResult) Sem effs a
currentRun =
FunOnMockChainResult a b -> [RawMockChainReturn a] -> [b]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FunOnMockChainResult a b
funOnResult ([RawMockChainReturn a] -> [b]) -> [RawMockChainReturn a] -> [b]
forall a b. (a -> b) -> a -> b
$
MockChainState -> Sem effs a -> [RawMockChainReturn a]
forall (effs :: EffectRow) a.
RunnableMockChain effs =>
MockChainState -> Sem effs a -> [RawMockChainReturn a]
forall a. MockChainState -> Sem effs a -> [RawMockChainReturn a]
runMockChain MockChainState
initState (Sem effs a -> [RawMockChainReturn a])
-> Sem effs a -> [RawMockChainReturn a]
forall a b. (a -> b) -> a -> b
$
InitialDistribution -> Sem effs Utxos
forall (effs :: EffectRow).
Member MockChainWrite effs =>
InitialDistribution -> Sem effs Utxos
forceOutputs InitialDistribution
initDist Sem effs Utxos -> Sem effs a -> Sem effs a
forall a b. Sem effs a -> Sem effs b -> Sem effs b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sem effs a
currentRun
runMockChainFromInitDist ::
( RunnableMockChain effs,
Member MockChainWrite effs
) =>
InitialDistribution ->
Sem effs a ->
[MockChainReturn a]
runMockChainFromInitDist :: forall (effs :: EffectRow) a.
(RunnableMockChain effs, Member MockChainWrite effs) =>
InitialDistribution -> Sem effs a -> [MockChainReturn a]
runMockChainFromInitDist InitialDistribution
initDist =
MockChainConf a (MockChainReturn a)
-> Sem effs a -> [MockChainReturn a]
forall (effs :: EffectRow) a b.
(RunnableMockChain effs, Member MockChainWrite effs) =>
MockChainConf a b -> Sem effs a -> [b]
runMockChainFromConf (MockChainConf a (MockChainReturn a)
-> Sem effs a -> [MockChainReturn a])
-> MockChainConf a (MockChainReturn a)
-> Sem effs a
-> [MockChainReturn a]
forall a b. (a -> b) -> a -> b
$ MockChainConf a (MockChainReturn a)
forall a. MockChainConf a (MockChainReturn a)
mockChainConfTemplate {mccInitialDistribution = initDist}
runMockChainFromInitDistTemplate ::
( RunnableMockChain effs,
Member MockChainWrite effs
) =>
Sem effs a ->
[MockChainReturn a]
runMockChainFromInitDistTemplate :: forall (effs :: EffectRow) a.
(RunnableMockChain effs, Member MockChainWrite effs) =>
Sem effs a -> [MockChainReturn a]
runMockChainFromInitDistTemplate = InitialDistribution -> Sem effs a -> [MockChainReturn a]
forall (effs :: EffectRow) a.
(RunnableMockChain effs, Member MockChainWrite effs) =>
InitialDistribution -> Sem effs a -> [MockChainReturn a]
runMockChainFromInitDist InitialDistribution
initialDistributionTemplate
runMockChainDef ::
( RunnableMockChain effs,
Member MockChainWrite effs
) =>
Sem effs a ->
[MockChainReturn a]
runMockChainDef :: forall (effs :: EffectRow) a.
(RunnableMockChain effs, Member MockChainWrite effs) =>
Sem effs a -> [MockChainReturn a]
runMockChainDef = MockChainConf a (MockChainReturn a)
-> Sem effs a -> [MockChainReturn a]
forall (effs :: EffectRow) a b.
(RunnableMockChain effs, Member MockChainWrite effs) =>
MockChainConf a b -> Sem effs a -> [b]
runMockChainFromConf MockChainConf a (MockChainReturn a)
forall a. MockChainConf a (MockChainReturn a)
mockChainConfTemplate