-
Notifications
You must be signed in to change notification settings - Fork 206
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
Repurpose templateId in ExerciseCommand and add interfaceId in ExerciseEvent #13660
Conversation
0df48dd
to
c99239a
Compare
case Some(choice) => | ||
Right(PackageInterface.ChoiceInfo.Template(choice)) | ||
case None => | ||
template.inheritedChoices.get(chName) match { |
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.
What happens with a choice name collision here?
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.
The collision check is still in place, so nothing problematic happens.
If we disable the check, we will just get one random choice among the one that collides.
This is only used to provide a backward compatible API for Canton until they update their protocol (to track of the interfaceId
field of the ExerciseNode). I am not sure it is worthwhile to make its semantics more sensible, since we should drop soon or latter.
We could decide to make the ledger API more lenient: try to infer the choice among all the inherited choice and crash if it is ambiguous. We could reuse this lookup for this purpose. In this case we will change it to produces error in case of collision.
I will add a comment to remove it (together with ReplayCommand.LenientExercise
) once Canton have fix their protocol.
...ngine/src/main/scala/com/digitalasset/daml/lf/engine/preprocessing/CommandPreprocessor.scala
Show resolved
Hide resolved
/** Exercise a template choice, by template Id or interface Id. */ | ||
final case class LenientExercise( | ||
templateId: TypeConName, | ||
contractId: Value.ContractId, | ||
choiceId: ChoiceName, | ||
argument: Value, | ||
) extends ReplayCommand |
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 a bit confused. It looks like the implementation for LenientExercise allows exercising only by template id?
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.
Maybe worth updating the comment.
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.
Good catch I will udpate the comment.
case command.ReplayCommand.Exercise(templateId, mbIfaceId, coid, choiceId, argument) => | ||
mbIfaceId match { | ||
case Some(ifaceId) => | ||
unsafePreprocessExerciseInterface(ifaceId, coid, choiceId, argument) |
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.
If you have both an interfaceId and templateId, you should pass both to the preprocessor, and use the templateid in the exercise guard (via the speedy command ExerciseByInterface
)
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.
There's also an argument to be made here that you should be able to pass a requiring interface id as the "template id" and the required interface id as the "interface id", and have that interpreted by the ExerciseByInheritedInterface
speedy 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.
Oh if this is replay commands then this last point shouldn't matter, since you know the actually know the template id. I thought this was api commands.
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.
My PR drops the possibility to do dynamic type checking in the ledger API as you described here.
With my changes, you have:
- in case of template choice you use the templateID
- in case of interface choice you use the interfaceID.
I wanted my change on the API to be minimal. The PR just adds the optional interfaceId filed to the ExerciseEvent API output. No change to input command (in particular we still have unique identifier in the ExerciceCommand).
With my changes, one will need to use an intermediary CreateAndExercise to perform the type checking (or any other guard).
I am fine to add the field in the Exercise Command and add back the dynamic type check in an upcoming PR.
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 was confused -- I thought I was looking at changes to API command, but this is a change in the Replay command. Here for replay commands, the template id argument always refers to a template id, and the interface id always refers to the interface that defines the choice (if the choice was defined in an interface). And since it's a replay we don't need the extra type checks in the guard. So this looks fine. 👍
c99239a
to
4678e2d
Compare
...ngine/src/main/scala/com/digitalasset/daml/lf/engine/preprocessing/CommandPreprocessor.scala
Show resolved
Hide resolved
daml-script/runner/src/main/scala/com/digitalasset/daml/lf/engine/script/ScriptF.scala
Show resolved
Hide resolved
@rgugliel-da @phoebe-da, the change of Basically |
"be unable to exercise T1 by interface I2 (stopped in preprocessor)" in { | ||
val command = ApiCommand.Exercise(idT1, cid1, "C2", ValueRecord(None, ImmArray.empty)) | ||
preprocessApi(command) shouldBe a[Left[_, _]] | ||
} |
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.
please also add a test where you try to exercise an interface choice (C1) by the template (T1) and it gets stopped in preprocessor; because you should only be able to exercise interface choice by interface id
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 good to me, thank you!
ledger-api/grpc-definitions/com/daml/ledger/api/v1/commands.proto
Outdated
Show resolved
Hide resolved
ledger-api/grpc-definitions/com/daml/ledger/api/v1/commands.proto
Outdated
Show resolved
Hide resolved
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.
Is it sufficiently well documented that running the dev version of daml means you have no data continuity?
For sandbox (and I assume VMBC ledgers), --dev-mode-unsafe
only says "Turns on development mode. Development mode allows development versions of Daml-LF language.". The less dangerous --early-access-unsafe
says "Enable preview version of the next Daml-LF language. Should not be used in production.".
Also, the status of this work seems to be PoC. Are we certain that the ledger API changes are good as is? It would be confusing if we merged this to master, then released an SDK version, and then realized we have to change the new fields.
If the documentation is not clear enough, we should extend it. We have the following warning in
Because each change to LF dev is breaking, we cannot provide any form of data continuity for the dev version of LF.
For early access it is a bit different. we provide data continuity on a principal of best effort.
For the language perspective, the language team is pretty confident this is a good idea. |
c0d8256
to
7661736
Compare
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.
As discussed elsewhere:
It's not clear yet how we will store the interface name in the database, however we can merge this as is: the new data is only generated using the unsupported dev version of Daml, and the ledger api changes are benign.
00f338f
to
a03edff
Compare
CHANGELOG_BEGIN CHANGELOG_END
a03edff
to
c536422
Compare
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.
LGTM! 👍
part of #13653
CHANGELOG_BEGIN
CHANGELOG_END