Skip to content

Commit

Permalink
[LF] Make ApiCommand.Exercise work directly with type constructor (di…
Browse files Browse the repository at this point in the history
…gital-asset#15360)

CHANGELOG_BEGIN
CHANGELOG_END
  • Loading branch information
remyhaemmerle-da authored Oct 26, 2022
1 parent 96fb3be commit 0bba409
Show file tree
Hide file tree
Showing 14 changed files with 60 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,4 @@ sealed abstract class TemplateOrInterface[+T, +I] extends Product with Serializa
object TemplateOrInterface {
final case class Template[+T](value: T) extends TemplateOrInterface[T, Nothing]
final case class Interface[+I](value: I) extends TemplateOrInterface[Nothing, I]

implicit class MergeableTemplateOrInterface[A](private val x: TemplateOrInterface[A, A])
extends AnyVal {
def merge: A = x match {
case Template(a) => a
case Interface(a) => a
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,17 @@ private[lf] final class CommandPreprocessor(
}

def unsafePreprocessExercise(
typeId: data.TemplateOrInterface[Ref.Identifier, Ref.Identifier],
typeId: Ref.Identifier,
contractId: Value.ContractId,
choiceId: Ref.ChoiceName,
argument: Value,
): speedy.Command = typeId match {
// TODO: https://github.com/digital-asset/daml/issues/14747
// In order to split the issue in several PRs, we allow abusing the templateId case as an interface.
// We will change once we have added the interface_id field to the legder API Exercise command
case TemplateOrInterface.Template(templateId) =>
handleLookup(pkgInterface.lookupTemplateOrInterface(templateId)) match {
case TemplateOrInterface.Template(_) =>
unsafePreprocessExerciseTemplate(templateId, contractId, choiceId, argument)
case TemplateOrInterface.Interface(_) =>
unsafePreprocessExerciseInterface(templateId, contractId, choiceId, argument)
}
case TemplateOrInterface.Interface(ifaceId) =>
unsafePreprocessExerciseInterface(ifaceId, contractId, choiceId, argument)
}
): speedy.Command =
handleLookup(pkgInterface.lookupTemplateOrInterface(typeId)) match {
case TemplateOrInterface.Template(_) =>
unsafePreprocessExerciseTemplate(typeId, contractId, choiceId, argument)
case TemplateOrInterface.Interface(_) =>
unsafePreprocessExerciseInterface(typeId, contractId, choiceId, argument)
}

def unsafePreprocessExerciseTemplate(
templateId: Ref.Identifier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private[engine] final class Preprocessor(
private[engine] def preprocessApiCommand(
cmd: command.ApiCommand
): Result[speedy.Command] =
safelyRun(pullTemplatePackage(List(cmd.typeId.merge))) {
safelyRun(pullTemplatePackage(List(cmd.typeId))) {
commandPreprocessor.unsafePreprocessApiCommand(cmd)
}

Expand All @@ -146,7 +146,7 @@ private[engine] final class Preprocessor(
def preprocessApiCommands(
cmds: data.ImmArray[command.ApiCommand]
): Result[ImmArray[speedy.Command]] =
safelyRun(pullTemplatePackage(cmds.toSeq.view.map(_.typeId.merge))) {
safelyRun(pullTemplatePackage(cmds.toSeq.view.map(_.typeId))) {
commandPreprocessor.unsafePreprocessApiCommands(cmds)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class ApiCommandPreprocessorSpec
)
// TEST_EVIDENCE: Integrity: well formed exercise API command is accepted
val validExeTemplate = ApiCommand.Exercise(
TemplateOrInterface.Template("Mod:Record"),
"Mod:Record",
newCid,
"Transfer",
ValueRecord("", ImmArray("content" -> ValueList(FrontStack(ValueParty("Clara"))))),
Expand All @@ -133,7 +133,7 @@ class ApiCommandPreprocessorSpec
)
// TEST_EVIDENCE: Integrity: well formed exercise-by-interface command is accepted
val validExeInterface = ApiCommand.Exercise(
TemplateOrInterface.Interface("Mod:Iface"),
"Mod:Iface",
newCid,
"IfaceChoice",
ValueUnit,
Expand Down Expand Up @@ -162,9 +162,7 @@ class ApiCommandPreprocessorSpec
validCreate.copy(argument = ValueRecord("", ImmArray("content" -> ValueInt64(42)))) ->
a[Error.Preprocessing.TypeMismatch],
// TEST_EVIDENCE: Integrity: ill-formed exercise API command is rejected
validExeTemplate.copy(typeId = TemplateOrInterface.Template("Mod:Undefined")) ->
a[Error.Preprocessing.Lookup],
validExeTemplate.copy(typeId = TemplateOrInterface.Interface("Mod:Undefined")) ->
validExeTemplate.copy(typeId = "Mod:Undefined") ->
a[Error.Preprocessing.Lookup],
validExeTemplate.copy(choiceId = "Undefined") ->
a[Error.Preprocessing.Lookup],
Expand Down Expand Up @@ -217,13 +215,13 @@ class ApiCommandPreprocessorSpec
ValueRecord("", ImmArray("" -> valueParties, "" -> ValueContractId(culpritCid))),
),
ApiCommand.Exercise(
TemplateOrInterface.Template("Mod:RecordRef"),
"Mod:RecordRef",
innocentCid,
"Change",
ValueContractId(culpritCid),
),
ApiCommand.Exercise(
TemplateOrInterface.Template("Mod:RecordRef"),
"Mod:RecordRef",
culpritCid,
"Change",
ValueContractId(innocentCid),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package engine
import com.daml.bazeltools.BazelRunfiles
import com.daml.lf.archive.UniversalArchiveDecoder
import com.daml.lf.command.{ApiCommand, ApiCommands}
import com.daml.lf.data.{Bytes, FrontStack, ImmArray, TemplateOrInterface, Time}
import com.daml.lf.data.{Bytes, FrontStack, ImmArray, Time}
import com.daml.lf.data.Ref.{Identifier, Name, PackageId, ParticipantId, Party, QualifiedName}
import com.daml.lf.language.Ast.Package
import com.daml.lf.ledger.FailedAuthorization.{
Expand Down Expand Up @@ -220,7 +220,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"ok (Alice signed contract; Bob exercised Choice)" in {
val command: ApiCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template("T1"),
"T1",
toContractId("t1a"),
"Choice1",
ValueRecord(
Expand All @@ -242,7 +242,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"fail: ExerciseMissingAuthorization" in {
val command: ApiCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template("T1"),
"T1",
toContractId("t1a"),
"Choice1",
ValueRecord(
Expand Down Expand Up @@ -274,7 +274,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"fail: CreateMissingAuthorization" in {
val command: ApiCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template("T1"),
"T1",
toContractId("t1a"),
"Choice1",
ValueRecord(
Expand Down Expand Up @@ -305,7 +305,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"ok (Bob signed contract; Alice exercised Choice)" in {
val command: ApiCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template("T1"),
"T1",
toContractId("t1b"),
"Choice1",
ValueRecord(
Expand Down Expand Up @@ -333,7 +333,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"fail (no implicit authority from outer exercise's contract's signatories)" in {
val command: ApiCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template("X1"),
"X1",
toContractId("x1b"),
"ChoiceA",
ValueRecord(
Expand Down Expand Up @@ -376,7 +376,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"ok" in {
val command: ApiCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template("X1"),
"X1",
toContractId("x1b"),
"ChoiceA",
ValueRecord(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ class EngineTest
val cid = toContractId("BasicTests:Simple:1")
val command =
ApiCommand.Exercise(
TemplateOrInterface.Template(templateId),
templateId,
cid,
"Hello",
ValueRecord(Some(hello), ImmArray.Empty),
Expand Down Expand Up @@ -1048,7 +1048,7 @@ class EngineTest
// we need to fix time as cid are depending on it
val let = Time.Timestamp.assertFromString("1969-07-20T20:17:00Z")
val command = ApiCommand.Exercise(
TemplateOrInterface.Template(templateId),
templateId,
originalCoid,
"Transfer",
ValueRecord(None, ImmArray((Some[Name]("newReceiver"), ValueParty(clara)))),
Expand Down Expand Up @@ -1231,7 +1231,7 @@ class EngineTest

def runExample(cid: ContractId, exerciseActor: Party) = {
val command = ApiCommand.Exercise(
TemplateOrInterface.Template(fetcherTid),
fetcherTid,
cid,
"DoFetch",
ValueRecord(None, ImmArray((Some[Name]("cid"), ValueContractId(fetchedCid)))),
Expand Down Expand Up @@ -1395,7 +1395,7 @@ class EngineTest

"mark all lookupByKey nodes as byKey" in {
val exerciseCmd = ApiCommand.Exercise(
TemplateOrInterface.Template(lookerUpTemplateId),
lookerUpTemplateId,
lookerUpCid,
"Lookup",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(42)))),
Expand Down Expand Up @@ -1427,7 +1427,7 @@ class EngineTest

"be reinterpreted to the same node when lookup finds a contract" in {
val exerciseCmd = ApiCommand.Exercise(
TemplateOrInterface.Template(lookerUpTemplateId),
lookerUpTemplateId,
lookerUpCid,
"Lookup",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(42)))),
Expand Down Expand Up @@ -1470,7 +1470,7 @@ class EngineTest

"be reinterpreted to the same node when lookup doesn't find a contract" in {
val exerciseCmd = ApiCommand.Exercise(
TemplateOrInterface.Template(lookerUpTemplateId),
lookerUpTemplateId,
lookerUpCid,
"Lookup",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(57)))),
Expand Down Expand Up @@ -1747,7 +1747,7 @@ class EngineTest
.preprocessApiCommands(
ImmArray(
ApiCommand.Exercise(
TemplateOrInterface.Template(fetcherTemplateId),
fetcherTemplateId,
fetcherCid,
"Fetch",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(42)))),
Expand Down Expand Up @@ -1814,21 +1814,21 @@ class EngineTest
val lookupContract = contracts.get _
val correctCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template(withKeyId),
withKeyId,
cid,
"SumToK",
ValueRecord(None, ImmArray((None, ValueInt64(42)))),
)
val incorrectCommand =
ApiCommand.Exercise(
TemplateOrInterface.Template(simpleId),
simpleId,
cid,
"Hello",
ValueRecord(None, ImmArray.Empty),
)
val incorrectFetch =
ApiCommand.Exercise(
TemplateOrInterface.Template(fetcherId),
fetcherId,
fetcherCid,
"DoFetch",
ValueRecord(None, ImmArray((None, ValueContractId(cid)))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class InterfacesTest
/* generic exercise tests */
"be able to exercise interface I1 on a T1 contract" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
idI1,
cid1,
"C1",
ValueRecord(None, ImmArray.empty),
Expand All @@ -126,7 +126,7 @@ class InterfacesTest
}
"be able to exercise interface I1 on a T2 contract" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
idI1,
cid2,
"C1",
ValueRecord(None, ImmArray.empty),
Expand All @@ -135,7 +135,7 @@ class InterfacesTest
}
"be able to exercise interface I2 on a T2 contract" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI2),
idI2,
cid2,
"C2",
ValueRecord(None, ImmArray.empty),
Expand All @@ -144,7 +144,7 @@ class InterfacesTest
}
"be unable to exercise interface I2 on a T1 contract" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI2),
idI2,
cid1,
"C2",
ValueRecord(None, ImmArray.empty),
Expand All @@ -157,7 +157,7 @@ class InterfacesTest
}
"be able to exercise T1 by interface I1" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
idI1,
cid1,
"C1",
ValueRecord(None, ImmArray.empty),
Expand All @@ -166,7 +166,7 @@ class InterfacesTest
}
"be able to exercise T2 by interface I1" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
idI1,
cid2,
"C1",
ValueRecord(None, ImmArray.empty),
Expand All @@ -175,7 +175,7 @@ class InterfacesTest
}
"be able to exercise T2 by interface I2" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI2),
idI2,
cid2,
"C2",
ValueRecord(None, ImmArray.empty),
Expand All @@ -184,7 +184,7 @@ class InterfacesTest
}
"be unable to exercise T1 by interface I2 (stopped in preprocessor)" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idT1),
idT1,
cid1,
"C2",
ValueRecord(None, ImmArray.empty),
Expand All @@ -194,7 +194,7 @@ class InterfacesTest

"be able to exercise T2 by interface I5 and usedPackages should include I5's packageId" in {
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI5),
idI5,
cid2,
"C5",
ValueRecord(None, ImmArray.empty),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.io.File
import com.daml.bazeltools.BazelRunfiles
import com.daml.lf.archive.UniversalArchiveDecoder
import com.daml.lf.data.Ref._
import com.daml.lf.data.{FrontStack, ImmArray, Ref, TemplateOrInterface, Time}
import com.daml.lf.data.{FrontStack, ImmArray, Ref, Time}
import com.daml.lf.language.Ast
import com.daml.lf.scenario.ScenarioLedger
import com.daml.lf.transaction.{Node, SubmittedTransaction, VersionedTransaction}
Expand Down Expand Up @@ -321,7 +321,7 @@ class LargeTransactionTest extends AnyWordSpec with Matchers with BazelRunfiles
): ApiCommand.Exercise = {
val choice = "ToListContainer"
val emptyArgs = ValueRecord(None, ImmArray.Empty)
ApiCommand.Exercise(TemplateOrInterface.Template(templateId), contractId, choice, (emptyArgs))
ApiCommand.Exercise(templateId, contractId, choice, (emptyArgs))
}

private def toListOfIntContainers(
Expand All @@ -330,7 +330,7 @@ class LargeTransactionTest extends AnyWordSpec with Matchers with BazelRunfiles
): ApiCommand.Exercise = {
val choice = "ToListOfIntContainers"
val emptyArgs = ValueRecord(None, ImmArray.Empty)
ApiCommand.Exercise(TemplateOrInterface.Template(templateId), contractId, choice, (emptyArgs))
ApiCommand.Exercise(templateId, contractId, choice, (emptyArgs))
}

private def listUtilCreateCmd(templateId: Identifier): ApiCommand.Create = {
Expand All @@ -345,7 +345,7 @@ class LargeTransactionTest extends AnyWordSpec with Matchers with BazelRunfiles
val choiceDefRef = Identifier(templateId.packageId, qn(s"LargeTransaction:$choice"))
val damlList = ValueList(List.range(0L, size.toLong).map(ValueInt64).to(FrontStack))
val choiceArgs = ValueRecord(Some(choiceDefRef), ImmArray((None, damlList)))
ApiCommand.Exercise(TemplateOrInterface.Template(templateId), contractId, choice, choiceArgs)
ApiCommand.Exercise(templateId, contractId, choice, choiceArgs)
}

private def assertSizeExerciseTransaction(
Expand Down
Loading

0 comments on commit 0bba409

Please sign in to comment.