LF: distinguish template Id from interface Id in exercise command (#14755)

preliminary work for #14747

CHANGELOG_BEGIN
CHANGELOG_END
This commit is contained in:
Remy 2022-08-19 14:00:40 +02:00 committed by GitHub
parent e3c2662ed9
commit 48abfeb9dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 151 additions and 72 deletions

View File

@ -5,9 +5,17 @@ package com.daml.lf
package data
// glorified Either to handle template or interface cases
sealed abstract class TemplateOrInterface[+T, +I]
sealed abstract class TemplateOrInterface[+T, +I] extends Product with Serializable
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
}
}
}

View File

@ -5,6 +5,7 @@ package com.daml.lf
package engine
package preprocessing
import com.daml.lf.data
import com.daml.lf.data._
import com.daml.lf.language.{Ast, PackageInterface}
import com.daml.lf.transaction.TransactionVersion
@ -79,17 +80,24 @@ private[lf] final class CommandPreprocessor(
}
def unsafePreprocessExercise(
typeId: Ref.Identifier,
typeId: data.TemplateOrInterface[Ref.Identifier, Ref.Identifier],
contractId: Value.ContractId,
choiceId: Ref.ChoiceName,
argument: Value,
): speedy.Command =
handleLookup(pkgInterface.lookupTemplateOrInterface(typeId)) match {
case TemplateOrInterface.Template(_) =>
unsafePreprocessExerciseTemplate(typeId, contractId, choiceId, argument)
case TemplateOrInterface.Interface(_) =>
unsafePreprocessExerciseInterface(typeId, contractId, choiceId, argument)
}
): 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)
}
def unsafePreprocessExerciseTemplate(
templateId: Ref.Identifier,
@ -178,8 +186,8 @@ private[lf] final class CommandPreprocessor(
cmd match {
case command.ApiCommand.Create(templateId, argument) =>
unsafePreprocessCreate(templateId, argument)
case command.ApiCommand.Exercise(templateId, contractId, choiceId, argument) =>
unsafePreprocessExercise(templateId, contractId, choiceId, argument)
case command.ApiCommand.Exercise(typeId, contractId, choiceId, argument) =>
unsafePreprocessExercise(typeId, contractId, choiceId, argument)
case command.ApiCommand.ExerciseByKey(templateId, contractKey, choiceId, argument) =>
unsafePreprocessExerciseByKey(templateId, contractKey, choiceId, argument)
case command.ApiCommand.CreateAndExercise(

View File

@ -137,7 +137,7 @@ private[engine] final class Preprocessor(
private[engine] def preprocessApiCommand(
cmd: command.ApiCommand
): Result[speedy.Command] =
safelyRun(pullTemplatePackage(List(cmd.typeId))) {
safelyRun(pullTemplatePackage(List(cmd.typeId.merge))) {
commandPreprocessor.unsafePreprocessApiCommand(cmd)
}
@ -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))) {
safelyRun(pullTemplatePackage(cmds.toSeq.view.map(_.typeId.merge))) {
commandPreprocessor.unsafePreprocessApiCommands(cmds)
}

View File

@ -119,7 +119,7 @@ class ApiCommandPreprocessorSpec
)
// TEST_EVIDENCE: Input Validation: well formed exercise API command is accepted
val validExeTemplate = ApiCommand.Exercise(
"Mod:Record",
TemplateOrInterface.Template("Mod:Record"),
newCid,
"Transfer",
ValueRecord("", ImmArray("content" -> ValueList(FrontStack(ValueParty("Clara"))))),
@ -133,7 +133,7 @@ class ApiCommandPreprocessorSpec
)
// TEST_EVIDENCE: Input Validation: well formed exercise-by-interface command is accepted
val validExeInterface = ApiCommand.Exercise(
"Mod:Iface",
TemplateOrInterface.Interface("Mod:Iface"),
newCid,
"IfaceChoice",
ValueUnit,
@ -162,7 +162,9 @@ class ApiCommandPreprocessorSpec
validCreate.copy(argument = ValueRecord("", ImmArray("content" -> ValueInt64(42)))) ->
a[Error.Preprocessing.TypeMismatch],
// TEST_EVIDENCE: Input Validation: ill-formed exercise API command is rejected
validExeTemplate.copy(typeId = "Mod:Undefined") ->
validExeTemplate.copy(typeId = TemplateOrInterface.Template("Mod:Undefined")) ->
a[Error.Preprocessing.Lookup],
validExeTemplate.copy(typeId = TemplateOrInterface.Interface("Mod:Undefined")) ->
a[Error.Preprocessing.Lookup],
validExeTemplate.copy(choiceId = "Undefined") ->
a[Error.Preprocessing.Lookup],
@ -215,13 +217,13 @@ class ApiCommandPreprocessorSpec
ValueRecord("", ImmArray("" -> valueParties, "" -> ValueContractId(culpritCid))),
),
ApiCommand.Exercise(
"Mod:RecordRef",
TemplateOrInterface.Template("Mod:RecordRef"),
innocentCid,
"Change",
ValueContractId(culpritCid),
),
ApiCommand.Exercise(
"Mod:RecordRef",
TemplateOrInterface.Template("Mod:RecordRef"),
culpritCid,
"Change",
ValueContractId(innocentCid),

View File

@ -7,10 +7,8 @@ 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.FrontStack
import com.daml.lf.data.{Bytes, FrontStack, ImmArray, TemplateOrInterface, Time}
import com.daml.lf.data.Ref.{Identifier, Name, PackageId, ParticipantId, Party, QualifiedName}
import com.daml.lf.data.Time
import com.daml.lf.data.{Bytes, ImmArray}
import com.daml.lf.language.Ast.Package
import com.daml.lf.ledger.FailedAuthorization.{
CreateMissingAuthorization,
@ -222,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(
"T1",
TemplateOrInterface.Template("T1"),
toContractId("t1a"),
"Choice1",
ValueRecord(
@ -244,7 +242,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"fail: ExerciseMissingAuthorization" in {
val command: ApiCommand =
ApiCommand.Exercise(
"T1",
TemplateOrInterface.Template("T1"),
toContractId("t1a"),
"Choice1",
ValueRecord(
@ -276,7 +274,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"fail: CreateMissingAuthorization" in {
val command: ApiCommand =
ApiCommand.Exercise(
"T1",
TemplateOrInterface.Template("T1"),
toContractId("t1a"),
"Choice1",
ValueRecord(
@ -307,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(
"T1",
TemplateOrInterface.Template("T1"),
toContractId("t1b"),
"Choice1",
ValueRecord(
@ -335,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(
"X1",
TemplateOrInterface.Template("X1"),
toContractId("x1b"),
"ChoiceA",
ValueRecord(
@ -378,7 +376,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz
"ok" in {
val command: ApiCommand =
ApiCommand.Exercise(
"X1",
TemplateOrInterface.Template("X1"),
toContractId("x1b"),
"ChoiceA",
ValueRecord(

View File

@ -266,7 +266,12 @@ class EngineTest
val seeding = Engine.initialSeeding(submissionSeed, participant, let)
val cid = toContractId("BasicTests:Simple:1")
val command =
ApiCommand.Exercise(templateId, cid, "Hello", ValueRecord(Some(hello), ImmArray.Empty))
ApiCommand.Exercise(
TemplateOrInterface.Template(templateId),
cid,
"Hello",
ValueRecord(Some(hello), ImmArray.Empty),
)
val submitters = Set(party)
val readAs = (Set.empty: Set[Party])
@ -1043,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(
templateId,
TemplateOrInterface.Template(templateId),
originalCoid,
"Transfer",
ValueRecord(None, ImmArray((Some[Name]("newReceiver"), ValueParty(clara)))),
@ -1226,7 +1231,7 @@ class EngineTest
def runExample(cid: ContractId, exerciseActor: Party) = {
val command = ApiCommand.Exercise(
fetcherTid,
TemplateOrInterface.Template(fetcherTid),
cid,
"DoFetch",
ValueRecord(None, ImmArray((Some[Name]("cid"), ValueContractId(fetchedCid)))),
@ -1390,7 +1395,7 @@ class EngineTest
"mark all lookupByKey nodes as byKey" in {
val exerciseCmd = ApiCommand.Exercise(
lookerUpTemplateId,
TemplateOrInterface.Template(lookerUpTemplateId),
lookerUpCid,
"Lookup",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(42)))),
@ -1422,7 +1427,7 @@ class EngineTest
"be reinterpreted to the same node when lookup finds a contract" in {
val exerciseCmd = ApiCommand.Exercise(
lookerUpTemplateId,
TemplateOrInterface.Template(lookerUpTemplateId),
lookerUpCid,
"Lookup",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(42)))),
@ -1465,7 +1470,7 @@ class EngineTest
"be reinterpreted to the same node when lookup doesn't find a contract" in {
val exerciseCmd = ApiCommand.Exercise(
lookerUpTemplateId,
TemplateOrInterface.Template(lookerUpTemplateId),
lookerUpCid,
"Lookup",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(57)))),
@ -1742,7 +1747,7 @@ class EngineTest
.preprocessApiCommands(
ImmArray(
ApiCommand.Exercise(
fetcherTemplateId,
TemplateOrInterface.Template(fetcherTemplateId),
fetcherCid,
"Fetch",
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(42)))),
@ -1809,16 +1814,21 @@ class EngineTest
val lookupContract = contracts.get _
val correctCommand =
ApiCommand.Exercise(
withKeyId,
TemplateOrInterface.Template(withKeyId),
cid,
"SumToK",
ValueRecord(None, ImmArray((None, ValueInt64(42)))),
)
val incorrectCommand =
ApiCommand.Exercise(simpleId, cid, "Hello", ValueRecord(None, ImmArray.Empty))
ApiCommand.Exercise(
TemplateOrInterface.Template(simpleId),
cid,
"Hello",
ValueRecord(None, ImmArray.Empty),
)
val incorrectFetch =
ApiCommand.Exercise(
fetcherId,
TemplateOrInterface.Template(fetcherId),
fetcherCid,
"DoFetch",
ValueRecord(None, ImmArray((None, ValueContractId(cid)))),

View File

@ -110,19 +110,39 @@ class InterfacesTest
/* generic exercise tests */
"be able to exercise interface I1 on a T1 contract" in {
val command = ApiCommand.Exercise(idI1, cid1, "C1", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
cid1,
"C1",
ValueRecord(None, ImmArray.empty),
)
runApi(command) shouldBe a[Right[_, _]]
}
"be able to exercise interface I1 on a T2 contract" in {
val command = ApiCommand.Exercise(idI1, cid2, "C1", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
cid2,
"C1",
ValueRecord(None, ImmArray.empty),
)
runApi(command) shouldBe a[Right[_, _]]
}
"be able to exercise interface I2 on a T2 contract" in {
val command = ApiCommand.Exercise(idI2, cid2, "C2", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI2),
cid2,
"C2",
ValueRecord(None, ImmArray.empty),
)
runApi(command) shouldBe a[Right[_, _]]
}
"be unable to exercise interface I2 on a T1 contract" in {
val command = ApiCommand.Exercise(idI2, cid1, "C2", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI2),
cid1,
"C2",
ValueRecord(None, ImmArray.empty),
)
inside(runApi(command)) { case Left(Error.Interpretation(err, _)) =>
err shouldBe Error.Interpretation.DamlException(
IE.ContractDoesNotImplementInterface(idI2, cid1, idT1)
@ -130,19 +150,39 @@ class InterfacesTest
}
}
"be able to exercise T1 by interface I1" in {
val command = ApiCommand.Exercise(idI1, cid1, "C1", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
cid1,
"C1",
ValueRecord(None, ImmArray.empty),
)
runApi(command) shouldBe a[Right[_, _]]
}
"be able to exercise T2 by interface I1" in {
val command = ApiCommand.Exercise(idI1, cid2, "C1", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI1),
cid2,
"C1",
ValueRecord(None, ImmArray.empty),
)
runApi(command) shouldBe a[Right[_, _]]
}
"be able to exercise T2 by interface I2" in {
val command = ApiCommand.Exercise(idI2, cid2, "C2", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idI2),
cid2,
"C2",
ValueRecord(None, ImmArray.empty),
)
runApi(command) shouldBe a[Right[_, _]]
}
"be unable to exercise T1 by interface I2 (stopped in preprocessor)" in {
val command = ApiCommand.Exercise(idT1, cid1, "C2", ValueRecord(None, ImmArray.empty))
val command = ApiCommand.Exercise(
TemplateOrInterface.Interface(idT1),
cid1,
"C2",
ValueRecord(None, ImmArray.empty),
)
preprocessApi(command) shouldBe a[Left[_, _]]
}
}

View File

@ -5,11 +5,10 @@ package com.daml.lf
package engine
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, Time}
import com.daml.lf.data.{FrontStack, ImmArray, Ref, TemplateOrInterface, Time}
import com.daml.lf.language.Ast
import com.daml.lf.scenario.ScenarioLedger
import com.daml.lf.transaction.{Node, SubmittedTransaction, VersionedTransaction}
@ -322,7 +321,7 @@ class LargeTransactionTest extends AnyWordSpec with Matchers with BazelRunfiles
): ApiCommand.Exercise = {
val choice = "ToListContainer"
val emptyArgs = ValueRecord(None, ImmArray.Empty)
ApiCommand.Exercise(templateId, contractId, choice, (emptyArgs))
ApiCommand.Exercise(TemplateOrInterface.Template(templateId), contractId, choice, (emptyArgs))
}
private def toListOfIntContainers(
@ -331,7 +330,7 @@ class LargeTransactionTest extends AnyWordSpec with Matchers with BazelRunfiles
): ApiCommand.Exercise = {
val choice = "ToListOfIntContainers"
val emptyArgs = ValueRecord(None, ImmArray.Empty)
ApiCommand.Exercise(templateId, contractId, choice, (emptyArgs))
ApiCommand.Exercise(TemplateOrInterface.Template(templateId), contractId, choice, (emptyArgs))
}
private def listUtilCreateCmd(templateId: Identifier): ApiCommand.Create = {
@ -346,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(templateId, contractId, choice, choiceArgs)
ApiCommand.Exercise(TemplateOrInterface.Template(templateId), contractId, choice, choiceArgs)
}
private def assertSizeExerciseTransaction(

View File

@ -380,6 +380,14 @@ object TransactionBuilder {
implicit def toField(t: (String, Value)): (Option[Ref.Name], Value) = toTuple(t)
implicit def toTypeId(
x: TemplateOrInterface[String, String]
): TemplateOrInterface[Ref.TypeConName, Ref.TypeConName] =
x match {
case TemplateOrInterface.Template(value) => TemplateOrInterface.Template(value)
case TemplateOrInterface.Interface(value) => TemplateOrInterface.Interface(value)
}
}
def valueRecord(id: Option[Ref.Identifier], fields: (Option[Ref.Name], Value)*) =

View File

@ -6,11 +6,11 @@ package command
import com.daml.lf.data.Ref._
import com.daml.lf.value.Value
import com.daml.lf.data.{ImmArray, Time}
import com.daml.lf.data.{ImmArray, TemplateOrInterface, Time}
/** Accepted commands coming from API */
sealed abstract class ApiCommand extends Product with Serializable {
def typeId: TypeConName
def typeId: TemplateOrInterface[TypeConName, TypeConName]
}
object ApiCommand {
@ -21,7 +21,7 @@ object ApiCommand {
* @param argument value passed to the template
*/
final case class Create(templateId: TypeConName, argument: Value) extends ApiCommand {
def typeId: TypeConName = templateId
def typeId: TemplateOrInterface.Template[TypeConName] = TemplateOrInterface.Template(templateId)
}
/** Command for exercising a choice on an existing contract
@ -32,7 +32,7 @@ object ApiCommand {
* @param argument value passed for the choice
*/
final case class Exercise(
typeId: TypeConName,
typeId: TemplateOrInterface[TypeConName, TypeConName],
contractId: Value.ContractId,
choiceId: ChoiceName,
argument: Value,
@ -51,7 +51,7 @@ object ApiCommand {
choiceId: ChoiceName,
argument: Value,
) extends ApiCommand {
def typeId: TypeConName = templateId
def typeId: TemplateOrInterface.Template[TypeConName] = TemplateOrInterface.Template(templateId)
}
/** Command for creating a contract and exercising a choice
@ -68,7 +68,7 @@ object ApiCommand {
choiceId: ChoiceName,
choiceArgument: Value,
) extends ApiCommand {
def typeId: TypeConName = templateId
def typeId: TemplateOrInterface.Template[TypeConName] = TemplateOrInterface.Template(templateId)
}
}

View File

@ -268,14 +268,14 @@ object Converter {
} yield anyChoice match {
case AnyChoice.Template(name, arg) =>
command.ApiCommand.Exercise(
typeId = tplId,
typeId = TemplateOrInterface.Template(tplId),
contractId = cid,
choiceId = name,
argument = arg.toUnnormalizedValue,
)
case AnyChoice.Interface(ifaceId, name, arg) =>
command.ApiCommand.Exercise(
typeId = ifaceId,
typeId = TemplateOrInterface.Interface(ifaceId),
contractId = cid,
choiceId = name,
argument = arg.toUnnormalizedValue,

View File

@ -296,11 +296,13 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
for {
arg <- lfValueToApiRecord(true, argument)
} yield Command().withCreate(CreateCommand(Some(toApiIdentifier(templateId)), Some(arg)))
case command.ExerciseCommand(templateId, contractId, choice, argument) =>
case command.ExerciseCommand(typeId, contractId, choice, argument) =>
for {
arg <- lfValueToApiValue(true, argument)
} yield Command().withExercise(
ExerciseCommand(Some(toApiIdentifier(templateId)), contractId.coid, choice, Some(arg))
// TODO: https://github.com/digital-asset/daml/issues/14747
// Fix once the new field interface_id have been added to the API Exercise Command
ExerciseCommand(Some(toApiIdentifier(typeId.merge)), contractId.coid, choice, Some(arg))
)
case command.ExerciseByKeyCommand(templateId, key, choice, argument) =>
for {

View File

@ -251,8 +251,10 @@ class JsonLedgerClient(
cmd match {
case command.CreateCommand(tplId, argument) =>
create(tplId, argument, partySets)
case command.ExerciseCommand(tplId, cid, choice, argument) =>
exercise(tplId, cid, choice, argument, partySets)
case command.ExerciseCommand(typeId, cid, choice, argument) =>
// TODO: https://github.com/digital-asset/daml/issues/14747
// Fix once Json API distinguish between template and interfaceId within Exercise Command
exercise(typeId.merge, cid, choice, argument, partySets)
case command.ExerciseByKeyCommand(tplId, key, choice, argument) =>
exerciseByKey(tplId, key, choice, argument, partySets)
case command.CreateAndExerciseCommand(tplId, template, choice, argument) =>

View File

@ -154,7 +154,9 @@ final class CommandsValidator(ledgerId: LedgerId) {
value <- requirePresence(e.value.choiceArgument, "value")
validatedValue <- validateValue(value)
} yield ApiCommand.Exercise(
typeId = validatedTemplateId,
// TODO: https://github.com/digital-asset/daml/issues/14747
// Fix once the new field interface_id have been added to the API Exercise Command
typeId = TemplateOrInterface.Template(validatedTemplateId),
contractId = contractId,
choiceId = choice,
argument = validatedValue,

View File

@ -7,9 +7,9 @@
- badly-authorized create is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L60)
- badly-authorized create is rejected: [AbstractHttpServiceIntegrationTest.scala](ledger-service/http-json/src/itlib/scala/http/AbstractHttpServiceIntegrationTest.scala#L1174)
- badly-authorized exercise is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L158)
- badly-authorized exercise/create (create is unauthorized) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L275)
- badly-authorized exercise/create (exercise is unauthorized) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L243)
- badly-authorized exercise/exercise (no implicit authority from outer exercise) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L334)
- badly-authorized exercise/create (create is unauthorized) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L273)
- badly-authorized exercise/create (exercise is unauthorized) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L241)
- badly-authorized exercise/exercise (no implicit authority from outer exercise) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L332)
- badly-authorized fetch is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L95)
- badly-authorized lookup is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L117)
- create IOU should fail if overwritten actAs & readAs result in missing permission even if the user would have the rights: [HttpServiceIntegrationTestUserManagement.scala](ledger-service/http-json/src/it/scala/http/HttpServiceIntegrationTestUserManagement.scala#L135)
@ -40,8 +40,8 @@
- websocket request without protocol token should be denied: [AbstractWebsocketServiceIntegrationTest.scala](ledger-service/http-json/src/itlib/scala/http/AbstractWebsocketServiceIntegrationTest.scala#L105)
- well-authorized create is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L43)
- well-authorized exercise is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L141)
- well-authorized exercise/create is accepted: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L221)
- well-authorized exercise/exercise is accepted: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L377)
- well-authorized exercise/create is accepted: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L219)
- well-authorized exercise/exercise is accepted: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L375)
- well-authorized fetch is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L89)
- well-authorized lookup is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L111)
@ -175,7 +175,7 @@
- Evaluation order of successful lookup_by_key of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2925)
- Evaluation order of successful lookup_by_key of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2773)
- Exceptions, throw/catch.: [ExceptionTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ExceptionTest.scala#L25)
- Rollback creates cannot be exercise: [EngineTest.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala#L2064)
- Rollback creates cannot be exercise: [EngineTest.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala#L2074)
- This checks that type checking in exercise_interface is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1860)
- This checks that type checking is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1750)
- This checks that type checking is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2717)
@ -218,16 +218,16 @@
- ensure expression forms have the correct type: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L108)
- error on specifying both authCommonUri and authInternalUri/authExternalUri for the trigger service: [AuthorizationConfigTest.scala](triggers/service/src/test-suite/scala/com/daml/lf/engine/trigger/AuthorizationConfigTest.scala#L24)
- error on specifying only authInternalUri and no authExternalUri for the trigger service: [AuthorizationConfigTest.scala](triggers/service/src/test-suite/scala/com/daml/lf/engine/trigger/AuthorizationConfigTest.scala#L52)
- exercise-by-interface command is rejected for a: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L171)
- exercise-by-interface command is rejected for a: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L173)
- give a 'not found' response for a stop request on an unknown UUID in the trigger service: [TriggerServiceTest.scala](triggers/service/src/test/scala/com/digitalasset/daml/lf/engine/trigger/TriggerServiceTest.scala#L552)
- give a 'not found' response for a stop request with an unparseable UUID in the trigger service: [TriggerServiceTest.scala](triggers/service/src/test/scala/com/digitalasset/daml/lf/engine/trigger/TriggerServiceTest.scala#L537)
- ill-formed create API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L159)
- ill-formed create replay command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L109)
- ill-formed create-and-exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L184)
- ill-formed create-and-exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L186)
- ill-formed exception definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1764)
- ill-formed exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L164)
- ill-formed exercise replay command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L114)
- ill-formed exercise-by-key API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L175)
- ill-formed exercise-by-key API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L177)
- ill-formed exercise-by-key replay command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L121)
- ill-formed expressions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L450)
- ill-formed fetch command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L168)