Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Module, containing function to interpret Michelson instructions against given context and input stack.
Synopsis
- type ContractEnv = ContractEnv' EvalOp
- data ContractEnv' m = ContractEnv {
- ceNow :: Timestamp
- ceMaxSteps :: RemainingSteps
- ceBalance :: Mutez
- ceContracts :: ContractAddress -> m (Maybe ContractState)
- ceSelf :: ContractAddress
- ceSource :: L1Address
- ceSender :: L1Address
- ceAmount :: Mutez
- ceVotingPowers :: VotingPowers
- ceChainId :: ChainId
- ceOperationHash :: Maybe OperationHash
- ceLevel :: Natural
- ceErrorSrcPos :: ErrorSrcPos
- ceMinBlockTime :: Natural
- ceMetaWrapper :: forall i o. Instr i o -> Instr i o
- data InterpreterState = InterpreterState {}
- data MichelsonFailed ext where
- MichelsonFailedWith :: (SingI t, ConstantScope t) => Value t -> MichelsonFailed ext
- MichelsonArithError :: (Typeable n, Typeable m) => ArithError (Value n) (Value m) -> MichelsonFailed ext
- MichelsonGasExhaustion :: MichelsonFailed ext
- MichelsonFailedTestAssert :: Text -> MichelsonFailed ext
- MichelsonUnsupported :: Text -> MichelsonFailed ext
- MichelsonExt :: ext -> MichelsonFailed ext
- data MichelsonFailureWithStack ext = MichelsonFailureWithStack {}
- newtype RemainingSteps = RemainingSteps Word64
- data SomeItStack meta where
- SomeItStack :: ExtInstr inp -> Rec (StkEl meta) inp -> SomeItStack meta
- newtype MorleyLogs = MorleyLogs {
- unMorleyLogs :: [Text]
- buildMorleyLogs :: MorleyLogsBuilder -> MorleyLogs
- newtype MorleyLogsBuilder = MorleyLogsBuilder (Endo [Text])
- interpret :: Contract cp st -> EntrypointCallT cp arg -> Value arg -> Value st -> GlobalCounter -> BigMapCounter -> ContractEnv -> ContractReturn st
- interpretInstr :: ContractEnv -> Instr inp out -> Rec Value inp -> Either (MichelsonFailureWithStack Void) (Rec Value out)
- interpretInstrAnnotated :: ContractEnv -> Instr inp out -> Rec Value inp -> Either (MichelsonFailureWithStack Void) (Rec (StkEl NoStkElMeta) out)
- type InterpretReturn ty = RunEvalOpReturn (Value ty)
- type ContractReturn st = InterpretReturn (ContractOut1 st)
- type RunEvalOpReturn a = ResultStateLogs (Either (MichelsonFailureWithStack Void) a)
- data ResultStateLogs res = ResultStateLogs {
- rslResult :: res
- rslState :: InterpreterState
- rslLogs :: MorleyLogs
- mkInitStack :: Value param -> Value st -> Rec Value (ContractInp param st)
- data InterpretError ext = InterpretError {}
- type InterpretResult ty = ResultStateLogs (Value ty)
- type ContractResult ty = InterpretResult (ContractOut1 ty)
- extractValOps :: Value (ContractOut1 st) -> ([Operation], Value st)
- type EvalM m = EvalM' Void m
- type EvalM' ext m = (MonadReader (ContractEnv' m) m, InterpreterStateMonad m, MonadWriter MorleyLogsBuilder m, MonadError (MichelsonFailureWithStack ext) m)
- class Monad m => InterpreterStateMonad m where
- getInterpreterState :: m InterpreterState
- putInterpreterState :: InterpreterState -> m ()
- stateInterpreterState :: (InterpreterState -> (a, InterpreterState)) -> m a
- modifyInterpreterState :: (InterpreterState -> InterpreterState) -> m ()
- data StkEl meta t where
- data NoStkElMeta t = NoStkElMeta
- seValueL :: forall meta t. Lens' (StkEl meta t) (Value t)
- seMetaL :: forall meta t meta. Lens (StkEl meta t) (StkEl meta t) (meta t) (meta t)
- type InstrRunner meta m = forall inp out. Instr inp out -> Rec (StkEl meta) inp -> m (Rec (StkEl meta) out)
- runInstr :: forall ext meta m. (StkElMeta meta m, EvalM' ext m) => InstrRunner meta m
- runInstrNoGas :: EvalM m => InstrRunner NoStkElMeta m
- runUnpack :: forall t. UnpackedValScope t => ByteString -> Either UnpackError (Value t)
- data ViewLookupError
- interpretView :: View arg st ret -> Value st -> Value arg -> ContractEnv -> InterpreterState -> InterpretReturn ret
- getViewByName :: Contract cp st -> ViewName -> Either ViewLookupError (SomeView st)
- getViewByNameAndType :: forall arg ret cp st. (SingI arg, SingI ret) => Contract cp st -> ViewName -> Either ViewLookupError (View arg st ret)
- initInterpreterState :: GlobalCounter -> BigMapCounter -> ContractEnv -> InterpreterState
- handleReturn :: InterpretReturn res -> Either (InterpretError Void) (ResultStateLogs (Value res))
- runEvalOp :: EvalOp a -> ContractEnv -> InterpreterState -> RunEvalOpReturn a
- runInstrImpl :: forall ext meta m. (EvalM' ext m, StkElMeta meta m) => InstrRunner meta m -> InstrRunner meta m
- assignBigMapIds :: MonadState BigMapCounter m => Bool -> Value t -> m (Value t)
- mapToStkEl :: forall meta inp m. (Applicative m, StkElMeta meta m) => Rec Value inp -> m (Rec (StkEl meta) inp)
- mapToValue :: Rec (StkEl meta) inp -> Rec Value inp
- mkStkEl :: forall meta t m. (Applicative m, StkElMeta meta m) => Value t -> m (StkEl meta t)
- mkDuplicateStkEl :: forall meta t m. (Applicative m, StkElMeta meta m) => StkEl meta t -> m (StkEl meta t)
- runEvalOpT :: Monad m => EvalOpT m a -> ContractEnv' (EvalOpT m) -> InterpreterState -> m (RunEvalOpReturn a)
- interpret' :: forall cp st arg m. Monad m => Contract cp st -> EntrypointCallT cp arg -> Value arg -> Value st -> ContractEnv' (EvalOpT m) -> InterpreterState -> m (ContractReturn st)
- interpretView' :: forall ret st m arg ext meta. (StkElMeta meta m, EvalM' ext m) => (forall inp out. Instr inp out -> Rec (StkEl meta) inp -> m (Rec (StkEl meta) out)) -> (ContractEnv' m -> ContractEnv' m) -> View arg st ret -> Value st -> Value arg -> m (Value ret)
- class (forall t. Eq (meta t), forall t. Show (meta t)) => StkElMeta meta m where
- mkStkElMeta :: Maybe (meta t) -> Value t -> m (meta t)
- newtype EvalOpT m a = EvalOpT (ExceptT (MichelsonFailureWithStack Void) (RWST (ContractEnv' (EvalOpT m)) MorleyLogsBuilder InterpreterState m) a)
- type EvalOp = EvalOpT Identity
- _MorleyLogs :: Iso' MorleyLogs [Text]
Documentation
type ContractEnv = ContractEnv' EvalOp Source #
data ContractEnv' m Source #
Environment for contract execution. Parametrized by the execution monad,
i.e. EvalOp
by default, but downstream consumers may define their own if
using low-level runners.
ContractEnv | |
|
Instances
Monad m => MonadReader (ContractEnv' (EvalOpT m)) (EvalOpT m) Source # | |
Defined in Morley.Michelson.Interpret ask :: EvalOpT m (ContractEnv' (EvalOpT m)) # local :: (ContractEnv' (EvalOpT m) -> ContractEnv' (EvalOpT m)) -> EvalOpT m a -> EvalOpT m a # reader :: (ContractEnv' (EvalOpT m) -> a) -> EvalOpT m a # |
data InterpreterState Source #
Instances
data MichelsonFailed ext where Source #
Errors that can be thrown by the interpreter. The ext
type variable
allow the downstreams consumer to add additional exceptions.
MichelsonFailedWith | |
| |
MichelsonArithError :: (Typeable n, Typeable m) => ArithError (Value n) (Value m) -> MichelsonFailed ext | |
MichelsonGasExhaustion :: MichelsonFailed ext | |
MichelsonFailedTestAssert :: Text -> MichelsonFailed ext | |
MichelsonUnsupported :: Text -> MichelsonFailed ext | |
MichelsonExt :: ext -> MichelsonFailed ext |
Instances
Show ext => Show (MichelsonFailed ext) Source # | |
Defined in Morley.Michelson.Interpret showsPrec :: Int -> MichelsonFailed ext -> ShowS # show :: MichelsonFailed ext -> String # showList :: [MichelsonFailed ext] -> ShowS # | |
NFData ext => NFData (MichelsonFailed ext) Source # | |
Defined in Morley.Michelson.Interpret rnf :: MichelsonFailed ext -> () # | |
Eq ext => Eq (MichelsonFailed ext) Source # | |
Defined in Morley.Michelson.Interpret (==) :: MichelsonFailed ext -> MichelsonFailed ext -> Bool # (/=) :: MichelsonFailed ext -> MichelsonFailed ext -> Bool # | |
Buildable ext => Buildable (MichelsonFailed ext) Source # | |
Defined in Morley.Michelson.Interpret build :: MichelsonFailed ext -> Doc buildList :: [MichelsonFailed ext] -> Doc |
data MichelsonFailureWithStack ext Source #
Carries a MichelsonFailed
ext
error and the ErrorSrcPos
at which it was raised
Instances
Generic (MichelsonFailureWithStack ext) Source # | |
Defined in Morley.Michelson.Interpret type Rep (MichelsonFailureWithStack ext) :: Type -> Type # from :: MichelsonFailureWithStack ext -> Rep (MichelsonFailureWithStack ext) x # to :: Rep (MichelsonFailureWithStack ext) x -> MichelsonFailureWithStack ext # | |
Show ext => Show (MichelsonFailureWithStack ext) Source # | |
Defined in Morley.Michelson.Interpret showsPrec :: Int -> MichelsonFailureWithStack ext -> ShowS # show :: MichelsonFailureWithStack ext -> String # showList :: [MichelsonFailureWithStack ext] -> ShowS # | |
NFData ext => NFData (MichelsonFailureWithStack ext) Source # | |
Defined in Morley.Michelson.Interpret rnf :: MichelsonFailureWithStack ext -> () # | |
Eq ext => Eq (MichelsonFailureWithStack ext) Source # | |
Defined in Morley.Michelson.Interpret (==) :: MichelsonFailureWithStack ext -> MichelsonFailureWithStack ext -> Bool # (/=) :: MichelsonFailureWithStack ext -> MichelsonFailureWithStack ext -> Bool # | |
Buildable ext => Buildable (MichelsonFailureWithStack ext) Source # | Pretty-printer for
|
Defined in Morley.Michelson.Interpret build :: MichelsonFailureWithStack ext -> Doc buildList :: [MichelsonFailureWithStack ext] -> Doc | |
Monad m => MonadError (MichelsonFailureWithStack Void) (EvalOpT m) Source # | |
Defined in Morley.Michelson.Interpret throwError :: MichelsonFailureWithStack Void -> EvalOpT m a # catchError :: EvalOpT m a -> (MichelsonFailureWithStack Void -> EvalOpT m a) -> EvalOpT m a # | |
type Rep (MichelsonFailureWithStack ext) Source # | |
Defined in Morley.Michelson.Interpret type Rep (MichelsonFailureWithStack ext) = D1 ('MetaData "MichelsonFailureWithStack" "Morley.Michelson.Interpret" "morley-1.20.0-inplace" 'False) (C1 ('MetaCons "MichelsonFailureWithStack" 'PrefixI 'True) (S1 ('MetaSel ('Just "mfwsFailed") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 (MichelsonFailed ext)) :*: S1 ('MetaSel ('Just "mfwsErrorSrcPos") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 ErrorSrcPos))) |
newtype RemainingSteps Source #
Instances
data SomeItStack meta where Source #
SomeItStack :: ExtInstr inp -> Rec (StkEl meta) inp -> SomeItStack meta |
newtype MorleyLogs Source #
Morley logs appearing as interpreter result.
MorleyLogs | |
|
Instances
newtype MorleyLogsBuilder Source #
Morley logs accumulator, for incremental building.
Instances
interpret :: Contract cp st -> EntrypointCallT cp arg -> Value arg -> Value st -> GlobalCounter -> BigMapCounter -> ContractEnv -> ContractReturn st Source #
interpretInstr :: ContractEnv -> Instr inp out -> Rec Value inp -> Either (MichelsonFailureWithStack Void) (Rec Value out) Source #
Interpret an instruction in vacuum, putting no extra constraints on its execution.
Mostly for testing purposes.
interpretInstrAnnotated :: ContractEnv -> Instr inp out -> Rec Value inp -> Either (MichelsonFailureWithStack Void) (Rec (StkEl NoStkElMeta) out) Source #
Interpret an instruction in vacuum, putting no extra constraints on its execution while preserving its annotations.
Mostly for testing purposes.
type InterpretReturn ty = RunEvalOpReturn (Value ty) Source #
Result of interpretView
. A version of RunEvalOpReturn
specialized to Value
.
type ContractReturn st = InterpretReturn (ContractOut1 st) Source #
Result of interpret
. A version of InterpretReturn
specialized to ContractOut1
.
type RunEvalOpReturn a = ResultStateLogs (Either (MichelsonFailureWithStack Void) a) Source #
Result of runEvalOp
. Essentially, return value (possibly failing), state
and logs.
data ResultStateLogs res Source #
ResultStateLogs | |
|
Instances
mkInitStack :: Value param -> Value st -> Rec Value (ContractInp param st) Source #
data InterpretError ext Source #
Instances
type InterpretResult ty = ResultStateLogs (Value ty) Source #
Pure result of an interpretation, i.e. return value, final interpreter state and execution logs.
type ContractResult ty = InterpretResult (ContractOut1 ty) Source #
Pure result of contract interpretation. A specialized version of
InterpretResult
.
extractValOps :: Value (ContractOut1 st) -> ([Operation], Value st) Source #
Extract list of operations from ContractOut1
Value
.
type EvalM' ext m = (MonadReader (ContractEnv' m) m, InterpreterStateMonad m, MonadWriter MorleyLogsBuilder m, MonadError (MichelsonFailureWithStack ext) m) Source #
class Monad m => InterpreterStateMonad m where Source #
Nothing
getInterpreterState :: m InterpreterState Source #
putInterpreterState :: InterpreterState -> m () Source #
stateInterpreterState :: (InterpreterState -> (a, InterpreterState)) -> m a Source #
modifyInterpreterState :: (InterpreterState -> InterpreterState) -> m () Source #
Instances
Represents a value on the stack. Aside from the value itself, it contains
arbitrary user-defined metadata. The metadata in question is defined by
StkElMeta
type class, the interpreter doesn't know anything about it.
The metadata should not be copied between different stack elements, the only
case where it can be copied is when the stack element is copied in its
entirety, i.e. when running instructions like DUP
.
To create a new StkEl
from a value, mkStkEl
should always be used. For
duplicated stack elements, mkDuplicateStkEl
should be used instead, to
still give the user an option to override metadata for the duplicated
element.
The data constructor should almost never be used by itself.
data NoStkElMeta t Source #
Default metadata that does nothing.
Instances
Applicative m => StkElMeta (NoStkElMeta :: T -> Type) m Source # | |
Defined in Morley.Michelson.Interpret mkStkElMeta :: forall (t :: T). Maybe (NoStkElMeta t) -> Value t -> m (NoStkElMeta t) Source # | |
Show (NoStkElMeta t) Source # | |
Defined in Morley.Michelson.Interpret showsPrec :: Int -> NoStkElMeta t -> ShowS # show :: NoStkElMeta t -> String # showList :: [NoStkElMeta t] -> ShowS # | |
Eq (NoStkElMeta t) Source # | |
Defined in Morley.Michelson.Interpret (==) :: NoStkElMeta t -> NoStkElMeta t -> Bool # (/=) :: NoStkElMeta t -> NoStkElMeta t -> Bool # |
type InstrRunner meta m = forall inp out. Instr inp out -> Rec (StkEl meta) inp -> m (Rec (StkEl meta) out) Source #
runInstr :: forall ext meta m. (StkElMeta meta m, EvalM' ext m) => InstrRunner meta m Source #
Function to change amount of remaining steps stored in State monad.
runInstrNoGas :: EvalM m => InstrRunner NoStkElMeta m Source #
runUnpack :: forall t. UnpackedValScope t => ByteString -> Either UnpackError (Value t) Source #
Unpacks given raw data into a typed value.
Views
data ViewLookupError Source #
Instances
Show ViewLookupError Source # | |
Defined in Morley.Michelson.Interpret showsPrec :: Int -> ViewLookupError -> ShowS # show :: ViewLookupError -> String # showList :: [ViewLookupError] -> ShowS # | |
Buildable ViewLookupError Source # | |
Defined in Morley.Michelson.Interpret build :: ViewLookupError -> Doc buildList :: [ViewLookupError] -> Doc |
interpretView :: View arg st ret -> Value st -> Value arg -> ContractEnv -> InterpreterState -> InterpretReturn ret Source #
Interpret a contract's view for given ContractEnv
and initial
InterpreterState
. It is assumed ContractEnv
is suitable for the view
call, that is, the view is executed exactly in the env that's passed here.
getViewByName :: Contract cp st -> ViewName -> Either ViewLookupError (SomeView st) Source #
Attempt to find a view with a given name in a given contract.
getViewByNameAndType :: forall arg ret cp st. (SingI arg, SingI ret) => Contract cp st -> ViewName -> Either ViewLookupError (View arg st ret) Source #
Attempt to find a view with a given name and given type in a given contract.
Internals
handleReturn :: InterpretReturn res -> Either (InterpretError Void) (ResultStateLogs (Value res)) Source #
On failure, attach logs to failure, but throw away the final state.
runEvalOp :: EvalOp a -> ContractEnv -> InterpreterState -> RunEvalOpReturn a Source #
runInstrImpl :: forall ext meta m. (EvalM' ext m, StkElMeta meta m) => InstrRunner meta m -> InstrRunner meta m Source #
Function to interpret Michelson instruction(s) against given stack.
The ext
type variable specifies additional exceptions that can be thrown from the inner
runner function (via MichelsonExt
). In Morley, it's set to Void
, but downstream consumers
may use other type here.
:: MonadState BigMapCounter m | |
=> Bool | If true, assign a new ID even if the bigmap already has one. Otherwise, assign IDs only to bigmaps that don't have one yet. |
-> Value t | |
-> m (Value t) |
All big_maps stored in a chain have a globally unique ID.
We use this function to assign a new ID whenever a big_map is created.
mapToStkEl :: forall meta inp m. (Applicative m, StkElMeta meta m) => Rec Value inp -> m (Rec (StkEl meta) inp) Source #
Helper function to convert a record of Value
to StkEl
.
mapToValue :: Rec (StkEl meta) inp -> Rec Value inp Source #
Helper function to convert a record of StkEl
to Value
.
mkStkEl :: forall meta t m. (Applicative m, StkElMeta meta m) => Value t -> m (StkEl meta t) Source #
Make an entirely new StkEl
from a value.
mkDuplicateStkEl :: forall meta t m. (Applicative m, StkElMeta meta m) => StkEl meta t -> m (StkEl meta t) Source #
Make a duplicate StkEl
, constructing metadata via mkStkElMeta
.
runEvalOpT :: Monad m => EvalOpT m a -> ContractEnv' (EvalOpT m) -> InterpreterState -> m (RunEvalOpReturn a) Source #
interpret' :: forall cp st arg m. Monad m => Contract cp st -> EntrypointCallT cp arg -> Value arg -> Value st -> ContractEnv' (EvalOpT m) -> InterpreterState -> m (ContractReturn st) Source #
interpretView' :: forall ret st m arg ext meta. (StkElMeta meta m, EvalM' ext m) => (forall inp out. Instr inp out -> Rec (StkEl meta) inp -> m (Rec (StkEl meta) out)) -> (ContractEnv' m -> ContractEnv' m) -> View arg st ret -> Value st -> Value arg -> m (Value ret) Source #
EvalM
view interpretation helper.
class (forall t. Eq (meta t), forall t. Show (meta t)) => StkElMeta meta m where Source #
Arbitrary stack element metadata that can be constructed in a particular
monad. Interpreter doesn't know anything about metadata, and doesn't try to
do anything with it. mkStkElMeta
describes how to construct metadata for
new stack elements based on its value. When a stack element is duplicated,
specifically with instructions like DUP
, old metadata is passed to
mkStkElMeta
to provide an opportunity to modify it. Implementation is free
to either copy it verbatim or ignore the old and generate new.
See StkEl
documentation for an overview of the motivation and design.
:: Maybe (meta t) | For instructions duplicating the value, this |
-> Value t | The value for the new stack element. |
-> m (meta t) |
How to construct new metadata.
Instances
Applicative m => StkElMeta (NoStkElMeta :: T -> Type) m Source # | |
Defined in Morley.Michelson.Interpret mkStkElMeta :: forall (t :: T). Maybe (NoStkElMeta t) -> Value t -> m (NoStkElMeta t) Source # |
The main interpreter monad transformer. Provides a more convenient way of enriching the interpreter monad without redefining it entirely.
This is a newtype and not a type synonym due to the reader environment, i.e.
ContractEnv
, being parameterized by the interpreter monad.
EvalOpT (ExceptT (MichelsonFailureWithStack Void) (RWST (ContractEnv' (EvalOpT m)) MorleyLogsBuilder InterpreterState m) a) |
Instances
type EvalOp = EvalOpT Identity Source #
The main interpreter monad, used by the higher-level functions like
interpret
and interpretView
.
Downstream consumers which use runInstrImpl
directly may define their own
monad similar to this one, or alternatively use EvalOpT
with the slightly
lower-level functions, e.g. interpret'
and interpretView'
.
Prisms
_MorleyLogs :: Iso' MorleyLogs [Text] Source #