-
Notifications
You must be signed in to change notification settings - Fork 205
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
Infer templateId and choiceName in daml trigger commands #2945
Conversation
Add a layer of indirection to test `exerciseCmd` in the ACS test. The trigger first creates a `AssetMirrorProposal`, only when the proposal has been created, will it exercise the `Accept` choice to create the actual `AssetMirror` contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great with some minor comments, thank you!
@@ -24,6 +24,11 @@ data Identifier = Identifier | |||
, entityName : Text | |||
} deriving (Show, Eq) | |||
|
|||
data AnyContractId = AnyContractId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn’t we expose this type (but not the constructors). I also wonder if we might just want to keep calling this ContractId
for now until we have a variant with a phantom type parameter but I guess changing it now is better for backwards compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, we should expose it. I overlooked that, good catch!
Even if we introduce a ContractId t
with a phantom type parameter, we'd still need something like AnyContractId
for the Created
and Archived
events. I figured once we introduce ContractId t
we need to change exerciseCmd
anyway, but we can keep Created
and Archived
untouched.
I have no strong opinion on the name, though, so happy to rename it if you prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s keep AnyContractId
for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn’t we expose this type (but not the constructors)
For now we need access to the templateId
field in ACS.daml
updateEvent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable 👍
createCmd : Template t => TemplateId -> t -> Command | ||
createCmd templateId templateArg = | ||
CreateCommand templateId (toLedgerValue templateArg) | ||
createCmd : Template t => t -> Command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice, this is starting to look very usable!
@@ -177,13 +181,21 @@ object Converter { | |||
("name", SText(id.entityName))) | |||
} | |||
|
|||
private def fromAnyContractId(triggerIds: TriggerIds, templateId: value.Identifier, contractId: String): SValue = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this take a value of type AnyContractId
? Seems more consistent with toAnyContractId
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In principle that would be more consistent, yes. It's a bit noisy, though, because here we have a value.Identifier
, but AnyContractId
holds an Identifier
. So, we'd be converting back and forth between the two identifier types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see, makes sense to keep it this way then. There are clearly too many things called Identifier
here 🙂
updateAcs acs (Created _ cId tId) | ||
| tId.entityName == "Asset" = TM.insert cId tId acs | ||
updateAcs acs (Created _ cId) | ||
| cId.templateId.entityName == "Asset" = TM.insert cId.contractId cId.templateId acs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m confused, it looks like you don’t expose AnyContractId
(or more likely I’m too stupid to see it) but you can still access the fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, that's why I didn't notice that I hadn't exposed it. I don't know how the field is accessible without export. The code still compiles, even if I explicitly export the type without the constructors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I think that might be because of how our record desugaring (the dot syntax used here) works. That does seem rather confusing and potentially problematic since it removes the ability to have abstract record types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Thanks.
@@ -24,6 +25,11 @@ data Identifier = Identifier | |||
, entityName : Text | |||
} deriving (Show, Eq) | |||
|
|||
data AnyContractId = AnyContractId | |||
{ templateId : Identifier | |||
, contractId : Text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use something like ContractId ()
here? There as a DAML-LF function coerce_contract_id : ContractId a -> ContractId b
which we could use then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could but I think it makes more sense to keep this consistent with AnyTemplate
. I also deliberately don’t want to use the DAML-LF ContractId
type to avoid annoyances around the absence of things like Ord
instances.
Closes #2914
templateId
fromtemplateArg
increateCmd
.choiceName
fromchoiceArg
inexerciseCmd
.AnyContractId
, which carriestemplateId
andcontractId
.templateId
fromcontractId: AnyContractId
inexerciseCmd
.exerciseCmd
.In future we may wish to pass
ContractId t
instead ofAnyContractId
. This would require something likefromAnyContractId : AnyContractId -> Option (ContractId t)
ACS
test-case to useexerciseCmd
.Introduces an indirection, where the trigger first creates
AssetMirrorProposal
and then exercises theAccept
choice that creates the actualAssetMirror
.Pull Request Checklist
NOTE: CI is not automatically run on non-members pull-requests for security
reasons. The reviewer will have to comment with
/AzurePipelines run
totrigger the build.