Skip to content

Instantly share code, notes, and snippets.

@j-mueller
Created November 30, 2018 15:26
Show Gist options
  • Save j-mueller/a9d51837f218d4b4c2c9c5c6a1bfa206 to your computer and use it in GitHub Desktop.
Save j-mueller/a9d51837f218d4b4c2c9c5c6a1bfa206 to your computer and use it in GitHub Desktop.
State machine
{-# LANGUAGE TemplateHaskell #-}
module Language.Plutus.Coordination.StateMachine.TH(
StateMachine(..),
stateMachine
) where
import Language.Haskell.TH (Q, TExp)
import Language.Plutus.Runtime (PendingTx(..), ValidatorHash, DataScriptHash(..), RedeemerHash(..))
import qualified Language.Plutus.Runtime.TH as TH
import qualified Language.PlutusTx.Builtins as Builtins
data StateMachine s i = StateMachine {
step :: Q (TExp (PendingTx (ValidatorHash, DataScriptHash, RedeemerHash) -> s -> i -> s)),
eqState :: Q (TExp (s -> s -> Bool))
}
-- | A function that checks if the new state matches what is expected, and
-- verifies that the hash of the current redeemer matches that of the new data
-- script.
stateMachine ::
StateMachine s i
-> Q (TExp ((s, i) -> (s, i) -> PendingTx (ValidatorHash, DataScriptHash, RedeemerHash) -> Bool))
stateMachine s = [|| \(currentState, _) (newState, action) p ->
let
actualState = $$(step s) p currentState action
statesMatch = $$(eqState s) actualState newState
-- check that our redeemer script hash is the same as the data script hash of the first tx output
PendingTx _ (o1:_) _ _ _ _ (_, _, RedeemerHash h) = p
hashesMatch = case $$(TH.scriptOutput) o1 of
Nothing -> False -- o1 is a pay-to-pubkey output
Just (_, DataScriptHash h2) -> Builtins.equalsByteString h h2
in
statesMatch && hashesMatch ||]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment