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

Namespaces #337

Merged
merged 67 commits into from Jan 5, 2019
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
17a4208
initial
emilypi Nov 21, 2018
87981c6
Merge branch 'master' into feat/56-namespaces
emilypi Nov 30, 2018
e9ee5d5
make some headway for Monday on namespaces
emilypi Dec 2, 2018
e3c2382
TODO: finish the native def - see about env comparisons during eval p…
emilypi Dec 2, 2018
b43ea58
implementation time
emilypi Dec 3, 2018
6a3821d
finished - moving on to namespace toplevel call
emilypi Dec 3, 2018
fb5710b
defineNamespaceDef now uses Guards as opposed to Keysets
emilypi Dec 3, 2018
fb4fa6b
move up and redefine defineNamespace
emilypi Dec 3, 2018
6f7086e
remove stale commentary
emilypi Dec 3, 2018
82ac2e5
use foldM, lensing in constraint solver
emilypi Dec 3, 2018
e8734d7
fix native define-namespace
emilypi Dec 4, 2018
c1d421c
updates to evalNamespace
emilypi Dec 4, 2018
672f3b3
updates to evalNamespace
emilypi Dec 4, 2018
1b3868a
move eeNamespace to EvalState, fix accordingly
emilypi Dec 4, 2018
b65ef9e
cleaner defineNamespace functionality
emilypi Dec 4, 2018
5ef53aa
keep track of namespaces declared in compile phase in Modules
emilypi Dec 4, 2018
d425e46
small formatting fixes
emilypi Dec 4, 2018
4feec92
add additional check for defined namespace while parsing
emilypi Dec 4, 2018
debec59
amend ModuleName to include NamespaceName
emilypi Dec 4, 2018
f32aa2b
small fixes - need to discuss strategy with Stuart
emilypi Dec 5, 2018
9399289
updates to useForm
emilypi Dec 5, 2018
0d01cf7
remove unnecessary comment, newline
emilypi Dec 6, 2018
9571355
remove wrong namespacing
emilypi Dec 6, 2018
f973318
add namespacing to RefState, define native def
emilypi Dec 11, 2018
a5ea88d
add namespace policy - revert modulename changes
emilypi Dec 12, 2018
2744609
add namespace policy - revert modulename changes
emilypi Dec 12, 2018
36f873a
fix some stale stuff
emilypi Dec 12, 2018
98e8cac
amend namespace native fun to overwrite current namespace)
emilypi Dec 13, 2018
f1aab98
get back to where we were
emilypi Dec 18, 2018
d683a7d
PLATED M'FERS
emilypi Dec 21, 2018
0d70559
todo: fix tables
emilypi Dec 22, 2018
f1d099a
remove namespace.hs, small cleanups here and there
emilypi Dec 23, 2018
d3bd369
clean up
emilypi Dec 24, 2018
3a27c5f
namespaces work
emilypi Dec 24, 2018
daff719
add tests for namespaces
emilypi Dec 24, 2018
ac22bb4
swap out m's for mangled versions
emilypi Dec 24, 2018
9b64d04
Fix tests, native defs, reference lookups
emilypi Dec 27, 2018
135a9eb
add qualified atom form to ExpParser, break Use so that it only
emilypi Dec 28, 2018
f443a9e
Remove `qualifiedAtom`, inline the modulename qualifier atom parsing,
emilypi Dec 28, 2018
b9038c7
change shadowed name
emilypi Dec 28, 2018
5c65c3c
Start working on tests, commit fixes to plating defs, tables, and schema
emilypi Dec 28, 2018
d8e103f
Fix up repl tests to make sure `use` takes atoms instead of strings
emilypi Dec 28, 2018
85c222a
make the examples a little more expressive
emilypi Dec 28, 2018
b8140ed
fixed tests
emilypi Dec 28, 2018
20ed609
tick examples
emilypi Dec 28, 2018
5569e6c
fix pact-functions.md
emilypi Dec 28, 2018
f47f1d1
regen pact-functions.md
emilypi Dec 28, 2018
5ca5d9e
fix up the regression formatting
emilypi Dec 28, 2018
af55fe2
fix up on final pass
emilypi Dec 28, 2018
305b7a9
doc fixes
emilypi Dec 28, 2018
40ce9a2
docs fixes 2
emilypi Dec 28, 2018
73d2695
remove unnecessary space
emilypi Dec 29, 2018
0cf6bb2
fix stu's comments
emilypi Jan 3, 2019
e5f7247
remove some unnecessary cruft for NativeDFun, change default policy t…
emilypi Jan 3, 2019
961f290
permissive policy
emilypi Jan 3, 2019
aeda2dd
doc fixes
emilypi Jan 3, 2019
f90ec3d
default -> permissive
emilypi Jan 3, 2019
9b17780
sanity prevails
emilypi Jan 3, 2019
4dbdad8
purge the data typeable
emilypi Jan 4, 2019
604c254
purge data/typable 2
emilypi Jan 4, 2019
0a121b1
fix some test code
emilypi Jan 4, 2019
6d6cefb
fix some test code
emilypi Jan 4, 2019
7f858c1
fix whitespace problems
emilypi Jan 4, 2019
7098c61
pair down some stuff
emilypi Jan 4, 2019
676359b
revert whitespaces
emilypi Jan 4, 2019
09bde8d
fix docs, remove from error string
emilypi Jan 4, 2019
f4ab22e
Fix name parser for modulenames in Remote/Server.hs
emilypi Jan 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/en/pact-functions.md
Expand Up @@ -77,6 +77,19 @@ true
```


### define-namespace {#define-namespace}

*namespace* `string` *guard* `guard` *→* `string`


Create a namespace called NAMESPACE for a given GUARD. All expressions that occur in a given transaction will be tied to NAMESPACE, and may be accessed using the toplevel call (namespace NAMESPACE) when GUARD is in scope. If NAMESPACE is already defined, then the guard previously defined in NAMESPACE will be enforced, and GUARD will be rotated in its place.
```lisp
(define-namespace 'my-namespace (read-keyset 'my-keyset))
```

Top level only: this function will fail if used in module code.


### drop {#drop}

*count*&nbsp;`integer` *list*&nbsp;`<a[[<l>],string]>` *&rarr;*&nbsp;`<a[[<l>],string]>`
Expand Down Expand Up @@ -271,6 +284,19 @@ pact> (map (+ 1) [1 2 3])
```


