{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-unused-matches -Wno-name-shadowing #-}
module Convex.ThreatModel (
TxModifier,
Input (..),
Output (..),
Datum,
Redeemer,
IsInputOrOutput (..),
addOutput,
removeOutput,
addKeyInput,
addPlutusScriptInput,
addSimpleScriptInput,
addReferenceScriptInput,
addKeyReferenceInput,
addPlutusScriptReferenceInput,
addSimpleScriptReferenceInput,
removeInput,
changeRedeemerOf,
changeValidityRange,
changeValidityLowerBound,
changeValidityUpperBound,
replaceTx,
ThreatModel (Named),
ThreatModelEnv (currentTx, currentUTxOs, currentChainState),
mkThreatModelEnv,
pparams,
ThreatModelOutcome (..),
threatModelEnvs,
runThreatModel,
runThreatModelM,
runThreatModelMQuiet,
runThreatModelCheck,
runThreatModelCheckTraced,
ThreatModelCheckEntry (..),
finalOutcome,
assertThreatModel,
getThreatModelName,
threatPrecondition,
inPrecondition,
ensure,
ensureHasInputAt,
requireScriptExecution,
guardedScriptOutputs,
anyGuardedOutput,
anyGuardedOutputSuchThat,
anyGuardedOutputWithInlineDatum,
hasInlineDatum,
getInlineDatum,
toInlineDatum,
failPrecondition,
shouldValidate,
shouldNotValidate,
ValidityReport (..),
TxValidity (..),
validate,
getThreatModelEnv,
originalTx,
getTxInputs,
getTxReferenceInputs,
getTxOutputs,
getRedeemer,
getTxRequiredSigners,
forAllTM,
shrinkPositive,
pickAny,
anySigner,
anyInput,
anyReferenceInput,
anyOutput,
anyInputSuchThat,
anyReferenceInputSuchThat,
anyOutputSuchThat,
counterexampleTM,
tabulateTM,
collectTM,
classifyTM,
monitorThreatModel,
monitorLocalThreatModel,
SigningWallet (..),
projectAda,
leqValue,
keyAddressAny,
scriptAddressAny,
isKeyAddressAny,
txOutDatum,
toScriptData,
datumOfTxOut,
paragraph,
prettyAddress,
prettyValue,
prettyDatum,
prettyInput,
prettyOutput,
module X,
) where
import Cardano.Api as X
import Cardano.Ledger.Hashes qualified as Ledger (ScriptHash)
import Control.Applicative ((<|>))
import Control.Lens ((%~), (&))
import Control.Monad
import Data.Containers.ListUtils (nubOrd)
import Data.List (intercalate)
import Data.Map qualified as Map
import Data.Set qualified as Set
import Text.PrettyPrint hiding ((<>))
import Text.Printf
import Test.QuickCheck
import Test.QuickCheck qualified as QC
import Convex.Class (MockChainState, MonadMockchain (..), coverageData, setTimeToValidRange)
import Convex.MockChain (applyTransaction, runMockchain)
import Convex.NodeParams (NodeParams)
import Convex.ThreatModel.Cardano.Api
import Convex.ThreatModel.Cardano.Api qualified as TM (detectSigningWallet, rebalanceAndSign, txRequiredSigners)
import Convex.ThreatModel.Pretty
import Convex.ThreatModel.TxModifier
import Convex.Wallet (Wallet)
data ThreatModelEnv = ThreatModelEnv
{ ThreatModelEnv -> Tx Era
currentTx :: Tx Era
, ThreatModelEnv -> UTxO Era
currentUTxOs :: UTxO Era
, ThreatModelEnv -> TxBodyContent ViewTx Era
currentTxBodyContent :: TxBodyContent ViewTx Era
, ThreatModelEnv -> Set ScriptHash
runningPlutusScripts :: Set.Set Ledger.ScriptHash
, ThreatModelEnv -> MockChainState Era
currentChainState :: MockChainState Era
}
mkThreatModelEnv :: Tx Era -> MockChainState Era -> ThreatModelEnv
mkThreatModelEnv :: Tx Era -> MockChainState Era -> ThreatModelEnv
mkThreatModelEnv Tx Era
tx MockChainState Era
chainState =
ThreatModelEnv
{ currentTx :: Tx Era
currentTx = Tx Era
tx
, currentUTxOs :: UTxO Era
currentUTxOs = MockChainState Era -> UTxO Era
chainStateUTxO MockChainState Era
chainState
, currentTxBodyContent :: TxBodyContent ViewTx Era
currentTxBodyContent = Tx Era -> TxBodyContent ViewTx Era
txBodyContentOf Tx Era
tx
, runningPlutusScripts :: Set ScriptHash
runningPlutusScripts = UTxO (ShelleyLedgerEra Era) -> Tx Era -> Set ScriptHash
runningPlutusScriptHashes (MockChainState Era -> UTxO (ShelleyLedgerEra Era)
chainStateLedgerUTxO MockChainState Era
chainState) Tx Era
tx
, currentChainState :: MockChainState Era
currentChainState = MockChainState Era
chainState
}
pparams :: ThreatModelEnv -> LedgerProtocolParameters Era
pparams :: ThreatModelEnv -> LedgerProtocolParameters Era
pparams = MockChainState Era -> LedgerProtocolParameters Era
chainStatePParams (MockChainState Era -> LedgerProtocolParameters Era)
-> (ThreatModelEnv -> MockChainState Era)
-> ThreatModelEnv
-> LedgerProtocolParameters Era
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ThreatModelEnv -> MockChainState Era
currentChainState
data SigningWallet
=
AutoSign
|
SignWith Wallet
threatModelEnvs :: NodeParams Era -> [Tx Era] -> MockChainState Era -> [ThreatModelEnv]
threatModelEnvs :: NodeParams Era
-> [Tx Era] -> MockChainState Era -> [ThreatModelEnv]
threatModelEnvs NodeParams Era
params [Tx Era]
txs MockChainState Era
chainState0 = ([ThreatModelEnv], MockChainState Era) -> [ThreatModelEnv]
forall a b. (a, b) -> a
fst (([ThreatModelEnv], MockChainState Era) -> [ThreatModelEnv])
-> ([ThreatModelEnv], MockChainState Era) -> [ThreatModelEnv]
forall a b. (a -> b) -> a -> b
$ (MockChainState Era
-> Tx Era -> ([ThreatModelEnv], MockChainState Era))
-> MockChainState Era
-> [Tx Era]
-> ([ThreatModelEnv], MockChainState Era)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM MockChainState Era
-> Tx Era -> ([ThreatModelEnv], MockChainState Era)
go MockChainState Era
chainState0 [Tx Era]
txs
where
go :: MockChainState Era
-> Tx Era -> ([ThreatModelEnv], MockChainState Era)
go MockChainState Era
chainState Tx Era
tx =
let txBodyContent :: TxBodyContent ViewTx Era
txBodyContent = TxBody Era -> TxBodyContent ViewTx Era
forall era. TxBody era -> TxBodyContent ViewTx era
getTxBodyContent (TxBody Era -> TxBodyContent ViewTx Era)
-> TxBody Era -> TxBodyContent ViewTx Era
forall a b. (a -> b) -> a -> b
$ Tx Era -> TxBody Era
forall era. Tx era -> TxBody era
getTxBody Tx Era
tx
rng :: (TxValidityLowerBound Era, TxValidityUpperBound Era)
rng = (TxBodyContent ViewTx Era -> TxValidityLowerBound Era
forall build era.
TxBodyContent build era -> TxValidityLowerBound era
txValidityLowerBound TxBodyContent ViewTx Era
txBodyContent, TxBodyContent ViewTx Era -> TxValidityUpperBound Era
forall build era.
TxBodyContent build era -> TxValidityUpperBound era
txValidityUpperBound TxBodyContent ViewTx Era
txBodyContent)
((), MockChainState Era
chainState') = Mockchain Era ()
-> NodeParams Era -> MockChainState Era -> ((), MockChainState Era)
forall era a.
Mockchain era a
-> NodeParams era -> MockChainState era -> (a, MockChainState era)
runMockchain ((TxValidityLowerBound Era, TxValidityUpperBound Era)
-> Mockchain Era ()
forall era (m :: * -> *).
MonadMockchain era m =>
(TxValidityLowerBound era, TxValidityUpperBound era) -> m ()
setTimeToValidRange (TxValidityLowerBound Era, TxValidityUpperBound Era)
rng) NodeParams Era
params MockChainState Era
chainState
res :: Either
(SendTxError Era)
(MockChainState Era, Validated (Tx (ShelleyLedgerEra Era)))
res = NodeParams Era
-> MockChainState Era
-> Tx Era
-> Either
(SendTxError Era)
(MockChainState Era, Validated (Tx (ShelleyLedgerEra Era)))
forall era.
(EraStake (ShelleyLedgerEra era), IsEra era,
IsAlonzoBasedEra era) =>
NodeParams era
-> MockChainState era
-> Tx era
-> Either
(SendTxError era)
(MockChainState era, Validated (Tx (ShelleyLedgerEra era)))
applyTransaction NodeParams Era
params MockChainState Era
chainState' Tx Era
tx
threatModelEnv :: ThreatModelEnv
threatModelEnv = Tx Era -> MockChainState Era -> ThreatModelEnv
mkThreatModelEnv Tx Era
tx MockChainState Era
chainState'
in case Either
(SendTxError Era)
(MockChainState Era, Validated (Tx (ShelleyLedgerEra Era)))
res of
Left SendTxError Era
e -> String -> ([ThreatModelEnv], MockChainState Era)
forall a. HasCallStack => String -> a
error (String -> ([ThreatModelEnv], MockChainState Era))
-> String -> ([ThreatModelEnv], MockChainState Era)
forall a b. (a -> b) -> a -> b
$ String
"Unexpected error after replaying transactions: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SendTxError Era -> String
forall a. Show a => a -> String
show SendTxError Era
e
Right (MockChainState Era
chainState'', Validated (Tx (ShelleyLedgerEra Era))
_) -> ([ThreatModelEnv
threatModelEnv], MockChainState Era
chainState'')
data ThreatModelOutcome
=
TMPassed
|
TMFailed String
|
TMSkipped
|
TMSkippedPhase1
|
TMError String
deriving (ThreatModelOutcome -> ThreatModelOutcome -> Bool
(ThreatModelOutcome -> ThreatModelOutcome -> Bool)
-> (ThreatModelOutcome -> ThreatModelOutcome -> Bool)
-> Eq ThreatModelOutcome
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ThreatModelOutcome -> ThreatModelOutcome -> Bool
== :: ThreatModelOutcome -> ThreatModelOutcome -> Bool
$c/= :: ThreatModelOutcome -> ThreatModelOutcome -> Bool
/= :: ThreatModelOutcome -> ThreatModelOutcome -> Bool
Eq, Int -> ThreatModelOutcome -> String -> String
[ThreatModelOutcome] -> String -> String
ThreatModelOutcome -> String
(Int -> ThreatModelOutcome -> String -> String)
-> (ThreatModelOutcome -> String)
-> ([ThreatModelOutcome] -> String -> String)
-> Show ThreatModelOutcome
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ThreatModelOutcome -> String -> String
showsPrec :: Int -> ThreatModelOutcome -> String -> String
$cshow :: ThreatModelOutcome -> String
show :: ThreatModelOutcome -> String
$cshowList :: [ThreatModelOutcome] -> String -> String
showList :: [ThreatModelOutcome] -> String -> String
Show)
data ThreatModel a where
Validate
:: TxModifier
-> (ValidityReport -> ThreatModel a)
-> ThreatModel a
Generate
:: (Show a)
=> Gen a
-> (a -> [a])
-> (a -> ThreatModel b)
-> ThreatModel b
GetCtx :: (ThreatModelEnv -> ThreatModel a) -> ThreatModel a
Skip :: ThreatModel a
InPrecondition
:: (Bool -> ThreatModel a)
-> ThreatModel a
Fail
:: String
-> ThreatModel a
Monitor
:: (Property -> Property)
-> ThreatModel a
-> ThreatModel a
MonitorLocal
:: (Property -> Property)
-> ThreatModel a
-> ThreatModel a
Done
:: a
-> ThreatModel a
Named
:: String
-> ThreatModel a
-> ThreatModel a
instance Functor ThreatModel where
fmap :: forall a b. (a -> b) -> ThreatModel a -> ThreatModel b
fmap = (a -> b) -> ThreatModel a -> ThreatModel b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
instance Applicative ThreatModel where
pure :: forall a. a -> ThreatModel a
pure = a -> ThreatModel a
forall a. a -> ThreatModel a
Done
<*> :: forall a b. ThreatModel (a -> b) -> ThreatModel a -> ThreatModel b
(<*>) = ThreatModel (a -> b) -> ThreatModel a -> ThreatModel b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad ThreatModel where
Validate TxModifier
tx ValidityReport -> ThreatModel a
cont >>= :: forall a b. ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
>>= a -> ThreatModel b
k = TxModifier -> (ValidityReport -> ThreatModel b) -> ThreatModel b
forall a.
TxModifier -> (ValidityReport -> ThreatModel a) -> ThreatModel a
Validate TxModifier
tx (ValidityReport -> ThreatModel a
cont (ValidityReport -> ThreatModel a)
-> (a -> ThreatModel b) -> ValidityReport -> ThreatModel b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> ThreatModel b
k)
ThreatModel a
Skip >>= a -> ThreatModel b
_ = ThreatModel b
forall a. ThreatModel a
Skip
InPrecondition Bool -> ThreatModel a
cont >>= a -> ThreatModel b
k = (Bool -> ThreatModel b) -> ThreatModel b
forall a. (Bool -> ThreatModel a) -> ThreatModel a
InPrecondition (Bool -> ThreatModel a
cont (Bool -> ThreatModel a)
-> (a -> ThreatModel b) -> Bool -> ThreatModel b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> ThreatModel b
k)
Fail String
err >>= a -> ThreatModel b
_ = String -> ThreatModel b
forall a. String -> ThreatModel a
Fail String
err
Generate Gen a
gen a -> [a]
shr a -> ThreatModel a
cont >>= a -> ThreatModel b
k = Gen a -> (a -> [a]) -> (a -> ThreatModel b) -> ThreatModel b
forall a b.
Show a =>
Gen a -> (a -> [a]) -> (a -> ThreatModel b) -> ThreatModel b
Generate Gen a
gen a -> [a]
shr (a -> ThreatModel a
cont (a -> ThreatModel a) -> (a -> ThreatModel b) -> a -> ThreatModel b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> ThreatModel b
k)
GetCtx ThreatModelEnv -> ThreatModel a
cont >>= a -> ThreatModel b
k = (ThreatModelEnv -> ThreatModel b) -> ThreatModel b
forall a. (ThreatModelEnv -> ThreatModel a) -> ThreatModel a
GetCtx (ThreatModelEnv -> ThreatModel a
cont (ThreatModelEnv -> ThreatModel a)
-> (a -> ThreatModel b) -> ThreatModelEnv -> ThreatModel b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> ThreatModel b
k)
Monitor Property -> Property
m ThreatModel a
cont >>= a -> ThreatModel b
k = (Property -> Property) -> ThreatModel b -> ThreatModel b
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
Monitor Property -> Property
m (ThreatModel a
cont ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
forall a b. ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> ThreatModel b
k)
MonitorLocal Property -> Property
m ThreatModel a
cont >>= a -> ThreatModel b
k = (Property -> Property) -> ThreatModel b -> ThreatModel b
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
MonitorLocal Property -> Property
m (ThreatModel a
cont ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
forall a b. ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> ThreatModel b
k)
Done a
a >>= a -> ThreatModel b
k = a -> ThreatModel b
k a
a
Named String
n ThreatModel a
m >>= a -> ThreatModel b
k = String -> ThreatModel b -> ThreatModel b
forall a. String -> ThreatModel a -> ThreatModel a
Named String
n (ThreatModel a
m ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
forall a b. ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> ThreatModel b
k)
instance MonadFail ThreatModel where
fail :: forall a. String -> ThreatModel a
fail = String -> ThreatModel a
forall a. String -> ThreatModel a
Fail
runThreatModel :: ThreatModel a -> [ThreatModelEnv] -> Property
runThreatModel :: forall a. ThreatModel a -> [ThreatModelEnv] -> Property
runThreatModel = Bool -> ThreatModel a -> [ThreatModelEnv] -> Property
forall {a}. Bool -> ThreatModel a -> [ThreatModelEnv] -> Property
go Bool
False
where
go :: Bool -> ThreatModel a -> [ThreatModelEnv] -> Property
go Bool
b ThreatModel a
model [] = Bool
b Bool -> Property -> Property
forall prop. Testable prop => Bool -> prop -> Property
==> Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
go Bool
b ThreatModel a
model (ThreatModelEnv
env : [ThreatModelEnv]
envs) = (Property -> Property) -> ThreatModel a -> Property
interp (String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample (String -> Property -> Property) -> String -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Doc -> String
forall a. Show a => a -> String
show Doc
info) ThreatModel a
model
where
info :: Doc
info =
[Doc] -> Doc
vcat
[ Doc
""
, Doc -> [Doc] -> Doc
block
Doc
"Original UTxO set"
[ UTxO Era -> Doc
prettyUTxO (UTxO Era -> Doc) -> UTxO Era -> Doc
forall a b. (a -> b) -> a -> b
$
Tx Era -> UTxO Era -> UTxO Era
restrictUTxO (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) (UTxO Era -> UTxO Era) -> UTxO Era -> UTxO Era
forall a b. (a -> b) -> a -> b
$
ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env
]
, Doc
""
, Doc -> [Doc] -> Doc
block Doc
"Original transaction" [Tx Era -> Doc
prettyTx (Tx Era -> Doc) -> Tx Era -> Doc
forall a b. (a -> b) -> a -> b
$ ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env]
, Doc
""
]
interp :: (Property -> Property) -> ThreatModel a -> Property
interp Property -> Property
mon = \case
Validate TxModifier
mods ValidityReport -> ThreatModel a
k ->
(Property -> Property) -> ThreatModel a -> Property
interp Property -> Property
mon (ThreatModel a -> Property) -> ThreatModel a -> Property
forall a b. (a -> b) -> a -> b
$
ValidityReport -> ThreatModel a
k (ValidityReport -> ThreatModel a)
-> ValidityReport -> ThreatModel a
forall a b. (a -> b) -> a -> b
$
let (Tx Era
modifiedTx, UTxO Era
modifiedUtxo) = Tx Era -> UTxO Era -> TxModifier -> (Tx Era, UTxO Era)
applyTxModifier (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) (ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env) TxModifier
mods
in LedgerProtocolParameters Era
-> Tx Era -> UTxO Era -> ValidityReport
validateTx (ThreatModelEnv -> LedgerProtocolParameters Era
pparams ThreatModelEnv
env) Tx Era
modifiedTx UTxO Era
modifiedUtxo
Generate Gen a
gen a -> [a]
shr a -> ThreatModel a
k ->
Gen a -> (a -> [a]) -> (a -> Property) -> Property
forall prop a.
Testable prop =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrinkBlind Gen a
gen a -> [a]
shr ((a -> Property) -> Property) -> (a -> Property) -> Property
forall a b. (a -> b) -> a -> b
$
(Property -> Property) -> ThreatModel a -> Property
interp Property -> Property
mon (ThreatModel a -> Property)
-> (a -> ThreatModel a) -> a -> Property
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ThreatModel a
k
GetCtx ThreatModelEnv -> ThreatModel a
k ->
(Property -> Property) -> ThreatModel a -> Property
interp Property -> Property
mon (ThreatModel a -> Property) -> ThreatModel a -> Property
forall a b. (a -> b) -> a -> b
$
ThreatModelEnv -> ThreatModel a
k ThreatModelEnv
env
ThreatModel a
Skip -> Bool -> ThreatModel a -> [ThreatModelEnv] -> Property
go Bool
b ThreatModel a
model [ThreatModelEnv]
envs
InPrecondition Bool -> ThreatModel a
k -> (Property -> Property) -> ThreatModel a -> Property
interp Property -> Property
mon (Bool -> ThreatModel a
k Bool
False)
Fail String
err -> Property -> Property
mon (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ String -> Bool -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
err Bool
False
Monitor Property -> Property
m ThreatModel a
k -> Property -> Property
m (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ (Property -> Property) -> ThreatModel a -> Property
interp Property -> Property
mon ThreatModel a
k
MonitorLocal Property -> Property
m ThreatModel a
k -> (Property -> Property) -> ThreatModel a -> Property
interp (Property -> Property
mon (Property -> Property)
-> (Property -> Property) -> Property -> Property
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Property -> Property
m) ThreatModel a
k
Done{} -> Bool -> ThreatModel a -> [ThreatModelEnv] -> Property
go Bool
True ThreatModel a
model [ThreatModelEnv]
envs
Named String
_n ThreatModel a
k -> (Property -> Property) -> ThreatModel a -> Property
interp Property -> Property
mon ThreatModel a
k
assertThreatModel
:: ThreatModel a
-> [(Tx Era, MockChainState Era)]
-> Property
assertThreatModel :: forall a.
ThreatModel a -> [(Tx Era, MockChainState Era)] -> Property
assertThreatModel ThreatModel a
m [(Tx Era, MockChainState Era)]
txs =
ThreatModel a -> [ThreatModelEnv] -> Property
forall a. ThreatModel a -> [ThreatModelEnv] -> Property
runThreatModel ThreatModel a
m [Tx Era -> MockChainState Era -> ThreatModelEnv
mkThreatModelEnv Tx Era
tx MockChainState Era
chainState | (Tx Era
tx, MockChainState Era
chainState) <- [(Tx Era, MockChainState Era)]
txs]
runThreatModelM
:: (MonadMockchain Era m, MonadIO m)
=> SigningWallet
-> ThreatModel a
-> [ThreatModelEnv]
-> m Property
runThreatModelM :: forall (m :: * -> *) a.
(MonadMockchain Era m, MonadIO m) =>
SigningWallet -> ThreatModel a -> [ThreatModelEnv] -> m Property
runThreatModelM = Bool
-> SigningWallet -> ThreatModel a -> [ThreatModelEnv] -> m Property
forall (m :: * -> *) a.
(MonadMockchain Era m, MonadIO m) =>
Bool
-> SigningWallet -> ThreatModel a -> [ThreatModelEnv] -> m Property
runThreatModelM' Bool
False
runThreatModelMQuiet
:: (MonadMockchain Era m, MonadIO m)
=> SigningWallet
-> ThreatModel a
-> [ThreatModelEnv]
-> m Property
runThreatModelMQuiet :: forall (m :: * -> *) a.
(MonadMockchain Era m, MonadIO m) =>
SigningWallet -> ThreatModel a -> [ThreatModelEnv] -> m Property
runThreatModelMQuiet = Bool
-> SigningWallet -> ThreatModel a -> [ThreatModelEnv] -> m Property
forall (m :: * -> *) a.
(MonadMockchain Era m, MonadIO m) =>
Bool
-> SigningWallet -> ThreatModel a -> [ThreatModelEnv] -> m Property
runThreatModelM' Bool
True
runThreatModelM'
:: (MonadMockchain Era m, MonadIO m)
=> Bool
-> SigningWallet
-> ThreatModel a
-> [ThreatModelEnv]
-> m Property
runThreatModelM' :: forall (m :: * -> *) a.
(MonadMockchain Era m, MonadIO m) =>
Bool
-> SigningWallet -> ThreatModel a -> [ThreatModelEnv] -> m Property
runThreatModelM' Bool
quiet SigningWallet
signingWallet = Bool -> ThreatModel a -> [ThreatModelEnv] -> m Property
go Bool
False
where
go :: Bool -> ThreatModel a -> [ThreatModelEnv] -> m Property
go Bool
b ThreatModel a
_model [] = Property -> m Property
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Property -> m Property) -> Property -> m Property
forall a b. (a -> b) -> a -> b
$ Bool
b Bool -> Property -> Property
forall prop. Testable prop => Bool -> prop -> Property
==> Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
go Bool
b ThreatModel a
model (ThreatModelEnv
env : [ThreatModelEnv]
envs) = do
let resolvedWallet :: Either String Wallet
resolvedWallet = case SigningWallet
signingWallet of
SignWith Wallet
w -> Wallet -> Either String Wallet
forall a b. b -> Either a b
Right Wallet
w
SigningWallet
AutoSign -> Tx Era -> Either String Wallet
TM.detectSigningWallet (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env)
case Either String Wallet
resolvedWallet of
Left String
err -> Property -> m Property
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Property -> m Property) -> Property -> m Property
forall a b. (a -> b) -> a -> b
$ String -> Bool -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
err Bool
False
Right Wallet
wallet -> (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
initialMon Wallet
wallet ThreatModel a
model
where
initialMon :: Property -> Property
initialMon = if Bool
quiet then Property -> Property
forall a. a -> a
id else String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample (Doc -> String
forall a. Show a => a -> String
show Doc
info)
info :: Doc
info =
[Doc] -> Doc
vcat
[ Doc
""
, Doc -> [Doc] -> Doc
block
Doc
"Original UTxO set"
[ UTxO Era -> Doc
prettyUTxO (UTxO Era -> Doc) -> UTxO Era -> Doc
forall a b. (a -> b) -> a -> b
$
Tx Era -> UTxO Era -> UTxO Era
restrictUTxO (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) (UTxO Era -> UTxO Era) -> UTxO Era -> UTxO Era
forall a b. (a -> b) -> a -> b
$
ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env
]
, Doc
""
, Doc -> [Doc] -> Doc
block Doc
"Original transaction" [Tx Era -> Doc
prettyTx (Tx Era -> Doc) -> Tx Era -> Doc
forall a b. (a -> b) -> a -> b
$ ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env]
, Doc
""
]
interpM :: (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet = \case
Validate TxModifier
mods ValidityReport -> ThreatModel a
k -> do
let (Tx Era
modifiedTx, UTxO Era
modifiedUtxo) = Tx Era -> UTxO Era -> TxModifier -> (Tx Era, UTxO Era)
applyTxModifier (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) (ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env) TxModifier
mods
NodeParams Era
params <- m (NodeParams Era)
forall era (m :: * -> *).
MonadMockchain era m =>
m (NodeParams era)
askNodeParams
Either String (Tx Era)
rebalanceResult <- MockChainState Era
-> Wallet
-> Tx Era
-> Tx Era
-> UTxO Era
-> m (Either String (Tx Era))
forall (m :: * -> *).
MonadMockchain Era m =>
MockChainState Era
-> Wallet
-> Tx Era
-> Tx Era
-> UTxO Era
-> m (Either String (Tx Era))
TM.rebalanceAndSign (ThreatModelEnv -> MockChainState Era
currentChainState ThreatModelEnv
env) Wallet
wallet (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) Tx Era
modifiedTx UTxO Era
modifiedUtxo
case Either String (Tx Era)
rebalanceResult of
Left String
err ->
String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
QC.tabulate String
"Rebalancing failed with reason" [String
err] (Property -> Property) -> m Property -> m Property
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> ThreatModel a -> [ThreatModelEnv] -> m Property
go Bool
b ThreatModel a
model [ThreatModelEnv]
envs
Right Tx Era
rebalancedTx -> do
(ValidityReport
report, CoverageData
covData) <- NodeParams Era
-> MockChainState Era
-> Tx Era
-> UTxO Era
-> m (ValidityReport, CoverageData)
forall (m :: * -> *).
MonadMockchain Era m =>
NodeParams Era
-> MockChainState Era
-> Tx Era
-> UTxO Era
-> m (ValidityReport, CoverageData)
validateTxM NodeParams Era
params (ThreatModelEnv -> MockChainState Era
currentChainState ThreatModelEnv
env) Tx Era
rebalancedTx UTxO Era
modifiedUtxo
(MockChainState Era -> ((), MockChainState Era)) -> m ()
forall a. (MockChainState Era -> (a, MockChainState Era)) -> m a
forall era (m :: * -> *) a.
MonadMockchain era m =>
(MockChainState era -> (a, MockChainState era)) -> m a
modifyMockChainState ((MockChainState Era -> ((), MockChainState Era)) -> m ())
-> (MockChainState Era -> ((), MockChainState Era)) -> m ()
forall a b. (a -> b) -> a -> b
$ \MockChainState Era
s -> ((), MockChainState Era
s MockChainState Era
-> (MockChainState Era -> MockChainState Era) -> MockChainState Era
forall a b. a -> (a -> b) -> b
& (CoverageData -> Identity CoverageData)
-> MockChainState Era -> Identity (MockChainState Era)
forall era (f :: * -> *).
Functor f =>
(CoverageData -> f CoverageData)
-> MockChainState era -> f (MockChainState era)
coverageData ((CoverageData -> Identity CoverageData)
-> MockChainState Era -> Identity (MockChainState Era))
-> (CoverageData -> CoverageData)
-> MockChainState Era
-> MockChainState Era
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (CoverageData -> CoverageData -> CoverageData
forall a. Semigroup a => a -> a -> a
<> CoverageData
covData))
(Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet (ValidityReport -> ThreatModel a
k ValidityReport
report)
Generate Gen a
gen a -> [a]
_shr a -> ThreatModel a
k -> do
a
a <- IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ Gen a -> IO a
forall a. Gen a -> IO a
QC.generate Gen a
gen
(Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet (a -> ThreatModel a
k a
a)
GetCtx ThreatModelEnv -> ThreatModel a
k ->
(Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet (ThreatModelEnv -> ThreatModel a
k ThreatModelEnv
env)
ThreatModel a
Skip -> Bool -> ThreatModel a -> [ThreatModelEnv] -> m Property
go Bool
b ThreatModel a
model [ThreatModelEnv]
envs
InPrecondition Bool -> ThreatModel a
k -> (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet (Bool -> ThreatModel a
k Bool
False)
Fail String
err -> Property -> m Property
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Property -> m Property) -> Property -> m Property
forall a b. (a -> b) -> a -> b
$ if Bool
quiet then Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False else Property -> Property
mon (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ String -> Bool -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
err Bool
False
Monitor Property -> Property
m ThreatModel a
k -> if Bool
quiet then (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet ThreatModel a
k else Property -> Property
m (Property -> Property) -> m Property -> m Property
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet ThreatModel a
k
MonitorLocal Property -> Property
m ThreatModel a
k -> if Bool
quiet then (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet ThreatModel a
k else (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM (Property -> Property
mon (Property -> Property)
-> (Property -> Property) -> Property -> Property
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Property -> Property
m) Wallet
wallet ThreatModel a
k
Done{} -> Bool -> ThreatModel a -> [ThreatModelEnv] -> m Property
go Bool
True ThreatModel a
model [ThreatModelEnv]
envs
Named String
_n ThreatModel a
k -> (Property -> Property) -> Wallet -> ThreatModel a -> m Property
interpM Property -> Property
mon Wallet
wallet ThreatModel a
k
getThreatModelName :: ThreatModel a -> Maybe String
getThreatModelName :: forall a. ThreatModel a -> Maybe String
getThreatModelName (Named String
n ThreatModel a
_) = String -> Maybe String
forall a. a -> Maybe a
Just String
n
getThreatModelName ThreatModel a
_ = Maybe String
forall a. Maybe a
Nothing
runThreatModelCheck
:: (MonadMockchain Era m, MonadFail m, MonadIO m)
=> SigningWallet
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
runThreatModelCheck :: forall (m :: * -> *) a.
(MonadMockchain Era m, MonadFail m, MonadIO m) =>
SigningWallet
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
runThreatModelCheck SigningWallet
signingWallet = Bool
-> Bool
-> Maybe String
-> [Property -> Property]
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
go Bool
False Bool
False Maybe String
forall a. Maybe a
Nothing []
where
composeMonitors :: [b -> b] -> b -> b
composeMonitors = ((b -> b) -> (b -> b) -> b -> b) -> (b -> b) -> [b -> b] -> b -> b
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) b -> b
forall a. a -> a
id
go :: Bool
-> Bool
-> Maybe String
-> [Property -> Property]
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
go Bool
b Bool
hadPhase1Error Maybe String
firstErr [Property -> Property]
mons ThreatModel a
_model [] = (ThreatModelOutcome, Property -> Property)
-> m (ThreatModelOutcome, Property -> Property)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Bool -> Maybe String -> ThreatModelOutcome
finalOutcome Bool
b Bool
hadPhase1Error Maybe String
firstErr, [Property -> Property] -> Property -> Property
forall {b}. [b -> b] -> b -> b
composeMonitors [Property -> Property]
mons)
go Bool
b Bool
hadPhase1Error Maybe String
firstErr [Property -> Property]
mons ThreatModel a
model (ThreatModelEnv
env : [ThreatModelEnv]
envs) = do
let resolvedWallet :: Either String Wallet
resolvedWallet = case SigningWallet
signingWallet of
SignWith Wallet
w -> Wallet -> Either String Wallet
forall a b. b -> Either a b
Right Wallet
w
SigningWallet
AutoSign -> Tx Era -> Either String Wallet
TM.detectSigningWallet (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env)
case Either String Wallet
resolvedWallet of
Left String
err -> Bool
-> Bool
-> Maybe String
-> [Property -> Property]
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
go Bool
b Bool
hadPhase1Error (Maybe String
firstErr Maybe String -> Maybe String -> Maybe String
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> Maybe String
forall a. a -> Maybe a
Just String
err) (String -> Property -> Property
walletMonitor String
err (Property -> Property)
-> [Property -> Property] -> [Property -> Property]
forall a. a -> [a] -> [a]
: [Property -> Property]
mons) ThreatModel a
model [ThreatModelEnv]
envs
Right Wallet
wallet -> Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet [Property -> Property]
mons ThreatModel a
model
where
checkInterp :: Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet [Property -> Property]
mons' = \case
Validate TxModifier
mods ValidityReport -> ThreatModel a
k -> do
let (Tx Era
modifiedTx, UTxO Era
modifiedUtxo) = Tx Era -> UTxO Era -> TxModifier -> (Tx Era, UTxO Era)
applyTxModifier (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) (ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env) TxModifier
mods
NodeParams Era
params <- m (NodeParams Era)
forall era (m :: * -> *).
MonadMockchain era m =>
m (NodeParams era)
askNodeParams
Either String (Tx Era)
rebalanceResult <- MockChainState Era
-> Wallet
-> Tx Era
-> Tx Era
-> UTxO Era
-> m (Either String (Tx Era))
forall (m :: * -> *).
MonadMockchain Era m =>
MockChainState Era
-> Wallet
-> Tx Era
-> Tx Era
-> UTxO Era
-> m (Either String (Tx Era))
TM.rebalanceAndSign (ThreatModelEnv -> MockChainState Era
currentChainState ThreatModelEnv
env) Wallet
wallet (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) Tx Era
modifiedTx UTxO Era
modifiedUtxo
case Either String (Tx Era)
rebalanceResult of
Left String
_err ->
Bool
-> Bool
-> Maybe String
-> [Property -> Property]
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
go Bool
b Bool
True Maybe String
firstErr [Property -> Property]
mons' ThreatModel a
model [ThreatModelEnv]
envs
Right Tx Era
rebalancedTx -> do
(ValidityReport
report, CoverageData
covData) <- NodeParams Era
-> MockChainState Era
-> Tx Era
-> UTxO Era
-> m (ValidityReport, CoverageData)
forall (m :: * -> *).
MonadMockchain Era m =>
NodeParams Era
-> MockChainState Era
-> Tx Era
-> UTxO Era
-> m (ValidityReport, CoverageData)
validateTxM NodeParams Era
params (ThreatModelEnv -> MockChainState Era
currentChainState ThreatModelEnv
env) Tx Era
rebalancedTx UTxO Era
modifiedUtxo
(MockChainState Era -> ((), MockChainState Era)) -> m ()
forall a. (MockChainState Era -> (a, MockChainState Era)) -> m a
forall era (m :: * -> *) a.
MonadMockchain era m =>
(MockChainState era -> (a, MockChainState era)) -> m a
modifyMockChainState ((MockChainState Era -> ((), MockChainState Era)) -> m ())
-> (MockChainState Era -> ((), MockChainState Era)) -> m ()
forall a b. (a -> b) -> a -> b
$ \MockChainState Era
s -> ((), MockChainState Era
s MockChainState Era
-> (MockChainState Era -> MockChainState Era) -> MockChainState Era
forall a b. a -> (a -> b) -> b
& (CoverageData -> Identity CoverageData)
-> MockChainState Era -> Identity (MockChainState Era)
forall era (f :: * -> *).
Functor f =>
(CoverageData -> f CoverageData)
-> MockChainState era -> f (MockChainState era)
coverageData ((CoverageData -> Identity CoverageData)
-> MockChainState Era -> Identity (MockChainState Era))
-> (CoverageData -> CoverageData)
-> MockChainState Era
-> MockChainState Era
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (CoverageData -> CoverageData -> CoverageData
forall a. Semigroup a => a -> a -> a
<> CoverageData
covData))
case ValidityReport -> TxValidity
validity ValidityReport
report of
TxValidity
Phase1Invalid -> Bool
-> Bool
-> Maybe String
-> [Property -> Property]
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
go Bool
b Bool
True Maybe String
firstErr [Property -> Property]
mons' ThreatModel a
model [ThreatModelEnv]
envs
TxValidity
_ -> Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet [Property -> Property]
mons' (ValidityReport -> ThreatModel a
k ValidityReport
report)
Generate Gen a
gen a -> [a]
_shr a -> ThreatModel a
k -> do
a
a <- IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ Gen a -> IO a
forall a. Gen a -> IO a
QC.generate Gen a
gen
Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet [Property -> Property]
mons' (a -> ThreatModel a
k a
a)
GetCtx ThreatModelEnv -> ThreatModel a
k ->
Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet [Property -> Property]
mons' (ThreatModelEnv -> ThreatModel a
k ThreatModelEnv
env)
ThreatModel a
Skip -> Bool
-> Bool
-> Maybe String
-> [Property -> Property]
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
go Bool
b Bool
hadPhase1Error Maybe String
firstErr [Property -> Property]
mons' ThreatModel a
model [ThreatModelEnv]
envs
InPrecondition Bool -> ThreatModel a
k -> Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet [Property -> Property]
mons' (Bool -> ThreatModel a
k Bool
False)
Fail String
err -> (ThreatModelOutcome, Property -> Property)
-> m (ThreatModelOutcome, Property -> Property)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> ThreatModelOutcome
TMFailed String
err, [Property -> Property] -> Property -> Property
forall {b}. [b -> b] -> b -> b
composeMonitors [Property -> Property]
mons')
Monitor Property -> Property
m ThreatModel a
k -> Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet (Property -> Property
m (Property -> Property)
-> [Property -> Property] -> [Property -> Property]
forall a. a -> [a] -> [a]
: [Property -> Property]
mons') ThreatModel a
k
MonitorLocal Property -> Property
m ThreatModel a
k -> Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet (Property -> Property
m (Property -> Property)
-> [Property -> Property] -> [Property -> Property]
forall a. a -> [a] -> [a]
: [Property -> Property]
mons') ThreatModel a
k
Done{} -> Bool
-> Bool
-> Maybe String
-> [Property -> Property]
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, Property -> Property)
go Bool
True Bool
hadPhase1Error Maybe String
firstErr [Property -> Property]
mons' ThreatModel a
model [ThreatModelEnv]
envs
Named String
_n ThreatModel a
k -> Wallet
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, Property -> Property)
checkInterp Wallet
wallet [Property -> Property]
mons' ThreatModel a
k
data ThreatModelCheckEntry = ThreatModelCheckEntry
{ ThreatModelCheckEntry -> Int
tmceEnvIndex :: !Int
, ThreatModelCheckEntry -> TxModifier
tmceModifications :: !TxModifier
, ThreatModelCheckEntry -> Tx Era
tmceOriginalTx :: !(Tx Era)
, ThreatModelCheckEntry -> UTxO Era
tmceOriginalUtxo :: !(UTxO Era)
, ThreatModelCheckEntry -> Maybe (Tx Era)
tmceModifiedTx :: !(Maybe (Tx Era))
, ThreatModelCheckEntry -> UTxO Era
tmceModifiedUtxo :: !(UTxO Era)
, ThreatModelCheckEntry -> Maybe ValidityReport
tmceValidation :: !(Maybe ValidityReport)
, ThreatModelCheckEntry -> Maybe String
tmceRebalanceError :: !(Maybe String)
}
runThreatModelCheckTraced
:: (MonadMockchain Era m, MonadFail m, MonadIO m)
=> SigningWallet
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry], Property -> Property)
runThreatModelCheckTraced :: forall (m :: * -> *) a.
(MonadMockchain Era m, MonadFail m, MonadIO m) =>
SigningWallet
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
runThreatModelCheckTraced SigningWallet
signingWallet = Bool
-> Bool
-> Maybe String
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> Int
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
go Bool
False Bool
False Maybe String
forall a. Maybe a
Nothing [] [] Int
0
where
composeMonitors :: [b -> b] -> b -> b
composeMonitors = ((b -> b) -> (b -> b) -> b -> b) -> (b -> b) -> [b -> b] -> b -> b
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) b -> b
forall a. a -> a
id
go :: Bool
-> Bool
-> Maybe String
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> Int
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
go Bool
b Bool
hadPhase1Error Maybe String
firstErr [ThreatModelCheckEntry]
acc [Property -> Property]
mons Int
_envIdx ThreatModel a
_model [] = (ThreatModelOutcome, [ThreatModelCheckEntry], Property -> Property)
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Bool -> Maybe String -> ThreatModelOutcome
finalOutcome Bool
b Bool
hadPhase1Error Maybe String
firstErr, [ThreatModelCheckEntry] -> [ThreatModelCheckEntry]
forall a. [a] -> [a]
reverse [ThreatModelCheckEntry]
acc, [Property -> Property] -> Property -> Property
forall {b}. [b -> b] -> b -> b
composeMonitors [Property -> Property]
mons)
go Bool
b Bool
hadPhase1Error Maybe String
firstErr [ThreatModelCheckEntry]
acc [Property -> Property]
mons Int
envIdx ThreatModel a
model (ThreatModelEnv
env : [ThreatModelEnv]
envs) = do
let resolvedWallet :: Either String Wallet
resolvedWallet = case SigningWallet
signingWallet of
SignWith Wallet
w -> Wallet -> Either String Wallet
forall a b. b -> Either a b
Right Wallet
w
SigningWallet
AutoSign -> Tx Era -> Either String Wallet
TM.detectSigningWallet (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env)
case Either String Wallet
resolvedWallet of
Left String
err -> Bool
-> Bool
-> Maybe String
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> Int
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
go Bool
b Bool
hadPhase1Error (Maybe String
firstErr Maybe String -> Maybe String -> Maybe String
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> Maybe String
forall a. a -> Maybe a
Just String
err) [ThreatModelCheckEntry]
acc (String -> Property -> Property
walletMonitor String
err (Property -> Property)
-> [Property -> Property] -> [Property -> Property]
forall a. a -> [a] -> [a]
: [Property -> Property]
mons) (Int
envIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ThreatModel a
model [ThreatModelEnv]
envs
Right Wallet
wallet -> Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc [Property -> Property]
mons ThreatModel a
model
where
checkInterp :: Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc' [Property -> Property]
mons' = \case
Validate TxModifier
mods ValidityReport -> ThreatModel a
k -> do
let (Tx Era
modifiedTx, UTxO Era
modifiedUtxo) = Tx Era -> UTxO Era -> TxModifier -> (Tx Era, UTxO Era)
applyTxModifier (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) (ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env) TxModifier
mods
NodeParams Era
params <- m (NodeParams Era)
forall era (m :: * -> *).
MonadMockchain era m =>
m (NodeParams era)
askNodeParams
Either String (Tx Era)
rebalanceResult <- MockChainState Era
-> Wallet
-> Tx Era
-> Tx Era
-> UTxO Era
-> m (Either String (Tx Era))
forall (m :: * -> *).
MonadMockchain Era m =>
MockChainState Era
-> Wallet
-> Tx Era
-> Tx Era
-> UTxO Era
-> m (Either String (Tx Era))
TM.rebalanceAndSign (ThreatModelEnv -> MockChainState Era
currentChainState ThreatModelEnv
env) Wallet
wallet (ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env) Tx Era
modifiedTx UTxO Era
modifiedUtxo
case Either String (Tx Era)
rebalanceResult of
Left String
err -> do
let entry :: ThreatModelCheckEntry
entry =
ThreatModelCheckEntry
{ tmceEnvIndex :: Int
tmceEnvIndex = Int
envIdx
, tmceModifications :: TxModifier
tmceModifications = TxModifier
mods
, tmceOriginalTx :: Tx Era
tmceOriginalTx = ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env
, tmceOriginalUtxo :: UTxO Era
tmceOriginalUtxo = ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env
, tmceModifiedTx :: Maybe (Tx Era)
tmceModifiedTx = Maybe (Tx Era)
forall a. Maybe a
Nothing
, tmceModifiedUtxo :: UTxO Era
tmceModifiedUtxo = UTxO Era
modifiedUtxo
, tmceValidation :: Maybe ValidityReport
tmceValidation = Maybe ValidityReport
forall a. Maybe a
Nothing
, tmceRebalanceError :: Maybe String
tmceRebalanceError = String -> Maybe String
forall a. a -> Maybe a
Just String
err
}
Bool
-> Bool
-> Maybe String
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> Int
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
go Bool
b Bool
True Maybe String
firstErr (ThreatModelCheckEntry
entry ThreatModelCheckEntry
-> [ThreatModelCheckEntry] -> [ThreatModelCheckEntry]
forall a. a -> [a] -> [a]
: [ThreatModelCheckEntry]
acc') [Property -> Property]
mons' (Int
envIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ThreatModel a
model [ThreatModelEnv]
envs
Right Tx Era
rebalancedTx -> do
(ValidityReport
report, CoverageData
covData) <- NodeParams Era
-> MockChainState Era
-> Tx Era
-> UTxO Era
-> m (ValidityReport, CoverageData)
forall (m :: * -> *).
MonadMockchain Era m =>
NodeParams Era
-> MockChainState Era
-> Tx Era
-> UTxO Era
-> m (ValidityReport, CoverageData)
validateTxM NodeParams Era
params (ThreatModelEnv -> MockChainState Era
currentChainState ThreatModelEnv
env) Tx Era
rebalancedTx UTxO Era
modifiedUtxo
(MockChainState Era -> ((), MockChainState Era)) -> m ()
forall a. (MockChainState Era -> (a, MockChainState Era)) -> m a
forall era (m :: * -> *) a.
MonadMockchain era m =>
(MockChainState era -> (a, MockChainState era)) -> m a
modifyMockChainState ((MockChainState Era -> ((), MockChainState Era)) -> m ())
-> (MockChainState Era -> ((), MockChainState Era)) -> m ()
forall a b. (a -> b) -> a -> b
$ \MockChainState Era
s -> ((), MockChainState Era
s MockChainState Era
-> (MockChainState Era -> MockChainState Era) -> MockChainState Era
forall a b. a -> (a -> b) -> b
& (CoverageData -> Identity CoverageData)
-> MockChainState Era -> Identity (MockChainState Era)
forall era (f :: * -> *).
Functor f =>
(CoverageData -> f CoverageData)
-> MockChainState era -> f (MockChainState era)
coverageData ((CoverageData -> Identity CoverageData)
-> MockChainState Era -> Identity (MockChainState Era))
-> (CoverageData -> CoverageData)
-> MockChainState Era
-> MockChainState Era
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (CoverageData -> CoverageData -> CoverageData
forall a. Semigroup a => a -> a -> a
<> CoverageData
covData))
let entry :: ThreatModelCheckEntry
entry =
ThreatModelCheckEntry
{ tmceEnvIndex :: Int
tmceEnvIndex = Int
envIdx
, tmceModifications :: TxModifier
tmceModifications = TxModifier
mods
, tmceOriginalTx :: Tx Era
tmceOriginalTx = ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env
, tmceOriginalUtxo :: UTxO Era
tmceOriginalUtxo = ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env
, tmceModifiedTx :: Maybe (Tx Era)
tmceModifiedTx = Tx Era -> Maybe (Tx Era)
forall a. a -> Maybe a
Just Tx Era
rebalancedTx
, tmceModifiedUtxo :: UTxO Era
tmceModifiedUtxo = UTxO Era
modifiedUtxo
, tmceValidation :: Maybe ValidityReport
tmceValidation = ValidityReport -> Maybe ValidityReport
forall a. a -> Maybe a
Just ValidityReport
report
, tmceRebalanceError :: Maybe String
tmceRebalanceError = Maybe String
forall a. Maybe a
Nothing
}
case ValidityReport -> TxValidity
validity ValidityReport
report of
TxValidity
Phase1Invalid -> Bool
-> Bool
-> Maybe String
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> Int
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
go Bool
b Bool
True Maybe String
firstErr (ThreatModelCheckEntry
entry ThreatModelCheckEntry
-> [ThreatModelCheckEntry] -> [ThreatModelCheckEntry]
forall a. a -> [a] -> [a]
: [ThreatModelCheckEntry]
acc') [Property -> Property]
mons' (Int
envIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ThreatModel a
model [ThreatModelEnv]
envs
TxValidity
_ -> Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet (ThreatModelCheckEntry
entry ThreatModelCheckEntry
-> [ThreatModelCheckEntry] -> [ThreatModelCheckEntry]
forall a. a -> [a] -> [a]
: [ThreatModelCheckEntry]
acc') [Property -> Property]
mons' (ValidityReport -> ThreatModel a
k ValidityReport
report)
Generate Gen a
gen a -> [a]
_shr a -> ThreatModel a
k -> do
a
a <- IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ Gen a -> IO a
forall a. Gen a -> IO a
QC.generate Gen a
gen
Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc' [Property -> Property]
mons' (a -> ThreatModel a
k a
a)
GetCtx ThreatModelEnv -> ThreatModel a
k ->
Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc' [Property -> Property]
mons' (ThreatModelEnv -> ThreatModel a
k ThreatModelEnv
env)
ThreatModel a
Skip -> Bool
-> Bool
-> Maybe String
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> Int
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
go Bool
b Bool
hadPhase1Error Maybe String
firstErr [ThreatModelCheckEntry]
acc' [Property -> Property]
mons' (Int
envIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ThreatModel a
model [ThreatModelEnv]
envs
InPrecondition Bool -> ThreatModel a
k -> Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc' [Property -> Property]
mons' (Bool -> ThreatModel a
k Bool
False)
Fail String
err -> (ThreatModelOutcome, [ThreatModelCheckEntry], Property -> Property)
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> ThreatModelOutcome
TMFailed String
err, [ThreatModelCheckEntry] -> [ThreatModelCheckEntry]
forall a. [a] -> [a]
reverse [ThreatModelCheckEntry]
acc', [Property -> Property] -> Property -> Property
forall {b}. [b -> b] -> b -> b
composeMonitors [Property -> Property]
mons')
Monitor Property -> Property
m ThreatModel a
k -> Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc' (Property -> Property
m (Property -> Property)
-> [Property -> Property] -> [Property -> Property]
forall a. a -> [a] -> [a]
: [Property -> Property]
mons') ThreatModel a
k
MonitorLocal Property -> Property
m ThreatModel a
k -> Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc' (Property -> Property
m (Property -> Property)
-> [Property -> Property] -> [Property -> Property]
forall a. a -> [a] -> [a]
: [Property -> Property]
mons') ThreatModel a
k
Done{} -> Bool
-> Bool
-> Maybe String
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> Int
-> ThreatModel a
-> [ThreatModelEnv]
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
go Bool
True Bool
hadPhase1Error Maybe String
firstErr [ThreatModelCheckEntry]
acc' [Property -> Property]
mons' (Int
envIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ThreatModel a
model [ThreatModelEnv]
envs
Named String
_n ThreatModel a
k -> Wallet
-> [ThreatModelCheckEntry]
-> [Property -> Property]
-> ThreatModel a
-> m (ThreatModelOutcome, [ThreatModelCheckEntry],
Property -> Property)
checkInterp Wallet
wallet [ThreatModelCheckEntry]
acc' [Property -> Property]
mons' ThreatModel a
k
finalOutcome :: Bool -> Bool -> Maybe String -> ThreatModelOutcome
finalOutcome :: Bool -> Bool -> Maybe String -> ThreatModelOutcome
finalOutcome Bool
b Bool
hadPhase1Error Maybe String
firstErr
| Bool
b = ThreatModelOutcome
TMPassed
| Bool
hadPhase1Error = ThreatModelOutcome
TMSkippedPhase1
| Just String
err <- Maybe String
firstErr = String -> ThreatModelOutcome
TMError String
err
| Bool
otherwise = ThreatModelOutcome
TMSkipped
walletMonitor :: String -> (Property -> Property)
walletMonitor :: String -> Property -> Property
walletMonitor String
err = String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
QC.tabulate String
"Threat model could not detect a signing wallet" [String
err]
threatPrecondition :: ThreatModel a -> ThreatModel a
threatPrecondition :: forall a. ThreatModel a -> ThreatModel a
threatPrecondition = \case
ThreatModel a
Skip -> ThreatModel a
forall a. ThreatModel a
Skip
InPrecondition Bool -> ThreatModel a
k -> Bool -> ThreatModel a
k Bool
True
Fail String
reason -> (Property -> Property) -> ThreatModel a -> ThreatModel a
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
Monitor (String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulate String
"Precondition failed with reason" [String
reason]) ThreatModel a
forall a. ThreatModel a
Skip
Validate TxModifier
tx ValidityReport -> ThreatModel a
k -> TxModifier -> (ValidityReport -> ThreatModel a) -> ThreatModel a
forall a.
TxModifier -> (ValidityReport -> ThreatModel a) -> ThreatModel a
Validate TxModifier
tx (ThreatModel a -> ThreatModel a
forall a. ThreatModel a -> ThreatModel a
threatPrecondition (ThreatModel a -> ThreatModel a)
-> (ValidityReport -> ThreatModel a)
-> ValidityReport
-> ThreatModel a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ValidityReport -> ThreatModel a
k)
Generate Gen a
g a -> [a]
s a -> ThreatModel a
k -> Gen a -> (a -> [a]) -> (a -> ThreatModel a) -> ThreatModel a
forall a b.
Show a =>
Gen a -> (a -> [a]) -> (a -> ThreatModel b) -> ThreatModel b
Generate Gen a
g a -> [a]
s (ThreatModel a -> ThreatModel a
forall a. ThreatModel a -> ThreatModel a
threatPrecondition (ThreatModel a -> ThreatModel a)
-> (a -> ThreatModel a) -> a -> ThreatModel a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ThreatModel a
k)
GetCtx ThreatModelEnv -> ThreatModel a
k -> (ThreatModelEnv -> ThreatModel a) -> ThreatModel a
forall a. (ThreatModelEnv -> ThreatModel a) -> ThreatModel a
GetCtx (ThreatModel a -> ThreatModel a
forall a. ThreatModel a -> ThreatModel a
threatPrecondition (ThreatModel a -> ThreatModel a)
-> (ThreatModelEnv -> ThreatModel a)
-> ThreatModelEnv
-> ThreatModel a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ThreatModelEnv -> ThreatModel a
k)
Monitor Property -> Property
m ThreatModel a
k -> (Property -> Property) -> ThreatModel a -> ThreatModel a
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
Monitor Property -> Property
m (ThreatModel a -> ThreatModel a
forall a. ThreatModel a -> ThreatModel a
threatPrecondition ThreatModel a
k)
MonitorLocal Property -> Property
m ThreatModel a
k -> (Property -> Property) -> ThreatModel a -> ThreatModel a
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
MonitorLocal Property -> Property
m (ThreatModel a -> ThreatModel a
forall a. ThreatModel a -> ThreatModel a
threatPrecondition ThreatModel a
k)
Done a
a -> a -> ThreatModel a
forall a. a -> ThreatModel a
Done a
a
Named String
n ThreatModel a
k -> String -> ThreatModel a -> ThreatModel a
forall a. String -> ThreatModel a -> ThreatModel a
Named String
n (ThreatModel a -> ThreatModel a
forall a. ThreatModel a -> ThreatModel a
threatPrecondition ThreatModel a
k)
failPrecondition :: String -> ThreatModel a
failPrecondition :: forall a. String -> ThreatModel a
failPrecondition String
reason = (Property -> Property) -> ThreatModel a -> ThreatModel a
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
Monitor (String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulate String
"Precondition failed with reason" [String
reason]) ThreatModel a
forall a. ThreatModel a
Skip
ensure :: Bool -> ThreatModel ()
ensure :: Bool -> ThreatModel ()
ensure Bool
False = ThreatModel ()
forall a. ThreatModel a
Skip
ensure Bool
True = () -> ThreatModel ()
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
ensureHasInputAt :: AddressAny -> ThreatModel ()
ensureHasInputAt :: AddressAny -> ThreatModel ()
ensureHasInputAt AddressAny
addr = do
[Input]
inputs <- ThreatModel [Input]
getTxInputs
Bool -> ThreatModel ()
ensure (Bool -> ThreatModel ()) -> Bool -> ThreatModel ()
forall a b. (a -> b) -> a -> b
$ (Input -> Bool) -> [Input] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((AddressAny
addr AddressAny -> AddressAny -> Bool
forall a. Eq a => a -> a -> Bool
==) (AddressAny -> Bool) -> (Input -> AddressAny) -> Input -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Input -> AddressAny
forall t. IsInputOrOutput t => t -> AddressAny
addressOf) [Input]
inputs
requireScriptExecution :: ThreatModel ()
requireScriptExecution :: ThreatModel ()
requireScriptExecution = ThreatModel (Tx Era)
originalTx ThreatModel (Tx Era)
-> (Tx Era -> ThreatModel ()) -> ThreatModel ()
forall a b. ThreatModel a -> (a -> ThreatModel b) -> ThreatModel b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Bool -> ThreatModel ()
ensure (Bool -> ThreatModel ())
-> (Tx Era -> Bool) -> Tx Era -> ThreatModel ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tx Era -> Bool
txRunsPlutusScript
inPrecondition :: ThreatModel Bool
inPrecondition :: ThreatModel Bool
inPrecondition = (Bool -> ThreatModel Bool) -> ThreatModel Bool
forall a. (Bool -> ThreatModel a) -> ThreatModel a
InPrecondition Bool -> ThreatModel Bool
forall a. a -> ThreatModel a
Done
validate :: TxModifier -> ThreatModel ValidityReport
validate :: TxModifier -> ThreatModel ValidityReport
validate TxModifier
tx = TxModifier
-> (ValidityReport -> ThreatModel ValidityReport)
-> ThreatModel ValidityReport
forall a.
TxModifier -> (ValidityReport -> ThreatModel a) -> ThreatModel a
Validate TxModifier
tx ValidityReport -> ThreatModel ValidityReport
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
shouldValidate :: TxModifier -> ThreatModel ()
shouldValidate :: TxModifier -> ThreatModel ()
shouldValidate = Bool -> TxModifier -> ThreatModel ()
shouldValidateOrNot Bool
True
shouldNotValidate :: TxModifier -> ThreatModel ()
shouldNotValidate :: TxModifier -> ThreatModel ()
shouldNotValidate = Bool -> TxModifier -> ThreatModel ()
shouldValidateOrNot Bool
False
shouldValidateOrNot :: Bool -> TxModifier -> ThreatModel ()
shouldValidateOrNot :: Bool -> TxModifier -> ThreatModel ()
shouldValidateOrNot Bool
should TxModifier
txMod = do
ValidityReport
validReport <- TxModifier -> ThreatModel ValidityReport
validate TxModifier
txMod
ThreatModelEnv
env <- ThreatModel ThreatModelEnv
getThreatModelEnv
let tx :: Tx Era
tx = ThreatModelEnv -> Tx Era
currentTx ThreatModelEnv
env
newTx :: Tx Era
newTx = (Tx Era, UTxO Era) -> Tx Era
forall a b. (a, b) -> a
fst ((Tx Era, UTxO Era) -> Tx Era) -> (Tx Era, UTxO Era) -> Tx Era
forall a b. (a -> b) -> a -> b
$ Tx Era -> UTxO Era -> TxModifier -> (Tx Era, UTxO Era)
applyTxModifier Tx Era
tx (ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env) TxModifier
txMod
info :: String -> Doc
info String
str =
Doc -> [Doc] -> Doc
block
(String -> Doc
text String
str)
[ Doc -> [Doc] -> Doc
block
Doc
"Modifications to original transaction"
[TxModifier -> Doc
prettyTxModifier TxModifier
txMod]
, Doc -> [Doc] -> Doc
block
Doc
"Resulting transaction"
[Tx Era -> Doc
prettyTx Tx Era
newTx]
, String -> Doc
text String
""
]
n't :: String
n't
| Bool
should = String
"n't"
| Bool
otherwise = String
"" :: String
notN't :: String
notN't
| Bool
should = String
"" :: String
| Bool
otherwise = String
"n't"
case (ValidityReport -> TxValidity
validity ValidityReport
validReport, Bool
should) of
(TxValidity
Valid, Bool
True) -> () -> ThreatModel ()
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
(TxValidity
Phase2Invalid, Bool
False) -> () -> ThreatModel ()
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
(TxValidity
Phase1Invalid, Bool
_) -> ThreatModel ()
forall a. ThreatModel a
Skip
(TxValidity, Bool)
_ -> do
let distinctErrors :: [String]
distinctErrors = [String] -> [String]
forall a. Ord a => [a] -> [a]
nubOrd (ValidityReport -> [String]
errors ValidityReport
validReport)
failureLine :: String
failureLine = String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Test failure: the following transaction did%s validate" String
n't
messageLines :: [String]
messageLines =
String
failureLine
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [ String
" Validation errors:\n " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
" - " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) [String]
distinctErrors)
| Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
distinctErrors)
]
String -> ThreatModel ()
forall a. String -> ThreatModel a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> ThreatModel ()) -> String -> ThreatModel ()
forall a b. (a -> b) -> a -> b
$ Doc -> String
forall a. Show a => a -> String
show (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$ String -> Doc
info (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" [String]
messageLines
Bool
pre <- ThreatModel Bool
inPrecondition
Bool -> ThreatModel () -> ThreatModel ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
pre (ThreatModel () -> ThreatModel ())
-> ThreatModel () -> ThreatModel ()
forall a b. (a -> b) -> a -> b
$
String -> ThreatModel ()
counterexampleTM (String -> ThreatModel ()) -> String -> ThreatModel ()
forall a b. (a -> b) -> a -> b
$
Doc -> String
forall a. Show a => a -> String
show (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$
String -> Doc
info (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$
String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Satisfied precondition: the following transaction did%s validate" String
notN't
getThreatModelEnv :: ThreatModel ThreatModelEnv
getThreatModelEnv :: ThreatModel ThreatModelEnv
getThreatModelEnv = (ThreatModelEnv -> ThreatModel ThreatModelEnv)
-> ThreatModel ThreatModelEnv
forall a. (ThreatModelEnv -> ThreatModel a) -> ThreatModel a
GetCtx ThreatModelEnv -> ThreatModel ThreatModelEnv
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
originalTx :: ThreatModel (Tx Era)
originalTx :: ThreatModel (Tx Era)
originalTx = ThreatModelEnv -> Tx Era
currentTx (ThreatModelEnv -> Tx Era)
-> ThreatModel ThreatModelEnv -> ThreatModel (Tx Era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreatModel ThreatModelEnv
getThreatModelEnv
getTxOutputs :: ThreatModel [Output]
getTxOutputs :: ThreatModel [Output]
getTxOutputs =
(Word -> TxOut CtxTx Era -> Output)
-> [Word] -> [TxOut CtxTx Era] -> [Output]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((TxOut CtxTx Era -> TxIx -> Output)
-> TxIx -> TxOut CtxTx Era -> Output
forall a b c. (a -> b -> c) -> b -> a -> c
flip TxOut CtxTx Era -> TxIx -> Output
Output (TxIx -> TxOut CtxTx Era -> Output)
-> (Word -> TxIx) -> Word -> TxOut CtxTx Era -> Output
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> TxIx
TxIx) [Word
0 ..] ([TxOut CtxTx Era] -> [Output])
-> (ThreatModelEnv -> [TxOut CtxTx Era])
-> ThreatModelEnv
-> [Output]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxBodyContent ViewTx Era -> [TxOut CtxTx Era]
bodyContentOutputs (TxBodyContent ViewTx Era -> [TxOut CtxTx Era])
-> (ThreatModelEnv -> TxBodyContent ViewTx Era)
-> ThreatModelEnv
-> [TxOut CtxTx Era]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ThreatModelEnv -> TxBodyContent ViewTx Era
currentTxBodyContent
(ThreatModelEnv -> [Output])
-> ThreatModel ThreatModelEnv -> ThreatModel [Output]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreatModel ThreatModelEnv
getThreatModelEnv
guardedScriptOutputs :: ThreatModel [Output]
guardedScriptOutputs :: ThreatModel [Output]
guardedScriptOutputs = do
Set ScriptHash
running <- ThreatModelEnv -> Set ScriptHash
runningPlutusScripts (ThreatModelEnv -> Set ScriptHash)
-> ThreatModel ThreatModelEnv -> ThreatModel (Set ScriptHash)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreatModel ThreatModelEnv
getThreatModelEnv
let guarded :: Output -> Bool
guarded Output
o = Bool -> (ScriptHash -> Bool) -> Maybe ScriptHash -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (ScriptHash -> Set ScriptHash -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set ScriptHash
running) (AddressAny -> Maybe ScriptHash
scriptHashOfAddressAny (Output -> AddressAny
forall t. IsInputOrOutput t => t -> AddressAny
addressOf Output
o))
(Output -> Bool) -> [Output] -> [Output]
forall a. (a -> Bool) -> [a] -> [a]
filter Output -> Bool
guarded ([Output] -> [Output])
-> ThreatModel [Output] -> ThreatModel [Output]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreatModel [Output]
getTxOutputs
anyGuardedOutputSuchThat :: (Output -> Bool) -> ThreatModel Output
anyGuardedOutputSuchThat :: (Output -> Bool) -> ThreatModel Output
anyGuardedOutputSuchThat Output -> Bool
p = do
[Output]
outputs <- (Output -> Bool) -> [Output] -> [Output]
forall a. (a -> Bool) -> [a] -> [a]
filter Output -> Bool
p ([Output] -> [Output])
-> ThreatModel [Output] -> ThreatModel [Output]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreatModel [Output]
guardedScriptOutputs
ThreatModel () -> ThreatModel ()
forall a. ThreatModel a -> ThreatModel a
threatPrecondition (ThreatModel () -> ThreatModel ())
-> ThreatModel () -> ThreatModel ()
forall a b. (a -> b) -> a -> b
$ Bool -> ThreatModel ()
ensure (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Output] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Output]
outputs)
[Output] -> ThreatModel Output
forall a. Show a => [a] -> ThreatModel a
pickAny [Output]
outputs
anyGuardedOutput :: ThreatModel Output
anyGuardedOutput :: ThreatModel Output
anyGuardedOutput = (Output -> Bool) -> ThreatModel Output
anyGuardedOutputSuchThat (Bool -> Output -> Bool
forall a b. a -> b -> a
const Bool
True)
anyGuardedOutputWithInlineDatum :: ThreatModel (Output, ScriptData)
anyGuardedOutputWithInlineDatum :: ThreatModel (Output, ScriptData)
anyGuardedOutputWithInlineDatum = do
Output
target <- (Output -> Bool) -> ThreatModel Output
anyGuardedOutputSuchThat Output -> Bool
hasInlineDatum
case Output -> Maybe ScriptData
getInlineDatum Output
target of
Just ScriptData
datum -> (Output, ScriptData) -> ThreatModel (Output, ScriptData)
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Output
target, ScriptData
datum)
Maybe ScriptData
Nothing -> String -> ThreatModel (Output, ScriptData)
forall a. String -> ThreatModel a
failPrecondition String
"Script output missing inline datum"
hasInlineDatum :: Output -> Bool
hasInlineDatum :: Output -> Bool
hasInlineDatum Output
output =
case TxOut CtxTx Era -> TxOutDatum CtxTx Era
forall ctx. TxOut ctx Era -> TxOutDatum ctx Era
datumOfTxOut (Output -> TxOut CtxTx Era
outputTxOut Output
output) of
TxOutDatumInline{} -> Bool
True
TxOutDatum CtxTx Era
_ -> Bool
False
getInlineDatum :: Output -> Maybe ScriptData
getInlineDatum :: Output -> Maybe ScriptData
getInlineDatum Output
output =
case TxOut CtxTx Era -> TxOutDatum CtxTx Era
forall ctx. TxOut ctx Era -> TxOutDatum ctx Era
datumOfTxOut (Output -> TxOut CtxTx Era
outputTxOut Output
output) of
TxOutDatumInline BabbageEraOnwards Era
_ HashableScriptData
hashableData -> ScriptData -> Maybe ScriptData
forall a. a -> Maybe a
Just (HashableScriptData -> ScriptData
getScriptData HashableScriptData
hashableData)
TxOutDatum CtxTx Era
_ -> Maybe ScriptData
forall a. Maybe a
Nothing
toInlineDatum :: ScriptData -> Datum
toInlineDatum :: ScriptData -> TxOutDatum CtxTx Era
toInlineDatum ScriptData
sd =
BabbageEraOnwards Era -> HashableScriptData -> TxOutDatum CtxTx Era
forall era ctx.
BabbageEraOnwards era -> HashableScriptData -> TxOutDatum ctx era
TxOutDatumInline BabbageEraOnwards Era
BabbageEraOnwardsConway (ScriptData -> HashableScriptData
unsafeHashableScriptData ScriptData
sd)
getTxInputs :: ThreatModel [Input]
getTxInputs :: ThreatModel [Input]
getTxInputs = do
ThreatModelEnv
env <- ThreatModel ThreatModelEnv
getThreatModelEnv
let UTxO Map TxIn (TxOut CtxUTxO Era)
utxos = ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env
[Input] -> ThreatModel [Input]
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
[ TxOut CtxUTxO Era -> TxIn -> Input
Input TxOut CtxUTxO Era
txout TxIn
i
| TxIn
i <- TxBodyContent ViewTx Era -> [TxIn]
bodyContentInputs (ThreatModelEnv -> TxBodyContent ViewTx Era
currentTxBodyContent ThreatModelEnv
env)
, Just TxOut CtxUTxO Era
txout <- [TxIn -> Map TxIn (TxOut CtxUTxO Era) -> Maybe (TxOut CtxUTxO Era)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup TxIn
i Map TxIn (TxOut CtxUTxO Era)
utxos]
]
getTxReferenceInputs :: ThreatModel [Input]
getTxReferenceInputs :: ThreatModel [Input]
getTxReferenceInputs = do
ThreatModelEnv
env <- ThreatModel ThreatModelEnv
getThreatModelEnv
let UTxO Map TxIn (TxOut CtxUTxO Era)
utxos = ThreatModelEnv -> UTxO Era
currentUTxOs ThreatModelEnv
env
[Input] -> ThreatModel [Input]
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
[ TxOut CtxUTxO Era -> TxIn -> Input
Input TxOut CtxUTxO Era
txout TxIn
i
| TxIn
i <- TxBodyContent ViewTx Era -> [TxIn]
bodyContentReferenceInputs (ThreatModelEnv -> TxBodyContent ViewTx Era
currentTxBodyContent ThreatModelEnv
env)
, Just TxOut CtxUTxO Era
txout <- [TxIn -> Map TxIn (TxOut CtxUTxO Era) -> Maybe (TxOut CtxUTxO Era)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup TxIn
i Map TxIn (TxOut CtxUTxO Era)
utxos]
]
getRedeemer :: Input -> ThreatModel (Maybe Redeemer)
getRedeemer :: Input -> ThreatModel (Maybe ScriptData)
getRedeemer (Input TxOut CtxUTxO Era
_ TxIn
txIn) = do
Tx Era
tx <- ThreatModel (Tx Era)
originalTx
Maybe ScriptData -> ThreatModel (Maybe ScriptData)
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe ScriptData -> ThreatModel (Maybe ScriptData))
-> Maybe ScriptData -> ThreatModel (Maybe ScriptData)
forall a b. (a -> b) -> a -> b
$ Tx Era -> TxIn -> Maybe ScriptData
redeemerOfTxIn Tx Era
tx TxIn
txIn
getTxRequiredSigners :: ThreatModel [Hash PaymentKey]
getTxRequiredSigners :: ThreatModel [Hash PaymentKey]
getTxRequiredSigners = Tx Era -> [Hash PaymentKey]
TM.txRequiredSigners (Tx Era -> [Hash PaymentKey])
-> ThreatModel (Tx Era) -> ThreatModel [Hash PaymentKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreatModel (Tx Era)
originalTx
forAllTM :: (Show a) => Gen a -> (a -> [a]) -> ThreatModel a
forAllTM :: forall a. Show a => Gen a -> (a -> [a]) -> ThreatModel a
forAllTM Gen a
g a -> [a]
s = Gen a -> (a -> [a]) -> (a -> ThreatModel a) -> ThreatModel a
forall a b.
Show a =>
Gen a -> (a -> [a]) -> (a -> ThreatModel b) -> ThreatModel b
Generate Gen a
g a -> [a]
s a -> ThreatModel a
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
shrinkPositive :: Int -> [Int]
shrinkPositive :: Int -> [Int]
shrinkPositive = (Int -> Bool) -> [Int] -> [Int]
forall a. (a -> Bool) -> [a] -> [a]
filter (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
1) ([Int] -> [Int]) -> (Int -> [Int]) -> Int -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int]
forall a. Integral a => a -> [a]
shrinkIntegral
anyInput :: ThreatModel Input
anyInput :: ThreatModel Input
anyInput = (Input -> Bool) -> ThreatModel Input
anyInputSuchThat (Bool -> Input -> Bool
forall a b. a -> b -> a
const Bool
True)
anyReferenceInput :: ThreatModel Input
anyReferenceInput :: ThreatModel Input
anyReferenceInput = (Input -> Bool) -> ThreatModel Input
anyReferenceInputSuchThat (Bool -> Input -> Bool
forall a b. a -> b -> a
const Bool
True)
anyOutput :: ThreatModel Output
anyOutput :: ThreatModel Output
anyOutput = (Output -> Bool) -> ThreatModel Output
anyOutputSuchThat (Bool -> Output -> Bool
forall a b. a -> b -> a
const Bool
True)
anyInputSuchThat :: (Input -> Bool) -> ThreatModel Input
anyInputSuchThat :: (Input -> Bool) -> ThreatModel Input
anyInputSuchThat Input -> Bool
p = [Input] -> ThreatModel Input
forall a. Show a => [a] -> ThreatModel a
pickAny ([Input] -> ThreatModel Input)
-> ([Input] -> [Input]) -> [Input] -> ThreatModel Input
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Input -> Bool) -> [Input] -> [Input]
forall a. (a -> Bool) -> [a] -> [a]
filter Input -> Bool
p ([Input] -> ThreatModel Input)
-> ThreatModel [Input] -> ThreatModel Input
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ThreatModel [Input]
getTxInputs
anyReferenceInputSuchThat :: (Input -> Bool) -> ThreatModel Input
anyReferenceInputSuchThat :: (Input -> Bool) -> ThreatModel Input
anyReferenceInputSuchThat Input -> Bool
p = [Input] -> ThreatModel Input
forall a. Show a => [a] -> ThreatModel a
pickAny ([Input] -> ThreatModel Input)
-> ([Input] -> [Input]) -> [Input] -> ThreatModel Input
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Input -> Bool) -> [Input] -> [Input]
forall a. (a -> Bool) -> [a] -> [a]
filter Input -> Bool
p ([Input] -> ThreatModel Input)
-> ThreatModel [Input] -> ThreatModel Input
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ThreatModel [Input]
getTxReferenceInputs
anyOutputSuchThat :: (Output -> Bool) -> ThreatModel Output
anyOutputSuchThat :: (Output -> Bool) -> ThreatModel Output
anyOutputSuchThat Output -> Bool
p = [Output] -> ThreatModel Output
forall a. Show a => [a] -> ThreatModel a
pickAny ([Output] -> ThreatModel Output)
-> ([Output] -> [Output]) -> [Output] -> ThreatModel Output
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Output -> Bool) -> [Output] -> [Output]
forall a. (a -> Bool) -> [a] -> [a]
filter Output -> Bool
p ([Output] -> ThreatModel Output)
-> ThreatModel [Output] -> ThreatModel Output
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ThreatModel [Output]
getTxOutputs
pickAny :: (Show a) => [a] -> ThreatModel a
pickAny :: forall a. Show a => [a] -> ThreatModel a
pickAny [a]
xs = do
Bool -> ThreatModel ()
ensure (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
xs)
let xs' :: [(a, Int)]
xs' = [a] -> [Int] -> [(a, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs [Int
0 ..]
(a, Int) -> a
forall a b. (a, b) -> a
fst ((a, Int) -> a) -> ThreatModel (a, Int) -> ThreatModel a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (a, Int) -> ((a, Int) -> [(a, Int)]) -> ThreatModel (a, Int)
forall a. Show a => Gen a -> (a -> [a]) -> ThreatModel a
forAllTM ([(a, Int)] -> Gen (a, Int)
forall a. HasCallStack => [a] -> Gen a
elements [(a, Int)]
xs') (\(a
_, Int
i) -> Int -> [(a, Int)] -> [(a, Int)]
forall a. Int -> [a] -> [a]
take Int
i [(a, Int)]
xs')
anySigner :: ThreatModel (Hash PaymentKey)
anySigner :: ThreatModel (Hash PaymentKey)
anySigner = [Hash PaymentKey] -> ThreatModel (Hash PaymentKey)
forall a. Show a => [a] -> ThreatModel a
pickAny ([Hash PaymentKey] -> ThreatModel (Hash PaymentKey))
-> (Tx Era -> [Hash PaymentKey])
-> Tx Era
-> ThreatModel (Hash PaymentKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tx Era -> [Hash PaymentKey]
txSigners (Tx Era -> ThreatModel (Hash PaymentKey))
-> ThreatModel (Tx Era) -> ThreatModel (Hash PaymentKey)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ThreatModel (Tx Era)
originalTx
monitorThreatModel :: (Property -> Property) -> ThreatModel ()
monitorThreatModel :: (Property -> Property) -> ThreatModel ()
monitorThreatModel Property -> Property
m = (Property -> Property) -> ThreatModel () -> ThreatModel ()
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
Monitor Property -> Property
m (() -> ThreatModel ()
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
monitorLocalThreatModel :: (Property -> Property) -> ThreatModel ()
monitorLocalThreatModel :: (Property -> Property) -> ThreatModel ()
monitorLocalThreatModel Property -> Property
m = (Property -> Property) -> ThreatModel () -> ThreatModel ()
forall a. (Property -> Property) -> ThreatModel a -> ThreatModel a
MonitorLocal Property -> Property
m (() -> ThreatModel ()
forall a. a -> ThreatModel a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
counterexampleTM :: String -> ThreatModel ()
counterexampleTM :: String -> ThreatModel ()
counterexampleTM = (Property -> Property) -> ThreatModel ()
monitorLocalThreatModel ((Property -> Property) -> ThreatModel ())
-> (String -> Property -> Property) -> String -> ThreatModel ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
tabulateTM :: String -> [String] -> ThreatModel ()
tabulateTM :: String -> [String] -> ThreatModel ()
tabulateTM = ((Property -> Property) -> ThreatModel ()
monitorThreatModel ((Property -> Property) -> ThreatModel ())
-> ([String] -> Property -> Property) -> [String] -> ThreatModel ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) (([String] -> Property -> Property) -> [String] -> ThreatModel ())
-> (String -> [String] -> Property -> Property)
-> String
-> [String]
-> ThreatModel ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulate
collectTM :: (Show a) => a -> ThreatModel ()
collectTM :: forall a. Show a => a -> ThreatModel ()
collectTM = (Property -> Property) -> ThreatModel ()
monitorThreatModel ((Property -> Property) -> ThreatModel ())
-> (a -> Property -> Property) -> a -> ThreatModel ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Property -> Property
forall a prop. (Show a, Testable prop) => a -> prop -> Property
collect
classifyTM :: Bool -> String -> ThreatModel ()
classifyTM :: Bool -> String -> ThreatModel ()
classifyTM = ((Property -> Property) -> ThreatModel ()
monitorThreatModel ((Property -> Property) -> ThreatModel ())
-> (String -> Property -> Property) -> String -> ThreatModel ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((String -> Property -> Property) -> String -> ThreatModel ())
-> (Bool -> String -> Property -> Property)
-> Bool
-> String
-> ThreatModel ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> String -> Property -> Property
forall prop. Testable prop => Bool -> String -> prop -> Property
classify