From 9eb21f6919b9ae3f4c2bf01adc344b4da55780a8 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 02:12:37 -0600 Subject: [PATCH 01/67] Enforcing root ns test --- .../Pact/Core/Test/StaticErrorTests.hs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 8dd3c4746..d092510fd 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -540,7 +540,25 @@ desugarTests = executionTests :: [(String, PactErrorI -> Bool, Text)] executionTests = - [ ("import_unknown_module_namespaced_self_nons", isExecutionError _ModuleDoesNotExist, [text| + [ ("enforce_ns_install_module", isExecutionError _NamespaceInstallError, [text| + (module m g (defcap g () true) + (defun manage (ns guard) true) + ) + (env-namespace-policy false (manage)) + + (module another ag (defcap ag () true)) + |]) + , ("enforce_ns_install_module", isExecutionError _NamespaceInstallError, [text| + (module m g (defcap g () true) + (defun manage (ns guard) true) + ) + (env-namespace-policy false (manage)) + + (interface iface + (defun foo:string ()) + ) + |]) + , ("import_unknown_module_namespaced_self_nons", isExecutionError _ModuleDoesNotExist, [text| (env-data { "carl-keys" : ["carl"], "carl.carl-keys": ["carl"] }) (env-keys ["carl"]) From 75a03f3499a0ce74f6ae77892e95ed49c65d1199 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 13:28:55 -0600 Subject: [PATCH 02/67] Interface upgrade check --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index d092510fd..6b5c7aa51 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -558,6 +558,15 @@ executionTests = (defun foo:string ()) ) |]) + , ("interface_upgrade", isExecutionError _CannotUpgradeInterface, [text| + (interface iface + (defun foo:string ()) + ) + (interface iface + (defun foo:string ()) + (defun bar:string ()) + ) + |]) , ("import_unknown_module_namespaced_self_nons", isExecutionError _ModuleDoesNotExist, [text| (env-data { "carl-keys" : ["carl"], "carl.carl-keys": ["carl"] }) (env-keys ["carl"]) From 9b5b4ba429f8fa6d35e82dfb65b480a92c4ec5c9 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 13:59:56 -0600 Subject: [PATCH 03/67] Some module expectation tests --- .../Pact/Core/Test/StaticErrorTests.hs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 6b5c7aa51..2c336a7b1 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -567,6 +567,26 @@ executionTests = (defun bar:string ()) ) |]) + , ("interface_module", isExecutionError _ExpectedModule, [text| + (interface iface + (defun foo:string ()) + ) + (module iface g (defcap g () true)) + |]) + , ("modref_namespace", isExecutionError _ExpectedModule, [text| + (begin-tx) + (env-data { "carl-keys" : ["carl"], "carl.carl-keys": ["carl"] }) + (env-keys ["carl"]) + + (define-namespace 'carl (read-keyset 'carl-keys) (read-keyset 'carl-keys)) + (namespace 'carl) + (interface iface + (defun foo:string ()) + ) + (commit-tx) + + carl.iface + |]) , ("import_unknown_module_namespaced_self_nons", isExecutionError _ModuleDoesNotExist, [text| (env-data { "carl-keys" : ["carl"], "carl.carl-keys": ["carl"] }) (env-keys ["carl"]) From b4e44545a731de41cb90f082f832221d5fef1327 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 14:38:25 -0600 Subject: [PATCH 04/67] Express `getModule{,Data}` in terms of the corresponding `lookup` functions --- pact-core/Pact/Core/Environment/Utils.hs | 40 ++++-------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/pact-core/Pact/Core/Environment/Utils.hs b/pact-core/Pact/Core/Environment/Utils.hs index 2cd24297a..e0b5ab16a 100644 --- a/pact-core/Pact/Core/Environment/Utils.hs +++ b/pact-core/Pact/Core/Environment/Utils.hs @@ -125,43 +125,15 @@ lookupModuleData info pdb mn = -- | getModuleData, but only for modules, no interfaces getModule :: (MonadEval b i m) => i -> PactDb b i -> ModuleName -> m (EvalModule b i) -getModule info pdb mn = - useEvalState (esLoaded . loModules . at mn) >>= \case - Just (ModuleData md _) -> pure md - Just (InterfaceData _ _) -> - throwExecutionError info (ExpectedModule mn) - Nothing -> do - liftDbFunction info (_pdbRead pdb DModules mn) >>= \case - Just mdata@(ModuleData md deps) -> do - let newLoaded = M.fromList $ toFqDep mn (_mHash md) <$> _mDefs md - (esLoaded . loAllLoaded) %== M.union newLoaded . M.union deps - (esLoaded . loModules) %== M.insert mn mdata - pure md - Just (InterfaceData _ _) -> - throwExecutionError info (ExpectedModule mn) - Nothing -> - throwExecutionError info (ModuleDoesNotExist mn) +getModule info pdb mn = lookupModule info pdb mn >>= \case + Just md -> pure md + Nothing -> throwExecutionError info (ModuleDoesNotExist mn) -- | Get or load a module or interface based on the module name getModuleData :: (MonadEval b i m) => i -> PactDb b i -> ModuleName -> m (ModuleData b i) -getModuleData info pdb mn = - useEvalState (esLoaded . loModules . at mn) >>= \case - Just md -> pure md - Nothing -> do - liftDbFunction info (_pdbRead pdb DModules mn) >>= \case - Just mdata@(ModuleData md deps) -> do - let newLoaded = M.fromList $ toFqDep mn (_mHash md) <$> _mDefs md - (esLoaded . loAllLoaded) %== M.union newLoaded . M.union deps - (esLoaded . loModules) %== M.insert mn mdata - pure mdata - Just ifdata@(InterfaceData iface deps) -> do - let mdefs = mapMaybe ifDefToDef (_ifDefns iface) - let newLoaded = M.fromList $ toFqDep mn (_ifHash iface) <$> mdefs - (esLoaded . loAllLoaded) %== M.union newLoaded . M.union deps - (esLoaded . loModules) %== M.insert mn ifdata - pure ifdata - Nothing -> - throwExecutionError info (ModuleDoesNotExist mn) +getModuleData info pdb mn = lookupModuleData info pdb mn >>= \case + Just md -> pure md + Nothing -> throwExecutionError info (ModuleDoesNotExist mn) -- | getModuleData, but only for modules, no interfaces getModuleMember :: (MonadEval b i m) => i -> PactDb b i -> QualifiedName -> m (EvalDef b i) From 961fd8543ea8fb3aae8b38aa94c0ece301fcaa67 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 15:37:49 -0600 Subject: [PATCH 05/67] Comment fixup --- pact-core/Pact/Core/Environment/Utils.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pact-core/Pact/Core/Environment/Utils.hs b/pact-core/Pact/Core/Environment/Utils.hs index e0b5ab16a..ce4796346 100644 --- a/pact-core/Pact/Core/Environment/Utils.hs +++ b/pact-core/Pact/Core/Environment/Utils.hs @@ -135,7 +135,7 @@ getModuleData info pdb mn = lookupModuleData info pdb mn >>= \case Just md -> pure md Nothing -> throwExecutionError info (ModuleDoesNotExist mn) --- | getModuleData, but only for modules, no interfaces +-- | Returns a module member, but only for modules, no interfaces getModuleMember :: (MonadEval b i m) => i -> PactDb b i -> QualifiedName -> m (EvalDef b i) getModuleMember info pdb (QualifiedName qn mn) = do md <- getModule info pdb mn From 318702a1fd878e1f35886479832585644af22ac1 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 16:58:19 -0600 Subject: [PATCH 06/67] Environment.Utils covered --- .../Pact/Core/Test/StaticErrorTests.hs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 2c336a7b1..fc889889d 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -548,7 +548,7 @@ executionTests = (module another ag (defcap ag () true)) |]) - , ("enforce_ns_install_module", isExecutionError _NamespaceInstallError, [text| + , ("enforce_ns_install_interface", isExecutionError _NamespaceInstallError, [text| (module m g (defcap g () true) (defun manage (ns guard) true) ) @@ -558,6 +558,18 @@ executionTests = (defun foo:string ()) ) |]) + , ("enforce_ns_define_namespace", isExecutionError _DefineNamespaceError, [text| + (module m g (defcap g () true) + (defun manage (ns guard) false) + ) + (env-namespace-policy false (manage)) + + (env-data { "carl-keys" : ["carl"], "carl.carl-keys": ["carl"] }) + (env-keys ["carl"]) + + (define-namespace 'carl (read-keyset 'carl-keys) (read-keyset 'carl-keys)) + (namespace 'carl) + |]) , ("interface_upgrade", isExecutionError _CannotUpgradeInterface, [text| (interface iface (defun foo:string ()) @@ -597,6 +609,14 @@ executionTests = (use m) ) |]) + , ("get_module_unknown", isExecutionError _ModuleDoesNotExist, [text| + (describe-module 'nonexistent) + |]) + + , ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| + (module m g (defcap g () true)) + (env-namespace-policy false (m.g)) + |]) ] tests :: TestTree From 8922cad22b43a82ba6bb78370e10132f7a12f477 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 17:01:24 -0600 Subject: [PATCH 07/67] ConstEval covered --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index fc889889d..3c926a6b5 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -612,6 +612,16 @@ executionTests = , ("get_module_unknown", isExecutionError _ModuleDoesNotExist, [text| (describe-module 'nonexistent) |]) + , ("defconst_not_a_value_module", isExecutionError _ConstIsNotAPactValue, [text| + (module m g (defcap g () true) + (defconst not-a-value (lambda (x) x)) + ) + |]) + , ("defconst_not_a_value_iface", isExecutionError _ConstIsNotAPactValue, [text| + (interface iface + (defconst not-a-value (lambda (x) x)) + ) + |]) , ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) From b72338facf8ad51c1c20578cbffc8e0930af9537 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 20 Dec 2023 17:24:12 -0600 Subject: [PATCH 08/67] Some more keys tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 3c926a6b5..c438ec429 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -612,6 +612,20 @@ executionTests = , ("get_module_unknown", isExecutionError _ModuleDoesNotExist, [text| (describe-module 'nonexistent) |]) + , ("module_gov_keyset_nonexistent", isExecutionError _NoSuchKeySet, [text| + (module m 'nonexistent (defun f () true)) + |]) + , ("module_gov_keyset_empty", isExecutionError _ModuleGovernanceFailure, [text| + (module m "" (defun f () true)) + |]) + , ("module_gov_keyset_not_in_sigs", isExecutionError _ModuleGovernanceFailure, [text| + (env-data { "kall": ["a" "b" "c"], "kadmin": ["admin"] }) + (define-keyset 'kall) + (define-keyset 'kadmin) + + (env-keys ["admin"]) + (module m 'kall (defun f () true)) + |]) , ("defconst_not_a_value_module", isExecutionError _ConstIsNotAPactValue, [text| (module m g (defcap g () true) (defconst not-a-value (lambda (x) x)) From a82f11e4c47c453d2f590b7dc6a5d161b35161ab Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 21 Dec 2023 13:26:34 -0600 Subject: [PATCH 09/67] Modref without interfaces test --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index c438ec429..0a3ef989c 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -637,6 +637,12 @@ executionTests = ) |]) + -- CEK errors + , ("modref_no_ns", isExecutionError _ModRefNotRefined, [text| + (module m g (defcap g () true)) + m + |]) + , ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) (env-namespace-policy false (m.g)) From 4c2f874368f217559796cf9758237a0b7d21e064 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 21 Dec 2023 15:58:18 -0600 Subject: [PATCH 10/67] Leave some comments about invariant failures --- pact-core/Pact/Core/IR/Eval/CEK.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index 07f41ef9a..f73a6e95e 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -120,8 +120,13 @@ evalCEK cont handler env (Var n info) = do returnCEKValue cont handler (VClosure (CT clo)) Just d -> throwExecutionError info (InvalidDefKind (defKind d) "in var position") + -- TODO ^ shall this be an invariant failure? + -- apparently this can never happen because `renameTerm` checks for variable top-level variable occurrences, + -- erroring out with `InvalidDefInTermVariable` if it's violated. + -- And, the execution can't change that invariant once it's established during desugar. Nothing -> throwExecutionError info (NameNotInScope (FullyQualifiedName mname (_nName n) mh)) + -- TODO ^ ditto, `renameTerm` apparently always fails in this case as well NModRef m ifs -> case ifs of [x] -> returnCEKValue cont handler (VModRef (ModRef m ifs (Just (S.singleton x)))) [] -> throwExecutionError info (ModRefNotRefined (_nName n)) @@ -227,6 +232,8 @@ mkDefunClosure d mn e = case _dfunTerm d of pure (Closure (_dfunName d) mn NullaryClosure 0 body (_dfunRType d) e i) _ -> throwExecutionError (_dfunInfo d) (DefIsNotClosure (_dfunName d)) + -- TODO ^ apparently invariant failure, since the parser ensures defun has a form of `(defun ( args ) body)`, + -- and desugar converts that into a Lam or Nullary. mkDefPactClosure :: (MonadEval b i m) From 33f0bc215ec204bd95bf84f3f309c7ea3ccba866 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 21 Dec 2023 16:43:26 -0600 Subject: [PATCH 11/67] Fix some typos in error names --- pact-core/Pact/Core/Errors.hs | 20 ++++++++++---------- pact-core/Pact/Core/IR/Eval/CEK.hs | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pact-core/Pact/Core/Errors.hs b/pact-core/Pact/Core/Errors.hs index 485245ea3..15f592655 100644 --- a/pact-core/Pact/Core/Errors.hs +++ b/pact-core/Pact/Core/Errors.hs @@ -257,7 +257,7 @@ data EvalError -- ^ No Yield available in DefPactStep | InvalidDefPactStepSupplied DefPactStep DefPactExec -- ^ Supplied DefPactStep requests an invalid step - | DefPactIdMissmatch DefPactId DefPactId + | DefPactIdMismatch DefPactId DefPactId -- ^ Requested PactId does not match context PactId | CCDefPactContinuationError DefPactStep DefPactExec DefPactExec -- ^ Crosschain DefPact contunation must be at least 2 steps before CC continuation step @@ -266,9 +266,9 @@ data EvalError -- ^ No previouse DefPact execution could be found in the environment or database | DefPactAlreadyCompleted DefPactStep -- ^ DefPact already completed - | NestedDefPactParentStepCountMissmatch DefPactId Int Int + | NestedDefPactParentStepCountMismatch DefPactId Int Int -- ^ Nested DefPact does not match - | NestedDefPactParentRollbackMissmatch DefPactId Bool Bool + | NestedDefPactParentRollbackMismatch DefPactId Bool Bool -- ^ Nested DefPact does not match | NestedDefPactNeverStarted DefPactStep -- ^ Nested DefPact never started at prior step @@ -284,9 +284,9 @@ data EvalError -- ^ DefPactStep is not in the environment | NoDefPactIdAndExecEnvSupplied -- ^ No DefPactId supplied and no DefPactExec found in the environment - | DefPactRollbackMissmatch DefPactStep DefPactExec + | DefPactRollbackMismatch DefPactStep DefPactExec -- ^ DefPact rollback missmatch - | DefPactStepMissmatch DefPactStep DefPactExec + | DefPactStepMismatch DefPactStep DefPactExec -- ^ DefPact missmatch | CannotUpgradeInterface ModuleName -- ^ Interface cannot be upgrade @@ -365,7 +365,7 @@ instance Pretty EvalError where [ "DefPactStep does not match DefPact properties:" , "requested: "<> pretty step , "step count:" <> pretty (_peStepCount pe)] - DefPactIdMissmatch reqId envId -> + DefPactIdMismatch reqId envId -> Pretty.hsep [ "Requested DefPactId:", pretty reqId , "does not match context DefPactId:", pretty envId @@ -375,14 +375,14 @@ instance Pretty EvalError where [ "Crosschain DefPact continuation error:" , "DefPactId:" <> pretty (_psStep pactStep) ] - NestedDefPactParentRollbackMissmatch pid rollback parentRollback -> + NestedDefPactParentRollbackMismatch pid rollback parentRollback -> Pretty.hsep [ "Nested DefPact execution failed, parameter missmatch:" , "DefPactId: " <> pretty pid , "Rollback: " <> pretty rollback , "Parent rollback:" <> pretty parentRollback ] - NestedDefPactParentStepCountMissmatch pid stepCount parentStepCount -> + NestedDefPactParentStepCountMismatch pid stepCount parentStepCount -> Pretty.hsep [ "Nested DefPact execution failed, parameter missmatch:" , "PacId: " <> pretty pid @@ -408,13 +408,13 @@ instance Pretty EvalError where ["Step has no rollback:", "DefPactId: " <> pretty (_psDefPactId ps)] DefPactStepNotInEnvironment -> "No DefPactStep in the environment" NoDefPactIdAndExecEnvSupplied -> "No DefPactId or execution environment supplied" - DefPactRollbackMissmatch ps pe -> Pretty.hsep + DefPactRollbackMismatch ps pe -> Pretty.hsep [ "Rollback missmatch in DefPactStep and DefPact exeuction environment:" , "DefPactId: " <> pretty (_psDefPactId ps) , "step rollback: " <> pretty (_psRollback ps) , "DefPactExec rollback: " <> pretty (_peStepHasRollback pe) ] - DefPactStepMissmatch ps pe -> Pretty.hsep + DefPactStepMismatch ps pe -> Pretty.hsep [ "Step missmatch in DefPactStep and DefPact exeuction environment:" , "DefPactId: " <> pretty (_psDefPactId ps) , "step: " <> pretty (_psStep ps) diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index f73a6e95e..bef70039f 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -345,10 +345,10 @@ applyNestedPact i pc ps cont handler cenv = useEvalState esDefPactExec >>= \case isRollback = hasRollback step when (stepCount /= _peStepCount pe) $ - throwExecutionError i (NestedDefPactParentStepCountMissmatch (_peDefPactId pe) stepCount (_peStepCount pe)) + throwExecutionError i (NestedDefPactParentStepCountMismatch (_peDefPactId pe) stepCount (_peStepCount pe)) when (isRollback /= _peStepHasRollback pe) $ - throwExecutionError i (NestedDefPactParentRollbackMissmatch (_peDefPactId pe) isRollback (_peStepHasRollback pe)) + throwExecutionError i (NestedDefPactParentRollbackMismatch (_peDefPactId pe) isRollback (_peStepHasRollback pe)) exec <- case pe ^. peNestedDefPactExec . at (_psDefPactId ps) of Nothing @@ -424,16 +424,16 @@ resumePact i cont handler env crossChainContinuation = viewEvalEnv eeDefPactStep --resumeDefPactExec :: MonadEval b i m => DefPactExec -> m (EvalResult b i m) resumeDefPactExec pe = do when (_psDefPactId ps /= _peDefPactId pe) $ - throwExecutionError i (DefPactIdMissmatch (_psDefPactId ps) (_peDefPactId pe)) + throwExecutionError i (DefPactIdMismatch (_psDefPactId ps) (_peDefPactId pe)) when (_psStep ps < 0 || _psStep ps >= _peStepCount pe) $ throwExecutionError i (InvalidDefPactStepSupplied ps pe) if _psRollback ps then when (_psStep ps /= _peStep pe) $ - throwExecutionError i (DefPactRollbackMissmatch ps pe) + throwExecutionError i (DefPactRollbackMismatch ps pe) else when (_psStep ps /= succ (_peStep pe)) $ - throwExecutionError i (DefPactStepMissmatch ps pe) + throwExecutionError i (DefPactStepMismatch ps pe) let pc = view peContinuation pe args = VPactValue <$> _pcArgs pc From 81b156b11e233bd99c2c2c660210e1f1148836f5 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 21 Dec 2023 17:16:33 -0600 Subject: [PATCH 12/67] Some defpact failure tests --- .../Pact/Core/Test/StaticErrorTests.hs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 0a3ef989c..8356c33ea 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -643,6 +643,78 @@ executionTests = m |]) + , ("defpact_not_init", isExecutionError _NoDefPactIdAndExecEnvSupplied, [text| + (module m g (defcap g () true)) + (continue-pact 1) + |]) + , ("defpact_continuing_completed", isExecutionError _DefPactAlreadyCompleted, [text| + (module m g (defcap g () true) + (defpact p:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + ) + + (p) + (continue-pact 1) + (continue-pact 2) + (continue-pact 3) + |]) + , ("defpact_continuing_completed_samestep", isExecutionError _DefPactAlreadyCompleted, [text| + (module m g (defcap g () true) + (defpact p:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + ) + + (p) + (continue-pact 1) + (continue-pact 2) + (continue-pact 2) + |]) + , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactAlreadyCompleted, [text| + (module m g (defcap g () true) + (defpact p:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + ) + + (p) + (continue-pact 1) + (continue-pact 2) + (continue-pact 1) + |]) + , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactStepMismatch, [text| + (module m g (defcap g () true) + (defpact p:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + ) + + (p) + (continue-pact 0) + |]) + , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactStepMismatch, [text| + (module m g (defcap g () true) + (defpact p:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + ) + + (p) + (continue-pact 1) + (continue-pact 1) + |]) + , ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) (env-namespace-policy false (m.g)) From 2bffabeb824e66248abb4b3f91e10d4ea84fa31d Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 21 Dec 2023 17:18:29 -0600 Subject: [PATCH 13/67] Don't repeat the simple defpact --- .../Pact/Core/Test/StaticErrorTests.hs | 46 ++++--------------- 1 file changed, 9 insertions(+), 37 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 8356c33ea..9f662d0b7 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -647,75 +647,47 @@ executionTests = (module m g (defcap g () true)) (continue-pact 1) |]) - , ("defpact_continuing_completed", isExecutionError _DefPactAlreadyCompleted, [text| - (module m g (defcap g () true) + ] <> let simpleDefpact = [text|(module m g (defcap g () true) (defpact p:string () (step "hello1") (step "hello2") (step "hello3") ) - ) - + )|] in + [ ("defpact_continuing_completed", isExecutionError _DefPactAlreadyCompleted, [text| + $simpleDefpact (p) (continue-pact 1) (continue-pact 2) (continue-pact 3) |]) , ("defpact_continuing_completed_samestep", isExecutionError _DefPactAlreadyCompleted, [text| - (module m g (defcap g () true) - (defpact p:string () - (step "hello1") - (step "hello2") - (step "hello3") - ) - ) - + $simpleDefpact (p) (continue-pact 1) (continue-pact 2) (continue-pact 2) |]) , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactAlreadyCompleted, [text| - (module m g (defcap g () true) - (defpact p:string () - (step "hello1") - (step "hello2") - (step "hello3") - ) - ) - + $simpleDefpact (p) (continue-pact 1) (continue-pact 2) (continue-pact 1) |]) , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactStepMismatch, [text| - (module m g (defcap g () true) - (defpact p:string () - (step "hello1") - (step "hello2") - (step "hello3") - ) - ) - + $simpleDefpact (p) (continue-pact 0) |]) , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactStepMismatch, [text| - (module m g (defcap g () true) - (defpact p:string () - (step "hello1") - (step "hello2") - (step "hello3") - ) - ) - + $simpleDefpact (p) (continue-pact 1) (continue-pact 1) |]) - , ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| + ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) (env-namespace-policy false (m.g)) |]) From a30353852101ec17829d0f625003b66c3778c313 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 21 Dec 2023 17:20:27 -0600 Subject: [PATCH 14/67] Fixup test labels --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 9f662d0b7..17bfa5683 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -675,12 +675,12 @@ executionTests = (continue-pact 2) (continue-pact 1) |]) - , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactStepMismatch, [text| + , ("defpact_continuing_firststep", isExecutionError _DefPactStepMismatch, [text| $simpleDefpact (p) (continue-pact 0) |]) - , ("defpact_continuing_completed_prevstep", isExecutionError _DefPactStepMismatch, [text| + , ("defpact_continuing_incomplete_samestep", isExecutionError _DefPactStepMismatch, [text| $simpleDefpact (p) (continue-pact 1) From ee0833212e465dcf64d8c0fa32fda5c61a9069d1 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 21 Dec 2023 17:23:48 -0600 Subject: [PATCH 15/67] Couple more defpact failure tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 17bfa5683..de759af9f 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -686,6 +686,16 @@ executionTests = (continue-pact 1) (continue-pact 1) |]) + , ("defpact_continuing_incomplete_badstep", isExecutionError _InvalidDefPactStepSupplied, [text| + $simpleDefpact + (p) + (continue-pact 100) + |]) + , ("defpact_continuing_incomplete_negstep", isExecutionError _InvalidDefPactStepSupplied, [text| + $simpleDefpact + (p) + (continue-pact (- 1)) + |]) ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) From 387f40fd7e4974708d7fd40d46d8047484c4a527 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Mon, 25 Dec 2023 13:34:47 -0600 Subject: [PATCH 16/67] Add some comments about what's been tested --- pact-core/Pact/Core/Environment/Utils.hs | 1 + pact-core/Pact/Core/IR/Eval/CEK.hs | 2 +- pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pact-core/Pact/Core/Environment/Utils.hs b/pact-core/Pact/Core/Environment/Utils.hs index ce4796346..482bc076e 100644 --- a/pact-core/Pact/Core/Environment/Utils.hs +++ b/pact-core/Pact/Core/Environment/Utils.hs @@ -144,6 +144,7 @@ getModuleMember info pdb (QualifiedName qn mn) = do Nothing -> do let fqn = FullyQualifiedName mn qn (_mHash md) throwExecutionError info (NameNotInScope fqn) + -- TODO ^ failed to find a test mangleNamespace :: (MonadEvalState b i m) => ModuleName -> m ModuleName diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index bef70039f..74dd3088e 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -395,7 +395,7 @@ resumePact -> Maybe DefPactExec -> m (EvalResult b i m) resumePact i cont handler env crossChainContinuation = viewEvalEnv eeDefPactStep >>= \case - Nothing -> throwExecutionError i DefPactStepNotInEnvironment + Nothing -> throwExecutionError i DefPactStepNotInEnvironment -- <- TODO apparently can't happen, `continuePact` ensures that Just ps -> do pdb <- viewEvalEnv eePactDb dbState <- liftDbFunction i (readDefPacts pdb (_psDefPactId ps)) diff --git a/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs b/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs index 96242513c..392b1ac2a 100644 --- a/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs +++ b/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs @@ -172,6 +172,7 @@ argsError -> m a argsError info b args = throwExecutionError info (NativeArgumentsError (builtinName b) (toArgTypeError <$> args)) + -- NOTE ^ this is already tested asString From 4d3c8ea0cf1f4e4f5a0da5c1b58e3b0a580e6f3e Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Mon, 25 Dec 2023 16:45:57 -0600 Subject: [PATCH 17/67] Add a comment about potential more test --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index de759af9f..fc3b83b20 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -696,6 +696,7 @@ executionTests = (p) (continue-pact (- 1)) |]) + -- TODO (-1) here errors out ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) From 8f5af5735d96c8f5d7427394c952b5bea104db9d Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 4 Jan 2024 11:49:43 -0600 Subject: [PATCH 18/67] Test nested defpact execution failure modes --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index fc3b83b20..72fc4bc29 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -695,8 +695,18 @@ executionTests = $simpleDefpact (p) (continue-pact (- 1)) + |]) -- TODO (-1) here errors out + , ("defpact_same_nested", isExecutionError _MultipleOrNestedDefPactExecFound, [text| + $simpleDefpact + (p) + (p) + |]) + , ("defpact_same_nested_inprogress", isExecutionError _MultipleOrNestedDefPactExecFound, [text| + $simpleDefpact + (p) + (continue-pact 1) + (p) |]) - -- TODO (-1) here errors out ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) From 123873ec70905086f7836a1e3955dab9243e4a4a Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 4 Jan 2024 14:37:23 -0600 Subject: [PATCH 19/67] Some (no)rollback tests --- .../Pact/Core/Test/StaticErrorTests.hs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 72fc4bc29..91b925a38 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -647,7 +647,8 @@ executionTests = (module m g (defcap g () true)) (continue-pact 1) |]) - ] <> let simpleDefpact = [text|(module m g (defcap g () true) + ] <> let simpleDefpact = [text| + (module m g (defcap g () true) (defpact p:string () (step "hello1") (step "hello2") @@ -707,8 +708,27 @@ executionTests = (continue-pact 1) (p) |]) - - ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| + , ("defpact_continuing_norollback_samestep", isExecutionError _DefPactStepHasNoRollback, [text| + $simpleDefpact + (p) + (continue-pact 1) + (continue-pact 1 true) + |]) + , ("defpact_continuing_norollback_diffstep", isExecutionError _DefPactRollbackMismatch, [text| + $simpleDefpact + (p) + (continue-pact 1) + (continue-pact 2 true) + |]) + , ("defpact_continuing_rollback_final", isExecutionError _DefPactAlreadyCompleted, [text| + $simpleDefpact + (p) + (continue-pact 1) + (continue-pact 2) + (continue-pact 2 true) + |]) + ] <> + [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) (env-namespace-policy false (m.g)) |]) From 8ab0f9bdddea1d8a60bcb43cf983fbac19ad0292 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 4 Jan 2024 14:58:23 -0600 Subject: [PATCH 20/67] Nested step count mismatch test is easy --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 91b925a38..41e004409 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -728,6 +728,20 @@ executionTests = (continue-pact 2 true) |]) ] <> + [ ("defpact_nested_stepcount", isExecutionError _NestedDefPactParentStepCountMismatch, [text| + (module m g (defcap g () true) + (defpact n:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + (defpact p:string () + (step (n)) + ) + ) + (p) + |]) + ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) (env-namespace-policy false (m.g)) From 79741840e87f9557b9624095db301dfee931d450 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 4 Jan 2024 15:04:44 -0600 Subject: [PATCH 21/67] Test rolling back the very first (unrollable) step too --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 41e004409..e8c612003 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -714,6 +714,11 @@ executionTests = (continue-pact 1) (continue-pact 1 true) |]) + , ("defpact_continuing_norollback_diffstep", isExecutionError _DefPactStepHasNoRollback, [text| + $simpleDefpact + (p) + (continue-pact 0 true) + |]) , ("defpact_continuing_norollback_diffstep", isExecutionError _DefPactRollbackMismatch, [text| $simpleDefpact (p) From 0f1f0de14bc8429b4f199ff4c47e6e1b6922159e Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 5 Jan 2024 12:49:07 -0600 Subject: [PATCH 22/67] One more way to trigger nested evaluation --- .../Pact/Core/Test/StaticErrorTests.hs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index e8c612003..f44c5eb64 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -746,6 +746,38 @@ executionTests = ) (p) |]) + , ("defpact_nested_already_started_before", isExecutionError _MultipleOrNestedDefPactExecFound, [text| + (module m g (defcap g () true) + (defpact n:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + (defpact p:string () + (step (n)) + (step (continue (n))) + (step (continue (n))) + ) + ) + (n) + (p) + |]) + , ("defpact_nested_already_started_after", isExecutionError _MultipleOrNestedDefPactExecFound, [text| + (module m g (defcap g () true) + (defpact n:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + (defpact p:string () + (step (n)) + (step (continue (n))) + (step (continue (n))) + ) + ) + (p) + (n) + |]) ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) From f5af89a59d4d0561c57d1607da4e1f20c50356d6 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 5 Jan 2024 13:40:41 -0600 Subject: [PATCH 23/67] Doing multiple inner steps of a pact might also be erroring --- .../Pact/Core/Test/StaticErrorTests.hs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index f44c5eb64..97cb959b6 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -778,6 +778,23 @@ executionTests = (p) (n) |]) + -- TODO better error type here? v + , ("defpact_nested", isExecutionError _NestedDefPactNeverStarted, [text| + (module m g (defcap g () true) + (defpact n:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + (defpact p:string () + (step (n)) + (step (+ (continue (n)) (continue (n)))) + (step (continue (n))) + ) + ) + (p) + (continue-pact 1) + |]) ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) From 5fd4ba8c14615f06f1eeef694d766b281fa2b031 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 5 Jan 2024 13:58:03 -0600 Subject: [PATCH 24/67] Nested rollback mismatch tests --- .../Pact/Core/Test/StaticErrorTests.hs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 97cb959b6..c1749351b 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -778,6 +778,40 @@ executionTests = (p) (n) |]) + , ("defpact_nested_rollback_mismatch_outer_missing", isExecutionError _NestedDefPactParentRollbackMismatch, [text| + (module m g (defcap g () true) + (defpact n:string () + (step "hello1") + (step-with-rollback "hello2" "bye2") + (step "hello3") + ) + (defpact p:string () + (step (n)) + (step (continue (n))) + (step (continue (n))) + ) + ) + (p) + (continue-pact 1) + (continue-pact 1 true) + |]) + , ("defpact_nested_rollback_mismatch_inner_missing", isExecutionError _NestedDefPactParentRollbackMismatch, [text| + (module m g (defcap g () true) + (defpact n:string () + (step "hello1") + (step "hello2") + (step "hello3") + ) + (defpact p:string () + (step (n)) + (step-with-rollback (continue (n)) "bye-outer") + (step (continue (n))) + ) + ) + (p) + (continue-pact 1) + (continue-pact 1 true) + |]) -- TODO better error type here? v , ("defpact_nested", isExecutionError _NestedDefPactNeverStarted, [text| (module m g (defcap g () true) From 5a19fba2b02e29ccfe6e1efd0dbbd1dc273ec2a7 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 5 Jan 2024 14:52:41 -0600 Subject: [PATCH 25/67] Better test name --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index c1749351b..dfd6213d2 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -813,7 +813,7 @@ executionTests = (continue-pact 1 true) |]) -- TODO better error type here? v - , ("defpact_nested", isExecutionError _NestedDefPactNeverStarted, [text| + , ("defpact_nested_dynamic_step_count_mismatch", isExecutionError _NestedDefPactNeverStarted, [text| (module m g (defcap g () true) (defpact n:string () (step "hello1") From 918536b16aeb614685eebff4e99ae9b68f4ea18c Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Mon, 8 Jan 2024 12:04:41 -0600 Subject: [PATCH 26/67] Ignore a supposed invariant failure --- pact-core/Pact/Core/IR/Eval/CEK.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index 74dd3088e..e9efb8e19 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -458,6 +458,7 @@ nameToFQN info env (Name n nk) = case nk of md <- getModule info (view cePactDb env) (_mrModule mr) pure (FullyQualifiedName (_mrModule mr) dArg (_mHash md)) Just _ -> throwExecutionError info (DynNameIsNotModRef dArg) + -- TODO this ^ is supposedly caught by the typechecker, so it's an invariant error now Nothing -> failInvariant info ("unbound identifier" <> T.pack (show n)) _ -> failInvariant info ("invalid name in fq position" <> T.pack (show n)) From 97cda6ef97f9cfd4305cbab477609a04290ec39b Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Mon, 8 Jan 2024 17:29:08 -0600 Subject: [PATCH 27/67] Some things I just don't understand how to trigger yet --- pact-core/Pact/Core/IR/Eval/CEK.hs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index e9efb8e19..0b7f412dd 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -294,7 +294,7 @@ applyPact i pc ps cont handler cenv nested = useEvalState esDefPactExec >>= \cas -- Check we try to apply the correct pact Step unless (ps ^. psStep < nSteps) $ - throwExecutionError i (DefPactStepNotFound ps nSteps) + throwExecutionError i (DefPactStepNotFound ps nSteps) -- TODO TODO how to trigger this? step <- maybe (failInvariant i "Step not found") pure $ _dpSteps defPact ^? ix (ps ^. psStep) @@ -362,7 +362,7 @@ applyNestedPact i pc ps cont handler cenv = useEvalState esDefPactExec >>= \case , _peNestedDefPactExec = mempty } | otherwise -> - throwExecutionError i (NestedDefPactDoubleExecution ps) + throwExecutionError i (NestedDefPactDoubleExecution ps) -- TODO TODO how to trigger this? Just npe | _psStep ps >= 0 && isRollback && _peStep npe == _psStep ps -> pure (set peStepHasRollback isRollback npe) @@ -401,7 +401,7 @@ resumePact i cont handler env crossChainContinuation = viewEvalEnv eeDefPactStep dbState <- liftDbFunction i (readDefPacts pdb (_psDefPactId ps)) case (dbState, crossChainContinuation) of (Just Nothing, _) -> throwExecutionError i (DefPactAlreadyCompleted ps) - (Nothing, Nothing) -> throwExecutionError i (NoPreviousDefPactExecutionFound ps) + (Nothing, Nothing) -> throwExecutionError i (NoPreviousDefPactExecutionFound ps) -- TODO TODO how to trigger this? (Nothing, Just ccExec) -> resumeDefPactExec ccExec (Just (Just dbExec), Nothing) -> resumeDefPactExec dbExec (Just (Just dbExec), Just ccExec) -> do @@ -413,18 +413,18 @@ resumePact i cont handler env crossChainContinuation = viewEvalEnv eeDefPactStep -- Validate continuation db state when (_peContinuation dbExec /= _peContinuation ccExec) $ - throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) + throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) -- TODO TODO how to trigger this? -- Validate step count against db state when (_peStepCount dbExec /= _peStepCount ccExec) $ - throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) + throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) -- TODO TODO how to trigger this? resumeDefPactExec ccExec where --resumeDefPactExec :: MonadEval b i m => DefPactExec -> m (EvalResult b i m) resumeDefPactExec pe = do when (_psDefPactId ps /= _peDefPactId pe) $ - throwExecutionError i (DefPactIdMismatch (_psDefPactId ps) (_peDefPactId pe)) + throwExecutionError i (DefPactIdMismatch (_psDefPactId ps) (_peDefPactId pe)) -- TODO TODO how to trigger this? when (_psStep ps < 0 || _psStep ps >= _peStepCount pe) $ throwExecutionError i (InvalidDefPactStepSupplied ps pe) @@ -482,7 +482,7 @@ enforceBlessedHashes :: (MonadEval b i m) => i -> EvalModule b i -> ModuleHash - enforceBlessedHashes info md mh | _mHash md == mh = return () | mh `S.member` (_mBlessed md) = return () - | otherwise = throwExecutionError info (HashNotBlessed (_mName md) mh) + | otherwise = throwExecutionError info (HashNotBlessed (_mName md) mh) -- TODO TODO how to trigger this? guardForModuleCall :: (MonadEval b i m) => i -> CEKEnv b i m -> ModuleName -> m () -> m () guardForModuleCall i env currMod onFound = @@ -502,7 +502,7 @@ acquireModuleAdmin i env mdl = do -- *special* use of `evalCap` here to evaluate module governance. evalCap i Mt CEKNoHandler env (CapToken fqn []) (CapBodyC PopCapInvoke) wcapBody >>= \case VError _ _ -> - throwExecutionError i (ModuleGovernanceFailure (_mName mdl)) + throwExecutionError i (ModuleGovernanceFailure (_mName mdl)) -- TODO TODO how to trigger this? EvalValue _ -> do esCaps . csModuleAdmin %== S.insert (_mName mdl) @@ -573,7 +573,7 @@ evalCap info currCont handler env origToken@(CapToken fqn args) modCont contbody cont' = modCont env (Just qualCapToken) (Just (fqctToPactEvent origToken)) contbody currCont installCap info env c' False >>= evalUserManagedCap cont' newLocals capBody Nothing -> - throwExecutionError info (CapNotInstalled fqn) + throwExecutionError info (CapNotInstalled fqn) -- TODO TODO how to trigger this? Just managedCap -> do let cont' = modCont env (Just qualCapToken) (Just (fqctToPactEvent origToken)) contbody currCont evalUserManagedCap cont' newLocals capBody managedCap @@ -590,7 +590,7 @@ evalCap info currCont handler env origToken@(CapToken fqn args) modCont contbody let c' = set ctName fqn c installCap info env c' False >>= evalAutomanagedCap cont' newLocals capBody Nothing -> - throwExecutionError info (CapNotInstalled fqn) + throwExecutionError info (CapNotInstalled fqn) -- TODO TODO how to trigger this? Just managedCap -> evalAutomanagedCap cont' newLocals capBody managedCap -- if b then From 4d9608a3de064101591ba6a296b5898489e831ba Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 9 Jan 2024 13:25:49 -0600 Subject: [PATCH 28/67] Yay figurd out HashNotBlessed scenario --- .../Pact/Core/Test/StaticErrorTests.hs | 20 +++++++++++++++++++ pact-core/Pact/Core/IR/Eval/CEK.hs | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index dfd6213d2..39ff64aa8 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -834,6 +834,26 @@ executionTests = (module m g (defcap g () true)) (env-namespace-policy false (m.g)) |]) + , ("changing_hash_makes_it_nonblessed", isExecutionError _HashNotBlessed, [text| + (define-keyset 'k (sig-keyset)) + + (module impure 'k + (defconst VERSION 1) + (defschema foo-schema value:integer) + (deftable foo:{foo-schema}) + (defun ins (k v) (insert foo k v))) + + (module dep 'k + (defun dep-impure (k v) (ins k { "value": v }))) + + (module impure 'k + (defconst VERSION 2) + (defschema foo-schema value:integer) + (deftable foo:{foo-schema}) + (defun ins (k v) (insert foo k v))) + + (dep.dep-impure "b" 1) + |]) ] tests :: TestTree diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index 0b7f412dd..ea3a84c11 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -482,7 +482,7 @@ enforceBlessedHashes :: (MonadEval b i m) => i -> EvalModule b i -> ModuleHash - enforceBlessedHashes info md mh | _mHash md == mh = return () | mh `S.member` (_mBlessed md) = return () - | otherwise = throwExecutionError info (HashNotBlessed (_mName md) mh) -- TODO TODO how to trigger this? + | otherwise = throwExecutionError info (HashNotBlessed (_mName md) mh) guardForModuleCall :: (MonadEval b i m) => i -> CEKEnv b i m -> ModuleName -> m () -> m () guardForModuleCall i env currMod onFound = From 36f759fde87df9e61e85b123b798960176aac661 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 9 Jan 2024 14:43:18 -0600 Subject: [PATCH 29/67] Figure out CapNotInstalled tests --- .../Pact/Core/Test/StaticErrorTests.hs | 33 +++++++++++++++++++ pact-core/Pact/Core/IR/Eval/CEK.hs | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 39ff64aa8..0987eb509 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -854,6 +854,39 @@ executionTests = (dep.dep-impure "b" 1) |]) + , ("managed_auto_cap_not_installed", isExecutionError _CapNotInstalled, [text| + (module m g (defcap g () true) + (defcap PAY (sender:string receiver:string amount:integer) + @managed + (enforce-keyset (read-keyset sender)) + ) + (defun pay (sender receiver amount) + (with-capability (PAY sender receiver amount) amount) + ) + ) + + (env-data { "alice": ["alice"] }) + (env-keys ["alice"]) + + (pay "alice" "bob" 10) + |]) + , ("managed_cap_not_installed", isExecutionError _CapNotInstalled, [text| + (module m g (defcap g () true) + (defcap PAY (sender:string receiver:string amount:integer) + @managed amount PAY-mgr + (enforce-keyset (read-keyset sender)) + ) + (defun PAY-mgr (mgd req) 0) + (defun pay (sender receiver amount) + (with-capability (PAY sender receiver amount) amount) + ) + ) + + (env-data { "alice": ["alice"] }) + (env-keys ["alice"]) + + (pay "alice" "bob" 10) + |]) ] tests :: TestTree diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index ea3a84c11..997c581d7 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -573,7 +573,7 @@ evalCap info currCont handler env origToken@(CapToken fqn args) modCont contbody cont' = modCont env (Just qualCapToken) (Just (fqctToPactEvent origToken)) contbody currCont installCap info env c' False >>= evalUserManagedCap cont' newLocals capBody Nothing -> - throwExecutionError info (CapNotInstalled fqn) -- TODO TODO how to trigger this? + throwExecutionError info (CapNotInstalled fqn) Just managedCap -> do let cont' = modCont env (Just qualCapToken) (Just (fqctToPactEvent origToken)) contbody currCont evalUserManagedCap cont' newLocals capBody managedCap @@ -590,7 +590,7 @@ evalCap info currCont handler env origToken@(CapToken fqn args) modCont contbody let c' = set ctName fqn c installCap info env c' False >>= evalAutomanagedCap cont' newLocals capBody Nothing -> - throwExecutionError info (CapNotInstalled fqn) -- TODO TODO how to trigger this? + throwExecutionError info (CapNotInstalled fqn) Just managedCap -> evalAutomanagedCap cont' newLocals capBody managedCap -- if b then From 253dfb1efc05140cbf0c86a31b21a982796b61e5 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 9 Jan 2024 15:30:21 -0600 Subject: [PATCH 30/67] Defpact nested double execution check --- .../Pact/Core/Test/StaticErrorTests.hs | 18 ++++++++++++++++++ pact-core/Pact/Core/IR/Eval/CEK.hs | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 0987eb509..042414451 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -829,6 +829,24 @@ executionTests = (p) (continue-pact 1) |]) + , ("defpact_nested_double_execution", isExecutionError _NestedDefPactDoubleExecution, [text| + (module m g (defcap g () true) + (defpact n1:string () + (step "hello1") + (step "hello2") + ) + (defpact n2:string () + (step "hello1") + (step "hello2") + ) + (defpact p:string () + (step (n1)) + (step (n2)) + ) + ) + (p) + (continue-pact 1) + |]) ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index 997c581d7..ff1fb194e 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -362,7 +362,7 @@ applyNestedPact i pc ps cont handler cenv = useEvalState esDefPactExec >>= \case , _peNestedDefPactExec = mempty } | otherwise -> - throwExecutionError i (NestedDefPactDoubleExecution ps) -- TODO TODO how to trigger this? + throwExecutionError i (NestedDefPactDoubleExecution ps) Just npe | _psStep ps >= 0 && isRollback && _peStep npe == _psStep ps -> pure (set peStepHasRollback isRollback npe) From db19076e0d16eedb842616736ce6597f68ea088d Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 9 Jan 2024 15:42:21 -0600 Subject: [PATCH 31/67] One more module governance test Co-authored-by: jmcardon --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 042414451..f7ecca620 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -615,6 +615,11 @@ executionTests = , ("module_gov_keyset_nonexistent", isExecutionError _NoSuchKeySet, [text| (module m 'nonexistent (defun f () true)) |]) + , ("module_gov_keyset_nonexistent", isExecutionError _ModuleGovernanceFailure, [text| + (env-data {"ks":["jose"]}) + (define-keyset 'somekeyset (read-keyset 'ks)) + (module m 'somekeyset (defun f () 1)) + |]) , ("module_gov_keyset_empty", isExecutionError _ModuleGovernanceFailure, [text| (module m "" (defun f () true)) |]) From e70b8266dee0756a245855d6fb506f7755324017 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 9 Jan 2024 17:54:23 -0600 Subject: [PATCH 32/67] EventDoesNotMatchModule covered --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index f7ecca620..741323aac 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -910,6 +910,17 @@ executionTests = (pay "alice" "bob" 10) |]) + , ("emit_event_module_mismatch", isExecutionError _EventDoesNotMatchModule, [text| + (module m1 g (defcap g () true) + (defcap ev () @event true) + ) + (module m2 g (defcap g () true) + (defun emit-ev () + (emit-event (ev)) + ) + ) + (emit-ev) + |]) ] tests :: TestTree From 337556ffefd871eecb196e478e87dbbed7c9667c Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 11:37:42 -0600 Subject: [PATCH 33/67] One more recursion check --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 741323aac..5e834c125 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -290,6 +290,13 @@ desugarTests = (defun f3 () f1) ) |]) + , ("cyclic_defcap", isDesugarError _RecursionDetected, [text| + (module m1 g (defcap g () true) + (defcap c () + (with-capability (c) 1) + ) + ) + |]) , ("dup_defs", isDesugarError _DuplicateDefinition, [text| (module m g (defcap g () true) (defun f () true) From d66be91ea16d5ed043d80560acc4b20f689d1ab6 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 11:42:06 -0600 Subject: [PATCH 34/67] Check capability within defcap --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 8 ++++++++ pact-core/Pact/Core/IR/Eval/CEK.hs | 2 ++ 2 files changed, 10 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 5e834c125..ac89c850a 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -543,6 +543,14 @@ desugarTests = (use m "A_fIcwIweiXXYXnKU59CNCAUoIXHXwQtB_D8xhEflLY") |]) + , ("with_capability_in_defcap", isDesugarError _NotAllowedWithinDefcap, [text| + (module m1 g (defcap g () true) + (defcap c1 () true) + (defcap c2 () + (with-capability (c1) 1) + ) + ) + |]) ] executionTests :: [(String, PactErrorI -> Bool, Text)] diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index ff1fb194e..711542873 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -187,6 +187,7 @@ evalCEK cont handler env (CapabilityForm cf info) = do -- Todo: duplication here in the x:xs case WithCapability _ args body -> do enforceNotWithinDefcap info env "with-capability" + -- TODO this seems to be an invariant failure at this point since desugar takes care of this check case args of x:xs -> do let capFrame = WithCapFrame fqn body @@ -715,6 +716,7 @@ enforceNotWithinDefcap -> m () enforceNotWithinDefcap info env form = when (_ceInCap env) $ throwExecutionError info (FormIllegalWithinDefcap form) + -- TODO this seems to be an invariant failure at the point where this is called, since desugar takes care of this requireCap :: MonadEval b i m From 2ba1a4e9daf06f348219943e74bb95d2e4c94a7e Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 12:20:39 -0600 Subject: [PATCH 35/67] install-capability managedness tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 7 +++++++ pact-core/Pact/Core/IR/Eval/CEK.hs | 2 ++ 2 files changed, 9 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index ac89c850a..ca3688ca7 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -936,6 +936,13 @@ executionTests = ) (emit-ev) |]) + , ("install_cap_not_managed", isExecutionError _InvalidManagedCap, [text| + (module m g (defcap g () true) + (defcap c:bool () + true) + ) + (install-capability (c)) + |]) ] tests :: TestTree diff --git a/pact-core/Pact/Core/IR/Eval/CEK.hs b/pact-core/Pact/Core/IR/Eval/CEK.hs index 711542873..ee124c206 100644 --- a/pact-core/Pact/Core/IR/Eval/CEK.hs +++ b/pact-core/Pact/Core/IR/Eval/CEK.hs @@ -796,6 +796,7 @@ installCap info _env (CapToken fqn args) autonomous = do DefManaged m -> case m of DefManagedMeta (paramIx,_) (FQName fqnMgr) -> do managedParam <- maybe (throwExecutionError info (InvalidManagedCap fqn)) pure (args ^? ix paramIx) + -- TODO ^ OOB index is invariant failure? let mcapType = ManagedParam fqnMgr managedParam paramIx ctFiltered = CapToken (fqnToQualName fqn) (filterIndex paramIx args) mcap = ManagedCap ctFiltered ct mcapType @@ -816,6 +817,7 @@ installCap info _env (CapToken fqn args) autonomous = do Just d -> -- todo: error loc here is not in install-cap throwExecutionError (defInfo d) (InvalidDefKind (defKind d) "install-capability") + -- TODO apparently this ^ is caught earlier by the type checker? Nothing -> throwExecutionError' (NoSuchDef fqn) -- Todo: should we typecheck / arity check here? From f0b485f442dfcde6080dd34de7761ff2910fd075 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 12:27:51 -0600 Subject: [PATCH 36/67] Test partial functions application --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index ca3688ca7..f2f856b8f 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -943,6 +943,15 @@ executionTests = ) (install-capability (c)) |]) + , ("partial_defun_user", isExecutionError _CannotApplyPartialClosure, [text| + (module m g (defcap g () true) + (defun f (n:integer s:string) s) + ) + ((f 1) "foo") + |]) + , ("partial_defun_native", isExecutionError _CannotApplyPartialClosure, [text| + ((take 1) "foo") + |]) ] tests :: TestTree From 2e50c2c2167aafb2ef13933d8ba776f4bae3d4d9 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 13:16:18 -0600 Subject: [PATCH 37/67] More defpact advancing tests --- .../Pact/Core/Test/StaticErrorTests.hs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index f2f856b8f..32f92d4b5 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -867,6 +867,42 @@ executionTests = (p) (continue-pact 1) |]) + , ("defpact_nested_advance_all", isExecutionError _NestedDefpactsNotAdvanced, [text| + (module m g (defcap g () true) + (defpact n1:string () + (step "hello1") + (step "hello2") + ) + (defpact n2:string () + (step "hello1") + (step "hello2") + ) + (defpact p:string () + (step [(n1) (n2)]) + (step ["hello2" "hello2"]) + ) + ) + (p) + (continue-pact 1) + |]) + , ("defpact_nested_advance_some", isExecutionError _NestedDefpactsNotAdvanced, [text| + (module m g (defcap g () true) + (defpact n1:string () + (step "hello1") + (step "hello2") + ) + (defpact n2:string () + (step "hello1") + (step "hello2") + ) + (defpact p:string () + (step [(n1) (n2)]) + (step [(n1) "hello2"]) + ) + ) + (p) + (continue-pact 1) + |]) ] <> [ ("env_namespace_wrong_kind", isExecutionError _NativeArgumentsError, [text| (module m g (defcap g () true)) From 07ae0e7d0b4b6a4a1d9024a555235f4a1ddc4219 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 14:58:48 -0600 Subject: [PATCH 38/67] Test closure oversatisfaction --- .../Pact/Core/Test/StaticErrorTests.hs | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 32f92d4b5..49a88b56d 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -675,7 +675,11 @@ executionTests = (step "hello3") ) )|] in - [ ("defpact_continuing_completed", isExecutionError _DefPactAlreadyCompleted, [text| + [ ("defpact_args", isExecutionError _ClosureAppliedToTooManyArgs, [text| + $simpleDefpact + (p 'meh) + |]) + , ("defpact_continuing_completed_samestep", isExecutionError _DefPactAlreadyCompleted, [text| $simpleDefpact (p) (continue-pact 1) @@ -988,6 +992,38 @@ executionTests = , ("partial_defun_native", isExecutionError _CannotApplyPartialClosure, [text| ((take 1) "foo") |]) + , ("closure_too_many_user", isExecutionError _ClosureAppliedToTooManyArgs, [text| + (module m g (defcap g () true) + (defun f (n:integer s:string) s) + ) + (f 1 "foo" "bar") + |]) + , ("closure_too_many_native", isExecutionError _ClosureAppliedToTooManyArgs, [text| + (take 1 "foo" "bar") + |]) + , ("closure_too_many_user_map", isExecutionError _NativeArgumentsError, [text| + (module m g (defcap g () true) + (defun f (n:integer s:string) s) + ) + (map (f 1 "foo") ["meh"]) + |]) + , ("closure_too_many_native_map", isExecutionError _NativeArgumentsError, [text| + (map (take 1 "foo") ["meh"]) + |]) + , ("closure_too_many_native_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| + (module m g (defcap g () true) + (defun f () 1) + ) + (map f ["meh"]) + |]) + , ("closure_too_many_native_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| + (module m g (defcap g () true) + (defcap c:bool () + @managed + true) + ) + (install-capability (c "meh")) + |]) ] tests :: TestTree From 8125d44afedac8ac468a98717c576ffdee669a76 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 16:36:08 -0600 Subject: [PATCH 39/67] Update builtin HOFs oversatisfied error type --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 7042d75c0..2140cecd4 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1001,13 +1001,13 @@ executionTests = , ("closure_too_many_native", isExecutionError _ClosureAppliedToTooManyArgs, [text| (take 1 "foo" "bar") |]) - , ("closure_too_many_user_map", isExecutionError _NativeArgumentsError, [text| + , ("closure_too_many_user_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| (module m g (defcap g () true) (defun f (n:integer s:string) s) ) (map (f 1 "foo") ["meh"]) |]) - , ("closure_too_many_native_map", isExecutionError _NativeArgumentsError, [text| + , ("closure_too_many_native_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| (map (take 1 "foo") ["meh"]) |]) , ("closure_too_many_native_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| From ae4ac0e43bff8a68d2ac9f27d329a2b481e9b23a Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 10 Jan 2024 16:37:53 -0600 Subject: [PATCH 40/67] Update some error types for EvalError --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 2140cecd4..a99dddd95 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -630,7 +630,7 @@ executionTests = , ("module_gov_keyset_nonexistent", isExecutionError _NoSuchKeySet, [text| (module m 'nonexistent (defun f () true)) |]) - , ("module_gov_keyset_nonexistent", isExecutionError _ModuleGovernanceFailure, [text| + , ("module_gov_keyset_different", isExecutionError _EvalError, [text| (env-data {"ks":["jose"]}) (define-keyset 'somekeyset (read-keyset 'ks)) (module m 'somekeyset (defun f () 1)) @@ -638,7 +638,7 @@ executionTests = , ("module_gov_keyset_empty", isExecutionError _ModuleGovernanceFailure, [text| (module m "" (defun f () true)) |]) - , ("module_gov_keyset_not_in_sigs", isExecutionError _ModuleGovernanceFailure, [text| + , ("module_gov_keyset_not_in_sigs", isExecutionError _EvalError, [text| (env-data { "kall": ["a" "b" "c"], "kadmin": ["admin"] }) (define-keyset 'kall) (define-keyset 'kadmin) @@ -646,12 +646,12 @@ executionTests = (env-keys ["admin"]) (module m 'kall (defun f () true)) |]) - , ("defconst_not_a_value_module", isExecutionError _ConstIsNotAPactValue, [text| + , ("defconst_not_a_value_module", isExecutionError _EvalError, [text| (module m g (defcap g () true) (defconst not-a-value (lambda (x) x)) ) |]) - , ("defconst_not_a_value_iface", isExecutionError _ConstIsNotAPactValue, [text| + , ("defconst_not_a_value_iface", isExecutionError _EvalError, [text| (interface iface (defconst not-a-value (lambda (x) x)) ) From f527bf742e7524db267e2a5d28e631d1a8254b0e Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 11 Jan 2024 12:37:17 -0600 Subject: [PATCH 41/67] Copypaste test names un-copypasted --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index a99dddd95..bfe723627 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1010,13 +1010,13 @@ executionTests = , ("closure_too_many_native_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| (map (take 1 "foo") ["meh"]) |]) - , ("closure_too_many_native_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| + , ("closure_too_many_user_map_unary", isExecutionError _ClosureAppliedToTooManyArgs, [text| (module m g (defcap g () true) (defun f () 1) ) (map f ["meh"]) |]) - , ("closure_too_many_native_map", isExecutionError _ClosureAppliedToTooManyArgs, [text| + , ("closure_too_many_defcap", isExecutionError _ClosureAppliedToTooManyArgs, [text| (module m g (defcap g () true) (defcap c:bool () @managed From d26739b6650cf5fb7910ccc066b671ab981f2865 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 12:40:35 -0600 Subject: [PATCH 42/67] Remove outdated note for self --- pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs b/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs index f779049bd..f78def432 100644 --- a/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs +++ b/pact-core/Pact/Core/IR/Eval/Runtime/Utils.hs @@ -197,7 +197,6 @@ argsError -> m a argsError info b args = throwExecutionError info (NativeArgumentsError (builtinName b) (toArgTypeError <$> args)) - -- NOTE ^ this is already tested {-# SPECIALIZE asString From 5f0d4fbe6f8ff5782275fa0819d2f0a5de5bc13b Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 13:07:56 -0600 Subject: [PATCH 43/67] Alright, let's start with the builtins tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index bfe723627..30f019a47 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1026,8 +1026,18 @@ executionTests = |]) ] +builtinTests :: [(String, PactErrorI -> Bool, Text)] +builtinTests = + [ ("integer_pow_negative", isExecutionError _ArithmeticException, [text| + (^ 0 -1) + |]) + , ("floating_pow_negative", isExecutionError _FloatingPointError, [text| + (^ 0.0 -1.0) + |]) + ] + tests :: TestTree tests = - testGroup "CoreStaticTests" (go <$> parseTests <> desugarTests <> executionTests) + testGroup "CoreStaticTests" (go <$> parseTests <> desugarTests <> executionTests <> builtinTests) where go (label, p, srcText) = testCase label $ runStaticTest label srcText p From 6ff7c05f845137c0ead4e868988e598bbef27f7f Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 13:30:51 -0600 Subject: [PATCH 44/67] Separate and deduplicate log arg and base checks for better error messages --- pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs b/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs index 7f72fa343..475a8e2c6 100644 --- a/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs +++ b/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs @@ -171,10 +171,10 @@ rawPow info b cont handler _env = \case returnCEKValue cont handler (VLiteral (LDecimal (f2Dec result))) args -> argsError info b args -rawLogBase :: (IsBuiltin b, CEKEval step b i m, MonadEval b i m) => NativeFunction step b i m +rawLogBase :: forall step b i m. (IsBuiltin b, CEKEval step b i m, MonadEval b i m) => NativeFunction step b i m rawLogBase info b cont handler _env = \case [VLiteral (LInteger base), VLiteral (LInteger n)] -> do - when (base < 0 || n <= 0) $ throwExecutionError info (ArithmeticException "Illegal log base") + checkArgs base n let base' = fromIntegral base :: Double n' = fromIntegral n result = Musl.trans_logBase base' n' @@ -183,11 +183,16 @@ rawLogBase info b cont handler _env = \case -- if i' == 0 then throwExecutionError' (ArithmeticException "div by zero") -- else returnCEKValue cont handler (VLiteral (LInteger (div i i'))) [VLiteral (LDecimal base), VLiteral (LDecimal arg)] -> do - when (base < 0 || arg <= 0) $ throwExecutionError info (ArithmeticException "Invalid base or argument in log") + checkArgs base arg let result = Musl.trans_logBase (dec2F base) (dec2F arg) guardNanOrInf info result returnCEKValue cont handler (VLiteral (LDecimal (f2Dec result))) args -> argsError info b args + where + checkArgs :: (Num a, Ord a) => a -> a -> m () + checkArgs base arg = do + when (base < 0) $ throwExecutionError info (ArithmeticException "Negative log base") + when (arg <= 0) $ throwExecutionError info (ArithmeticException "Non-positive log argument") rawDiv :: (IsBuiltin b, CEKEval step b i m, MonadEval b i m) => NativeFunction step b i m rawDiv info b cont handler _env = \case From 3f23267a90019522d3b54d44c699b902d5df6407 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 13:41:39 -0600 Subject: [PATCH 45/67] No need for text qq in (single-line) builtin tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 30f019a47..5165cac75 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1028,12 +1028,8 @@ executionTests = builtinTests :: [(String, PactErrorI -> Bool, Text)] builtinTests = - [ ("integer_pow_negative", isExecutionError _ArithmeticException, [text| - (^ 0 -1) - |]) - , ("floating_pow_negative", isExecutionError _FloatingPointError, [text| - (^ 0.0 -1.0) - |]) + [ ("integer_pow_negative", isExecutionError _ArithmeticException, "(^ 0 -1)") + , ("floating_pow_negative", isExecutionError _FloatingPointError, "(^ 0.0 -1.0)") ] tests :: TestTree From bea84def22483fbb6e5ee845c8ff765845cfcda8 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 13:50:16 -0600 Subject: [PATCH 46/67] Builtin logarithm tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 5165cac75..b945e1144 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1030,6 +1030,12 @@ builtinTests :: [(String, PactErrorI -> Bool, Text)] builtinTests = [ ("integer_pow_negative", isExecutionError _ArithmeticException, "(^ 0 -1)") , ("floating_pow_negative", isExecutionError _FloatingPointError, "(^ 0.0 -1.0)") + , ("integer_log_negative_base", isExecutionError _ArithmeticException, "(log -1 10)") + , ("integer_log_negative_arg", isExecutionError _ArithmeticException, "(log 2 -1)") + , ("integer_log_zero_arg", isExecutionError _ArithmeticException, "(log 2 0)") + , ("floating_log_negative_base", isExecutionError _ArithmeticException, "(log -1.0 10.0)") + , ("floating_log_negative_arg", isExecutionError _ArithmeticException, "(log 2.0 -1.0)") + , ("floating_log_zero_arg", isExecutionError _ArithmeticException, "(log 2.0 0.0)") ] tests :: TestTree From f41669227e9132da9f0fd9f09eea2e6c87554ca5 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 14:42:51 -0600 Subject: [PATCH 47/67] Add mixed types log/pow tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index b945e1144..954a8e2ac 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1030,12 +1030,22 @@ builtinTests :: [(String, PactErrorI -> Bool, Text)] builtinTests = [ ("integer_pow_negative", isExecutionError _ArithmeticException, "(^ 0 -1)") , ("floating_pow_negative", isExecutionError _FloatingPointError, "(^ 0.0 -1.0)") + -- TODO better error messages for the mixed ones + , ("mixed_pow_negative_flr", isExecutionError _NativeArgumentsError, "(^ 0 -1.0)") + , ("mixed_pow_negative_fll", isExecutionError _NativeArgumentsError, "(^ 0.0 -1)") , ("integer_log_negative_base", isExecutionError _ArithmeticException, "(log -1 10)") , ("integer_log_negative_arg", isExecutionError _ArithmeticException, "(log 2 -1)") , ("integer_log_zero_arg", isExecutionError _ArithmeticException, "(log 2 0)") , ("floating_log_negative_base", isExecutionError _ArithmeticException, "(log -1.0 10.0)") , ("floating_log_negative_arg", isExecutionError _ArithmeticException, "(log 2.0 -1.0)") , ("floating_log_zero_arg", isExecutionError _ArithmeticException, "(log 2.0 0.0)") + -- TODO better error messages for the mixed ones + , ("mixed_log_negative_base_fll", isExecutionError _NativeArgumentsError, "(log -1.0 10)") + , ("mixed_log_negative_arg_fll", isExecutionError _NativeArgumentsError, "(log 2.0 -1)") + , ("mixed_log_zero_arg_fll", isExecutionError _NativeArgumentsError, "(log 2.0 0)") + , ("mixed_log_negative_base_flr", isExecutionError _NativeArgumentsError, "(log -1 10.0)") + , ("mixed_log_negative_arg_flr", isExecutionError _NativeArgumentsError, "(log 2 -1.0)") + , ("mixed_log_zero_arg_flr", isExecutionError _NativeArgumentsError, "(log 2 0.0)") ] tests :: TestTree From 366b469e275dc8634b85d1d622a014d20c05e88b Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 15:01:29 -0600 Subject: [PATCH 48/67] More builtin arithmetic tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 954a8e2ac..24a8a2dc3 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1046,6 +1046,13 @@ builtinTests = , ("mixed_log_negative_base_flr", isExecutionError _NativeArgumentsError, "(log -1 10.0)") , ("mixed_log_negative_arg_flr", isExecutionError _NativeArgumentsError, "(log 2 -1.0)") , ("mixed_log_zero_arg_flr", isExecutionError _NativeArgumentsError, "(log 2 0.0)") + , ("integer_div_zero", isExecutionError _ArithmeticException, "(/ 2 0)") + , ("floating_div_zero", isExecutionError _ArithmeticException, "(/ 2.0 0.0)") + -- TODO better error messages for the mixed ones + , ("mixed_div_zero_fll", isExecutionError _NativeArgumentsError, "(/ 2.0 0)") + , ("mixed_div_zero_flr", isExecutionError _NativeArgumentsError, "(/ 2 0.0)") + , ("integer_square_negative", isExecutionError _ArithmeticException, "(sqrt -1)") + , ("floating_square_negative", isExecutionError _ArithmeticException, "(sqrt -1.0)") ] tests :: TestTree From 6eb59ad6fc70ef3ec9248a8628e24ec69a5a14de Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 15:08:47 -0600 Subject: [PATCH 49/67] Cleanup apparently outdated comment --- pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs b/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs index 475a8e2c6..9e8ae12d5 100644 --- a/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs +++ b/pact-core/Pact/Core/IR/Eval/CoreBuiltin.hs @@ -180,8 +180,6 @@ rawLogBase info b cont handler _env = \case result = Musl.trans_logBase base' n' guardNanOrInf info result returnCEKValue cont handler (VLiteral (LInteger (round result))) - -- if i' == 0 then throwExecutionError' (ArithmeticException "div by zero") - -- else returnCEKValue cont handler (VLiteral (LInteger (div i i'))) [VLiteral (LDecimal base), VLiteral (LDecimal arg)] -> do checkArgs base arg let result = Musl.trans_logBase (dec2F base) (dec2F arg) From def1a9278232dff9f1253db6f054108ca121304c Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 12 Jan 2024 16:34:35 -0600 Subject: [PATCH 50/67] `enumerate` divergence tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 24a8a2dc3..ddb324456 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1053,6 +1053,9 @@ builtinTests = , ("mixed_div_zero_flr", isExecutionError _NativeArgumentsError, "(/ 2 0.0)") , ("integer_square_negative", isExecutionError _ArithmeticException, "(sqrt -1)") , ("floating_square_negative", isExecutionError _ArithmeticException, "(sqrt -1.0)") + + , ("enumerate_up_diverging", isExecutionError _EnumerationError, "(enumerate 0 10 -1)") + , ("enumerate_down_diverging", isExecutionError _EnumerationError, "(enumerate 10 0 1)") ] tests :: TestTree From 5cce51a68651ed5a9bee910167651afb936486c4 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 16 Jan 2024 13:11:46 -0600 Subject: [PATCH 51/67] Access tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index ddb324456..16b9a8e5d 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1056,6 +1056,11 @@ builtinTests = , ("enumerate_up_diverging", isExecutionError _EnumerationError, "(enumerate 0 10 -1)") , ("enumerate_down_diverging", isExecutionError _EnumerationError, "(enumerate 10 0 1)") + , ("at_oob_bigger", isExecutionError _ArrayOutOfBoundsException, "(at 100 [1 2 3])") + , ("at_oob_bound", isExecutionError _ArrayOutOfBoundsException, "(at 3 [1 2 3])") + , ("at_oob_smaller", isExecutionError _ArrayOutOfBoundsException, "(at -1 [1 2 3])") + , ("at_oob_empty", isExecutionError _ArrayOutOfBoundsException, "(at 0 [])") + , ("at_key_missing", isExecutionError _EvalError, "(at 'bar { 'foo: 1 })") ] tests :: TestTree From a9472e91262f0e04dda8a0ae763c18d4798facdd Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 16 Jan 2024 13:26:48 -0600 Subject: [PATCH 52/67] Yielding outside of defpact is easy --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 16b9a8e5d..c595d1826 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1061,6 +1061,7 @@ builtinTests = , ("at_oob_smaller", isExecutionError _ArrayOutOfBoundsException, "(at -1 [1 2 3])") , ("at_oob_empty", isExecutionError _ArrayOutOfBoundsException, "(at 0 [])") , ("at_key_missing", isExecutionError _EvalError, "(at 'bar { 'foo: 1 })") + , ("yield_outside", isExecutionError _YieldOutsiteDefPact, "(yield {})") ] tests :: TestTree From 0a79050f54459230cf8aed92c18edc47f635d352 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 16 Jan 2024 14:58:04 -0600 Subject: [PATCH 53/67] Resume tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index c595d1826..807ab507a 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1062,6 +1062,17 @@ builtinTests = , ("at_oob_empty", isExecutionError _ArrayOutOfBoundsException, "(at 0 [])") , ("at_key_missing", isExecutionError _EvalError, "(at 'bar { 'foo: 1 })") , ("yield_outside", isExecutionError _YieldOutsiteDefPact, "(yield {})") + , ("resume_no_defpact", isExecutionError _NoActiveDefPactExec, "(resume { 'field := binder } binder)") + , ("resume_no_yield", isExecutionError _NoYieldInDefPactStep, [text| + (module m g (defcap g () true) + (defpact p () + (step "hello") + (step (resume { 'field := binder } binder))) + ) + + (p) + (continue-pact 1) + |]) ] tests :: TestTree From 149ce8d16937e43b54ddc740c4d2dcc433b50dbd Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 16 Jan 2024 15:40:57 -0600 Subject: [PATCH 54/67] Toplevel tests --- .../Pact/Core/Test/StaticErrorTests.hs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 807ab507a..b0b383465 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1073,6 +1073,69 @@ builtinTests = (p) (continue-pact 1) |]) + , ("toplevel_create_table", isExecutionError _NativeIsTopLevelOnly, [text| + (module m g (defcap g () true) + (defschema s a:integer) + (deftable t:{s}) + (defun f () (create-table t)) + ) + (f) + |]) + , ("toplevel_describe_table", isExecutionError _NativeIsTopLevelOnly, [text| + (module m g (defcap g () true) + (defschema s a:integer) + (deftable t:{s}) + (defun f () (describe-table t)) + ) + (f) + |]) + , ("toplevel_define_keyset", isExecutionError _NativeIsTopLevelOnly, [text| + (env-data { "kall": ["a" "b" "c"] }) + (module m g (defcap g () true) + (defun f () (define-keyset 'kall)) + ) + (f) + |]) + , ("toplevel_define_keyset_guarded", isExecutionError _NativeIsTopLevelOnly, [text| + (env-data { "kall": ["a" "b" "c"] }) + (module m g (defcap g () true) + (defun f () (define-keyset 'kall (sig-keyset))) + ) + (f) + |]) + , ("toplevel_describe_module", isExecutionError _NativeIsTopLevelOnly, [text| + (module m g (defcap g () true) + (defun f () (describe-module 'm)) + ) + (f) + |]) + , ("toplevel_describe_keyset", isExecutionError _NativeIsTopLevelOnly, [text| + (env-data { "kall": ["a" "b" "c"] }) + (define-keyset 'kall) + (module m g (defcap g () true) + (defun f () (describe-keyset 'kall)) + ) + (f) + |]) + , ("toplevel_namespace", isExecutionError _NativeIsTopLevelOnly, [text| + (env-data { "carl-keys" : ["carl"], "carl.carl-keys": ["carl"] }) + (env-keys ["carl"]) + + (define-namespace 'carl (read-keyset 'carl-keys) (read-keyset 'carl-keys)) + (module m g (defcap g () true) + (defun f () (namespace 'carl)) + ) + (f) + |]) + , ("toplevel_define_namespace", isExecutionError _NativeIsTopLevelOnly, [text| + (env-data { "carl-keys" : ["carl"], "carl.carl-keys": ["carl"] }) + (env-keys ["carl"]) + + (module m g (defcap g () true) + (defun f () (define-namespace 'carl (read-keyset 'carl-keys) (read-keyset 'carl-keys))) + ) + (f) + |]) ] tests :: TestTree From 7532de6e9012ce4f3349593700580d46880486cc Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Tue, 16 Jan 2024 15:44:09 -0600 Subject: [PATCH 55/67] base64 decoding error test --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index b0b383465..3954f0f36 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1136,6 +1136,9 @@ builtinTests = ) (f) |]) + , ("b64decode", isExecutionError _DecodeError, [text| + (base64-decode "foobar!") + |]) ] tests :: TestTree From edbf28c319285343272252684da500f27c7244cd Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 17 Jan 2024 12:51:30 -0600 Subject: [PATCH 56/67] ns keysets wrong ns error test --- .../Pact/Core/Test/StaticErrorTests.hs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 3954f0f36..df76621d6 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1139,6 +1139,26 @@ builtinTests = , ("b64decode", isExecutionError _DecodeError, [text| (base64-decode "foobar!") |]) + , ("keyset_def_ns_mismatch", isExecutionError _MismatchingKeysetNamespace, [text| + (env-exec-config ["RequireKeysetNs"]) + (env-data + { "alice-keys" : ["alice"] + , "bob-keys" : ["bob"] + , "alice.alice-keys": ["alice"] + , "bob.bob-keys" : ["bob"] + }) + (env-keys ["alice", "bob"]) + + (define-namespace 'alice + (read-keyset 'alice-keys) + (read-keyset 'alice-keys)) + + (define-namespace 'bob + (read-keyset 'bob-keys) + (read-keyset 'bob-keys)) + (namespace 'alice) + (define-keyset "bob.bob-keys") + |]) ] tests :: TestTree From 8f811a7d6aa0f184fac83a97503ba7cb24d5f3cc Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 17 Jan 2024 13:41:06 -0600 Subject: [PATCH 57/67] defcap unmanaged event failure test --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index df76621d6..88f259c8e 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1159,6 +1159,10 @@ builtinTests = (namespace 'alice) (define-keyset "bob.bob-keys") |]) + , ("emit_event_unmanaged", isExecutionError _InvalidEventCap, [text| + (module m g (defcap g () true)) + (emit-event (g)) + |]) ] tests :: TestTree From 5606909a0bb5befd8b45ed7270244aebd39879f1 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 17 Jan 2024 13:43:56 -0600 Subject: [PATCH 58/67] str-to-int variant of base64 decoding failure test --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 88f259c8e..b1e628d82 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1136,9 +1136,8 @@ builtinTests = ) (f) |]) - , ("b64decode", isExecutionError _DecodeError, [text| - (base64-decode "foobar!") - |]) + , ("b64decode", isExecutionError _DecodeError, [text|(base64-decode "foobar!")|]) + , ("b64decode-str-to-int", isExecutionError _DecodeError, [text|(str-to-int 64 "foobar!")|]) , ("keyset_def_ns_mismatch", isExecutionError _MismatchingKeysetNamespace, [text| (env-exec-config ["RequireKeysetNs"]) (env-data From a27d449ae2fd4b8435c1f3a9062d9fdce99fd958 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 17 Jan 2024 13:50:49 -0600 Subject: [PATCH 59/67] More str-to-int tests --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index b1e628d82..15be090ce 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -7,6 +7,7 @@ module Pact.Core.Test.StaticErrorTests(tests) where import Test.Tasty import Test.Tasty.HUnit +import qualified Data.Text as T import Control.Lens import Data.IORef import Data.Text (Text) @@ -1138,6 +1139,12 @@ builtinTests = |]) , ("b64decode", isExecutionError _DecodeError, [text|(base64-decode "foobar!")|]) , ("b64decode-str-to-int", isExecutionError _DecodeError, [text|(str-to-int 64 "foobar!")|]) + , let long = T.replicate 513 "0" in + ("str-to-int-too-long", isExecutionError _DecodeError, [text|(str-to-int "$long")|]) + , let long = T.replicate 513 "0" in + ("str-to-int-base-too-long", isExecutionError _DecodeError, [text|(str-to-int 2 "$long")|]) + , ("str-to-int-empty", isExecutionError _DecodeError, [text|(str-to-int "")|]) + , ("str-to-int-base-empty", isExecutionError _DecodeError, [text|(str-to-int 2 "")|]) , ("keyset_def_ns_mismatch", isExecutionError _MismatchingKeysetNamespace, [text| (env-exec-config ["RequireKeysetNs"]) (env-data From a33a0a27b09498cfa1ff88b9fddf971df02a8068 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 19 Jan 2024 14:48:32 -0600 Subject: [PATCH 60/67] defpact provenance failure test --- pact-core-tests/Pact/Core/Test/StaticErrorTests.hs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs index 15be090ce..245688ad2 100644 --- a/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-core-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1074,6 +1074,17 @@ builtinTests = (p) (continue-pact 1) |]) + , ("yield_provenance_mismatch", isExecutionError _YieldProvenanceDoesNotMatch, [text| + (module m g (defcap g () true) + (defpact p () + (step (yield { 'field: 1 } "1")) + (step (resume { 'field := binder } binder))) + ) + + (env-chain-data { 'chain-id: "0" }) + (p) + (continue-pact 1) + |]) , ("toplevel_create_table", isExecutionError _NativeIsTopLevelOnly, [text| (module m g (defcap g () true) (defschema s a:integer) From 91befc50659879ba1b383a4caf355b6afd6b1ba5 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 31 Jan 2024 23:14:29 -0600 Subject: [PATCH 61/67] Update error types --- pact-tests/Pact/Core/Test/StaticErrorTests.hs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pact-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-tests/Pact/Core/Test/StaticErrorTests.hs index 2a5fac370..b1804bcc8 100644 --- a/pact-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-tests/Pact/Core/Test/StaticErrorTests.hs @@ -1034,8 +1034,8 @@ builtinTests = [ ("integer_pow_negative", isExecutionError _ArithmeticException, "(^ 0 -1)") , ("floating_pow_negative", isExecutionError _FloatingPointError, "(^ 0.0 -1.0)") -- TODO better error messages for the mixed ones - , ("mixed_pow_negative_flr", isExecutionError _NativeArgumentsError, "(^ 0 -1.0)") - , ("mixed_pow_negative_fll", isExecutionError _NativeArgumentsError, "(^ 0.0 -1)") + , ("mixed_pow_negative_flr", isExecutionError _FloatingPointError, "(^ 0 -1.0)") + , ("mixed_pow_negative_fll", isExecutionError _FloatingPointError, "(^ 0.0 -1)") , ("integer_log_negative_base", isExecutionError _ArithmeticException, "(log -1 10)") , ("integer_log_negative_arg", isExecutionError _ArithmeticException, "(log 2 -1)") , ("integer_log_zero_arg", isExecutionError _ArithmeticException, "(log 2 0)") @@ -1043,17 +1043,17 @@ builtinTests = , ("floating_log_negative_arg", isExecutionError _ArithmeticException, "(log 2.0 -1.0)") , ("floating_log_zero_arg", isExecutionError _ArithmeticException, "(log 2.0 0.0)") -- TODO better error messages for the mixed ones - , ("mixed_log_negative_base_fll", isExecutionError _NativeArgumentsError, "(log -1.0 10)") - , ("mixed_log_negative_arg_fll", isExecutionError _NativeArgumentsError, "(log 2.0 -1)") - , ("mixed_log_zero_arg_fll", isExecutionError _NativeArgumentsError, "(log 2.0 0)") - , ("mixed_log_negative_base_flr", isExecutionError _NativeArgumentsError, "(log -1 10.0)") - , ("mixed_log_negative_arg_flr", isExecutionError _NativeArgumentsError, "(log 2 -1.0)") - , ("mixed_log_zero_arg_flr", isExecutionError _NativeArgumentsError, "(log 2 0.0)") + , ("mixed_log_negative_base_fll", isExecutionError _ArithmeticException, "(log -1.0 10)") + , ("mixed_log_negative_arg_fll", isExecutionError _ArithmeticException, "(log 2.0 -1)") + , ("mixed_log_zero_arg_fll", isExecutionError _ArithmeticException, "(log 2.0 0)") + , ("mixed_log_negative_base_flr", isExecutionError _ArithmeticException, "(log -1 10.0)") + , ("mixed_log_negative_arg_flr", isExecutionError _ArithmeticException, "(log 2 -1.0)") + , ("mixed_log_zero_arg_flr", isExecutionError _ArithmeticException, "(log 2 0.0)") , ("integer_div_zero", isExecutionError _ArithmeticException, "(/ 2 0)") , ("floating_div_zero", isExecutionError _ArithmeticException, "(/ 2.0 0.0)") -- TODO better error messages for the mixed ones - , ("mixed_div_zero_fll", isExecutionError _NativeArgumentsError, "(/ 2.0 0)") - , ("mixed_div_zero_flr", isExecutionError _NativeArgumentsError, "(/ 2 0.0)") + , ("mixed_div_zero_fll", isExecutionError _ArithmeticException, "(/ 2.0 0)") + , ("mixed_div_zero_flr", isExecutionError _ArithmeticException, "(/ 2 0.0)") , ("integer_square_negative", isExecutionError _ArithmeticException, "(sqrt -1)") , ("floating_square_negative", isExecutionError _ArithmeticException, "(sqrt -1.0)") From 11cef93d6b2e6da4865f05f7f9253a866faf9c69 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 8 Feb 2024 14:56:12 -0600 Subject: [PATCH 62/67] `applyPact`'s step check is indeed an invariant failure --- pact/Pact/Core/IR/Eval/CEK.hs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pact/Pact/Core/IR/Eval/CEK.hs b/pact/Pact/Core/IR/Eval/CEK.hs index 86b0aedab..41ed2d604 100644 --- a/pact/Pact/Core/IR/Eval/CEK.hs +++ b/pact/Pact/Core/IR/Eval/CEK.hs @@ -399,9 +399,11 @@ applyPact i pc ps cont handler cenv nested = useEvalState esDefPactExec >>= \cas DPact defPact -> do let nSteps = NE.length (_dpSteps defPact) - -- Check we try to apply the correct pact Step - unless (ps ^. psStep < nSteps) $ - throwExecutionError i (DefPactStepNotFound ps nSteps) -- TODO TODO how to trigger this? + -- `applyPact` is only called from `initPact` or `resumePact`. + -- `initPact` ensures that the step is 0, + -- and there are guaranteed more than 0 steps due to how the parser is written. + -- `resumePact` does a similar check before calling this function. + when (ps ^. psStep >= nSteps) $ failInvariant i "Step not found" step <- maybe (failInvariant i "Step not found") pure $ _dpSteps defPact ^? ix (ps ^. psStep) From 22c2d8f16d5e97f33abbc474d1496bde82ddd3a3 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Thu, 8 Feb 2024 14:59:36 -0600 Subject: [PATCH 63/67] Remove unused error type now --- pact/Pact/Core/Errors.hs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pact/Pact/Core/Errors.hs b/pact/Pact/Core/Errors.hs index b587ee996..8ab4531ce 100644 --- a/pact/Pact/Core/Errors.hs +++ b/pact/Pact/Core/Errors.hs @@ -294,8 +294,6 @@ data EvalError -- ^ Nested DefPact is executed twice | MultipleOrNestedDefPactExecFound DefPactExec -- ^ Unexpected DefPactExec found in the environment - | DefPactStepNotFound DefPactStep Int - -- ^ The expected step could not be found in the DefPact | DefPactStepHasNoRollback DefPactStep -- ^ The requested DefPactStep has no rollback | DefPactStepNotInEnvironment @@ -414,11 +412,6 @@ instance Pretty EvalError where ["Requested nested DefPact double execution:", "DefPactId: " <> pretty (_psDefPactId ps)] MultipleOrNestedDefPactExecFound pe -> Pretty.hsep ["DefPact execution context already in the environment: ", "DefPactId: " <> pretty (_peDefPactId pe)] - DefPactStepNotFound ps maxSteps -> Pretty.hsep - [ "Requested DefPact step exceeds available steps:" - , "requested: " <> pretty (_psStep ps) - , "available: " <> pretty maxSteps - ] DefPactStepHasNoRollback ps -> Pretty.hsep ["Step has no rollback:", "DefPactId: " <> pretty (_psDefPactId ps)] DefPactStepNotInEnvironment -> "No DefPactStep in the environment" From e03cc50ad8a1bad78ab588bdf582e902f5192961 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 9 Feb 2024 11:08:37 -0600 Subject: [PATCH 64/67] Add a `NameNotInScope` reserialization test --- pact-tests/Pact/Core/Test/StaticErrorTests.hs | 20 +++++++++++++++++++ pact/Pact/Core/Environment/Utils.hs | 1 - 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pact-tests/Pact/Core/Test/StaticErrorTests.hs b/pact-tests/Pact/Core/Test/StaticErrorTests.hs index b1804bcc8..da2426a17 100644 --- a/pact-tests/Pact/Core/Test/StaticErrorTests.hs +++ b/pact-tests/Pact/Core/Test/StaticErrorTests.hs @@ -630,6 +630,26 @@ executionTests = , ("get_module_unknown", isExecutionError _ModuleDoesNotExist, [text| (describe-module 'nonexistent) |]) + , ("reexposed_module_missing_name", isExecutionError _NameNotInScope, [text| + (module m g + (defcap g () true) + + (defun f () 1) + + (defschema foo-schema elem:guard) + (deftable foo:{foo-schema}) + ) + (create-table foo) + (insert foo "k" {"elem":(create-user-guard (f))}) + + (module m g + (defcap g () true) + (defschema foo-schema elem:guard) + (deftable foo:{foo-schema}) + ) + + (enforce-guard (at "elem" (read foo "k"))) + |]) , ("module_gov_keyset_nonexistent", isExecutionError _NoSuchKeySet, [text| (module m 'nonexistent (defun f () true)) |]) diff --git a/pact/Pact/Core/Environment/Utils.hs b/pact/Pact/Core/Environment/Utils.hs index e11c38888..0ba793aa7 100644 --- a/pact/Pact/Core/Environment/Utils.hs +++ b/pact/Pact/Core/Environment/Utils.hs @@ -150,7 +150,6 @@ getModuleMember info pdb (QualifiedName qn mn) = do Nothing -> do let fqn = FullyQualifiedName mn qn (_mHash md) throwExecutionError info (NameNotInScope fqn) - -- TODO ^ failed to find a test mangleNamespace :: (MonadEvalState b i m) => ModuleName -> m ModuleName From 99d443fe043e91eb02eb45b21aae06d694915cfa Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 9 Feb 2024 11:11:27 -0600 Subject: [PATCH 65/67] Leave the not-within-defcap check as an extra safeguard --- pact/Pact/Core/IR/Eval/CEK.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/pact/Pact/Core/IR/Eval/CEK.hs b/pact/Pact/Core/IR/Eval/CEK.hs index 41ed2d604..4f16d50af 100644 --- a/pact/Pact/Core/IR/Eval/CEK.hs +++ b/pact/Pact/Core/IR/Eval/CEK.hs @@ -266,7 +266,6 @@ evaluateTerm cont handler env (CapabilityForm cf info) = do case cf of WithCapability rawCap body -> do enforceNotWithinDefcap info env "with-capability" - -- TODO this seems to be an invariant failure at this point since desugar takes care of this check let capFrame = WithCapC body cont' = CapInvokeC env info capFrame cont evalCEK cont' handler env rawCap From 3cf509b9c9675161b2ca0ea541fb27f37e4fe431 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 9 Feb 2024 11:17:34 -0600 Subject: [PATCH 66/67] Remove a TODO since it's addressed elsewhere --- pact/Pact/Core/IR/Eval/CEK.hs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pact/Pact/Core/IR/Eval/CEK.hs b/pact/Pact/Core/IR/Eval/CEK.hs index 4f16d50af..6cfe119fe 100644 --- a/pact/Pact/Core/IR/Eval/CEK.hs +++ b/pact/Pact/Core/IR/Eval/CEK.hs @@ -617,7 +617,6 @@ nameToFQN info env (Name n nk) = case nk of md <- getModule info (view cePactDb env) (_mrModule mr) pure (FullyQualifiedName (_mrModule mr) dArg (_mHash md)) Just _ -> throwExecutionError info (DynNameIsNotModRef dArg) - -- TODO this ^ is supposedly caught by the typechecker, so it's an invariant error now Nothing -> failInvariant info ("unbound identifier " <> n) _ -> failInvariant info ("invalid name in fq position " <> n) {-# SPECIALIZE nameToFQN @@ -946,7 +945,6 @@ enforceNotWithinDefcap -> m () enforceNotWithinDefcap info env form = when (_ceInCap env) $ throwExecutionError info (FormIllegalWithinDefcap form) - -- TODO this seems to be an invariant failure at the point where this is called, since desugar takes care of this {-# SPECIALIZE enforceNotWithinDefcap :: () -> CoreCEKEnv From 32dbc8b45e87f62d0b73d2f9b38fdc2262333250 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Fri, 9 Feb 2024 11:29:44 -0600 Subject: [PATCH 67/67] Turn the rest of issues into invariant failures (stringly typed for now) --- pact/Pact/Core/IR/Eval/CEK.hs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/pact/Pact/Core/IR/Eval/CEK.hs b/pact/Pact/Core/IR/Eval/CEK.hs index 6cfe119fe..10561ed32 100644 --- a/pact/Pact/Core/IR/Eval/CEK.hs +++ b/pact/Pact/Core/IR/Eval/CEK.hs @@ -161,14 +161,9 @@ evaluateTerm cont handler env (Var n info) = do clo = CapTokenClosure fqn args (length args) info returnCEKValue cont handler (VClosure (CT clo)) Just d -> - throwExecutionError info (InvalidDefKind (defKind mname d) "in var position") - -- TODO ^ shall this be an invariant failure? - -- apparently this can never happen because `renameTerm` checks for variable top-level variable occurrences, - -- erroring out with `InvalidDefInTermVariable` if it's violated. - -- And, the execution can't change that invariant once it's established during desugar. + failInvariant info ("invalid def kind in var position: " <> T.pack (show $ defKind mname d)) Nothing -> - throwExecutionError info (NameNotInScope (FullyQualifiedName mname (_nName n) mh)) - -- TODO ^ ditto, `renameTerm` apparently always fails in this case as well + failInvariant info ("name not in scope: " <> T.pack (show $ FullyQualifiedName mname (_nName n) mh)) NModRef m ifs -> case ifs of [x] -> returnCEKValue cont handler (VModRef (ModRef m ifs (Just (S.singleton x)))) [] -> throwExecutionError info (ModRefNotRefined (_nName n)) @@ -331,9 +326,7 @@ mkDefunClosure d mn e = case _dfunTerm d of Nullary body i -> pure (Closure (_dfunName d) mn NullaryClosure 0 body (_dfunRType d) e i) _ -> - throwExecutionError (_dfunInfo d) (DefIsNotClosure (_dfunName d)) - -- TODO ^ apparently invariant failure, since the parser ensures defun has a form of `(defun ( args ) body)`, - -- and desugar converts that into a Lam or Nullary. + failInvariant (_dfunInfo d) ("definition is not a closure: " <> T.pack (show d)) mkDefPactClosure :: i @@ -545,13 +538,13 @@ resumePact -> Maybe DefPactExec -> m (CEKEvalResult step b i m) resumePact i cont handler env crossChainContinuation = viewEvalEnv eeDefPactStep >>= \case - Nothing -> throwExecutionError i DefPactStepNotInEnvironment -- <- TODO apparently can't happen, `continuePact` ensures that + Nothing -> throwExecutionError i DefPactStepNotInEnvironment -- TODO check with multichain Just ps -> do pdb <- viewEvalEnv eePactDb dbState <- liftDbFunction i (readDefPacts pdb (_psDefPactId ps)) case (dbState, crossChainContinuation) of (Just Nothing, _) -> throwExecutionError i (DefPactAlreadyCompleted ps) - (Nothing, Nothing) -> throwExecutionError i (NoPreviousDefPactExecutionFound ps) -- TODO TODO how to trigger this? + (Nothing, Nothing) -> throwExecutionError i (NoPreviousDefPactExecutionFound ps) -- TODO check with multichain (Nothing, Just ccExec) -> resumeDefPactExec ccExec (Just (Just dbExec), Nothing) -> resumeDefPactExec dbExec (Just (Just dbExec), Just ccExec) -> do @@ -563,18 +556,18 @@ resumePact i cont handler env crossChainContinuation = viewEvalEnv eeDefPactStep -- Validate continuation db state when (_peContinuation dbExec /= _peContinuation ccExec) $ - throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) -- TODO TODO how to trigger this? + throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) -- TODO check with multichain -- Validate step count against db state when (_peStepCount dbExec /= _peStepCount ccExec) $ - throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) -- TODO TODO how to trigger this? + throwExecutionError i (CCDefPactContinuationError ps ccExec dbExec) -- TODO check with multichain resumeDefPactExec ccExec where --resumeDefPactExec :: CEKEval step b i m, MonadEval b i m => DefPactExec -> m (CEKEvalResult step b i m) resumeDefPactExec pe = do when (_psDefPactId ps /= _peDefPactId pe) $ - throwExecutionError i (DefPactIdMismatch (_psDefPactId ps) (_peDefPactId pe)) -- TODO TODO how to trigger this? + throwExecutionError i (DefPactIdMismatch (_psDefPactId ps) (_peDefPactId pe)) -- TODO check with multichain when (_psStep ps < 0 || _psStep ps >= _peStepCount pe) $ throwExecutionError i (InvalidDefPactStepSupplied ps pe) @@ -1039,8 +1032,7 @@ installCap info _env (CapToken fqn args) autonomous = do case _dcapMeta d of DefManaged m -> case m of DefManagedMeta (paramIx,_) (FQName fqnMgr) -> do - managedParam <- maybe (throwExecutionError info (InvalidManagedCap fqn)) pure (args ^? ix paramIx) - -- TODO ^ OOB index is invariant failure? + managedParam <- maybe (failInvariant info $ "invalid managed cap idx: " <> T.pack (show fqn)) pure (args ^? ix paramIx) let mcapType = ManagedParam fqnMgr managedParam paramIx ctFiltered = CapToken (fqnToQualName fqn) (filterIndex paramIx args) mcap = ManagedCap ctFiltered ct mcapType