plutus-contract-model-1.2.0.0
Safe HaskellNone
LanguageHaskell2010

Plutus.Contract.Test.ContractModel.Internal

Description

This module provides a framework for testing Plutus contracts built on Test.QuickCheck. The testing is model based, so to test a contract you define a type modelling the state of the contract (or set of contracts) and provide an instance of the ContractModel class. This instance specifies what operations (Actions) the contract supports, how they interact with the model state, and how to execute them in the blockchain emulator (Plutus.Trace.Emulator). Tests are evaluated by running sequences of actions (random or user-specified) in the emulator and comparing the state of the blockchain to the model state at the end.

Test cases are written in the DL monad, which supports mixing fixed sequences of actions with random actions, making it easy to write properties like it is always possible to get all funds out of the contract.

Synopsis

Documentation

pattern UnderlyingAction :: Action s -> Action (WithInstances s) Source #

pattern Unilateral :: Wallet -> Action (WithInstances s) Source #

data CoverageOptions Source #

Options for controlling coverage checking requirements

  • checkCoverage tells you whether or not to run the coverage checks at all.
  • `endpointCoverageEq instance endpointName` tells us what percentage of tests are required to include a call to the endpoint endpointName in the contract at `instance`.
  • coverIndex is the coverage index obtained from the CompiledCodeIn of the validator.

Constructors

CoverageOptions 

Fields

newtype WithInstances s Source #

Constructors

WithInstances 

Fields

Instances

Instances details
Eq (Action s) => Eq (Action (WithInstances s)) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Methods

(==) :: Action (WithInstances s) -> Action (WithInstances s) -> Bool Source #

(/=) :: Action (WithInstances s) -> Action (WithInstances s) -> Bool Source #

Eq s => Eq (WithInstances s) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Show (Action s) => Show (Action (WithInstances s)) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Methods

showsPrec :: Int -> Action (WithInstances s) -> ShowS Source #

show :: Action (WithInstances s) -> String Source #

showList :: [Action (WithInstances s)] -> ShowS Source #

Show s => Show (WithInstances s) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Generic (Action (WithInstances s)) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Associated Types

type Rep (Action (WithInstances s)) :: Type -> Type Source #

Methods

from :: Action (WithInstances s) -> Rep (Action (WithInstances s)) x Source #

to :: Rep (Action (WithInstances s)) x -> Action (WithInstances s) Source #

Generic (WithInstances s) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Associated Types

type Rep (WithInstances s) :: Type -> Type Source #

ContractModel s => ContractModel (WithInstances s) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Associated Types

data Action (WithInstances s)

HasSymbolics (Action s) => HasSymbolics (Action (WithInstances s)) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Methods

getAllSymbolics :: Action (WithInstances s) -> SymCollectionIndex #

CheckableContractModel state => RunModel (WithInstances state) (EmulatorTraceWithInstances state) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

Methods

perform :: ModelState (WithInstances state) -> Action (WithInstances state) -> (forall t. HasSymbolicRep t => Symbolic t -> t) -> RunMonad (EmulatorTraceWithInstances state) ()

monitoring :: (ModelState (WithInstances state), ModelState (WithInstances state)) -> Action (WithInstances state) -> (forall t. HasSymbolicRep t => Symbolic t -> t) -> SymIndex -> Property -> Property

type Rep (Action (WithInstances s)) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

type Rep (Action (WithInstances s)) = D1 ('MetaData "Action" "Plutus.Contract.Test.ContractModel.Internal" "plutus-contract-model-1.2.0.0-AT5Aekx0s4LCgIL1y0MF95" 'False) (C1 ('MetaCons "UnderlyingAction" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Action s))) :+: C1 ('MetaCons "Unilateral" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Wallet)))
type Rep (WithInstances s) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

