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

[LF] change singature Fetch/Lookup primitive #19598

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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 sdk/bazel_tools/ghc-lib/version.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ GHC_LIB_PATCHES = [
]

GHC_REPO_URL = "https://github.com/digital-asset/ghc"
GHC_REV = "a16d9661a9bc2df38974c635b96cec32b1d92939"
GHC_REV = "766a41e545e36fbbc70523f87f50128c462c9cb7"
GHC_PATCHES = [
]

Expand Down
10 changes: 5 additions & 5 deletions sdk/compiler/daml-lf-tools/src/DA/Daml/LF/TypeChecker/Check.hs
Original file line number Diff line number Diff line change
Expand Up @@ -645,12 +645,12 @@ typeOfUpdate = \case
UEmbedExpr typ e -> do
checkExpr e (TUpdate typ)
return (TUpdate typ)
UFetchByKey retrieveByKey -> do
(keyType, cidType, contractType) <- checkRetrieveByKey retrieveByKey
UFetchByKey template -> do
(keyType, cidType, contractType) <- checkRetrieveByKey template
return (keyType :-> TUpdate (TTuple2 cidType contractType))
ULookupByKey retrieveByKey -> do
(keyType, cidType, _contractType) <- checkRetrieveByKey retrieveByKey
return (keyType :-> TUpdate (TOptional cidType))
ULookupByKey template -> do
(keyType, cidType, _contractType) <- checkRetrieveByKey template
return (TInt64 :-> keyType :-> TUpdate (TList cidType))
UTryCatch typ expr var handler -> do
checkType typ KStar
checkExpr expr (TUpdate typ)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,9 @@ convertPrim _ "UExerciseByKey"
where
choiceName = ChoiceName (T.intercalate "." $ unTypeConName $ qualObject choice)

convertPrim _ "ULookupByKey" (_ :-> TUpdate (TOptional (TContractId (TCon template)))) =
pure $ EUpdate $ ULookupByKey template

convertPrim _ "UFetchByKey"
(_ :-> TUpdate (TTuple2 (TContractId (TCon template)) ty2))
| ty2 == TCon template =
pure $ EUpdate $ UFetchByKey template
convertPrim _ "ULookupByKey"
(TInt64 :-> _ :-> TUpdate (TList (TContractId (TCon tmpl)))) =
pure $ EUpdate $ ULookupByKey tmpl

