mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
ifaces:support exercising by required interface (#13554)
* ifaces:support exercising by required interface This adds support to exercise an interface choice on a contract ID, where the interface is required by one of the implemented interfaces of the contract template. Fixes #13434. CHANGELOG_BEGIN CHANGELOG_END * some improvements based on review * added a test plus a bugfix * Update daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/PhaseOne.scala Co-authored-by: Sofia Faro <sofia.faro@digitalasset.com> * 2 more interface tests for the command preprocessor Co-authored-by: Sofia Faro <sofia.faro@digitalasset.com>
This commit is contained in:
parent
4a3d0b316b
commit
fcd3b6622b
@ -446,6 +446,22 @@ prettyScenarioErrorError (Just err) = do
|
||||
(prettyDefName world)
|
||||
scenarioError_ContractDoesNotImplementInterfaceInterfaceId
|
||||
]
|
||||
ScenarioErrorErrorContractDoesNotImplementRequiringInterface ScenarioError_ContractDoesNotImplementRequiringInterface {..} ->
|
||||
pure $ vcat
|
||||
[ "Attempt to use a contract via a required interface, but the contract does not implement the requiring interface"
|
||||
, label_ "Contract: " $
|
||||
prettyMay "<missing contract>"
|
||||
(prettyContractRef world)
|
||||
scenarioError_ContractDoesNotImplementRequiringInterfaceContractRef
|
||||
, label_ "Required interface: " $
|
||||
prettyMay "<missing interface>"
|
||||
(prettyDefName world)
|
||||
scenarioError_ContractDoesNotImplementRequiringInterfaceRequiredInterfaceId
|
||||
, label_ "Requiring interface: " $
|
||||
prettyMay "<missing interface>"
|
||||
(prettyDefName world)
|
||||
scenarioError_ContractDoesNotImplementRequiringInterfaceRequiringInterfaceId
|
||||
]
|
||||
|
||||
partyDifference :: V.Vector Party -> V.Vector Party -> Doc SyntaxClass
|
||||
partyDifference with without =
|
||||
|
@ -229,6 +229,12 @@ message ScenarioError {
|
||||
Identifier interface_id = 2;
|
||||
}
|
||||
|
||||
message ContractDoesNotImplementRequiringInterface {
|
||||
ContractRef contract_ref = 1;
|
||||
Identifier requiring_interface_id = 2;
|
||||
Identifier required_interface_id = 3;
|
||||
}
|
||||
|
||||
// The state of the ledger at the time of the error
|
||||
repeated ScenarioStep scenario_steps = 1;
|
||||
repeated Node nodes = 2;
|
||||
@ -297,6 +303,8 @@ message ScenarioError {
|
||||
PartiesNotAllocated scenario_parties_not_allocated = 33;
|
||||
ChoiceGuardFailed choice_guard_failed = 34;
|
||||
ContractDoesNotImplementInterface contract_does_not_implement_interface = 35;
|
||||
ContractDoesNotImplementRequiringInterface contract_does_not_implement_requiring_interface
|
||||
= 36;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,19 @@ final class Conversions(
|
||||
.setInterfaceId(convertIdentifier(interfaceId))
|
||||
.build
|
||||
)
|
||||
case ContractDoesNotImplementRequiringInterface(
|
||||
requiredIfaceId,
|
||||
requiringIfaceId,
|
||||
coid,
|
||||
templateId,
|
||||
) =>
|
||||
builder.setContractDoesNotImplementRequiringInterface(
|
||||
proto.ScenarioError.ContractDoesNotImplementRequiringInterface.newBuilder
|
||||
.setContractRef(mkContractRef(coid, templateId))
|
||||
.setRequiredInterfaceId(convertIdentifier(requiredIfaceId))
|
||||
.setRequiringInterfaceId(convertIdentifier(requiringIfaceId))
|
||||
.build
|
||||
)
|
||||
case FailedAuthorization(nid, fa) =>
|
||||
builder.setScenarioCommitError(
|
||||
proto.CommitError.newBuilder
|
||||
|
@ -59,6 +59,12 @@ private[lf] final class CommandPreprocessor(
|
||||
command(choice, speedy.Command.ExerciseInterface(identifier, cid, choiceId, _))
|
||||
case ChoiceInfo.Inherited(ifaceId, choice) =>
|
||||
command(choice, speedy.Command.ExerciseByInterface(ifaceId, identifier, cid, choiceId, _))
|
||||
case ChoiceInfo.InterfaceInherited(ifaceId, choice) =>
|
||||
command(
|
||||
choice,
|
||||
speedy.Command
|
||||
.ExerciseByInheritedInterface(ifaceId, identifier, cid, choiceId, _),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,14 @@ class ApiCommandPreprocessorSpec
|
||||
controllers Mod:Record {owners} this,
|
||||
observers Nil @Party
|
||||
to create @Mod:Record Mod:Record { owners = Mod:Box @(List Party) {content} box, data = Mod:Record {data} this } ;
|
||||
implements Mod:Iface{
|
||||
method getCtrls = Mod:Record {owners} this;
|
||||
choice IfaceChoice;
|
||||
};
|
||||
implements Mod:Iface3{
|
||||
method getCtrls = Mod:Record {owners} this;
|
||||
choice IfaceChoice3;
|
||||
};
|
||||
key @(List Party) (Mod:Record {owners} this) (\ (parties: List Party) -> parties);
|
||||
};
|
||||
|
||||
@ -62,6 +70,31 @@ class ApiCommandPreprocessorSpec
|
||||
key @(List Party) (Mod:RecordRef {owners} this) (\ (parties: List Party) -> parties);
|
||||
};
|
||||
|
||||
interface (this: Iface) = {
|
||||
requires Mod:Iface3;
|
||||
precondition True;
|
||||
method getCtrls: List Party;
|
||||
choice IfaceChoice (self) (u:Unit) : Unit
|
||||
, controllers (call_method @Mod:Iface getCtrls this)
|
||||
to upure @Unit ();
|
||||
} ;
|
||||
|
||||
interface (this: Iface2) = {
|
||||
precondition True;
|
||||
method getCtrls: List Party;
|
||||
choice IfaceChoice2 (self) (u:Unit) : Unit
|
||||
, controllers (call_method @Mod:Iface2 getCtrls this)
|
||||
to upure @Unit ();
|
||||
} ;
|
||||
|
||||
interface (this: Iface3) = {
|
||||
precondition True;
|
||||
method getCtrls: List Party;
|
||||
choice IfaceChoice3 (self) (u:Unit) : Unit
|
||||
, controllers (call_method @Mod:Iface3 getCtrls this)
|
||||
to upure @Unit ();
|
||||
} ;
|
||||
|
||||
}
|
||||
"""
|
||||
|
||||
@ -96,6 +129,21 @@ class ApiCommandPreprocessorSpec
|
||||
"Transfer",
|
||||
ValueRecord("", ImmArray("content" -> ValueList(FrontStack(ValueParty("Clara"))))),
|
||||
)
|
||||
// TEST_EVIDENCE: Input Validation: well formed exercise-by-interface command is accepted
|
||||
val validExeByInterface = ApiCommand.Exercise(
|
||||
"Mod:Iface",
|
||||
newCid,
|
||||
"IfaceChoice",
|
||||
ValueUnit,
|
||||
)
|
||||
|
||||
// TEST_EVIDENCE: Input Validation: well formed exercise-by-interface via required interface command is accepted
|
||||
val validExeByRequiredInterface = ApiCommand.Exercise(
|
||||
"Mod:Iface",
|
||||
newCid,
|
||||
"IfaceChoice3",
|
||||
ValueUnit,
|
||||
)
|
||||
// TEST_EVIDENCE: Input Validation: well formed create-and-exercise API command is accepted
|
||||
val validCreateAndExe = ApiCommand.CreateAndExercise(
|
||||
"Mod:Record",
|
||||
@ -108,6 +156,8 @@ class ApiCommandPreprocessorSpec
|
||||
validCreate,
|
||||
validExe,
|
||||
validExeByKey,
|
||||
validExeByInterface,
|
||||
validExeByRequiredInterface,
|
||||
validCreateAndExe,
|
||||
)
|
||||
|
||||
@ -125,6 +175,10 @@ class ApiCommandPreprocessorSpec
|
||||
a[Error.Preprocessing.Lookup],
|
||||
validExe.copy(argument = ValueRecord("", ImmArray("content" -> ValueInt64(42)))) ->
|
||||
a[Error.Preprocessing.TypeMismatch],
|
||||
// TEST_EVIDENCE: Input Validation: exercise-by-interface command is rejected for a
|
||||
// choice of another interface.
|
||||
validExeByInterface.copy(choiceId = "IfaceChoice2") ->
|
||||
a[Error.Preprocessing.Lookup],
|
||||
// TEST_EVIDENCE: Input Validation: ill-formed exercise-by-key API command is rejected
|
||||
validExeByKey.copy(templateId = "Mod:Undefined") ->
|
||||
a[Error.Preprocessing.Lookup],
|
||||
|
@ -58,6 +58,8 @@ class InterfacesTest
|
||||
val lookupPackage = allInterfacesPkgs.get(_)
|
||||
val idI1 = Identifier(interfacesPkgId, "Interfaces:I1")
|
||||
val idI2 = Identifier(interfacesPkgId, "Interfaces:I2")
|
||||
val idI3 = Identifier(interfacesPkgId, "Interfaces:I3")
|
||||
val idI4 = Identifier(interfacesPkgId, "Interfaces:I4")
|
||||
val idT1 = Identifier(interfacesPkgId, "Interfaces:T1")
|
||||
val idT2 = Identifier(interfacesPkgId, "Interfaces:T2")
|
||||
val let = Time.Timestamp.now()
|
||||
@ -128,6 +130,14 @@ class InterfacesTest
|
||||
)
|
||||
}
|
||||
}
|
||||
"be unable to exercise an interface I4 choice via I3 on a T1 contract" in {
|
||||
val command = ApiCommand.Exercise(idI3, cid2, "C4", ValueRecord(None, ImmArray.empty))
|
||||
inside(runApi(command)) { case Left(Error.Interpretation(err, _)) =>
|
||||
err shouldBe Error.Interpretation.DamlException(
|
||||
IE.ContractDoesNotImplementRequiringInterface(idI3, idI4, cid2, idT2)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
"be able to exercise T1 by interface I1" in {
|
||||
val command = ApiCommand.Exercise(idT1, cid1, "C1", ValueRecord(None, ImmArray.empty))
|
||||
|
@ -46,6 +46,14 @@ private[lf] object Command {
|
||||
argument: SValue,
|
||||
) extends Command
|
||||
|
||||
final case class ExerciseByInheritedInterface(
|
||||
requiredIface: Identifier,
|
||||
requiringIface: Identifier,
|
||||
contractId: SContractId,
|
||||
choiceId: ChoiceName,
|
||||
argument: SValue,
|
||||
) extends Command
|
||||
|
||||
final case class ExerciseByKey(
|
||||
templateId: Identifier,
|
||||
contractKey: SValue,
|
||||
|
@ -859,6 +859,26 @@ private[lf] final class Compiler(
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def compileExerciseByInheritedInterface(
|
||||
env: Env,
|
||||
requiredIfaceId: TypeConName,
|
||||
requiringIfaceId: TypeConName,
|
||||
contractId: SValue,
|
||||
choiceId: ChoiceName,
|
||||
argument: SValue,
|
||||
): s.SExpr =
|
||||
unaryFunction(env) { (tokenPos, env) =>
|
||||
t.GuardedChoiceDefRef(requiredIfaceId, choiceId)(
|
||||
s.SEValue(contractId),
|
||||
s.SEValue(argument),
|
||||
s.SEApp(
|
||||
s.SEBuiltin(SBGuardRequiredInterfaceId(requiredIfaceId, requiringIfaceId)),
|
||||
List(s.SEValue(contractId)),
|
||||
),
|
||||
env.toSEVar(tokenPos),
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def compileFetchByInterface(
|
||||
env: Env,
|
||||
interfaceId: TypeConName,
|
||||
@ -880,6 +900,21 @@ private[lf] final class Compiler(
|
||||
compileExerciseByInterface(env, interfaceId, templateId, contractId, choiceId, argument)
|
||||
case Command.ExerciseInterface(interfaceId, contractId, choiceId, argument) =>
|
||||
t.ChoiceDefRef(interfaceId, choiceId)(s.SEValue(contractId), s.SEValue(argument))
|
||||
case Command.ExerciseByInheritedInterface(
|
||||
requiredIfaceId,
|
||||
requiringIfaceId,
|
||||
contractId,
|
||||
choiceId,
|
||||
argument,
|
||||
) =>
|
||||
compileExerciseByInheritedInterface(
|
||||
env,
|
||||
requiredIfaceId,
|
||||
requiringIfaceId,
|
||||
contractId,
|
||||
choiceId,
|
||||
argument,
|
||||
)
|
||||
case Command.ExerciseByKey(templateId, contractKey, choiceId, argument) =>
|
||||
t.ChoiceByKeyDefRef(templateId, choiceId)(s.SEValue(contractKey), s.SEValue(argument))
|
||||
case Command.Fetch(templateId, coid) =>
|
||||
|
@ -349,10 +349,12 @@ private[lf] final class PhaseOne(
|
||||
compileExp(env, exp) { exp =>
|
||||
Return(SBFromRequiredInterface(requiringIfaceId)(exp))
|
||||
}
|
||||
case EUnsafeFromRequiredInterface(requiredIfaceId @ _, requiringIfaceId, cidExp, ifaceExp) =>
|
||||
case EUnsafeFromRequiredInterface(requiredIfaceId, requiringIfaceId, cidExp, ifaceExp) =>
|
||||
compileExp(env, cidExp) { cidExp =>
|
||||
compileExp(env, ifaceExp) { ifaceExp =>
|
||||
Return(SBUnsafeFromRequiredInterface(requiringIfaceId)(cidExp, ifaceExp))
|
||||
Return(
|
||||
SBUnsafeFromRequiredInterface(requiredIfaceId, requiringIfaceId)(cidExp, ifaceExp)
|
||||
)
|
||||
}
|
||||
}
|
||||
case EInterfaceTemplateTypeRep(ifaceId, exp) =>
|
||||
|
@ -87,6 +87,18 @@ private[lf] object Pretty {
|
||||
) /
|
||||
text("Expected contract to implement interface") & prettyTypeConName(interfaceId) &
|
||||
text("but contract has type") & prettyTypeConName(templateId)
|
||||
case ContractDoesNotImplementRequiringInterface(
|
||||
requiringIfaceId,
|
||||
requiredIfaceId,
|
||||
coid,
|
||||
templateId,
|
||||
) =>
|
||||
text("Update failed due to contract") & prettyContractId(coid) & text(
|
||||
"not implementing the requiring interface"
|
||||
) /
|
||||
text("Expected contract to implement interface") & prettyTypeConName(requiringIfaceId) &
|
||||
text("requirring the interface") & prettyTypeConName(requiredIfaceId) &
|
||||
text("but contract has type") & prettyTypeConName(templateId)
|
||||
case CreateEmptyContractKeyMaintainers(tid, arg, key) =>
|
||||
text("Update failed due to a contract key with an empty sey of maintainers when creating") &
|
||||
prettyTypeConName(tid) & text("with") & prettyValue(true)(arg) /
|
||||
|
@ -1136,6 +1136,32 @@ private[lf] object SBuiltin {
|
||||
}
|
||||
}
|
||||
|
||||
final case class SBGuardRequiredInterfaceId(
|
||||
requiredIfaceId: TypeConName,
|
||||
requiringIfaceId: TypeConName,
|
||||
) extends SBuiltin(2) {
|
||||
override private[speedy] def execute(
|
||||
args: util.ArrayList[SValue],
|
||||
machine: Machine,
|
||||
) = {
|
||||
val contractId = getSContractId(args, 0)
|
||||
val (actualTmplId, record @ _) = getSAnyContract(args, 1)
|
||||
machine.returnValue = machine.compiledPackages.interface.lookupTemplate(actualTmplId) match {
|
||||
case Right(ifaceSignature) if ifaceSignature.implements.contains(requiringIfaceId) =>
|
||||
SBool(true)
|
||||
case _ =>
|
||||
throw SErrorDamlException(
|
||||
IE.ContractDoesNotImplementRequiringInterface(
|
||||
requiringIfaceId,
|
||||
requiredIfaceId,
|
||||
contractId,
|
||||
actualTmplId,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final case class SBResolveSBUBeginExercise(
|
||||
choiceName: ChoiceName,
|
||||
consuming: Boolean,
|
||||
@ -1243,7 +1269,8 @@ private[lf] object SBuiltin {
|
||||
// Convert an interface `requiredIface` to another interface `requiringIface`, if
|
||||
// the `requiringIface` implements `requiredIface`.
|
||||
final case class SBUnsafeFromRequiredInterface(
|
||||
requiringIface: TypeConName
|
||||
requiredIfaceId: TypeConName,
|
||||
requiringIfaceId: TypeConName,
|
||||
) extends SBuiltin(2) {
|
||||
|
||||
override private[speedy] def execute(
|
||||
@ -1256,10 +1283,17 @@ private[lf] object SBuiltin {
|
||||
// TODO https://github.com/digital-asset/daml/issues/11345
|
||||
// The lookup is probably slow. We may want to investigate way to make the feature faster.
|
||||
machine.returnValue = machine.compiledPackages.interface.lookupTemplate(tyCon) match {
|
||||
case Right(ifaceSignature) if ifaceSignature.implements.contains(requiringIface) =>
|
||||
case Right(ifaceSignature) if ifaceSignature.implements.contains(requiringIfaceId) =>
|
||||
SAnyContract(tyCon, record)
|
||||
case _ =>
|
||||
throw SErrorDamlException(IE.WronglyTypedContract(coid, requiringIface, tyCon))
|
||||
throw SErrorDamlException(
|
||||
IE.ContractDoesNotImplementRequiringInterface(
|
||||
requiringIfaceId,
|
||||
requiredIfaceId,
|
||||
coid,
|
||||
tyCon,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,19 @@ private[lf] class PackageInterface(signatures: PartialFunction[PackageId, Packag
|
||||
case Right(interface) =>
|
||||
interface.fixedChoices.get(chName) match {
|
||||
case Some(choice) => Right(ChoiceInfo.Interface(choice))
|
||||
case None => Left(LookupError(context, context))
|
||||
case None => {
|
||||
// TODO(drsk) improve the performance of this lookup. Tracked in issue
|
||||
// https://github.com/digital-asset/daml/issues/11345.
|
||||
interface.requires.view
|
||||
.map((iface) =>
|
||||
lookupInterfaceChoice(iface, chName, context).map((choice) => (choice, iface))
|
||||
)
|
||||
.collectFirst({ case Right((choice, iface)) => (choice, iface) }) match {
|
||||
case Some((choice, iface)) =>
|
||||
Right(ChoiceInfo.InterfaceInherited(iface, choice))
|
||||
case None => Left(LookupError(context, context))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -449,6 +461,11 @@ object PackageInterface {
|
||||
final case class Inherited(ifaceId: Identifier, choice: TemplateChoiceSignature)
|
||||
extends ChoiceInfo
|
||||
|
||||
final case class InterfaceInherited(
|
||||
ifaceId: Identifier,
|
||||
choice: TemplateChoiceSignature,
|
||||
) extends ChoiceInfo
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,13 @@ interface I2 where
|
||||
controller getOwner2 this
|
||||
do pure ()
|
||||
|
||||
interface I3 requires I4 where
|
||||
interface I4 where
|
||||
getOwner4 : Party
|
||||
choice C4 : ()
|
||||
controller getOwner4 this
|
||||
do pure ()
|
||||
|
||||
template T1
|
||||
with
|
||||
owner1 : Party
|
||||
@ -35,3 +42,5 @@ template T2
|
||||
getOwner1 = owner2
|
||||
implements I2 where
|
||||
getOwner2 = owner2
|
||||
implements I4 where
|
||||
getOwner4 = owner2
|
||||
|
@ -98,6 +98,16 @@ object Error {
|
||||
templateId: TypeConName,
|
||||
) extends Error
|
||||
|
||||
/** We tried to exercise a contract by required interface, but
|
||||
* the contract does not implement the requiring interface.
|
||||
*/
|
||||
final case class ContractDoesNotImplementRequiringInterface(
|
||||
requiringInterfaceId: TypeConName,
|
||||
requiredInterfaceId: TypeConName,
|
||||
coid: ContractId,
|
||||
templateId: TypeConName,
|
||||
) extends Error
|
||||
|
||||
/** There was an authorization failure during execution. */
|
||||
final case class FailedAuthorization(
|
||||
nid: NodeId,
|
||||
|
@ -106,6 +106,11 @@ object RejectionGenerators {
|
||||
.Error(
|
||||
renderedMessage
|
||||
)
|
||||
case _: LfInterpretationError.ContractDoesNotImplementRequiringInterface =>
|
||||
LedgerApiErrors.CommandExecution.Interpreter.InvalidArgumentInterpretationError
|
||||
.Error(
|
||||
renderedMessage
|
||||
)
|
||||
case LfInterpretationError.NonComparableValues =>
|
||||
LedgerApiErrors.CommandExecution.Interpreter.InvalidArgumentInterpretationError
|
||||
.Error(
|
||||
|
@ -212,15 +212,16 @@
|
||||
- ensure expression forms have the correct type: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L107)
|
||||
- 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#L178)
|
||||
- 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#L515)
|
||||
- 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#L500)
|
||||
- ill-formed create API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L116)
|
||||
- ill-formed create API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L166)
|
||||
- ill-formed create replay command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L108)
|
||||
- ill-formed create-and-exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L137)
|
||||
- ill-formed create-and-exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L191)
|
||||
- ill-formed exception definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1609)
|
||||
- ill-formed exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L121)
|
||||
- ill-formed exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L171)
|
||||
- ill-formed exercise replay command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L113)
|
||||
- ill-formed exercise-by-key API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L128)
|
||||
- ill-formed exercise-by-key API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L182)
|
||||
- ill-formed exercise-by-key replay command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L120)
|
||||
- ill-formed expressions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L441)
|
||||
- ill-formed fetch command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L167)
|
||||
@ -234,12 +235,14 @@
|
||||
- ill-formed type synonyms definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1797)
|
||||
- ill-formed types are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L99)
|
||||
- ill-formed variants are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1774)
|
||||
- well formed create API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L80)
|
||||
- well formed create API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L113)
|
||||
- well formed create replay command is accepted: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L80)
|
||||
- well formed create-and-exercise API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L99)
|
||||
- well formed exercise API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L85)
|
||||
- well formed create-and-exercise API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L147)
|
||||
- well formed exercise API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L118)
|
||||
- well formed exercise replay command is accepted: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L85)
|
||||
- well formed exercise-by-key API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L92)
|
||||
- well formed exercise-by-interface command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L132)
|
||||
- well formed exercise-by-interface via required interface command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L140)
|
||||
- well formed exercise-by-key API command is accepted: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L125)
|
||||
- well formed exercise-by-key command is accepted: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L92)
|
||||
- well formed fetch replay command is accepted: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L144)
|
||||
- well formed fetch-by-key replay command is accepted: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L149)
|
||||
|
Loading…
Reference in New Issue
Block a user