type Rep (WithInstances s) = D1 ('MetaData "WithInstances" "Plutus.Contract.Test.ContractModel.Internal" "plutus-contract-model-1.2.0.0-AT5Aekx0s4LCgIL1y0MF95" 'True) (C1 ('MetaCons "WithInstances" 'PrefixI 'True) (S1 ('MetaSel ('Just "withoutInstances") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 s)))
data Action (WithInstances s) Source # 
Instance details

Defined in Plutus.Contract.Test.ContractModel.Internal

data Action (WithInstances s)

type EmulatorTraceWithInstances s = Eff (State (Handles s) ': EmulatorEffects) Source #

type SpecificationEmulatorTrace s = Eff (Reader (Handles s) ': BaseEmulatorEffects) Source #

contractHandle :: (ContractInstanceModel state, Typeable w, Typeable schema, Typeable err, Typeable params) => ContractInstanceKey state w schema err params -> RunMonad (SpecificationEmulatorTrace state) (ContractHandle w schema err) Source #

activateWallets :: ContractInstanceModel state => (forall t. HasSymbolicRep t => Symbolic t -> t) -> [StartContract state] -> EmulatorTraceWithInstances state () Source #

instancesForOtherWallets :: Wallet -> Handles state -> [ContractInstanceId] Source #

Used to freeze other wallets when checking a NoLockedFundsProof.

delay :: Integer -> RunMonad (SpecificationEmulatorTrace state) () Source #

`delay n` delays emulator execution by n slots

newtype Whitelist Source #

A whitelist entry tells you what final log entry prefixes are acceptable for a given error

Constructors

Whitelist 

Fields

data NoLockedFundsProof model Source #

A "proof" that you can always recover the funds locked by a contract. The first component is a strategy that from any state of the contract can get all the funds out. The second component is a strategy for each wallet that from the same state, shows how that wallet can recover the same (or bigger) amount as using the first strategy, without relying on any actions being taken by the other wallets.

For instance, in a two player game where each player bets some amount of funds and the winner gets the pot, there needs to be a mechanism for the players to recover their bid if the other player simply walks away (perhaps after realising the game is lost). If not, it won't be possible to construct a NoLockedFundsProof that works in a state where both players need to move before any funds can be collected.

Constructors

NoLockedFundsProof 

Fields

  • nlfpMainStrategy :: DL (WithInstances model) ()

    Strategy to recover all funds from the contract in any reachable state.

  • nlfpWalletStrategy :: Wallet -> DL (WithInstances model) ()

    A strategy for each wallet to recover as much (or more) funds as the main strategy would give them in a given state, without the assistance of any other wallet.

  • nlfpOverhead :: ModelState (WithInstances model) -> SymValue

    An initial amount of overhead value that may be lost - e.g. setup fees for scripts that can't be recovered.

  • nlfpErrorMargin :: ModelState (WithInstances model) -> SymValue

    The total amount of margin for error in the value collected by the WalletStrategy compared to the MainStrategy. This is useful if your contract contains rounding code that makes the order of operations have a small but predictable effect on the value collected by different wallets.

coverageIORef :: Lens' CoverageOptions (Maybe (IORef CoverageData)) Source #

coverageIndex :: Lens' CoverageOptions CoverageIndex Source #

endpointCoverageReq :: Lens' CoverageOptions (ContractInstanceTag -> String -> Double) Source #

defaultCoverageOptions :: CoverageOptions Source #

Default coverage checking options are: * not to check coverage * set the requriements for every endpoint to 20% and * not to cover any source locations in the validator scripts.

defaultCheckOptionsContractModel :: CheckOptions Source #

Default check options that include a large amount of Ada in the initial distributions to avoid having to write ContractModels that keep track of balances.

quickCheckWithCoverage :: Testable prop => Args -> CoverageOptions -> (CoverageOptions -> prop) -> IO CoverageReport Source #

Run QuickCheck on a property that tracks coverage and print its coverage report.

quickCheckWithCoverageAndResult :: Testable prop => Args -> CoverageOptions -> (CoverageOptions -> prop) -> IO (CoverageReport, Result) Source #

balanceChangePredicate :: ProtocolParameters -> ContractModelResult state -> Property Source #

threatModelPredicate :: ThreatModel a -> ProtocolParameters -> ContractModelResult state -> Property Source #

checkThreatModel Source #

Arguments

:: CheckableContractModel state 
=> ThreatModel a 
-> Actions (WithInstances state)

The actions to run

-> Property 

Check a threat model on all transactions produced by the given actions.

checkThreatModelWithOptions Source #

Arguments

:: CheckableContractModel state 
=> CheckOptions

Emulator options

-> CoverageOptions

Coverage options

-> ThreatModel a 
-> Actions (WithInstances state)

The actions to run

-> Property 

Check a threat model on all transactions produced by the given actions.

propRunActions_ Source #

Arguments

:: CheckableContractModel state 
=> Actions (WithInstances state)

The actions to run

-> Property 

Run a Actions in the emulator and check that the model and the emulator agree on the final wallet balance changes. Equivalent to

propRunActions_ hs actions = propRunActions hs (const $ pure True) actions

propRunActions Source #

Arguments

:: CheckableContractModel state 
=> (ModelState (WithInstances state) -> TracePredicate)

Predicate to check at the end

-> (ProtocolParameters -> ContractModelResult (WithInstances state) -> Property)

Predicate to run on the contract model

-> Actions (WithInstances state)

The actions to run

-> Property 

Run a Actions in the emulator and check that the model and the emulator agree on the final wallet balance changes, and that the given TracePredicate holds at the end. Equivalent to:

propRunActions = propRunActionsWithOptions defaultCheckOptionsContractModel defaultCoverageOptions

propRunActionsWithOptions Source #

Arguments

:: forall state. CheckableContractModel state 
=> CheckOptions

Emulator options

-> CoverageOptions

Coverage options

-> (ModelState (WithInstances state) -> TracePredicate)

Predicate to check at the end of execution

-> (ProtocolParameters -> ContractModelResult (WithInstances state) -> Property)

Predicate to run on the contract model

-> Actions (WithInstances state)

The actions to run

-> Property 

defaultNLFP :: NoLockedFundsProof model Source #

The default skeleton of a NoLockedFundsProof - doesn't permit any overhead or error margin.

checkNoLockedFundsProof :: CheckableContractModel model => NoLockedFundsProof model -> Property Source #

Check a NoLockedFundsProof. Each test will generate an arbitrary sequence of actions (anyActions_) and ask the nlfpMainStrategy to recover all funds locked by the contract after performing those actions. This results in some distribution of the contract funds to the wallets, and the test then asks each nlfpWalletStrategy to show how to recover their allotment of funds without any assistance from the other wallets (assuming the main strategy did not execute). When executing wallet strategies, the off-chain instances for other wallets are killed and their private keys are deleted from the emulator state.

checkNoLockedFundsProof' :: CheckableContractModel model => (Actions (WithInstances model) -> Property) -> NoLockedFundsProof model -> Property Source #

actionsFromList :: [Action s] -> Actions s Source #

walletAddress :: Wallet -> AddressInEra Era Source #

addressToWallet :: AddressInEra Era -> Maybe Wallet Source #

isAcceptedBy :: Maybe Text -> Whitelist -> Bool Source #

Check that the last entry in a log is accepted by a whitelist entry

whitelistOk :: Whitelist -> Bool Source #

Check that a whitelist does not accept any partial functions

checkErrorWhitelist :: CheckableContractModel m => Whitelist -> Actions (WithInstances m) -> Property Source #

Check that running a contract model does not result in validation failures that are not accepted by the whitelist.

checkErrorWhitelistWithOptions :: forall m. CheckableContractModel m => CheckOptions -> CoverageOptions -> Whitelist -> Actions (WithInstances m) -> Property Source #

Check that running a contract model does not result in validation failures that are not accepted by the whitelist.

Orphan instances

HasVariables Wallet Source # 
Instance details

Methods

getAllVariables :: Wallet -> Set (Any Var)

(HasChainIndex (Eff effs), Member Waiting effs) => IsRunnable (Eff effs) Source # 
Instance details

Methods

awaitSlot :: SlotNo -> Eff effs ()

Member EmulatorControl effs => HasChainIndex (Eff effs) Source # 
Instance details

Methods

getChainIndex :: Eff effs ChainIndex

getChainState :: Eff effs ChainState