From b73054575264bde9a8af14078bb06d835dcd5da4 Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Thu, 14 Oct 2021 14:58:16 +0100 Subject: [PATCH 01/11] Test authorization within Exercise choice. CHANGELOG_BEGIN CHANGELOG_END --- daml-lf/engine/BUILD.bazel | 1 + .../daml/lf/engine/AuthPropagationSpec.scala | 322 ++++++++++++++++++ daml-lf/tests/AuthTests.daml | 23 ++ daml-lf/tests/BUILD.bazel | 1 + 4 files changed, 347 insertions(+) create mode 100644 daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala create mode 100644 daml-lf/tests/AuthTests.daml diff --git a/daml-lf/engine/BUILD.bazel b/daml-lf/engine/BUILD.bazel index fa551c5b97e3..9d70484de996 100644 --- a/daml-lf/engine/BUILD.bazel +++ b/daml-lf/engine/BUILD.bazel @@ -47,6 +47,7 @@ da_scala_test_suite( ], ), data = [ + "//daml-lf/tests:AuthTests.dar", "//daml-lf/tests:BasicTests.dar", "//daml-lf/tests:Exceptions.dar", "//daml-lf/tests:MultiKeys.dar", diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala new file mode 100644 index 000000000000..303716c0a34a --- /dev/null +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -0,0 +1,322 @@ +// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.daml.lf +package engine + +import com.daml.bazeltools.BazelRunfiles +import com.daml.lf.archive.UniversalArchiveDecoder +import com.daml.lf.command.{ApiCommand, Commands, CreateCommand, ExerciseCommand} +import com.daml.lf.data.Ref.{ + Name, + Party, + ParticipantId, + PackageId, + Identifier, + QualifiedName, + ChoiceName, +} +import com.daml.lf.data.Time +import com.daml.lf.data.{ImmArray, Bytes} +import com.daml.lf.language.Ast.Package +import com.daml.lf.ledger.FailedAuthorization.{ + CreateMissingAuthorization, + ExerciseMissingAuthorization, +} +import com.daml.lf.transaction.GlobalKeyWithMaintainers +import com.daml.lf.transaction.Transaction.Metadata +import com.daml.lf.transaction.{SubmittedTransaction, TransactionVersion} +import com.daml.lf.value.Value +import com.daml.lf.value.Value.{ContractId, ContractInst, VersionedValue, ValueRecord, ValueParty} + +import java.io.File + +import org.scalatest.Inside +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers + +class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with BazelRunfiles { + + def loadPackage(resource: String): (PackageId, Package, Map[PackageId, Package]) = { + val packages = UniversalArchiveDecoder.assertReadFile(new File(rlocation(resource))) + val (mainPkgId, mainPkg) = packages.main + (mainPkgId, mainPkg, packages.all.toMap) + } + + val (packageId, _, allPackages) = loadPackage( + "daml-lf/tests/AuthTests.dar" + ) + + def toContractId(s: String): ContractId = { + def dummySuffix: Bytes = Bytes.assertFromString("00") + ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), dummySuffix) + } + + // field names + def party: Name = Name.assertFromString("party") + def party1: Name = Name.assertFromString("party1") + def party2: Name = Name.assertFromString("party2") + + def t1: Identifier = + Identifier(packageId, QualifiedName.assertFromString("AuthTests:T1")) + + def t2: Identifier = + Identifier(packageId, QualifiedName.assertFromString("AuthTests:T2")) + + def choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") + def choice1type: Identifier = + Identifier(packageId, QualifiedName.assertFromString("AuthTests:Choice1")) + + def alice: Party = Party.assertFromString("Alice") + def bob: Party = Party.assertFromString("Bob") + + def t1InstanceFor(x: Party): ContractInst[Value.VersionedValue] = { + ContractInst( + t1, + VersionedValue( + TransactionVersion.VDev, + ValueRecord( + Some(t1), + ImmArray((Some[Name](party), ValueParty(x))), + ), + ), + "", + ) + } + + val t1a = t1InstanceFor(alice) + val t1b = t1InstanceFor(bob) + + val defaultContracts: Map[ContractId, ContractInst[Value.VersionedValue]] = + Map( + toContractId("t1a") -> t1a, + toContractId("t1b") -> t1b, + ) + + def readAs: Set[Party] = Set.empty + def let: Time.Timestamp = Time.Timestamp.now() + def participant: ParticipantId = ParticipantId.assertFromString("participant") + def submissionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("submissionSeed") + + def lookupPackage: PackageId => Option[Package] = + pkgId => allPackages.get(pkgId) + + def lookupContract: ContractId => Option[ContractInst[VersionedValue]] = + cid => defaultContracts.get(cid) + + def lookupKey: GlobalKeyWithMaintainers => Option[ContractId] = + _ => None + + def testEngine: Engine = + Engine.DevEngine() + + def go( + submitters: Set[Party], + command: ApiCommand, + ): Either[engine.Error, (SubmittedTransaction, Metadata)] = { + + val interpretResult = + testEngine + .submit( + submitters, + readAs, + Commands(ImmArray(command), let, "commands-tag"), + participant, + submissionSeed, + ) + .consume(lookupContract, lookupPackage, lookupKey) + + interpretResult + } + + "Create(T1)" - { + def command: ApiCommand = + CreateCommand( + t1, + ValueRecord( + Some(t1), + ImmArray( + (Some[Name](party), ValueParty(alice)) + ), + ), + ) + "ok" in { + val interpretResult = go( + submitters = Set(alice), + command = command, + ) + inside(interpretResult) { case Right(_) => + } + } + "fail" in { + val interpretResult = go( + submitters = Set.empty, + command = command, + ) + inside(interpretResult) { + case Left( + engine.Error.Interpretation( + engine.Error.Interpretation.DamlException( + interpretation.Error + .FailedAuthorization(_, CreateMissingAuthorization(_, _, _, _)) + ), + _, + ) + ) => + } + } + } + + "Create(T2)" - { + def command: ApiCommand = + CreateCommand( + t2, + ValueRecord( + Some(t2), + ImmArray( + (Some[Name](party1), ValueParty(alice)), + (Some[Name](party2), ValueParty(bob)), + ), + ), + ) + + "ok" in { + val interpretResult = go( + submitters = Set(alice, bob), + command = command, + ) + inside(interpretResult) { case Right(_) => + } + } + "fail" in { + val interpretResult = go( + submitters = Set(alice), + command = command, + ) + inside(interpretResult) { + case Left( + engine.Error.Interpretation( + engine.Error.Interpretation.DamlException( + interpretation.Error + .FailedAuthorization(_, CreateMissingAuthorization(_, _, _, _)) + ), + _, + ) + ) => + } + } + } + + // Test authorization of an exercise choice collects authority from both + // the contract signatory and the choice controller + + "Exercise(Choice1 of T1 to create T2)" - { + + "ok (Alice signed contract; Bob exercised Choice)" in { + def command: ApiCommand = + ExerciseCommand( + t1, + toContractId("t1a"), + choice1name, + ValueRecord( + Some(choice1type), + ImmArray( + (Some[Name](party1), ValueParty(alice)), + (Some[Name](party2), ValueParty(bob)), + ), + ), + ) + val interpretResult = go( + submitters = Set(bob), + command = command, + ) + inside(interpretResult) { case Right(_) => + } + } + + "fail: ExerciseMissingAuthorization" in { + def command: ApiCommand = + ExerciseCommand( + t1, + toContractId("t1a"), + choice1name, + ValueRecord( + Some(choice1type), + ImmArray( + (Some[Name](party1), ValueParty(alice)), + (Some[Name](party2), ValueParty(bob)), + ), + ), + ) + val interpretResult = go( + submitters = Set(alice), + command = command, + ) + inside(interpretResult) { + case Left( + engine.Error.Interpretation( + engine.Error.Interpretation.DamlException( + interpretation.Error + .FailedAuthorization(_, ExerciseMissingAuthorization(_, _, _, _, _)) + ), + _, + ) + ) => + } + } + + "fail: CreateMissingAuthorization" in { + def command: ApiCommand = + ExerciseCommand( + t1, + toContractId("t1a"), + choice1name, + ValueRecord( + Some(choice1type), + ImmArray( + (Some[Name](party1), ValueParty(bob)), + (Some[Name](party2), ValueParty(alice)), + ), + ), + ) + val interpretResult = go( + submitters = Set(alice), + command = command, + ) + inside(interpretResult) { + case Left( + engine.Error.Interpretation( + engine.Error.Interpretation.DamlException( + interpretation.Error + .FailedAuthorization(_, CreateMissingAuthorization(_, _, _, _)) + ), + _, + ) + ) => + } + } + + "ok (Bob signed contract; Alice exercised Choice)" in { + def command: ApiCommand = + ExerciseCommand( + t1, + toContractId("t1b"), + choice1name, + ValueRecord( + Some(choice1type), + ImmArray( + (Some[Name](party1), ValueParty(bob)), + (Some[Name](party2), ValueParty(alice)), + ), + ), + ) + val interpretResult = go( + submitters = Set(alice), + command = command, + ) + inside(interpretResult) { case Right(_) => + } + } + + } +} diff --git a/daml-lf/tests/AuthTests.daml b/daml-lf/tests/AuthTests.daml new file mode 100644 index 000000000000..4633897f2c97 --- /dev/null +++ b/daml-lf/tests/AuthTests.daml @@ -0,0 +1,23 @@ +-- Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +-- SPDX-License-Identifier: Apache-2.0 + +module AuthTests where + +template T1 with + party : Party + where + signatory party + + nonconsuming choice Choice1 : ContractId T2 + with + party1 : Party + party2 : Party + controller party2 + do + create T2 with party1; party2 + +template T2 with + party1 : Party + party2 : Party + where + signatory [party1,party2] diff --git a/daml-lf/tests/BUILD.bazel b/daml-lf/tests/BUILD.bazel index 1fca229ed0eb..0377e1a551d7 100644 --- a/daml-lf/tests/BUILD.bazel +++ b/daml-lf/tests/BUILD.bazel @@ -19,6 +19,7 @@ TEST_FILES = \ "LargeTransaction", "ConjunctionChoices", "ContractKeys", + "AuthTests", ] [ From cdce1a990ed83ae25dcbfd344d3aa0b2d471bb66 Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Thu, 14 Oct 2021 15:32:21 +0100 Subject: [PATCH 02/11] fix build following rebase --- .../daml/lf/engine/AuthPropagationSpec.scala | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index 303716c0a34a..a0b6fe317d3c 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -26,8 +26,7 @@ import com.daml.lf.ledger.FailedAuthorization.{ import com.daml.lf.transaction.GlobalKeyWithMaintainers import com.daml.lf.transaction.Transaction.Metadata import com.daml.lf.transaction.{SubmittedTransaction, TransactionVersion} -import com.daml.lf.value.Value -import com.daml.lf.value.Value.{ContractId, ContractInst, VersionedValue, ValueRecord, ValueParty} +import com.daml.lf.value.Value.{ContractId, ValueRecord, ValueParty, VersionedContractInstance} import java.io.File @@ -70,15 +69,13 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz def alice: Party = Party.assertFromString("Alice") def bob: Party = Party.assertFromString("Bob") - def t1InstanceFor(x: Party): ContractInst[Value.VersionedValue] = { - ContractInst( + def t1InstanceFor(x: Party): VersionedContractInstance = { + VersionedContractInstance( + TransactionVersion.VDev, t1, - VersionedValue( - TransactionVersion.VDev, - ValueRecord( - Some(t1), - ImmArray((Some[Name](party), ValueParty(x))), - ), + ValueRecord( + Some(t1), + ImmArray((Some[Name](party), ValueParty(x))), ), "", ) @@ -87,7 +84,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz val t1a = t1InstanceFor(alice) val t1b = t1InstanceFor(bob) - val defaultContracts: Map[ContractId, ContractInst[Value.VersionedValue]] = + val defaultContracts: Map[ContractId, VersionedContractInstance] = Map( toContractId("t1a") -> t1a, toContractId("t1b") -> t1b, @@ -101,7 +98,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz def lookupPackage: PackageId => Option[Package] = pkgId => allPackages.get(pkgId) - def lookupContract: ContractId => Option[ContractInst[VersionedValue]] = + def lookupContract: ContractId => Option[VersionedContractInstance] = cid => defaultContracts.get(cid) def lookupKey: GlobalKeyWithMaintainers => Option[ContractId] = From 17dca9e02a74b94e85712e2d3fb69166820a801a Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Fri, 15 Oct 2021 11:00:46 +0100 Subject: [PATCH 03/11] 4x shouldBe a Right --- .../daml/lf/engine/AuthPropagationSpec.scala | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index a0b6fe317d3c..09584436c5c6 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -142,8 +142,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz submitters = Set(alice), command = command, ) - inside(interpretResult) { case Right(_) => - } + interpretResult shouldBe a[Right[_, _]] } "fail" in { val interpretResult = go( @@ -182,8 +181,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz submitters = Set(alice, bob), command = command, ) - inside(interpretResult) { case Right(_) => - } + interpretResult shouldBe a[Right[_, _]] } "fail" in { val interpretResult = go( @@ -227,8 +225,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz submitters = Set(bob), command = command, ) - inside(interpretResult) { case Right(_) => - } + interpretResult shouldBe a[Right[_, _]] } "fail: ExerciseMissingAuthorization" in { @@ -311,8 +308,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz submitters = Set(alice), command = command, ) - inside(interpretResult) { case Right(_) => - } + interpretResult shouldBe a[Right[_, _]] } } From de63a6a9bffb11d27cd6b1d7168392ba64686576 Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Fri, 15 Oct 2021 16:50:03 +0100 Subject: [PATCH 04/11] test for exercise within exercise --- .../daml/lf/engine/AuthPropagationSpec.scala | 119 +++++++++++++++++- daml-lf/tests/AuthTests.daml | 38 ++++++ 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index 09584436c5c6..8104120e08fd 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -7,6 +7,7 @@ package engine import com.daml.bazeltools.BazelRunfiles import com.daml.lf.archive.UniversalArchiveDecoder import com.daml.lf.command.{ApiCommand, Commands, CreateCommand, ExerciseCommand} +import com.daml.lf.data.FrontStack import com.daml.lf.data.Ref.{ Name, Party, @@ -26,7 +27,14 @@ import com.daml.lf.ledger.FailedAuthorization.{ import com.daml.lf.transaction.GlobalKeyWithMaintainers import com.daml.lf.transaction.Transaction.Metadata import com.daml.lf.transaction.{SubmittedTransaction, TransactionVersion} -import com.daml.lf.value.Value.{ContractId, ValueRecord, ValueParty, VersionedContractInstance} +import com.daml.lf.value.Value.{ + ContractId, + ValueRecord, + ValueParty, + VersionedContractInstance, + ValueContractId, + ValueList, +} import java.io.File @@ -51,10 +59,14 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), dummySuffix) } - // field names + // field names //NICK: prefix? -- or perhaps inline bindings; with implicit?! + def f_cid: Name = Name.assertFromString("cid") + def controllerA: Name = Name.assertFromString("controllerA") + def controllersB: Name = Name.assertFromString("controllersB") def party: Name = Name.assertFromString("party") def party1: Name = Name.assertFromString("party1") def party2: Name = Name.assertFromString("party2") + def party3: Name = Name.assertFromString("party3") def t1: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:T1")) @@ -62,12 +74,21 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz def t2: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:T2")) + // NICK: simplfy examples so just have one set of templates (not T and X) + def x1: Identifier = + Identifier(packageId, QualifiedName.assertFromString("AuthTests:X1")) + def choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") def choice1type: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:Choice1")) + def choiceAname: ChoiceName = ChoiceName.assertFromString("ChoiceA") + def choiceAtype: Identifier = + Identifier(packageId, QualifiedName.assertFromString("AuthTests:ChoiceA")) + def alice: Party = Party.assertFromString("Alice") def bob: Party = Party.assertFromString("Bob") + def charlie: Party = Party.assertFromString("Charlie") def t1InstanceFor(x: Party): VersionedContractInstance = { VersionedContractInstance( @@ -81,13 +102,30 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ) } + def x1InstanceFor(p: Party): VersionedContractInstance = { + VersionedContractInstance( + TransactionVersion.VDev, + x1, + ValueRecord( + Some(x1), + ImmArray((Some[Name](party), ValueParty(p))), + ), + "", + ) + } + val t1a = t1InstanceFor(alice) val t1b = t1InstanceFor(bob) + val x1b = x1InstanceFor(bob) + val x1c = x1InstanceFor(charlie) + val defaultContracts: Map[ContractId, VersionedContractInstance] = Map( toContractId("t1a") -> t1a, toContractId("t1b") -> t1b, + toContractId("x1b") -> x1b, + toContractId("x1c") -> x1c, ) def readAs: Set[Party] = Set.empty @@ -310,6 +348,83 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ) interpretResult shouldBe a[Right[_, _]] } + } + + "Exercise (within exercise)" - { + + "fail (no implicit authority from outer exercise's contract's signatories)" in { + def command: ApiCommand = + ExerciseCommand( + x1, + toContractId("x1b"), + choiceAname, + ValueRecord( + Some(choiceAtype), + ImmArray( + (Some(f_cid), ValueContractId(toContractId("x1c"))), + (Some(controllerA), ValueParty(alice)), + ( + Some(controllersB), + ValueList( + FrontStack( + ValueParty(alice) + ) + ), + ), + (Some(party1), ValueParty(alice)), + (Some(party2), ValueParty(bob)), + (Some(party3), ValueParty(charlie)), + ), + ), + ) + val interpretResult = go( + submitters = Set(alice), + command = command, + ) + inside(interpretResult) { + case Left( + engine.Error.Interpretation( + engine.Error.Interpretation.DamlException( + interpretation.Error + .FailedAuthorization(_, CreateMissingAuthorization(_, _, _, _)) + ), + _, + ) + ) => + } + } + "ok" in { + def command: ApiCommand = + ExerciseCommand( + x1, + toContractId("x1b"), + choiceAname, + ValueRecord( + Some(choiceAtype), + ImmArray( + (Some(f_cid), ValueContractId(toContractId("x1c"))), + (Some(controllerA), ValueParty(alice)), + ( + Some(controllersB), + ValueList( + FrontStack( + ValueParty(alice), + ValueParty(bob), // bob must be an explicit controller on inner exercise + ) + ), + ), + (Some(party1), ValueParty(alice)), + (Some(party2), ValueParty(bob)), + (Some(party3), ValueParty(charlie)), + ), + ), + ) + val interpretResult = go( + submitters = Set(alice), + command = command, + ) + interpretResult shouldBe a[Right[_, _]] + } } } diff --git a/daml-lf/tests/AuthTests.daml b/daml-lf/tests/AuthTests.daml index 4633897f2c97..07b85e4529ed 100644 --- a/daml-lf/tests/AuthTests.daml +++ b/daml-lf/tests/AuthTests.daml @@ -21,3 +21,41 @@ template T2 with party2 : Party where signatory [party1,party2] + + +---------------------------------------------------------------------- +-- templates for exercise-within-exercise testcase + +template X1 with + party : Party + where + signatory party + + nonconsuming choice ChoiceA : ContractId X2 + with + cid : ContractId X1 + controllerA : Party + controllersB : [Party] + party1 : Party + party2 : Party + party3 : Party + controller controllerA + do + exercise cid ChoiceB with controllersB; party1; party2; party3 + + nonconsuming choice ChoiceB : ContractId X2 + with + controllersB : [Party] + party1 : Party + party2 : Party + party3 : Party + controller controllersB + do + create X2 with party1; party2; party3 + +template X2 with + party1 : Party + party2 : Party + party3 : Party + where + signatory [party1,party2,party3] From 207725b40794fbd28e881e9c63a7c0a794620634 Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Mon, 18 Oct 2021 10:46:41 +0100 Subject: [PATCH 05/11] implicit Name.assertFromString --- .../daml/lf/engine/AuthPropagationSpec.scala | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index 8104120e08fd..3403d5732db1 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -42,8 +42,12 @@ import org.scalatest.Inside import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers +import scala.language.implicitConversions + class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with BazelRunfiles { + implicit def toName(s: String): Name = Name.assertFromString(s) + def loadPackage(resource: String): (PackageId, Package, Map[PackageId, Package]) = { val packages = UniversalArchiveDecoder.assertReadFile(new File(rlocation(resource))) val (mainPkgId, mainPkg) = packages.main @@ -59,15 +63,6 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), dummySuffix) } - // field names //NICK: prefix? -- or perhaps inline bindings; with implicit?! - def f_cid: Name = Name.assertFromString("cid") - def controllerA: Name = Name.assertFromString("controllerA") - def controllersB: Name = Name.assertFromString("controllersB") - def party: Name = Name.assertFromString("party") - def party1: Name = Name.assertFromString("party1") - def party2: Name = Name.assertFromString("party2") - def party3: Name = Name.assertFromString("party3") - def t1: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:T1")) @@ -90,25 +85,25 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz def bob: Party = Party.assertFromString("Bob") def charlie: Party = Party.assertFromString("Charlie") - def t1InstanceFor(x: Party): VersionedContractInstance = { + def t1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( TransactionVersion.VDev, t1, ValueRecord( Some(t1), - ImmArray((Some[Name](party), ValueParty(x))), + ImmArray((Some[Name]("party"), ValueParty(party))), ), "", ) } - def x1InstanceFor(p: Party): VersionedContractInstance = { + def x1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( TransactionVersion.VDev, x1, ValueRecord( Some(x1), - ImmArray((Some[Name](party), ValueParty(p))), + ImmArray((Some[Name]("party"), ValueParty(party))), ), "", ) @@ -171,7 +166,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(t1), ImmArray( - (Some[Name](party), ValueParty(alice)) + (Some[Name]("party"), ValueParty(alice)) ), ), ) @@ -208,8 +203,8 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(t2), ImmArray( - (Some[Name](party1), ValueParty(alice)), - (Some[Name](party2), ValueParty(bob)), + (Some[Name]("party1"), ValueParty(alice)), + (Some[Name]("party2"), ValueParty(bob)), ), ), ) @@ -254,8 +249,8 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(choice1type), ImmArray( - (Some[Name](party1), ValueParty(alice)), - (Some[Name](party2), ValueParty(bob)), + (Some[Name]("party1"), ValueParty(alice)), + (Some[Name]("party2"), ValueParty(bob)), ), ), ) @@ -275,8 +270,8 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(choice1type), ImmArray( - (Some[Name](party1), ValueParty(alice)), - (Some[Name](party2), ValueParty(bob)), + (Some[Name]("party1"), ValueParty(alice)), + (Some[Name]("party2"), ValueParty(bob)), ), ), ) @@ -306,8 +301,8 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(choice1type), ImmArray( - (Some[Name](party1), ValueParty(bob)), - (Some[Name](party2), ValueParty(alice)), + (Some[Name]("party1"), ValueParty(bob)), + (Some[Name]("party2"), ValueParty(alice)), ), ), ) @@ -337,8 +332,8 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(choice1type), ImmArray( - (Some[Name](party1), ValueParty(bob)), - (Some[Name](party2), ValueParty(alice)), + (Some[Name]("party1"), ValueParty(bob)), + (Some[Name]("party2"), ValueParty(alice)), ), ), ) @@ -361,19 +356,19 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(choiceAtype), ImmArray( - (Some(f_cid), ValueContractId(toContractId("x1c"))), - (Some(controllerA), ValueParty(alice)), + (Some("cid"), ValueContractId(toContractId("x1c"))), + (Some("controllerA"), ValueParty(alice)), ( - Some(controllersB), + Some("controllersB"), ValueList( FrontStack( ValueParty(alice) ) ), ), - (Some(party1), ValueParty(alice)), - (Some(party2), ValueParty(bob)), - (Some(party3), ValueParty(charlie)), + (Some("party1"), ValueParty(alice)), + (Some("party2"), ValueParty(bob)), + (Some("party3"), ValueParty(charlie)), ), ), ) @@ -403,10 +398,10 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some(choiceAtype), ImmArray( - (Some(f_cid), ValueContractId(toContractId("x1c"))), - (Some(controllerA), ValueParty(alice)), + (Some("cid"), ValueContractId(toContractId("x1c"))), + (Some("controllerA"), ValueParty(alice)), ( - Some(controllersB), + Some("controllersB"), ValueList( FrontStack( ValueParty(alice), @@ -414,9 +409,9 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ) ), ), - (Some(party1), ValueParty(alice)), - (Some(party2), ValueParty(bob)), - (Some(party3), ValueParty(charlie)), + (Some("party1"), ValueParty(alice)), + (Some("party2"), ValueParty(bob)), + (Some("party3"), ValueParty(charlie)), ), ), ) From 413e9e53f06a9e23ab8409968e0f0d15f1f6455e Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Mon, 18 Oct 2021 10:54:56 +0100 Subject: [PATCH 06/11] def --> val. massive speedup! --- .../daml/lf/engine/AuthPropagationSpec.scala | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index 3403d5732db1..e6b7b540095b 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -59,31 +59,31 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ) def toContractId(s: String): ContractId = { - def dummySuffix: Bytes = Bytes.assertFromString("00") + val dummySuffix: Bytes = Bytes.assertFromString("00") ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), dummySuffix) } - def t1: Identifier = + val t1: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:T1")) - def t2: Identifier = + val t2: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:T2")) // NICK: simplfy examples so just have one set of templates (not T and X) - def x1: Identifier = + val x1: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:X1")) - def choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") - def choice1type: Identifier = + val choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") + val choice1type: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:Choice1")) - def choiceAname: ChoiceName = ChoiceName.assertFromString("ChoiceA") - def choiceAtype: Identifier = + val choiceAname: ChoiceName = ChoiceName.assertFromString("ChoiceA") + val choiceAtype: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:ChoiceA")) - def alice: Party = Party.assertFromString("Alice") - def bob: Party = Party.assertFromString("Bob") - def charlie: Party = Party.assertFromString("Charlie") + val alice: Party = Party.assertFromString("Alice") + val bob: Party = Party.assertFromString("Bob") + val charlie: Party = Party.assertFromString("Charlie") def t1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( @@ -123,21 +123,21 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz toContractId("x1c") -> x1c, ) - def readAs: Set[Party] = Set.empty - def let: Time.Timestamp = Time.Timestamp.now() - def participant: ParticipantId = ParticipantId.assertFromString("participant") - def submissionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("submissionSeed") + val readAs: Set[Party] = Set.empty + val let: Time.Timestamp = Time.Timestamp.now() + val participant: ParticipantId = ParticipantId.assertFromString("participant") + val submissionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("submissionSeed") - def lookupPackage: PackageId => Option[Package] = + val lookupPackage: PackageId => Option[Package] = pkgId => allPackages.get(pkgId) - def lookupContract: ContractId => Option[VersionedContractInstance] = + val lookupContract: ContractId => Option[VersionedContractInstance] = cid => defaultContracts.get(cid) - def lookupKey: GlobalKeyWithMaintainers => Option[ContractId] = + val lookupKey: GlobalKeyWithMaintainers => Option[ContractId] = _ => None - def testEngine: Engine = + val testEngine: Engine = Engine.DevEngine() def go( @@ -160,7 +160,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz } "Create(T1)" - { - def command: ApiCommand = + val command: ApiCommand = CreateCommand( t1, ValueRecord( @@ -197,7 +197,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz } "Create(T2)" - { - def command: ApiCommand = + val command: ApiCommand = CreateCommand( t2, ValueRecord( @@ -241,7 +241,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "Exercise(Choice1 of T1 to create T2)" - { "ok (Alice signed contract; Bob exercised Choice)" in { - def command: ApiCommand = + val command: ApiCommand = ExerciseCommand( t1, toContractId("t1a"), @@ -262,7 +262,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz } "fail: ExerciseMissingAuthorization" in { - def command: ApiCommand = + val command: ApiCommand = ExerciseCommand( t1, toContractId("t1a"), @@ -293,7 +293,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz } "fail: CreateMissingAuthorization" in { - def command: ApiCommand = + val command: ApiCommand = ExerciseCommand( t1, toContractId("t1a"), @@ -324,7 +324,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz } "ok (Bob signed contract; Alice exercised Choice)" in { - def command: ApiCommand = + val command: ApiCommand = ExerciseCommand( t1, toContractId("t1b"), @@ -348,7 +348,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "Exercise (within exercise)" - { "fail (no implicit authority from outer exercise's contract's signatories)" in { - def command: ApiCommand = + val command: ApiCommand = ExerciseCommand( x1, toContractId("x1b"), @@ -390,7 +390,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz } "ok" in { - def command: ApiCommand = + val command: ApiCommand = ExerciseCommand( x1, toContractId("x1b"), From 4acb8d355b5e379b06ab8b99811735bb7c93cea2 Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Mon, 18 Oct 2021 11:01:21 +0100 Subject: [PATCH 07/11] be more private --- .../daml/lf/engine/AuthPropagationSpec.scala | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index e6b7b540095b..30d9c0fdf7c4 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -46,46 +46,46 @@ import scala.language.implicitConversions class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with BazelRunfiles { - implicit def toName(s: String): Name = Name.assertFromString(s) + implicit private def toName(s: String): Name = Name.assertFromString(s) - def loadPackage(resource: String): (PackageId, Package, Map[PackageId, Package]) = { + private def loadPackage(resource: String): (PackageId, Package, Map[PackageId, Package]) = { val packages = UniversalArchiveDecoder.assertReadFile(new File(rlocation(resource))) val (mainPkgId, mainPkg) = packages.main (mainPkgId, mainPkg, packages.all.toMap) } - val (packageId, _, allPackages) = loadPackage( + private val (packageId, _, allPackages) = loadPackage( "daml-lf/tests/AuthTests.dar" ) - def toContractId(s: String): ContractId = { + private def toContractId(s: String): ContractId = { val dummySuffix: Bytes = Bytes.assertFromString("00") ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), dummySuffix) } - val t1: Identifier = + private val t1: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:T1")) - val t2: Identifier = + private val t2: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:T2")) // NICK: simplfy examples so just have one set of templates (not T and X) - val x1: Identifier = + private val x1: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:X1")) - val choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") - val choice1type: Identifier = + private val choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") + private val choice1type: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:Choice1")) - val choiceAname: ChoiceName = ChoiceName.assertFromString("ChoiceA") - val choiceAtype: Identifier = + private val choiceAname: ChoiceName = ChoiceName.assertFromString("ChoiceA") + private val choiceAtype: Identifier = Identifier(packageId, QualifiedName.assertFromString("AuthTests:ChoiceA")) - val alice: Party = Party.assertFromString("Alice") - val bob: Party = Party.assertFromString("Bob") - val charlie: Party = Party.assertFromString("Charlie") + private val alice: Party = Party.assertFromString("Alice") + private val bob: Party = Party.assertFromString("Bob") + private val charlie: Party = Party.assertFromString("Charlie") - def t1InstanceFor(party: Party): VersionedContractInstance = { + private def t1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( TransactionVersion.VDev, t1, @@ -97,7 +97,7 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ) } - def x1InstanceFor(party: Party): VersionedContractInstance = { + private def x1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( TransactionVersion.VDev, x1, @@ -109,13 +109,13 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ) } - val t1a = t1InstanceFor(alice) - val t1b = t1InstanceFor(bob) + private val t1a = t1InstanceFor(alice) + private val t1b = t1InstanceFor(bob) - val x1b = x1InstanceFor(bob) - val x1c = x1InstanceFor(charlie) + private val x1b = x1InstanceFor(bob) + private val x1c = x1InstanceFor(charlie) - val defaultContracts: Map[ContractId, VersionedContractInstance] = + private val defaultContracts: Map[ContractId, VersionedContractInstance] = Map( toContractId("t1a") -> t1a, toContractId("t1b") -> t1b, @@ -123,24 +123,24 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz toContractId("x1c") -> x1c, ) - val readAs: Set[Party] = Set.empty - val let: Time.Timestamp = Time.Timestamp.now() - val participant: ParticipantId = ParticipantId.assertFromString("participant") - val submissionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("submissionSeed") + private val readAs: Set[Party] = Set.empty + private val let: Time.Timestamp = Time.Timestamp.now() + private val participant: ParticipantId = ParticipantId.assertFromString("participant") + private val submissionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("submissionSeed") - val lookupPackage: PackageId => Option[Package] = + private val lookupPackage: PackageId => Option[Package] = pkgId => allPackages.get(pkgId) - val lookupContract: ContractId => Option[VersionedContractInstance] = + private val lookupContract: ContractId => Option[VersionedContractInstance] = cid => defaultContracts.get(cid) - val lookupKey: GlobalKeyWithMaintainers => Option[ContractId] = + private val lookupKey: GlobalKeyWithMaintainers => Option[ContractId] = _ => None - val testEngine: Engine = + private val testEngine: Engine = Engine.DevEngine() - def go( + private def go( submitters: Set[Party], command: ApiCommand, ): Either[engine.Error, (SubmittedTransaction, Metadata)] = { From a4c6f404c82abfbe5d09dd4ab7b27170394d20fb Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Mon, 18 Oct 2021 11:16:45 +0100 Subject: [PATCH 08/11] implicit Identifier creation --- .../daml/lf/engine/AuthPropagationSpec.scala | 72 +++++++------------ 1 file changed, 27 insertions(+), 45 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index 30d9c0fdf7c4..c74e33aae52f 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -58,28 +58,16 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "daml-lf/tests/AuthTests.dar" ) + implicit private def toIdentifier(s: String): Identifier = + Identifier(packageId, QualifiedName.assertFromString(s"AuthTests:$s")) + private def toContractId(s: String): ContractId = { val dummySuffix: Bytes = Bytes.assertFromString("00") ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), dummySuffix) } - private val t1: Identifier = - Identifier(packageId, QualifiedName.assertFromString("AuthTests:T1")) - - private val t2: Identifier = - Identifier(packageId, QualifiedName.assertFromString("AuthTests:T2")) - - // NICK: simplfy examples so just have one set of templates (not T and X) - private val x1: Identifier = - Identifier(packageId, QualifiedName.assertFromString("AuthTests:X1")) - private val choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") - private val choice1type: Identifier = - Identifier(packageId, QualifiedName.assertFromString("AuthTests:Choice1")) - private val choiceAname: ChoiceName = ChoiceName.assertFromString("ChoiceA") - private val choiceAtype: Identifier = - Identifier(packageId, QualifiedName.assertFromString("AuthTests:ChoiceA")) private val alice: Party = Party.assertFromString("Alice") private val bob: Party = Party.assertFromString("Bob") @@ -88,9 +76,9 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz private def t1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( TransactionVersion.VDev, - t1, + "T1", ValueRecord( - Some(t1), + Some("T1"), ImmArray((Some[Name]("party"), ValueParty(party))), ), "", @@ -100,27 +88,21 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz private def x1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( TransactionVersion.VDev, - x1, + "X1", ValueRecord( - Some(x1), + Some("X1"), ImmArray((Some[Name]("party"), ValueParty(party))), ), "", ) } - private val t1a = t1InstanceFor(alice) - private val t1b = t1InstanceFor(bob) - - private val x1b = x1InstanceFor(bob) - private val x1c = x1InstanceFor(charlie) - private val defaultContracts: Map[ContractId, VersionedContractInstance] = Map( - toContractId("t1a") -> t1a, - toContractId("t1b") -> t1b, - toContractId("x1b") -> x1b, - toContractId("x1c") -> x1c, + toContractId("t1a") -> t1InstanceFor(alice), + toContractId("t1b") -> t1InstanceFor(bob), + toContractId("x1b") -> x1InstanceFor(bob), + toContractId("x1c") -> x1InstanceFor(charlie), ) private val readAs: Set[Party] = Set.empty @@ -162,9 +144,9 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "Create(T1)" - { val command: ApiCommand = CreateCommand( - t1, + "T1", ValueRecord( - Some(t1), + Some("T1"), ImmArray( (Some[Name]("party"), ValueParty(alice)) ), @@ -199,9 +181,9 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "Create(T2)" - { val command: ApiCommand = CreateCommand( - t2, + "T2", ValueRecord( - Some(t2), + Some("T2"), ImmArray( (Some[Name]("party1"), ValueParty(alice)), (Some[Name]("party2"), ValueParty(bob)), @@ -243,11 +225,11 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "ok (Alice signed contract; Bob exercised Choice)" in { val command: ApiCommand = ExerciseCommand( - t1, + "T1", toContractId("t1a"), choice1name, ValueRecord( - Some(choice1type), + Some("Choice1"), ImmArray( (Some[Name]("party1"), ValueParty(alice)), (Some[Name]("party2"), ValueParty(bob)), @@ -264,11 +246,11 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "fail: ExerciseMissingAuthorization" in { val command: ApiCommand = ExerciseCommand( - t1, + "T1", toContractId("t1a"), choice1name, ValueRecord( - Some(choice1type), + Some("Choice1"), ImmArray( (Some[Name]("party1"), ValueParty(alice)), (Some[Name]("party2"), ValueParty(bob)), @@ -295,11 +277,11 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "fail: CreateMissingAuthorization" in { val command: ApiCommand = ExerciseCommand( - t1, + "T1", toContractId("t1a"), choice1name, ValueRecord( - Some(choice1type), + Some("Choice1"), ImmArray( (Some[Name]("party1"), ValueParty(bob)), (Some[Name]("party2"), ValueParty(alice)), @@ -326,11 +308,11 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "ok (Bob signed contract; Alice exercised Choice)" in { val command: ApiCommand = ExerciseCommand( - t1, + "T1", toContractId("t1b"), choice1name, ValueRecord( - Some(choice1type), + Some("Choice1"), ImmArray( (Some[Name]("party1"), ValueParty(bob)), (Some[Name]("party2"), ValueParty(alice)), @@ -350,11 +332,11 @@ 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 = ExerciseCommand( - x1, + "X1", toContractId("x1b"), choiceAname, ValueRecord( - Some(choiceAtype), + Some("ChoiceA"), ImmArray( (Some("cid"), ValueContractId(toContractId("x1c"))), (Some("controllerA"), ValueParty(alice)), @@ -392,11 +374,11 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "ok" in { val command: ApiCommand = ExerciseCommand( - x1, + "X1", toContractId("x1b"), choiceAname, ValueRecord( - Some(choiceAtype), + Some("ChoiceA"), ImmArray( (Some("cid"), ValueContractId(toContractId("x1c"))), (Some("controllerA"), ValueParty(alice)), From e7030a83e2a14019a246c162c0bd66e03ee5459d Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Mon, 18 Oct 2021 11:25:41 +0100 Subject: [PATCH 09/11] use implicit for Party and ChoiceName creation --- .../daml/lf/engine/AuthPropagationSpec.scala | 100 ++++++++---------- 1 file changed, 43 insertions(+), 57 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index c74e33aae52f..1319f677c63c 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -8,15 +8,7 @@ import com.daml.bazeltools.BazelRunfiles import com.daml.lf.archive.UniversalArchiveDecoder import com.daml.lf.command.{ApiCommand, Commands, CreateCommand, ExerciseCommand} import com.daml.lf.data.FrontStack -import com.daml.lf.data.Ref.{ - Name, - Party, - ParticipantId, - PackageId, - Identifier, - QualifiedName, - ChoiceName, -} +import com.daml.lf.data.Ref.{Name, Party, ParticipantId, PackageId, Identifier, QualifiedName} import com.daml.lf.data.Time import com.daml.lf.data.{ImmArray, Bytes} import com.daml.lf.language.Ast.Package @@ -47,6 +39,7 @@ import scala.language.implicitConversions class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with BazelRunfiles { implicit private def toName(s: String): Name = Name.assertFromString(s) + implicit private def toParty(s: String): Party = Party.assertFromString(s) private def loadPackage(resource: String): (PackageId, Package, Map[PackageId, Package]) = { val packages = UniversalArchiveDecoder.assertReadFile(new File(rlocation(resource))) @@ -66,13 +59,6 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), dummySuffix) } - private val choice1name: ChoiceName = ChoiceName.assertFromString("Choice1") - private val choiceAname: ChoiceName = ChoiceName.assertFromString("ChoiceA") - - private val alice: Party = Party.assertFromString("Alice") - private val bob: Party = Party.assertFromString("Bob") - private val charlie: Party = Party.assertFromString("Charlie") - private def t1InstanceFor(party: Party): VersionedContractInstance = { VersionedContractInstance( TransactionVersion.VDev, @@ -99,10 +85,10 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz private val defaultContracts: Map[ContractId, VersionedContractInstance] = Map( - toContractId("t1a") -> t1InstanceFor(alice), - toContractId("t1b") -> t1InstanceFor(bob), - toContractId("x1b") -> x1InstanceFor(bob), - toContractId("x1c") -> x1InstanceFor(charlie), + toContractId("t1a") -> t1InstanceFor("Alice"), + toContractId("t1b") -> t1InstanceFor("Bob"), + toContractId("x1b") -> x1InstanceFor("Bob"), + toContractId("x1c") -> x1InstanceFor("Charlie"), ) private val readAs: Set[Party] = Set.empty @@ -148,13 +134,13 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some("T1"), ImmArray( - (Some[Name]("party"), ValueParty(alice)) + (Some[Name]("party"), ValueParty("Alice")) ), ), ) "ok" in { val interpretResult = go( - submitters = Set(alice), + submitters = Set("Alice"), command = command, ) interpretResult shouldBe a[Right[_, _]] @@ -185,22 +171,22 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueRecord( Some("T2"), ImmArray( - (Some[Name]("party1"), ValueParty(alice)), - (Some[Name]("party2"), ValueParty(bob)), + (Some[Name]("party1"), ValueParty("Alice")), + (Some[Name]("party2"), ValueParty("Bob")), ), ), ) "ok" in { val interpretResult = go( - submitters = Set(alice, bob), + submitters = Set("Alice", "Bob"), command = command, ) interpretResult shouldBe a[Right[_, _]] } "fail" in { val interpretResult = go( - submitters = Set(alice), + submitters = Set("Alice"), command = command, ) inside(interpretResult) { @@ -227,17 +213,17 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ExerciseCommand( "T1", toContractId("t1a"), - choice1name, + "Choice1", ValueRecord( Some("Choice1"), ImmArray( - (Some[Name]("party1"), ValueParty(alice)), - (Some[Name]("party2"), ValueParty(bob)), + (Some[Name]("party1"), ValueParty("Alice")), + (Some[Name]("party2"), ValueParty("Bob")), ), ), ) val interpretResult = go( - submitters = Set(bob), + submitters = Set("Bob"), command = command, ) interpretResult shouldBe a[Right[_, _]] @@ -248,17 +234,17 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ExerciseCommand( "T1", toContractId("t1a"), - choice1name, + "Choice1", ValueRecord( Some("Choice1"), ImmArray( - (Some[Name]("party1"), ValueParty(alice)), - (Some[Name]("party2"), ValueParty(bob)), + (Some[Name]("party1"), ValueParty("Alice")), + (Some[Name]("party2"), ValueParty("Bob")), ), ), ) val interpretResult = go( - submitters = Set(alice), + submitters = Set("Alice"), command = command, ) inside(interpretResult) { @@ -279,17 +265,17 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ExerciseCommand( "T1", toContractId("t1a"), - choice1name, + "Choice1", ValueRecord( Some("Choice1"), ImmArray( - (Some[Name]("party1"), ValueParty(bob)), - (Some[Name]("party2"), ValueParty(alice)), + (Some[Name]("party1"), ValueParty("Bob")), + (Some[Name]("party2"), ValueParty("Alice")), ), ), ) val interpretResult = go( - submitters = Set(alice), + submitters = Set("Alice"), command = command, ) inside(interpretResult) { @@ -310,17 +296,17 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ExerciseCommand( "T1", toContractId("t1b"), - choice1name, + "Choice1", ValueRecord( Some("Choice1"), ImmArray( - (Some[Name]("party1"), ValueParty(bob)), - (Some[Name]("party2"), ValueParty(alice)), + (Some[Name]("party1"), ValueParty("Bob")), + (Some[Name]("party2"), ValueParty("Alice")), ), ), ) val interpretResult = go( - submitters = Set(alice), + submitters = Set("Alice"), command = command, ) interpretResult shouldBe a[Right[_, _]] @@ -334,28 +320,28 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ExerciseCommand( "X1", toContractId("x1b"), - choiceAname, + "ChoiceA", ValueRecord( Some("ChoiceA"), ImmArray( (Some("cid"), ValueContractId(toContractId("x1c"))), - (Some("controllerA"), ValueParty(alice)), + (Some("controllerA"), ValueParty("Alice")), ( Some("controllersB"), ValueList( FrontStack( - ValueParty(alice) + ValueParty("Alice") ) ), ), - (Some("party1"), ValueParty(alice)), - (Some("party2"), ValueParty(bob)), - (Some("party3"), ValueParty(charlie)), + (Some("party1"), ValueParty("Alice")), + (Some("party2"), ValueParty("Bob")), + (Some("party3"), ValueParty("Charlie")), ), ), ) val interpretResult = go( - submitters = Set(alice), + submitters = Set("Alice"), command = command, ) inside(interpretResult) { @@ -376,29 +362,29 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ExerciseCommand( "X1", toContractId("x1b"), - choiceAname, + "ChoiceA", ValueRecord( Some("ChoiceA"), ImmArray( (Some("cid"), ValueContractId(toContractId("x1c"))), - (Some("controllerA"), ValueParty(alice)), + (Some("controllerA"), ValueParty("Alice")), ( Some("controllersB"), ValueList( FrontStack( - ValueParty(alice), - ValueParty(bob), // bob must be an explicit controller on inner exercise + ValueParty("Alice"), + ValueParty("Bob"), // Bob must be an explicit controller on inner exercise ) ), ), - (Some("party1"), ValueParty(alice)), - (Some("party2"), ValueParty(bob)), - (Some("party3"), ValueParty(charlie)), + (Some("party1"), ValueParty("Alice")), + (Some("party2"), ValueParty("Bob")), + (Some("party3"), ValueParty("Charlie")), ), ), ) val interpretResult = go( - submitters = Set(alice), + submitters = Set("Alice"), command = command, ) interpretResult shouldBe a[Right[_, _]] From c971f54e2828248f92703034fcd0ee9820a4755f Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Mon, 18 Oct 2021 11:31:19 +0100 Subject: [PATCH 10/11] comment test purpose --- .../digitalasset/daml/lf/engine/AuthPropagationSpec.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index 1319f677c63c..2971d5487321 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -315,6 +315,11 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "Exercise (within exercise)" - { + Specifically the interesting case is that in the body of + + // Test that an inner exercise has only the authorization of the signatories and + // controllers; with no implicit authorization of signatories of the outer exercise. + "fail (no implicit authority from outer exercise's contract's signatories)" in { val command: ApiCommand = ExerciseCommand( @@ -373,7 +378,8 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz ValueList( FrontStack( ValueParty("Alice"), - ValueParty("Bob"), // Bob must be an explicit controller on inner exercise + // Adding Bob as an explicit controller of the inner exercise make the Authorization check pass again: + ValueParty("Bob"), ) ), ), From b439d79199c90096a5f750e118f41acce5bac2d1 Mon Sep 17 00:00:00 2001 From: Nick Chapman Date: Mon, 18 Oct 2021 11:55:57 +0100 Subject: [PATCH 11/11] delete stray text; fix build --- .../com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala index 2971d5487321..ba712aad983f 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala @@ -315,8 +315,6 @@ class AuthPropagationSpec extends AnyFreeSpec with Matchers with Inside with Baz "Exercise (within exercise)" - { - Specifically the interesting case is that in the body of - // Test that an inner exercise has only the authorization of the signatories and // controllers; with no implicit authorization of signatories of the outer exercise.