Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
The API to the CEK machine.
Synopsis
- runCek ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → ExBudgetMode cost uni fun → EmitterMode uni fun → Term Name uni fun ann → (Either (CekEvaluationException Name uni fun) (Term Name uni fun ()), cost, [Text])
- runCekDeBruijn ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → ExBudgetMode cost uni fun → EmitterMode uni fun → NTerm uni fun ann → (Either (CekEvaluationException NamedDeBruijn uni fun) (NTerm uni fun ()), cost, [Text])
- runCekNoEmit ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → ExBudgetMode cost uni fun → Term Name uni fun ann → (Either (CekEvaluationException Name uni fun) (Term Name uni fun ()), cost)
- evaluateCek ∷ ThrowableBuiltins uni fun ⇒ EmitterMode uni fun → MachineParameters CekMachineCosts fun (CekValue uni fun ann) → Term Name uni fun ann → (Either (CekEvaluationException Name uni fun) (Term Name uni fun ()), [Text])
- evaluateCekNoEmit ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → Term Name uni fun ann → Either (CekEvaluationException Name uni fun) (Term Name uni fun ())
- data EvaluationResult a
- splitStructuralOperational ∷ Either (EvaluationException structural operational term) a → Either (ErrorWithCause structural term) (EvaluationResult a)
- unsafeSplitStructuralOperational ∷ (PrettyPlc structural, PrettyPlc term, Typeable structural, Typeable term) ⇒ Either (EvaluationException structural operational term) a → EvaluationResult a
- data CekUserError
- data ErrorWithCause err cause = ErrorWithCause {}
- type CekEvaluationException name uni fun = EvaluationException (MachineError fun) CekUserError (Term name uni fun ())
- data EvaluationError structural operational
- = StructuralEvaluationError !structural
- | OperationalEvaluationError !operational
- data ExBudgetCategory fun
- = BStep StepKind
- | BBuiltinApp fun
- | BStartup
- newtype CekBudgetSpender uni fun s = CekBudgetSpender {
- unCekBudgetSpender ∷ ExBudgetCategory fun → ExBudget → CekM uni fun s ()
- newtype ExBudgetMode cost uni fun = ExBudgetMode {
- unExBudgetMode ∷ ∀ s. ST s (ExBudgetInfo cost uni fun s)
- data StepKind
- newtype CekExTally fun = CekExTally (MonoidalHashMap (ExBudgetCategory fun) ExBudget)
- newtype CountingSt = CountingSt ExBudget
- data TallyingSt fun = TallyingSt (CekExTally fun) ExBudget
- newtype RestrictingSt = RestrictingSt ExRestrictingBudget
- type CekMachineCosts = CekMachineCostsBase Identity
- monoidalBudgeting ∷ Monoid cost ⇒ (ExBudgetCategory fun → ExBudget → cost) → ExBudgetMode cost uni fun
- counting ∷ ExBudgetMode CountingSt uni fun
- tallying ∷ Hashable fun ⇒ ExBudgetMode (TallyingSt fun) uni fun
- restricting ∷ ThrowableBuiltins uni fun ⇒ ExRestrictingBudget → ExBudgetMode RestrictingSt uni fun
- restrictingEnormous ∷ ThrowableBuiltins uni fun ⇒ ExBudgetMode RestrictingSt uni fun
- enormousBudget ∷ ExRestrictingBudget
- noEmitter ∷ EmitterMode uni fun
- logEmitter ∷ EmitterMode uni fun
- logWithTimeEmitter ∷ EmitterMode uni fun
- logWithBudgetEmitter ∷ EmitterMode uni fun
- data BuiltinsRuntime fun val = BuiltinsRuntime {
- unBuiltinsRuntime ∷ fun → BuiltinRuntime val
- data CekValue uni fun ann
- readKnownCek ∷ (ThrowableBuiltins uni fun, ReadKnown (Term Name uni fun ()) a) ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → Term Name uni fun ann → Either (CekEvaluationException Name uni fun) a
- class Eq a ⇒ Hashable a
- type ThrowableBuiltins uni fun = (PrettyUni uni, Pretty fun, Typeable uni, Typeable fun)
Running the machine
runCek ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → ExBudgetMode cost uni fun → EmitterMode uni fun → Term Name uni fun ann → (Either (CekEvaluationException Name uni fun) (Term Name uni fun ()), cost, [Text]) Source #
Evaluate a term using the CEK machine with logging enabled and keep track of costing. A wrapper around the internal runCek to debruijn input and undebruijn output. *THIS FUNCTION IS PARTIAL if the input term contains free variables*
runCekDeBruijn ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → ExBudgetMode cost uni fun → EmitterMode uni fun → NTerm uni fun ann → (Either (CekEvaluationException NamedDeBruijn uni fun) (NTerm uni fun ()), cost, [Text]) Source #
Evaluate a term using the CEK machine and keep track of costing, logging is optional.
runCekNoEmit ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → ExBudgetMode cost uni fun → Term Name uni fun ann → (Either (CekEvaluationException Name uni fun) (Term Name uni fun ()), cost) Source #
Evaluate a term using the CEK machine with logging disabled and keep track of costing. *THIS FUNCTION IS PARTIAL if the input term contains free variables*
evaluateCek ∷ ThrowableBuiltins uni fun ⇒ EmitterMode uni fun → MachineParameters CekMachineCosts fun (CekValue uni fun ann) → Term Name uni fun ann → (Either (CekEvaluationException Name uni fun) (Term Name uni fun ()), [Text]) Source #
Evaluate a term using the CEK machine with logging enabled. *THIS FUNCTION IS PARTIAL if the input term contains free variables*
evaluateCekNoEmit ∷ ThrowableBuiltins uni fun ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → Term Name uni fun ann → Either (CekEvaluationException Name uni fun) (Term Name uni fun ()) Source #
Evaluate a term using the CEK machine with logging disabled. *THIS FUNCTION IS PARTIAL if the input term contains free variables*
data EvaluationResult a Source #
The parameterized type of results various evaluation engines return.
On the PLC side this becomes (via makeKnown
) either a call to Error
or
a value of the PLC counterpart of type a
.
Instances
splitStructuralOperational ∷ Either (EvaluationException structural operational term) a → Either (ErrorWithCause structural term) (EvaluationResult a) Source #
Preserve the contents of an StructuralEvaluationError
as a Left
and turn an
OperationalEvaluationError
into a Right EvaluationFailure
(thus erasing the content of the
error in the latter case).
unsafeSplitStructuralOperational ∷ (PrettyPlc structural, PrettyPlc term, Typeable structural, Typeable term) ⇒ Either (EvaluationException structural operational term) a → EvaluationResult a Source #
Throw on a StructuralEvaluationError
and turn an OperationalEvaluationError
into an
EvaluationFailure
(thus erasing the content of the error in the latter case).
Errors
data CekUserError Source #
CekOutOfExError !ExRestrictingBudget | The final overspent (i.e. negative) budget. |
CekEvaluationFailure | Error has been called or a builtin application has failed |
Instances
data ErrorWithCause err cause Source #
An error and (optionally) what caused it.
Instances
type CekEvaluationException name uni fun = EvaluationException (MachineError fun) CekUserError (Term name uni fun ()) Source #
The CEK machine-specific EvaluationException
.
data EvaluationError structural operational Source #
The type of errors that can occur during evaluation. There are two kinds of errors:
- Structural ones -- these are errors that are indicative of the _structure_ of the program being
wrong. For example, a free variable was encountered during evaluation, a non-function was
applied to an argument or
tailList
was applied to a non-list. - Operational ones -- these are errors that are indicative of the _logic_ of the program being
wrong. For example,
error
was executed,tailList
was applied to an empty list or evaluation ran out of gas.
On the chain both of these are just regular failures and we don't distinguish between them there: if a script fails, it fails, it doesn't matter what the reason was. However in the tests it does matter why the failure occurred: a structural error may indicate that the test was written incorrectly while an operational error may be entirely expected.
In other words, structural errors are "runtime type errors" and operational errors are regular runtime errors. Which means that evaluating an (erased) well-typed program should never produce a structural error, only an operational one. This creates a sort of "runtime type system" for UPLC and it would be great to stick to it and enforce in tests etc, but we currently don't.
StructuralEvaluationError !structural | |
OperationalEvaluationError !operational |
Instances
Costing
data ExBudgetCategory fun Source #
Instances
newtype CekBudgetSpender uni fun s Source #
The CEK machine is parameterized over a spendBudget
function. This makes the budgeting machinery extensible
and allows us to separate budgeting logic from evaluation logic and avoid branching on the union
of all possible budgeting state types during evaluation.
CekBudgetSpender | |
|
newtype ExBudgetMode cost uni fun Source #
A budgeting mode to execute the CEK machine in.
ExBudgetMode | |
|
Instances
newtype CekExTally fun Source #
For a detailed report on what costs how much + the same overall budget that Counting
gives.
The (derived) Monoid
instance of CekExTally
is the main piece of the machinery.
Instances
newtype CountingSt Source #
Instances
Monoid CountingSt Source # | |
Semigroup CountingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode (<>) ∷ CountingSt → CountingSt → CountingSt Source # sconcat ∷ NonEmpty CountingSt → CountingSt Source # stimes ∷ Integral b ⇒ b → CountingSt → CountingSt Source # | |
Show CountingSt Source # | |
NFData CountingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode rnf ∷ CountingSt → () Source # | |
Eq CountingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode (==) ∷ CountingSt → CountingSt → Bool Source # (/=) ∷ CountingSt → CountingSt → Bool Source # | |
Pretty CountingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode pretty ∷ CountingSt → Doc ann Source # prettyList ∷ [CountingSt] → Doc ann Source # | |
PrettyBy config CountingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode prettyBy ∷ config → CountingSt → Doc ann Source # prettyListBy ∷ config → [CountingSt] → Doc ann Source # |
data TallyingSt fun Source #
TallyingSt (CekExTally fun) ExBudget |
Instances
newtype RestrictingSt Source #
Instances
Monoid RestrictingSt Source # | |
Semigroup RestrictingSt Source # | |
Show RestrictingSt Source # | |
NFData RestrictingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode rnf ∷ RestrictingSt → () Source # | |
Eq RestrictingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode (==) ∷ RestrictingSt → RestrictingSt → Bool Source # (/=) ∷ RestrictingSt → RestrictingSt → Bool Source # | |
Pretty RestrictingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode pretty ∷ RestrictingSt → Doc ann Source # prettyList ∷ [RestrictingSt] → Doc ann Source # | |
PrettyBy config RestrictingSt Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode prettyBy ∷ config → RestrictingSt → Doc ann Source # prettyListBy ∷ config → [RestrictingSt] → Doc ann Source # |
type CekMachineCosts = CekMachineCostsBase Identity Source #
Costs for evaluating AST nodes. Times should be specified in picoseconds, memory sizes in bytes.
Costing modes
monoidalBudgeting ∷ Monoid cost ⇒ (ExBudgetCategory fun → ExBudget → cost) → ExBudgetMode cost uni fun Source #
Construct an ExBudgetMode
out of a function returning a value of the budgeting state type.
The value then gets added to the current state via (<>)
.
counting ∷ ExBudgetMode CountingSt uni fun Source #
For calculating the cost of execution.
tallying ∷ Hashable fun ⇒ ExBudgetMode (TallyingSt fun) uni fun Source #
For a detailed report on what costs how much + the same overall budget that Counting
gives.
restricting ∷ ThrowableBuiltins uni fun ⇒ ExRestrictingBudget → ExBudgetMode RestrictingSt uni fun Source #
For execution, to avoid overruns.
restrictingEnormous ∷ ThrowableBuiltins uni fun ⇒ ExBudgetMode RestrictingSt uni fun Source #
restricting
instantiated at enormousBudget
.
enormousBudget ∷ ExRestrictingBudget Source #
When we want to just evaluate the program we use the Restricting
mode with an enormous
budget, so that evaluation costs of on-chain budgeting are reflected accurately in benchmarks.
Emitter modes
noEmitter ∷ EmitterMode uni fun Source #
No emitter.
logEmitter ∷ EmitterMode uni fun Source #
Emits log only.
logWithTimeEmitter ∷ EmitterMode uni fun Source #
Emits log with timestamp.
logWithBudgetEmitter ∷ EmitterMode uni fun Source #
Emits log with the budget.
Misc
data BuiltinsRuntime fun val Source #
A data
wrapper around a function returning the BuiltinRuntime
of a built-in function.
We use data
rather than newtype
, because GHC is able to see through newtype
s and may break
carefully set up optimizations, see
https://github.com/IntersectMBO/plutus/pull/4914#issuecomment-1396306606
Using data
may make things more expensive, however it was verified at the time of writing that
the wrapper is removed before the CEK machine starts, leaving the stored function to be used
directly.
In order for lookups to be efficient the BuiltinRuntime
s need to be cached, i.e. pulled out
of the function statically. See makeBuiltinMeaning
for how we achieve that.
BuiltinsRuntime | |
|
Instances
(Bounded fun, Enum fun) ⇒ NFData (BuiltinsRuntime fun val) Source # | |
Defined in PlutusCore.Builtin.Runtime rnf ∷ BuiltinsRuntime fun val → () Source # | |
(Bounded fun, Enum fun) ⇒ NoThunks (BuiltinsRuntime fun val) Source # | |
Defined in PlutusCore.Builtin.Runtime |
data CekValue uni fun ann Source #
VCon !(Some (ValueOf uni)) | |
VDelay !(NTerm uni fun ann) !(CekValEnv uni fun ann) | |
VLamAbs !NamedDeBruijn !(NTerm uni fun ann) !(CekValEnv uni fun ann) | |
VBuiltin | A partial builtin application, accumulating arguments for eventual full application.
We don't need a |
| |
VConstr !Word64 !(ArgStack uni fun ann) |
Instances
(PrettyUni uni, Pretty fun) ⇒ PrettyBy PrettyConfigPlc (CekValue uni fun ann) Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.Internal prettyBy ∷ PrettyConfigPlc → CekValue uni fun ann → Doc ann0 Source # prettyListBy ∷ PrettyConfigPlc → [CekValue uni fun ann] → Doc ann0 Source # | |
Show (BuiltinRuntime (CekValue uni fun ann)) Source # | |
(GShow uni, Everywhere uni Show, Show fun, Show ann, Closed uni) ⇒ Show (CekValue uni fun ann) Source # | |
HasConstant (CekValue uni fun ann) Source # | |
(Closed uni, Everywhere uni ExMemoryUsage) ⇒ ExMemoryUsage (CekValue uni fun ann) Source # | |
Defined in UntypedPlutusCore.Evaluation.Machine.Cek.Internal memoryUsage ∷ CekValue uni fun ann → CostRose Source # | |
type UniOf (CekValue uni fun ann) Source # | |
readKnownCek ∷ (ThrowableBuiltins uni fun, ReadKnown (Term Name uni fun ()) a) ⇒ MachineParameters CekMachineCosts fun (CekValue uni fun ann) → Term Name uni fun ann → Either (CekEvaluationException Name uni fun) a Source #
Unlift a value using the CEK machine. *THIS FUNCTION IS PARTIAL if the input term contains free variables*
class Eq a ⇒ Hashable a Source #
The class of types that can be converted to a hash value.
Minimal implementation: hashWithSalt
.
Hashable
is intended exclusively for use in in-memory data structures.
.
Hashable
does not have a fixed standard.
This allows it to improve over time.
.
Because it does not have a fixed standard, different computers or computers on different versions of the code will observe different hash values.
As such, Hashable
is not recommended for use other than in-memory datastructures.
Specifically, Hashable
is not intended for network use or in applications which persist hashed values.
For stable hashing use named hashes: sha256, crc32, xxhash etc.
If you are looking for Hashable
instance in time
package,
check time-compat