### namespace {#namespace}

*namespace*&nbsp;`string` *&rarr;*&nbsp;`string`


Set the current namespace to NAMESPACE. All expressions that occur in a current transaction will be contained in NAMESPACE, and once committed, mayy be accessed via their fully qualified name, which will include the namespace. For example, if Alice were to define an interface named AbstractBob in the namespace Carl, then it would be referenced by the name Carl.AbstractBob.
```lisp
(namespace 'my-namespace)
```

Top level only: this function will fail if used in module code.


### pact-id {#pact-id}

*&rarr;*&nbsp;`integer`
Expand Down
8 changes: 4 additions & 4 deletions examples/accounts/accounts.repl
Expand Up @@ -19,23 +19,23 @@
(env-data { "123-keyset": { "keys" : ["user123"], "pred": "keys-all" },
"456-keyset": { "keys": ["user456"], "pred": "keys-any" } })
(begin-tx)
(use 'accounts)
(use accounts)
(create-account "123" (read-keyset "123-keyset") "USD" (time "2016-07-22T11:26:35Z"))
(create-account "456" (read-keyset "456-keyset") "USD" (time "2016-07-22T11:26:35Z"))
(fund-account "123" 234.0 (time "2016-07-22T11:26:35Z"))
(commit-tx)
(begin-tx)
(use 'accounts)
(use accounts)
(transfer "123" "456" 5.0 (time "2016-07-22T11:26:35Z"))
(commit-tx)
(begin-tx)
(use 'accounts)
(use accounts)
;;admin reads
(expect "balance of 123 after transfer" 229.0 (with-read accounts "123" { "balance" := b } b))
(expect "balance of 456 after transfer" 5.0 (with-read accounts "456" { "balance" := b } b))
(commit-tx)
(begin-tx)
(use 'accounts)
(use accounts)
(env-keys ["user123" "user456"])
(expect-failure "should not allow read" (with-read accounts "123" { "balance" := b } b))

Expand Down
4 changes: 2 additions & 2 deletions src-ghc/Pact/Bench.hs
Expand Up @@ -72,7 +72,7 @@ loadBenchModule db = do
(object ["keyset" .= object ["keys" .= ["benchadmin"::Text], "pred" .= (">"::Text)]])
Nothing
initialHash
erRefStore <$> evalExec (setupEvalEnv db entity (Transactional 1) md initRefStore freeGasEnv) pc
erRefStore <$> evalExec (setupEvalEnv db entity (Transactional 1) md initRefStore freeGasEnv permissiveNamespacePolicy) pc

parseCode :: Text -> IO ParsedCode
parseCode m = ParsedCode m <$> eitherDie (parseExprs m)
Expand All @@ -83,7 +83,7 @@ benchNFIO bname = bench bname . nfIO
runPactExec :: PactDbEnv e -> RefStore -> ParsedCode -> IO Value
runPactExec dbEnv refStore pc = do
t <- Transactional . fromIntegral <$> getCPUTime
toJSON . erOutput <$> evalExec (setupEvalEnv dbEnv entity t (initMsgData initialHash) refStore freeGasEnv) pc
toJSON . erOutput <$> evalExec (setupEvalEnv dbEnv entity t (initMsgData initialHash) refStore freeGasEnv permissiveNamespacePolicy) pc

benchKeySet :: KeySet
benchKeySet = KeySet [PublicKey "benchadmin"] (Name ">" def)
Expand Down
15 changes: 12 additions & 3 deletions src-ghc/Pact/Interpreter.hs
Expand Up @@ -23,6 +23,7 @@ import Control.Monad.Catch
import Data.Maybe
import qualified Data.HashMap.Strict as HM

import Pact.Types.Term
import Pact.Types.Runtime
import Pact.Compile
import Pact.Eval
Expand Down Expand Up @@ -68,9 +69,16 @@ evalContinuation :: EvalEnv e -> Term Name -> IO EvalResult
evalContinuation ee pact = interpret ee [pact]


setupEvalEnv :: PactDbEnv e -> Maybe EntityName -> ExecutionMode ->
MsgData -> RefStore -> GasEnv -> EvalEnv e
setupEvalEnv dbEnv ent mode msgData refStore gasEnv =
setupEvalEnv
:: PactDbEnv e
-> Maybe EntityName
-> ExecutionMode
-> MsgData
-> RefStore
-> GasEnv
-> NamespacePolicy
-> EvalEnv e
setupEvalEnv dbEnv ent mode msgData refStore gasEnv np =
EvalEnv {
_eeRefStore = refStore
, _eeMsgSigs = mdSigs msgData
Expand All @@ -83,6 +91,7 @@ setupEvalEnv dbEnv ent mode msgData refStore gasEnv =
, _eePurity = PImpure
, _eeHash = mdHash msgData
, _eeGasEnv = gasEnv
, _eeNamespacePolicy = np
}
where modeToTx (Transactional t) = Just t
modeToTx Local = Nothing
Expand Down
6 changes: 4 additions & 2 deletions src-ghc/Pact/PersistPactDb/Regression.hs
Expand Up @@ -31,7 +31,9 @@ runRegression p = do
createUserTable' v user1 "someModule" "someKeyset"
assertEquals' "output of commit 2"
[TxLog "SYS_usertables" "user1" $
object [("utModule" .= String "someModule"),("utKeySet" .= String "someKeyset")]
object [ ("utModule" .= object [ ("name" .= String "someModule"), ("namespace" .= Null)])
, ("utKeySet" .= String "someKeyset")
]
]
(commit v)
t3 <- begin v t2
Expand All @@ -57,7 +59,7 @@ runRegression p = do
,("blessed" .= ([]::[Text]))
,("keyset" .= String "mod-admin-keyset")
,("interfaces" .= ([]::[Text]))
,("name" .= String "mod1")
,("name" .= object [ ("name" .= String "mod1"), ("namespace" .= Null)])
,("code" .= String "code")
,("meta" .= object [("model" .= ([] :: [Text]))
,("docs" .= Null)])]
Expand Down
2 changes: 1 addition & 1 deletion src-ghc/Pact/ReplTools.hs
Expand Up @@ -55,7 +55,7 @@ completeFn = completeQuotedWord (Just '\\') "\"" listFiles $
unName (Name name _) = name

nameOfModule :: ModuleName -> Text
nameOfModule (ModuleName name) = name
nameOfModule (ModuleName name _) = name

replSettings :: (MonadIO m, MonadState ReplState m) => Settings m
replSettings = Settings
Expand Down
12 changes: 6 additions & 6 deletions src-ghc/Pact/Server/PactService.hs
Expand Up @@ -101,7 +101,7 @@ applyExec rk (ExecMsg parsedCode edata) Command{..} = do
(CommandState refStore pacts) <- liftIO $ readMVar _ceState
let sigs = userSigsToPactKeySet _cmdSigs
evalEnv = setupEvalEnv _ceDbEnv _ceEntity _ceMode
(MsgData sigs edata Nothing _cmdHash) refStore _ceGasEnv
(MsgData sigs edata Nothing _cmdHash) refStore _ceGasEnv permissiveNamespacePolicy
pr <- liftIO $ evalExec evalEnv parsedCode
newCmdPact <- join <$> mapM (handlePactExec (erInput pr)) (erExec pr)
let newPacts = case newCmdPact of
Expand Down Expand Up @@ -145,15 +145,15 @@ applyContinuation rk msg@ContMsg{..} Command{..} = do
pactStep = Just $ PactStep _cmStep _cmRollback (PactId $ pack $ show _cmTxId) _cpYield
evalEnv = setupEvalEnv _ceDbEnv _ceEntity _ceMode
(MsgData sigs _cmData pactStep _cmdHash) _csRefStore
_ceGasEnv
_ceGasEnv permissiveNamespacePolicy
res <- tryAny (liftIO $ evalContinuation evalEnv _cpContinuation)

-- Update pacts state
case res of
Left (SomeException ex) -> throwM ex
Right EvalResult{..} -> do
exec@PactExec{..} <- maybe (throwCmdEx "No pact execution in continuation exec!")
return erExec
return erExec
if _cmRollback
then rollbackUpdate env msg state
else continuationUpdate env msg state pact exec
Expand All @@ -162,7 +162,7 @@ applyContinuation rk msg@ContMsg{..} Command{..} = do
rollbackUpdate :: CommandEnv p -> ContMsg -> CommandState -> CommandM p ()
rollbackUpdate CommandEnv{..} ContMsg{..} CommandState{..} = do
-- if step doesn't have a rollback function, no error thrown. Therefore, pact will be deleted
-- from state.
-- from state.
let newState = CommandState _csRefStore $ M.delete _cmTxId _csPacts
liftIO $ logLog _ceLogger "DEBUG" $ "applyContinuation: rollbackUpdate: reaping pact "
++ show _cmTxId
Expand All @@ -172,7 +172,7 @@ continuationUpdate :: CommandEnv p -> ContMsg -> CommandState -> CommandPact ->
continuationUpdate CommandEnv{..} ContMsg{..} CommandState{..} CommandPact{..} PactExec{..} = do
let nextStep = _cmStep + 1
isLast = nextStep >= _cpStepCount
updateState pacts = CommandState _csRefStore pacts -- never loading modules during continuations
updateState pacts = CommandState _csRefStore pacts -- never loading modules during continuations

if isLast
then do
Expand All @@ -183,4 +183,4 @@ continuationUpdate CommandEnv{..} ContMsg{..} CommandState{..} CommandPact{..} P
let newPact = CommandPact _cpTxId _cpContinuation _cpStepCount _cmStep _peYield
liftIO $ logLog _ceLogger "DEBUG" $ "applyContinuation: updated state of pact "
++ show _cmTxId ++ ": " ++ show newPact
void $ liftIO $ swapMVar _ceState $ updateState $ M.insert _cmTxId newPact _csPacts
void $ liftIO $ swapMVar _ceState $ updateState $ M.insert _cmTxId newPact _csPacts
sirlensalot marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 3 additions & 3 deletions src/Pact/Analyze/Remote/Server.hs
Expand Up @@ -90,9 +90,9 @@ validateRequest = do
Just mod' -> Right $ ValidRequest modsMap mod'
Nothing -> Left $ ClientError $
case modName of
ModuleName nm ->
ModuleName mn _ ->
let names = HM.keys modsMap
in show nm ++ " not found in list of provided modules: "
in show mn ++ " not found in list of provided modules: "
++ show names

initializeRepl :: IO ReplState
Expand Down Expand Up @@ -122,7 +122,7 @@ moduleNotFoundP = MP.string "<interactive>:"
*> digitsP *> MP.char ':'
*> digitsP *> MP.char ':'
*> MP.string " Module \""
*> fmap (ModuleName . T.pack) (MP.some $ MP.notChar '"')
*> fmap (\a -> ModuleName (T.pack a) Nothing) (MP.some $ MP.notChar '"')
Copy link
Member Author

Choose a reason for hiding this comment

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

This is something I'd like the folks handling the remote stuff to take a look at

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's create a dedicated issue for this

Copy link
Member Author

Choose a reason for hiding this comment

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

Done here: #350

Copy link
Member Author

Choose a reason for hiding this comment

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

This is actually breaking a test I think - we'll discuss tomorrow

<* MP.string "\" not found"
where
digitsP :: MP.Parsec Void String ()
Expand Down
62 changes: 35 additions & 27 deletions src/Pact/Compile.hs
Expand Up @@ -21,13 +21,10 @@
--

module Pact.Compile
(
compile,compileExps
,MkInfo,mkEmptyInfo,mkStringInfo,mkTextInfo
,Reserved(..)
)

where
( compile,compileExps
, MkInfo,mkEmptyInfo,mkStringInfo,mkTextInfo
, Reserved(..)
) where

import qualified Text.Trifecta as TF hiding (expected)
import Control.Applicative hiding (some,many)
Expand Down Expand Up @@ -127,6 +124,9 @@ instance AsString Reserved where

instance Show Reserved where show = unpack . asString

checkReserved :: Text -> Compile ()
checkReserved t = when (t `elem` reserved) $ unexpected' "reserved word"

reserveds :: HM.HashMap Text Reserved
reserveds = (`foldMap` [minBound .. maxBound]) $ \r -> HM.singleton (asString r) r

Expand Down Expand Up @@ -158,7 +158,7 @@ withModuleState :: ModuleState -> Compile a -> Compile (a,ModuleState)
withModuleState ms0 act = do
psUser . csModule .= Just ms0
a <- act
ms1 <- state $ \s -> (view (psUser . csModule) s,set (psUser .csModule) Nothing s)
ms1 <- state $ \s -> (view (psUser . csModule) s, set (psUser . csModule) Nothing s)
case ms1 of
Nothing -> syntaxError "Invalid internal state, module data not found"
Just ms -> return (a,ms)
Expand All @@ -167,6 +167,16 @@ withModuleState ms0 act = do
currentModuleName :: Compile ModuleName
currentModuleName = _msName <$> moduleState

-- | Construct a potentially namespaced module name from qualified atom
qualifiedModuleName :: Compile ModuleName
qualifiedModuleName = do
AtomExp{..} <- atom
checkReserved _atomAtom
case _atomQualifiers of
[] -> return $ ModuleName _atomAtom Nothing
[n] -> return $ ModuleName _atomAtom (Just . NamespaceName $ n)
_ -> expected "qualified module name reference"

freshTyVar :: Compile (Type (Term Name))
freshTyVar = do
c <- state (view (psUser . csFresh) &&& over (psUser . csFresh) succ)
Expand Down Expand Up @@ -219,7 +229,7 @@ moduleLevel = specialForm $ \r -> case r of
RDefun -> returnl $ defunOrCap Defun
RDefcap -> returnl $ defunOrCap Defcap
RDefpact -> returnl defpact
RImplements -> return (implements >> return [])
RImplements -> return $ implements >> return []
_ -> expected "module level form (use, def..., special form)"
where returnl a = return (pure <$> a)

Expand All @@ -231,15 +241,13 @@ literals =
<|> objectLiteral


-- | User-available atoms (excluding reserved words).
-- | Bare atoms (excluding reserved words).
userAtom :: Compile (AtomExp Info)
userAtom = do
a@AtomExp{..} <- bareAtom
when (_atomAtom `elem` reserved) $ unexpected' "reserved word"
checkReserved _atomAtom
pure a



app :: Compile (Term Name)
app = do
v <- varAtom
Expand All @@ -266,13 +274,16 @@ bindingForm = do
varAtom :: Compile (Term Name)
varAtom = do
AtomExp{..} <- atom
when (_atomAtom `elem` reserved) $ unexpected' "reserved word"
checkReserved _atomAtom
n <- case _atomQualifiers of
[] -> return $ Name _atomAtom _atomInfo
[q] -> do
when (q `elem` reserved) $ unexpected' "reserved word"
return $ QName (ModuleName q) _atomAtom _atomInfo
_ -> expected "single qualifier"
checkReserved q
return $ QName (ModuleName q Nothing) _atomAtom _atomInfo
[ns,q] -> do
checkReserved ns >> checkReserved q
return $ QName (ModuleName q (Just . NamespaceName $ ns)) _atomAtom _atomInfo
_ -> expected "bareword or qualified atom"
commit
return $ TVar n _atomInfo

Expand Down Expand Up @@ -310,8 +321,6 @@ withCapability = do
i <- contextInfo
return $ TApp (App wcVar [capApp,TList body TyAny (_tInfo top)] i) i



deftable :: Compile (Term Name)
deftable = do
ModuleState{..} <- moduleState
Expand All @@ -335,7 +344,6 @@ defconst = do
modName <- currentModuleName
a <- arg
v <- valueLevel

m <- meta ModelNotAllowed
TConst a modName (CVRaw v) m <$> contextInfo

Expand Down Expand Up @@ -414,7 +422,7 @@ moduleForm = do
let code = case i of
Info Nothing -> "<code unavailable>"
Info (Just (c,_)) -> c
modName = ModuleName modName'
modName = ModuleName modName' Nothing
modHash = hash $ encodeUtf8 $ _unCode code
((bd,bi),ModuleState{..}) <- withModuleState (initModuleState modName modHash) $ bodyForm' moduleLevel
return $ TModule
Expand All @@ -423,8 +431,8 @@ moduleForm = do

implements :: Compile ()
implements = do
ifName <- (ModuleName . _atomAtom) <$> bareAtom
overModuleState msImplements (ifName:)
ifn <- qualifiedModuleName
overModuleState msImplements (ifn:)


interface :: Compile (Term Name)
Expand All @@ -438,7 +446,7 @@ interface = do
let code = case info of
Info Nothing -> "<code unavailable>"
Info (Just (c,_)) -> c
iname = ModuleName iname'
iname = ModuleName iname' Nothing
ihash = hash $ encodeUtf8 (_unCode code)
(bd,ModuleState{..}) <- withModuleState (initModuleState iname ihash) $
bodyForm $ specialForm $ \r -> case r of
Expand Down Expand Up @@ -513,9 +521,9 @@ letsForm = do

useForm :: Compile (Term Name)
useForm = do
modName <- (_atomAtom <$> userAtom) <|> str <|> expected "bare atom, string, symbol"
i <- contextInfo
u <- Use (ModuleName modName) <$> optional hash' <*> pure i
mn <- qualifiedModuleName
i <- contextInfo
u <- Use mn <$> optional hash' <*> pure i
-- this is the one place module may not be present, use traversal
psUser . csModule . _Just . msImports %= (u:)
return $ TUse u i
Expand Down