content: {-# LANGUAGE AllowAmbiguousTypes #-}
  {-# LANGUAGE DataKinds           #-}
  {-# LANGUAGE DerivingStrategies  #-}
  {-# LANGUAGE FlexibleContexts    #-}
  {-# LANGUAGE GADTs               #-}
  {-# LANGUAGE LambdaCase          #-}
  {-# LANGUAGE NamedFieldPuns      #-}
  {-# LANGUAGE RankNTypes          #-}
  {-# LANGUAGE ScopedTypeVariables #-}
  {-# LANGUAGE TypeApplications    #-}
  {-# LANGUAGE TypeFamilies        #-}
  {-# LANGUAGE TypeOperators       #-}
  {-
  
  A trace is a sequence of actions on some Plutus contracts. This module defines
  the types and functions for constructing and running traces.
  
  Some examples of actions that can be performed during a trace:
  
  * Starting a new instance of a contract
  * Calling an endpoint on a contract instance
  * Inspecting the state of a contract instance
  * Waiting for blockchain events to happen
  * Modifying the state of the blockchain emulator
  
  The syntax of traces is given as a number of @freer-simple@ effects under
  "Plutus.Trace.Effects". There is a concrete list of trace effects to be used in
  a testing environment ('Plutus.Trace.Emulator.EmulatorTrace'), and a similar
  type for use in the Playground ('Plutus.Trace.Playground.PlaygroundTrace').
  
  ** Running Traces
  
  Running a trace means handling its effects.
  'Plutus.Trace.Emulator.runEmulatorStream' interprets the
  'Plutus.Trace.Emulator.EmulatorTrace' type as a stream of emulator events. This
  stream includes all events that happen in the emulated environment while the
  trace is running: Transactions validated or rejected, endpoint calls, slot
  changes, and more. The module "Wallet.Emulator.Folds" defines a number of folds
  that extract interesting data from emulator event streams.
  
  -}
  module Plutus.Trace(
      module X
      , module Extract
      , Scheduler.SchedulerLog
      , Scheduler.ThreadEvent
      ) where
  
  import Plutus.Trace.Emulator as X
  import Plutus.Trace.Emulator.Extract as Extract
  import Plutus.Trace.Scheduler as Scheduler
  
  {- Note [Trace]
  
  Traces describe systems in which many things may happen at the same time.
  Imagine a trace that starts two contract instances and then waits for both of
  them to finish some initialisation procedure, while the node keeps adding new
  blocks to the chain in the background.
  
  To deal with this concurrency, traces are interpreted using a scheduler that
  runs some concurrent threads. Each contract instance runs in its own thread,
  and (in the emulated environment) there is a system thread that takes care of
  producing new blocks periodically.
  
  The scheduler defined in "Plutus.Trace.Scheduler"
  is pure and deterministic. It runs in a single GHC thread, and it performs the
  same actions in the same order every time the same trace is run. So a thread
  here is a coroutine that runs for a little while before yielding control
  back to the scheduler, which then selects the next coroutine to run.
  
  -}
  