convertPrim _ "ETemplateTypeRep"
(tProxy@(TApp _ tCon@(TCon _)) :-> TTypeRep) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ class HasFromAnyChoice t c r | t c -> r where
type TemplateKey t k =
( Template t
, HasKey t k
, HasLookupByKey t k
, HasFetchByKey t k
-- , HasFetchByKey t k
, HasMaintainer t k
, HasToAnyContractKey t k
, HasFromAnyContractKey t k
Expand All @@ -195,29 +194,29 @@ class HasLookupByKey t k | t -> k where
-- You must pass the `t` using an explicit type application. For
-- instance, if you want to look up a contract of template `Account` by its
-- key `k`, you must call `lookupByKey @Account k`.
lookupByKey : k -> Update (Optional (ContractId t))

-- | Exposes `fetchByKey` function. Part of the `TemplateKey` constraint.
class HasFetchByKey t k | t -> k where
-- | Fetch the contract ID and contract data associated with a given
-- contract key.
--
-- You must pass the `t` using an explicit type application. For
-- instance, if you want to fetch a contract of template `Account` by its
-- key `k`, you must call `fetchByKey @Account k`.
fetchByKey : k -> Update (ContractId t, t)
-- NOTE(F. Mazzoli): the motivation for this function to return both the
-- contract ID and the contract instance is that `fetchByKey` results in
-- a fetch node in the transaction structure, and the fetch node
-- contains the contract data, so we might as well include it here.
--
-- The reason why turning it into a fetch node is necessary is that:
-- 1. We want to have it a more relaxed authorization rule than
-- `lookupByKey`, which gets turned into a LookupByKey node;
-- 2. We want it to have the same authorization rules of a normal
-- fetch, and to implement _that_, we need to know what the
-- stakeholders of the fetched contract are, which requires
-- getting the contract instance.
lookupNByKey : Int -> k -> Update [(ContractId t)]

---- | Exposes `fetchByKey` function. Part of the `TemplateKey` constraint.
--class HasFetchByKey t k | t -> k where
-- -- | Fetch the contract ID and contract data associated with a given
-- -- contract key.
-- --
-- -- You must pass the `t` using an explicit type application. For
-- -- instance, if you want to fetch a contract of template `Account` by its
-- -- key `k`, you must call `fetchByKey @Account k`.
-- fetchNByKey : Int -> k -> Update (ContractId t, t)
-- -- NOTE(F. Mazzoli): the motivation for this function to return both the
-- -- contract ID and the contract instance is that `fetchByKey` results in
-- -- a fetch node in the transaction structure, and the fetch node
-- -- contains the contract data, so we might as well include it here.
-- --
-- -- The reason why turning it into a fetch node is necessary is that:
-- -- 1. We want to have it a more relaxed authorization rule than
-- -- `lookupByKey`, which gets turned into a LookupByKey node;
-- -- 2. We want it to have the same authorization rules of a normal
-- -- fetch, and to implement _that_, we need to know what the
-- -- stakeholders of the fetched contract are, which requires
-- -- getting the contract instance.

-- | Exposes `maintainer` function. Part of the `TemplateKey` constraint.
class HasMaintainer t k | t -> k where
Expand Down Expand Up @@ -379,12 +378,33 @@ fromAnyContractKey (AnyContractKey any rep)
deriving instance Eq Archive
deriving instance Show Archive

fetchNByKey' : (HasLookupByKey t k, HasFetch t) => Int -> k -> Update [(ContractId t, t)]
fetchNByKey' n k = do
cids <- lookupNByKey n k
forA cids $ \cid -> do
c <- fetch cid
pure (cid, c)

fetchByKey : (HasLookupByKey t k, HasFetch t) => k -> Update (ContractId t, t)
fetchByKey k = do
l <- fetchNByKey' 1 k
case l of
(h :: _) -> pure h
_ -> error "key not found"

lookupByKey : HasLookupByKey t k => k -> Update (Optional (ContractId t))
lookupByKey k = do
l <- lookupNByKey 1 k
case l of
(h :: _) -> pure $ Some h
_ -> pure None

-- | True if contract exists, submitter is a stakeholder, and all maintainers
-- authorize. False if contract does not exist and all maintainers authorize.
-- Fails otherwise.
visibleByKey : forall t k. (HasLookupByKey t k) => k -> Update Bool
visibleByKey k = do
m <- lookupByKey @t k
m <- lookupNByKey @t 1 k
case m of
Some _ -> pure True
None -> pure False
(_ :: _) -> pure True
_ -> pure False
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-- @SUPPORTS-LF-FEATURE DAML_CONTRACT_KEYS

-- @ERROR range=29:1-29:32; no contract with that key was found
-- @ERROR range=29:1-29:32; key not found
-- @ERROR range=39:1-39:29; consumed in same transaction
module ConsumedContractKey where

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-- @SUPPORTS-LF-FEATURE DAML_CONTRACT_KEYS

-- Error typically prefixed with `contract 000fffe8781952ace1141fabd7d28d48c8a157788c53392a6e698a534f89ee2779`, where the hash may change
-- @ERROR range=29:1-29:19; not effective, but we found its key!
-- @ERROR range=29:1-29:19; key not found
module ContractKeyNotEffective where

import Daml.Script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,8 @@ instance DA.Internal.Desugar.HasMaintainer K (Party, Int) where
((DA.Internal.Record.getField @"_1" key))
where
_ = key
instance DA.Internal.Desugar.HasFetchByKey K (Party, Int) where
fetchByKey = GHC.Types.primitive @"UFetchByKey"
instance DA.Internal.Desugar.HasLookupByKey K (Party, Int) where
lookupByKey = GHC.Types.primitive @"ULookupByKey"
lookupNByKey = GHC.Types.primitive @"ULookupByKey"
instance DA.Internal.Desugar.HasToAnyContractKey K (Party,
Int) where
_toAnyContractKey = GHC.Types.primitive @"EToAnyContractKey"
Expand Down
4 changes: 2 additions & 2 deletions sdk/compiler/damlc/tests/daml-test-files/FetchByKey.daml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-- @SUPPORTS-LF-FEATURE DAML_CONTRACT_KEYS

-- @ERROR range=34:1-34:11; Attempt to fetch or exercise by key
-- @ERROR range=38:1-38:11; Attempt to fetch or exercise by key
-- @ERROR range=34:1-34:11; key not found
-- @ERROR range=38:1-38:11; key not found
module FetchByKey where

import Daml.Script
Expand Down
14 changes: 7 additions & 7 deletions sdk/compiler/damlc/tests/daml-test-files/LFContractKeys.daml
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ lookupTest = script do
mcid <- submit sig do createAndExerciseCmd (Helper sig) (LookupByKey sig)
assert (mcid == Some keyedCid)

-- Stakeholder can fetch
do
(cid, l) <- submit obs do createAndExerciseCmd (Helper obs) (FetchByKey sig)
assert (keyedCid == cid)
-- Stakeholder can't lookup without authorization
submitMustFail obs do createAndExerciseCmd (Helper obs) (LookupByKey sig)
-- Stakeholder can lookup with authorization
-- FixMe nuck -- Stakeholder can fetch
Copy link
Contributor

Choose a reason for hiding this comment

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

What does nuck mean in this context? Or is it meant to be nuke?

Copy link
Contributor

Choose a reason for hiding this comment

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

Based on latter comments, maybe non-UCK is its meaning here? So I guess its an abbreviation of non-unique contract key?

-- do
-- (cid, l) <- submit obs do createAndExerciseCmd (Helper obs) (FetchByKey sig)
-- assert (keyedCid == cid)
-- -- Stakeholder can't lookup without authorization
-- submitMustFail obs do createAndExerciseCmd (Helper obs) (LookupByKey sig)
-- -- Stakeholder can lookup with authorization
do
mcid <- submit obs do
exerciseCmd sigDelegationCid LookupKeyed with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Transactions:
TX 0 1970-01-01T00:00:00Z (LfDevContractKeys:99:11)
#0:0
│ consumed by: #8:0
│ referenced by #4:2, #5:2, #8:0
│ referenced by #4:2, #5:2, #5:3, #8:0
│ disclosed to (since): 'Alice' (0), 'Bob' (0)
└─> 'Alice' creates LfDevContractKeys:TextKey
with
Expand Down Expand Up @@ -60,8 +60,14 @@ Transactions:
children:
#5:2
│ disclosed to (since): 'Alice' (5)
└─> lookupByKey LfDevContractKeys:TextKey
with key
_1 = 'Alice'; _2 = "some-key"
found: #0:0

#5:3
│ disclosed to (since): 'Alice' (5)
└─> 'Alice' fetches #0:0 (LfDevContractKeys:TextKey)
by key _1 = 'Alice'; _2 = "some-key"

TX 6 1970-01-01T00:00:00Z (LfDevContractKeys:126:13)
#6:0
Expand Down Expand Up @@ -222,7 +228,7 @@ Transactions:
└─> 'Alice' exercises Good on #13:0 (LfDevContractKeys:CreateAndLookup)
children:
#14:1
│ referenced by #14:2, #14:3
│ referenced by #14:2, #14:3, #14:4
│ disclosed to (since): 'Alice' (14)
└─> 'Alice' creates LfDevContractKeys:TextKey
with
Expand All @@ -237,8 +243,14 @@ Transactions:

#14:3
│ disclosed to (since): 'Alice' (14)
└─> lookupByKey LfDevContractKeys:TextKey
with key
_1 = 'Alice'; _2 = "same-choice-key"
found: #14:1

#14:4
│ disclosed to (since): 'Alice' (14)
└─> 'Alice' fetches #14:1 (LfDevContractKeys:TextKey)
by key _1 = 'Alice'; _2 = "same-choice-key"

TX 15 1970-01-01T00:00:00Z
mustFailAt actAs: {'Alice'} readAs: {} (LfDevContractKeys:171:3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,8 @@ instance DA.Internal.Desugar.HasMaintainer T (Party, Text) where
((DA.Internal.Record.getField @"_1" key))
where
_ = key
instance DA.Internal.Desugar.HasFetchByKey T (Party, Text) where
fetchByKey = GHC.Types.primitive @"UFetchByKey"
instance DA.Internal.Desugar.HasLookupByKey T (Party, Text) where
lookupByKey = GHC.Types.primitive @"ULookupByKey"
lookupNByKey = GHC.Types.primitive @"ULookupByKey"
instance DA.Internal.Desugar.HasToAnyContractKey T (Party,
Text) where
_toAnyContractKey = GHC.Types.primitive @"EToAnyContractKey"
Expand Down
Loading