Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

Commit b5ef897

Browse files
committed
Enforce and user guards as read-only
1 parent 8045a6a commit b5ef897

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

pact-repl/Pact/Core/IR/Eval/Direct/Evaluator.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ evaluate env = \case
275275
if b then evaluate env ifExpr
276276
else evaluate env elseExpr
277277
CEnforce cond str -> do
278-
let env' = sysOnlyEnv env
278+
let env' = readOnlyEnv env
279279
b <- enforceBool info =<< evaluate env' cond
280280
-- chargeGasArgs info (GAConstant constantWorkNodeGas)
281281
if b then return (VBool True)
@@ -888,7 +888,7 @@ runUserGuard info env (UserGuard qn args) =
888888
getModuleMemberWithHash info qn >>= \case
889889
(Dfun d, mh) -> do
890890
when (length (_dfunArgs d) /= length args) $ throwExecutionError info CannotApplyPartialClosure
891-
let env' = sysOnlyEnv env
891+
let env' = readOnlyEnv env
892892
clo <- mkDefunClosure d (qualNameToFqn qn mh) env'
893893
-- Todo: sys only here
894894
True <$ (applyLam info (C clo) (VPactValue <$> args) >>= enforcePactValue info)

pact-tests/pact-tests/caps.repl

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@
4646
(defun enforce-msg-keyset (key:string)
4747
(enforce-keyset (read-keyset key)))
4848

49+
(defun create-read-only-db-user-guard ()
50+
@doc "Creates a user guard which tries to read from the DB, which is not allowed. This will fail when the guard is enforced."
51+
; this insert succeeds:
52+
(insert ints 'y {'i: 0})
53+
(create-user-guard (read-only-user-guard-fun 'y)))
54+
55+
(defun read-only-user-guard-fun (x:string)
56+
(let ((row (read ints x)))
57+
(enforce (= 0 (at 'i row)) "int wasn't zero")
58+
))
59+
60+
4961
(defun create-bad-db-user-guard ()
5062
@doc "Creates a user guard which tries to read from the DB, which is not allowed. This will fail when the guard is enforced."
5163
; this insert succeeds:
@@ -54,7 +66,9 @@
5466

5567
(defun bad-user-guard-fun (x:string)
5668
(let ((row (read ints x)))
57-
(enforce (= 0 (at 'i row)) "int wasn't zero")))
69+
(enforce (= 0 (at 'i row)) "int wasn't zero")
70+
(write ints x {"i":(+ (at "i" row) 1)})
71+
))
5872

5973
(defpact test-pact-guards (id:string)
6074
(step (step1 id))
@@ -196,7 +210,14 @@
196210
(enforce-guard (keyset-ref-guard "k2")))
197211

198212
(let ((bad-db-user-guard (create-bad-db-user-guard)))
199-
(expect-failure "reading db from within user guard" (enforce-guard bad-db-user-guard)))
213+
(expect-failure "writing to db from within user guard" (enforce-guard bad-db-user-guard)))
214+
215+
(let ((read-only-user-guard (create-read-only-db-user-guard)))
216+
(expect "User guard works successfully in read-only mode" true (enforce-guard read-only-user-guard)))
217+
218+
; The previous test wrote to 'y, so we can just reuse that
219+
(let ((read-only-user-guard (create-user-guard (read-only-user-guard-fun "y"))))
220+
(expect "Read-only works successfully in enforce" true (enforce (enforce-guard read-only-user-guard) "enforce works")))
200221

201222
(env-hash (hash "pact-guards-a-id")) ;; equivalent of pact-id
202223
(test-pact-guards "a")

pact/Pact/Core/IR/Eval/CEK/Evaluator.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ evaluateTerm cont handler env (BuiltinForm c info) = case c of
227227
-- chargeGasArgs info (GAConstant constantWorkNodeGas)
228228
evalCEK (CondC env info (IfC e1 e2) cont) handler env cond
229229
CEnforce cond str -> do
230-
let env' = sysOnlyEnv env
230+
let env' = readOnlyEnv env
231231
-- chargeGasArgs info (GAConstant constantWorkNodeGas)
232232
evalCEK (CondC env' info (EnforceC str) cont) handler env' cond
233233
-- | ------ From --------------- | ------ To ------------------------ |
@@ -1582,7 +1582,7 @@ runUserGuard info cont handler env (UserGuard qn args) =
15821582
getModuleMemberWithHash info qn >>= \case
15831583
(Dfun d, mh) -> do
15841584
when (length (_dfunArgs d) /= length args) $ throwExecutionError info CannotApplyPartialClosure
1585-
let env' = sysOnlyEnv env
1585+
let env' = readOnlyEnv env
15861586
clo <- mkDefunClosure d (qualNameToFqn qn mh) env'
15871587
-- Todo: sys only here
15881588
applyLam (C clo) (VPactValue <$> args) (IgnoreValueC (PBool True) cont) handler

0 commit comments

Comments
 (0)