Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix name resolution within module redeploy #1235

Merged
merged 20 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/en/pact-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1928,7 +1928,7 @@ Retreive any accumulated events and optionally clear event state. Object returne
*→* `[string]`


Queries, or with arguments, sets execution config flags. Valid flags: ["AllowReadInLocal","DisableHistoryInTransactionalMode","DisableInlineMemCheck","DisableModuleInstall","DisableNewTrans","DisablePact40","DisablePact420","DisablePact43","DisablePact431","DisablePact44","DisablePact45","DisablePact46","DisablePact47","DisablePactEvents","DisableRuntimeReturnTypeChecking","EnforceKeyFormats","OldReadOnlyBehavior","PreserveModuleIfacesBug","PreserveModuleNameBug","PreserveNsModuleInstallBug","PreserveShowDefs"]
Queries, or with arguments, sets execution config flags. Valid flags: ["AllowReadInLocal","DisableHistoryInTransactionalMode","DisableInlineMemCheck","DisableModuleInstall","DisableNewTrans","DisablePact40","DisablePact420","DisablePact43","DisablePact431","DisablePact44","DisablePact45","DisablePact46","DisablePact47","DisablePact48","DisablePactEvents","DisableRuntimeReturnTypeChecking","EnforceKeyFormats","OldReadOnlyBehavior","PreserveModuleIfacesBug","PreserveModuleNameBug","PreserveNsModuleInstallBug","PreserveShowDefs"]
```lisp
pact> (env-exec-config ['DisableHistoryInTransactionalMode]) (env-exec-config)
["DisableHistoryInTransactionalMode"]
Expand Down
53 changes: 37 additions & 16 deletions src/Pact/Eval.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import Pact.Types.Purity
import Pact.Types.Runtime
import Pact.Types.SizeOf
import Pact.Types.Namespace
import Control.Applicative (liftA2)


evalBeginTx :: Info -> Eval e (Maybe TxId)
Expand Down Expand Up @@ -320,6 +321,11 @@ eval' (TModule _tm@(MDModule m) bod i) =
capMName <-
ifExecutionFlagSet' FlagPreserveNsModuleInstallBug (_mName m) (_mName mangledM)
void $ acquireModuleAdminCapability capMName $ return ()

unlessExecutionFlagSet FlagDisablePact48 $ do
evalRefs.rsLoadedModules %= HM.delete (_mName mangledM)
evalRefs.rsQualifiedDeps %= HM.filterWithKey (\k _ -> _fqModule k /= _mName mangledM)

-- build/install module from defs
(g,govM) <- loadModule mangledM bod i g0
szVer <- getSizeOfVersion
Expand Down Expand Up @@ -737,27 +743,42 @@ fullyQualifyDefs info mdef defs = do
checkAddDep = \case
Direct (TVar (FQName fq) _) -> modify' (Set.insert (_fqModule fq))
_ -> pure ()
-- | traverse to find deps and form graph
traverseGraph allDefs memo = fmap stronglyConnCompR $ forM (HM.toList allDefs) $ \(defName,defTerm) -> do
let defName' = FullyQualifiedName defName (_mName mdef) (moduleHash mdef)
defTerm' <- forM defTerm $ \(f :: Name) -> do

resolveBareName memo f@(BareName fn _) = case HM.lookup fn defs of
Just _ -> do
let name' = FullyQualifiedName fn (_mName mdef) (moduleHash mdef)
return (Left name') -- decl found
Nothing -> lift (resolveBareModRef info f fn memo (MDModule mdef)) >>= \case
Just mr -> return (Right mr) -- mod ref found
Nothing -> resolveError f

resolveError f = lift (evalError' f $ "Cannot resolve " <> dquotes (pretty f))

resolveName flagPact48Disabled memo = \case
(QName (QualifiedName (ModuleName mn mNs) fn i))
| not flagPact48Disabled
&& mn == _mnName (_mName mdef)
&& isNsMatch -> resolveBareName memo (BareName fn i)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compared to 4ca5571, we check if the symbol is prefixed by a namespace, if so we check against the module.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Great job

where
isNsMatch = fromMaybe True (liftA2 (==) modNs mNs)
modNs = _mnNamespace (_mName mdef)
f -> do
dm <- lift (resolveRefFQN f f) -- lookup ref, don't try modules for barenames
case (dm, f) of
(Just t, _) -> checkAddDep t *> return (Right t) -- ref found
-- for barenames, check decls and finally modules
(Nothing, Name (BareName fn _)) ->
case HM.lookup fn allDefs of
Just _ -> do
let name' = FullyQualifiedName fn (_mName mdef) (moduleHash mdef)
return (Left name') -- decl found
Nothing -> lift (resolveBareModRef info f fn memo (MDModule mdef)) >>= \r -> case r of
Just mr -> return (Right mr) -- mod ref found
Nothing ->
lift (evalError' f $ "Cannot resolve " <> dquotes (pretty f))
-- for qualified names, simply fail
(Nothing, _) -> lift (evalError' f $ "Cannot resolve " <> dquotes (pretty f))
-- for barenames, check decls and finally modules
(Nothing, Name bn@BareName{}) -> resolveBareName memo bn
-- for qualified names, simply fail
(Nothing, _) -> resolveError f

-- | traverse to find deps and form graph
traverseGraph allDefs memo = fmap stronglyConnCompR $ forM (HM.toList allDefs) $ \(defName,defTerm) -> do
let defName' = FullyQualifiedName defName (_mName mdef) (moduleHash mdef)
disablePact48 <- lift (isExecutionFlagSet FlagDisablePact48)
defTerm' <- forM defTerm $ \(f :: Name) -> resolveName disablePact48 memo f

return (defTerm', defName', mapMaybe (either Just (const Nothing)) $ toList defTerm')

moduleHash = _mhHash . _mHash


Expand Down
2 changes: 2 additions & 0 deletions src/Pact/Types/Runtime.hs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ data ExecutionFlag
| FlagDisablePact47
-- | Disable runtime return type checking.
| FlagDisableRuntimeReturnTypeChecking
-- | Disable Pact 4.8 Features
| FlagDisablePact48
deriving (Eq,Ord,Show,Enum,Bounded)

-- | Flag string representation
Expand Down
71 changes: 71 additions & 0 deletions tests/pact/fqns.repl
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,74 @@

(expect "selects correct test" (modB.get-test) "hello")
(commit-tx)

;;
;; Module redeploy name resolution
;;

(begin-tx)
(namespace 'free)
(module test-mod-redeploy-ref g
(defcap g () true)

(defcap test ()
(enforce false "boom"))

(defun f ()
(with-capability (test)
1))
)
(expect-failure "Execution fails due to the falsy defcap" (f))
(expect-failure "Execution fails due to the falsy defcap" (test-mod-redeploy-ref.f))
(expect-failure "Execution fails due to the falsy defcap" (free.test-mod-redeploy-ref.f))


(commit-tx)

(begin-tx)
(namespace 'free)
(module test-mod-redeploy-ref g
(defcap g () true)
(defcap test ()
true)
(defun f ()
(with-capability (free.test-mod-redeploy-ref.test)
1))

(defun f1 ()
(with-capability (test-mod-redeploy-ref.test)
1))

)
(expect "Name resolution should find new reference" 1 (f))
(expect "Name resolution should find new reference" 1 (test-mod-redeploy-ref.f))
(expect "Name resolution should find new reference" 1 (free.test-mod-redeploy-ref.f))

(expect "Name resolution should find new reference" 1 (f1))
(expect "Name resolution should find new reference" 1 (test-mod-redeploy-ref.f1))
(expect "Name resolution should find new reference" 1 (free.test-mod-redeploy-ref.f1))
(commit-tx)

; pact 4.7 behaviour

(begin-tx)
(namespace 'free)
(module test-mod-redeploy-ref g
(defcap g () true)

(defcap test ()
(enforce false "boom"))

(defun f ()
(with-capability (test)
1))
)
(commit-tx)

(begin-tx)
(env-exec-config ["DisablePact48"])
(namespace 'free)

(expect-failure "Name resolution should find old reference of prev. deployed module" (test-mod-redeploy-ref.f))
(expect-failure "Name resolution should find old reference of prev. deployed module" (free.test-mod-redeploy-ref.f))
(commit-tx)