Skip to content

Commit

Permalink
properly acquire module governance caps at upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
sirlensalot committed Sep 19, 2023
1 parent 0f221b8 commit e7d4741
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 8 deletions.
19 changes: 17 additions & 2 deletions src/Pact/Eval.hs
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,24 @@ enforceModuleAdmin i mn modGov =
Right d@Def{..} -> case _dDefType of
Defcap -> do
af <- prepareUserAppArgs d [] _dInfo
computeUserAppGas d _dInfo
void $ evalUserAppBody d af _dInfo reduceBody
ifExecutionFlagSet FlagDisablePact49 (runCapBody d af _dInfo) $ do
-- Properly acquire gov cap to allow scoping.
-- Note that nerfed manager functions mean that a gov cap with
-- @managed will fail, which is a good thing as management of a gov
-- cap is meaningless. However we should probably enforce this in
-- module load.
let cap = SigCapability (QualifiedName _dModule (asString _dDefName) i) []
void $ evalUserCapability i nerfedFuns CapCallStack cap d $
runCapBody d af i
_ -> evalError i "enforceModuleAdmin: module governance must be defcap"
where
runCapBody d af di = do
computeUserAppGas d di
void $ evalUserAppBody d af di reduceBody
nerfedFuns =
(\_ _ _ -> evalError i "Illegal managed function application in governance defcap"
,\_ _ -> evalError i "Illegal managed function install in governance defcap"
)

withModuleKeysetMagicCap :: HasInfo i => i -> ModuleName -> Eval e a -> Eval e a
withModuleKeysetMagicCap i mn =
Expand Down
13 changes: 7 additions & 6 deletions src/Pact/Runtime/Capabilities.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,13 @@ popCapStack act = do
-- Magic caps are not managed and do not allow nested acquisition.
--
withMagicCapability :: HasInfo i => i -> Text -> [PactValue] -> Eval e a -> Eval e a
withMagicCapability i name args action = do
inscope <- capabilityAcquired cap
when inscope $ evalError' i "Internal error, magic capability already acquired"
evalCapabilities . capStack %= (slot:)
r <- action
popCapStack (const (return r))
withMagicCapability i name args action =
ifExecutionFlagSet FlagDisablePact49 action $ do
inscope <- capabilityAcquired cap
when inscope $ evalError' i "Internal error, magic capability already acquired"
evalCapabilities . capStack %= (slot:)
r <- action
popCapStack (const (return r))
where
slot = CapSlot CapCallStack cap []
cap = SigCapability (QualifiedName "pact" name def) args
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 @@ -198,6 +198,8 @@ data ExecutionFlag
| FlagDisableRuntimeReturnTypeChecking
-- | Disable Pact 4.8 Features
| FlagDisablePact48
-- | Disable Pact 4.9 Features
| FlagDisablePact49
deriving (Eq,Ord,Show,Enum,Bounded)

-- | Flag string representation
Expand Down
2 changes: 2 additions & 0 deletions tests/PactTestsSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ badErrors = M.fromList
,"Keyset failure (keys-all): 'ns.magic")
,(pfx "bad-magic-module-keyset-upgrade.repl"
,"Keyset failure (keys-all): 'ns.magic")
,(pfx "bad-gov-cap-acquire.repl"
,"Keyset failure (keys-all): [gov]")

]
where
Expand Down
22 changes: 22 additions & 0 deletions tests/pact/bad/bad-gov-cap-acquire.repl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
;; ======== test governance cap acquire ========

(begin-tx)
(env-data { 'k: ['ns], 'gov: ['gov] })
(define-namespace 'ns (read-keyset 'k) (read-keyset 'k))
(namespace 'ns)
(env-keys ['ns])
(module govcap-acquire GOV
(defcap GOV ()
(enforce-guard (read-keyset 'gov)))
(defcap OTHER () true))
(commit-tx)

(begin-tx)
(env-sigs
[ { 'key: 'gov
, 'caps: [ (ns.govcap-acquire.OTHER) ] } ])
(namespace 'ns)
;; failure because wrong cap scoped
(module govcap-acquire GOV
(defcap GOV () true))
(rollback-tx)
24 changes: 24 additions & 0 deletions tests/pact/caps.repl
Original file line number Diff line number Diff line change
Expand Up @@ -939,3 +939,27 @@
(call-op2 "goodbye" false))

(commit-tx)



;; ======== test governance cap acquire ========

(begin-tx)
(env-data { 'k: ['ns], 'gov: ['gov] })
(define-namespace 'ns (read-keyset 'k) (read-keyset 'k))
(namespace 'ns)
(env-keys ['ns])
(module govcap-acquire GOV
(defcap GOV ()
(enforce-guard (read-keyset 'gov))))
(commit-tx)

(begin-tx)
(env-sigs
[ { 'key: 'gov
, 'caps: [ (ns.govcap-acquire.GOV) ] } ])
(namespace 'ns)
;; upgrade succeeds, failure in bad tests
(module govcap-acquire GOV
(defcap GOV () true))
(rollback-tx)

0 comments on commit e7d4741

Please sign in to comment.