|
6 | 6 | module Pos.Chain.Script
|
7 | 7 | ( Script(..)
|
8 | 8 | , PlutusError(..)
|
9 |
| - |
10 |
| - , txScriptCheck |
11 |
| - |
12 |
| - , parseValidator |
13 |
| - , parseRedeemer |
14 |
| - |
15 |
| - , stdlib |
16 |
| - |
17 |
| - , isKnownScriptVersion |
18 | 9 | ) where
|
19 | 10 |
|
20 |
| -import Universum hiding (lift) |
| 11 | +import Universum |
21 | 12 |
|
22 |
| -import Control.Exception (ArithException (..), ArrayException (..), |
23 |
| - ErrorCall (..), PatternMatchFail (..)) |
24 |
| -import Control.Exception.Safe (Handler (..), SomeException (..), |
25 |
| - catches, displayException) |
26 |
| -import Control.Lens (_Left) |
27 |
| -import Control.Monad.Error.Class (throwError) |
28 |
| -import qualified Data.ByteArray as BA |
29 |
| -import qualified Data.ByteString.Lazy as BSL |
30 |
| -import qualified Data.Set as S |
31 |
| -import qualified Elaboration.Contexts as PL |
32 | 13 | import qualified Formatting.Buildable as Buildable
|
33 |
| -import qualified Interface.Integration as PL |
34 |
| -import qualified Interface.Prelude as PL |
35 |
| -import Language.Haskell.TH.Syntax (Lift (..), runIO) |
36 |
| -import qualified PlutusCore.EvaluatorTypes as PLCore |
37 |
| -import qualified PlutusCore.Program as PL |
38 |
| -import System.IO.Unsafe (unsafePerformIO) |
39 |
| -import qualified Utils.Names as PL |
40 | 14 |
|
41 |
| -import qualified Pos.Binary.Class as Bi |
42 |
| -import Pos.Chain.Txp.TxWitness (TxSigData (..)) |
43 |
| -import Pos.Core.Binary () |
44 | 15 | import Pos.Core.Common (Script (..), ScriptVersion)
|
45 |
| -import Pos.Core.Script () |
46 |
| - |
47 |
| -{- NOTE |
48 |
| -
|
49 |
| -Scripts are versioned. The current version is 0. All functions below work |
50 |
| -with version 0 scripts. |
51 |
| -
|
52 |
| -Here's what would lead to script version increment: |
53 |
| - * changing serialization in any way |
54 |
| - * adding anything to the stdlib |
55 |
| --} |
56 | 16 |
|
57 |
| -isKnownScriptVersion :: ScriptVersion -> Bool |
58 |
| -isKnownScriptVersion v = v == 0 |
59 |
| - |
60 |
| --- | Post-process loaded program to remove stdlib references that were added |
61 |
| --- to the environment by 'loadValidator' or 'loadRedeemer'. |
62 |
| -stripStdlib :: PL.Program -> PL.Program |
63 |
| -stripStdlib (PL.Program xs) = PL.Program (filter (not . std) xs) |
64 |
| - where |
65 |
| - stds = S.fromList (map (PL.unsourced . fst) (PL.definitions stdlib)) |
66 |
| - std (name, _) = PL.unsourced name `elem` stds |
67 |
| - |
68 |
| --- | Parse a script intended to serve as a validator (or “lock”) in a |
69 |
| --- transaction output. |
70 |
| -parseValidator :: Text -> Either String Script |
71 |
| -parseValidator t = do |
72 |
| - scr <- stripStdlib <$> PL.loadValidator stdlib (toString t) |
73 |
| - return Script { |
74 |
| - scrScript = Bi.serialize' scr, |
75 |
| - scrVersion = 0 } |
76 |
| - |
77 |
| --- | Parse a script intended to serve as a redeemer (or “proof”) in a |
78 |
| --- transaction input. |
79 |
| -parseRedeemer :: Text -> Either String Script |
80 |
| -parseRedeemer t = do |
81 |
| - scr <- stripStdlib <$> PL.loadRedeemer stdlib (toString t) |
82 |
| - return Script { |
83 |
| - scrScript = Bi.serialize' scr, |
84 |
| - scrVersion = 0 } |
85 | 17 |
|
86 | 18 | -- | The type for errors that can appear when validating a script-protected
|
87 | 19 | -- transaction.
|
@@ -112,60 +44,3 @@ instance Buildable PlutusError where
|
112 | 44 | build PlutusReturnedFalse =
|
113 | 45 | "script execution resulted in 'failure'"
|
114 | 46 |
|
115 |
| --- | Validate a transaction, given a validator and a redeemer. |
116 |
| -txScriptCheck |
117 |
| - :: TxSigData |
118 |
| - -> Script -- ^ Validator |
119 |
| - -> Script -- ^ Redeemer |
120 |
| - -> Either PlutusError () |
121 |
| -txScriptCheck sigData validator redeemer = case spoon result of |
122 |
| - Left err -> throwError (PlutusException (toText err)) |
123 |
| - Right (Left err) -> throwError err |
124 |
| - Right (Right False) -> throwError PlutusReturnedFalse |
125 |
| - Right (Right True) -> pass |
126 |
| - where |
127 |
| - result :: Either PlutusError Bool |
128 |
| - result = do |
129 |
| - -- TODO: when we support more than one version, complain if versions |
130 |
| - -- don't match |
131 |
| - valScr <- case scrVersion validator of |
132 |
| - 0 -> over _Left PlutusDecodingFailure $ |
133 |
| - Bi.decodeFull' (scrScript validator) |
134 |
| - v -> Left (PlutusUnknownVersion v) |
135 |
| - redScr <- case scrVersion redeemer of |
136 |
| - 0 -> over _Left PlutusDecodingFailure $ |
137 |
| - Bi.decodeFull' (scrScript redeemer) |
138 |
| - v -> Left (PlutusUnknownVersion v) |
139 |
| - (script, env) <- over _Left (PlutusExecutionFailure . toText) $ |
140 |
| - PL.buildValidationScript stdlib valScr redScr |
141 |
| - let txInfo = PLCore.TransactionInfo |
142 |
| - { txHash = BSL.fromStrict . BA.convert $ |
143 |
| - txSigTxHash sigData } |
144 |
| - over _Left (PlutusExecutionFailure . toText) $ |
145 |
| - PL.checkValidationResult txInfo (script, env) |
146 |
| - |
147 |
| -stdlib :: PL.DeclContext |
148 |
| -stdlib = case PL.loadLibrary PL.emptyDeclContext prelude of |
149 |
| - Right x -> x |
150 |
| - Left err -> error $ toText |
151 |
| - ("stdlib: error while parsing Plutus prelude: " ++ err) |
152 |
| - where |
153 |
| - prelude = $(lift . toString =<< runIO PL.preludeString) |
154 |
| - |
155 |
| ----------------------------------------------------------------------------- |
156 |
| --- Error catching |
157 |
| ----------------------------------------------------------------------------- |
158 |
| - |
159 |
| -{-# INLINEABLE defaultHandles #-} |
160 |
| -defaultHandles :: [Handler IO (Either String a)] |
161 |
| -defaultHandles = |
162 |
| - [ Handler $ \(x :: ArithException) -> return (Left (displayException x)) |
163 |
| - , Handler $ \(x :: ArrayException) -> return (Left (displayException x)) |
164 |
| - , Handler $ \(x :: ErrorCall) -> return (Left (displayException x)) |
165 |
| - , Handler $ \(x :: PatternMatchFail) -> return (Left (displayException x)) |
166 |
| - , Handler $ \(x :: SomeException) -> throwM x ] |
167 |
| - |
168 |
| -{-# INLINE spoon #-} |
169 |
| -spoon :: NFData a => a -> Either String a |
170 |
| -spoon a = unsafePerformIO $ |
171 |
| - deepseq a (Right `fmap` return a) `catches` defaultHandles |
0 commit comments