module Pigy.Chain.Types (
MaryAddress
, MaryScript
, Origins
, Pendings
, History
, Chain
, ChainState(..)
, activeLens
, currentLens
, originsLens
, pendingsLens
, historyLens
, withChainState
) where
import Cardano.Api (AddressInEra(..), MaryEra, ScriptHash, ScriptInEra(..), SlotNo(..), TxIn(..), Value)
import Control.Lens (Lens', lens)
import Control.Monad.State.Strict (StateT(..))
import Data.Default (Default(..))
import Data.IORef (IORef, readIORef, writeIORef)
import Pigy.Types (Context(..))
import qualified Data.Map.Strict as M (Map, empty)
type MaryAddress = AddressInEra MaryEra
type MaryScript = ScriptInEra MaryEra
type Origins = M.Map TxIn MaryAddress
type Pendings = M.Map TxIn ([MaryAddress], Value)
type History = [(SlotNo, (Origins, Pendings))]
data ChainState =
ChainState
{
ChainState -> Context
context :: Context
, ChainState -> Bool
active :: Bool
, ChainState -> SlotNo
current :: SlotNo
, ChainState -> Origins
origins :: Origins
, ChainState -> Pendings
pendings :: Pendings
, ChainState -> History
history :: History
, ChainState -> MaryAddress
scriptAddress :: MaryAddress
, ChainState -> MaryScript
script :: MaryScript
, ChainState -> ScriptHash
scriptHash :: ScriptHash
, ChainState -> Value -> Bool
checker :: Value -> Bool
}
instance Default ChainState where
def :: ChainState
def =
ChainState :: Context
-> Bool
-> SlotNo
-> Origins
-> Pendings
-> History
-> MaryAddress
-> MaryScript
-> ScriptHash
-> (Value -> Bool)
-> ChainState
ChainState
{
context :: Context
context = Context
forall a. HasCallStack => a
undefined
, active :: Bool
active = Bool
False
, current :: SlotNo
current = Word64 -> SlotNo
SlotNo Word64
0
, origins :: Origins
origins = Origins
forall k a. Map k a
M.empty
, pendings :: Pendings
pendings = Pendings
forall k a. Map k a
M.empty
, history :: History
history = [(Word64 -> SlotNo
SlotNo Word64
0, (Origins
forall k a. Map k a
M.empty, Pendings
forall k a. Map k a
M.empty))]
, scriptAddress :: MaryAddress
scriptAddress = MaryAddress
forall a. HasCallStack => a
undefined
, script :: MaryScript
script = MaryScript
forall a. HasCallStack => a
undefined
, scriptHash :: ScriptHash
scriptHash = ScriptHash
forall a. HasCallStack => a
undefined
, checker :: Value -> Bool
checker = Value -> Bool
forall a. HasCallStack => a
undefined
}
activeLens :: Lens' ChainState Bool
activeLens :: (Bool -> f Bool) -> ChainState -> f ChainState
activeLens = (ChainState -> Bool)
-> (ChainState -> Bool -> ChainState)
-> Lens ChainState ChainState Bool Bool
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ChainState -> Bool
active ((ChainState -> Bool -> ChainState)
-> Lens ChainState ChainState Bool Bool)
-> (ChainState -> Bool -> ChainState)
-> Lens ChainState ChainState Bool Bool
forall a b. (a -> b) -> a -> b
$ \ChainState
x Bool
active' -> ChainState
x {active :: Bool
active = Bool
active'}
currentLens :: Lens' ChainState SlotNo
currentLens :: (SlotNo -> f SlotNo) -> ChainState -> f ChainState
currentLens = (ChainState -> SlotNo)
-> (ChainState -> SlotNo -> ChainState)
-> Lens ChainState ChainState SlotNo SlotNo
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ChainState -> SlotNo
current ((ChainState -> SlotNo -> ChainState)
-> Lens ChainState ChainState SlotNo SlotNo)
-> (ChainState -> SlotNo -> ChainState)
-> Lens ChainState ChainState SlotNo SlotNo
forall a b. (a -> b) -> a -> b
$ \ChainState
x SlotNo
current' -> ChainState
x {current :: SlotNo
current = SlotNo
current'}
originsLens :: Lens' ChainState Origins
originsLens :: (Origins -> f Origins) -> ChainState -> f ChainState
originsLens = (ChainState -> Origins)
-> (ChainState -> Origins -> ChainState)
-> Lens ChainState ChainState Origins Origins
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ChainState -> Origins
origins ((ChainState -> Origins -> ChainState)
-> Lens ChainState ChainState Origins Origins)
-> (ChainState -> Origins -> ChainState)
-> Lens ChainState ChainState Origins Origins
forall a b. (a -> b) -> a -> b
$ \ChainState
x Origins
origins' -> ChainState
x {origins :: Origins
origins = Origins
origins'}
pendingsLens :: Lens' ChainState Pendings
pendingsLens :: (Pendings -> f Pendings) -> ChainState -> f ChainState
pendingsLens = (ChainState -> Pendings)
-> (ChainState -> Pendings -> ChainState)
-> Lens ChainState ChainState Pendings Pendings
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ChainState -> Pendings
pendings ((ChainState -> Pendings -> ChainState)
-> Lens ChainState ChainState Pendings Pendings)
-> (ChainState -> Pendings -> ChainState)
-> Lens ChainState ChainState Pendings Pendings
forall a b. (a -> b) -> a -> b
$ \ChainState
x Pendings
pendings' -> ChainState
x {pendings :: Pendings
pendings = Pendings
pendings'}
historyLens :: Lens' ChainState History
historyLens :: (History -> f History) -> ChainState -> f ChainState
historyLens = (ChainState -> History)
-> (ChainState -> History -> ChainState)
-> Lens ChainState ChainState History History
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens ChainState -> History
history ((ChainState -> History -> ChainState)
-> Lens ChainState ChainState History History)
-> (ChainState -> History -> ChainState)
-> Lens ChainState ChainState History History
forall a b. (a -> b) -> a -> b
$ \ChainState
x History
history' -> ChainState
x {history :: History
history = History
history'}
type Chain a = StateT ChainState IO a
withChainState :: IORef ChainState
-> Chain a
-> IO a
withChainState :: IORef ChainState -> Chain a -> IO a
withChainState IORef ChainState
ref Chain a
transition =
do
ChainState
initial <- IORef ChainState -> IO ChainState
forall a. IORef a -> IO a
readIORef IORef ChainState
ref
(a
result, ChainState
final) <- Chain a -> ChainState -> IO (a, ChainState)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT Chain a
transition ChainState
initial
IORef ChainState -> ChainState -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef ChainState
ref ChainState
final
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
result