diff --git a/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Base.hs b/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Base.hs index 4cf60edf57e3..9f0c2e02c5f1 100644 --- a/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Base.hs +++ b/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Base.hs @@ -301,9 +301,6 @@ data BuiltinExpr | BEFoldr -- :: ∀a b. (a -> b -> b) -> b -> List a -> b | BEEqualList -- :: ∀a. (a -> a -> Bool) -> List a -> List a -> Bool - -- Authority operations - | BEWithAuthority -- :: ∀ a. List Party -> Update a -> Update a - -- Map operations | BETextMapEmpty -- :: ∀ a. TextMap a | BETextMapInsert -- :: ∀ a. Text -> a -> TextMap a -> TextMap a diff --git a/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Pretty.hs b/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Pretty.hs index fe17c42e9616..096247e72abc 100644 --- a/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Pretty.hs +++ b/compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Pretty.hs @@ -267,7 +267,6 @@ instance Pretty BuiltinExpr where BEExpInt64 -> "EXP_INT64" BEFoldl -> "FOLDL" BEFoldr -> "FOLDR" - BEWithAuthority -> "WITH_AUTHORITY" BETextMapEmpty -> "TEXTMAP_EMPTY" BETextMapInsert -> "TEXTMAP_INSERT" BETextMapLookup -> "TEXTMAP_LOOKUP" diff --git a/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/DecodeV1.hs b/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/DecodeV1.hs index f00f41732cb6..a0b6b2f83d06 100644 --- a/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/DecodeV1.hs +++ b/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/DecodeV1.hs @@ -476,7 +476,6 @@ decodeBuiltinFunction = \case LF1.BuiltinFunctionFOLDL -> pure BEFoldl LF1.BuiltinFunctionFOLDR -> pure BEFoldr - LF1.BuiltinFunctionWITH_AUTHORITY -> pure BEWithAuthority LF1.BuiltinFunctionEQUAL_LIST -> pure BEEqualList LF1.BuiltinFunctionAPPEND_TEXT -> pure BEAppendText diff --git a/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/EncodeV1.hs b/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/EncodeV1.hs index d59825eb6655..cd9c9f4378e3 100644 --- a/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/EncodeV1.hs +++ b/compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/EncodeV1.hs @@ -516,7 +516,6 @@ encodeBuiltinExpr = \case BEFoldl -> builtin P.BuiltinFunctionFOLDL BEFoldr -> builtin P.BuiltinFunctionFOLDR - BEWithAuthority -> builtin P.BuiltinFunctionWITH_AUTHORITY BEEqualList -> builtin P.BuiltinFunctionEQUAL_LIST BEExplodeText -> builtin P.BuiltinFunctionEXPLODE_TEXT BEAppendText -> builtin P.BuiltinFunctionAPPEND_TEXT diff --git a/compiler/daml-lf-tools/src/DA/Daml/LF/Simplifier.hs b/compiler/daml-lf-tools/src/DA/Daml/LF/Simplifier.hs index 7a83c0ada995..967353805edc 100644 --- a/compiler/daml-lf-tools/src/DA/Daml/LF/Simplifier.hs +++ b/compiler/daml-lf-tools/src/DA/Daml/LF/Simplifier.hs @@ -137,7 +137,6 @@ safetyStep = \case BEExpInt64 -> Safe 1 BEFoldl -> Safe 2 BEFoldr -> Safe 2 - BEWithAuthority -> Safe 2 -- not reachable; so "undefined" would suffice BETextMapEmpty -> Safe 0 BETextMapInsert -> Safe 3 BETextMapLookup -> Safe 2 diff --git a/compiler/daml-lf-tools/src/DA/Daml/LF/TypeChecker/Check.hs b/compiler/daml-lf-tools/src/DA/Daml/LF/TypeChecker/Check.hs index c8dcc1b96723..a41f7a064ba5 100644 --- a/compiler/daml-lf-tools/src/DA/Daml/LF/TypeChecker/Check.hs +++ b/compiler/daml-lf-tools/src/DA/Daml/LF/TypeChecker/Check.hs @@ -278,12 +278,6 @@ typeOfBuiltin = \case BEFoldr -> pure $ TForall (alpha, KStar) $ TForall (beta, KStar) $ (tAlpha :-> tBeta :-> tBeta) :-> tBeta :-> TList tAlpha :-> tBeta - BEWithAuthority -> - pure $ TForall (alpha, KStar) $ - TList TParty :-> - TUpdate tAlpha :-> - TUpdate tAlpha - BETextMapEmpty -> pure $ TForall (alpha, KStar) $ TTextMap tAlpha BETextMapInsert -> pure $ TForall (alpha, KStar) $ TText :-> tAlpha :-> TTextMap tAlpha :-> TTextMap tAlpha BETextMapLookup -> pure $ TForall (alpha, KStar) $ TText :-> TTextMap tAlpha :-> TOptional tAlpha diff --git a/compiler/damlc/daml-lf-conversion/src/DA/Daml/LFConversion/Primitives.hs b/compiler/damlc/daml-lf-conversion/src/DA/Daml/LFConversion/Primitives.hs index a269e889cd3f..dc5509b1187e 100644 --- a/compiler/damlc/daml-lf-conversion/src/DA/Daml/LFConversion/Primitives.hs +++ b/compiler/damlc/daml-lf-conversion/src/DA/Daml/LFConversion/Primitives.hs @@ -88,10 +88,6 @@ convertPrim _ "BEFoldl" ((b1 :-> a1 :-> b2) :-> b3 :-> TList a2 :-> b4) | a1 == convertPrim _ "BEFoldr" ((a1 :-> b1 :-> b2) :-> b3 :-> TList a2 :-> b4) | a1 == a2, b1 == b2, b2 == b3, b3 == b4 = pure $ EBuiltin BEFoldr `ETyApp` a1 `ETyApp` b1 --- Authority operations -convertPrim _ "BEWithAuthority" (TList TParty :-> TUpdate a1 :-> TUpdate a2) | a1 == a2 = - pure $ EBuiltin BEWithAuthority `ETyApp` a1 - -- Error convertPrim _ "BEError" (TText :-> t2) = pure $ ETyApp (EBuiltin BEError) t2 diff --git a/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml b/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml index b430072c5d57..4f577350df39 100644 --- a/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml +++ b/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml @@ -48,10 +48,6 @@ module DA.Internal.LF , AnyException #endif - #ifdef DAML_WITH_AUTHORITY - , withAuthorityOf - #endif - ) where import GHC.Stack.Types (HasCallStack) @@ -276,11 +272,3 @@ instance Ord TypeRep where data AnyException = AnyException Opaque #endif - -#ifdef DAML_WITH_AUTHORITY - --- | Authority operations. -withAuthorityOf : [Party] -> Update a -> Update a -withAuthorityOf = primitive @"BEWithAuthority" - -#endif diff --git a/compiler/damlc/tests/daml-test-files/WithAuthority.daml b/compiler/damlc/tests/daml-test-files/WithAuthority.daml index f7adf2837ae9..509b816e298b 100644 --- a/compiler/damlc/tests/daml-test-files/WithAuthority.daml +++ b/compiler/damlc/tests/daml-test-files/WithAuthority.daml @@ -29,3 +29,6 @@ template ProposeConsortiumAuthority withAuthorityOf accepted $ do withAuthorityOf [consortiumParty] $ do create HasConsortiumAutority with consortiumParty + +withAuthorityOf : [Party] -> Update a -> Update a +withAuthorityOf _ u = u -- TODO #15882 -- require rework diff --git a/daml-lf/archive/src/main/protobuf/com/daml/daml_lf_dev/daml_lf_1.proto b/daml-lf/archive/src/main/protobuf/com/daml/daml_lf_dev/daml_lf_1.proto index 987eec4bb148..a00c6334f25b 100644 --- a/daml-lf/archive/src/main/protobuf/com/daml/daml_lf_dev/daml_lf_1.proto +++ b/daml-lf/archive/src/main/protobuf/com/daml/daml_lf_dev/daml_lf_1.proto @@ -571,9 +571,7 @@ enum BuiltinFunction { TYPE_REP_TYCON_NAME = 148; // *Available in versions >= 1.dev* - WITH_AUTHORITY = 149; // *Available in versions >= 1.dev* - - // Next id is 150. + // Next id is 149. // EXPERIMENTAL TEXT PRIMITIVES -- these do not yet have stable numbers. TEXT_TO_UPPER = 9901; // *Available in versions >= 1.dev* diff --git a/daml-lf/archive/src/main/scala/com/digitalasset/daml/lf/archive/DecodeV1.scala b/daml-lf/archive/src/main/scala/com/digitalasset/daml/lf/archive/DecodeV1.scala index d5cb8edd2c54..6030be532d7a 100644 --- a/daml-lf/archive/src/main/scala/com/digitalasset/daml/lf/archive/DecodeV1.scala +++ b/daml-lf/archive/src/main/scala/com/digitalasset/daml/lf/archive/DecodeV1.scala @@ -2099,7 +2099,6 @@ private[archive] object DecodeV1 { BuiltinFunctionInfo(NUMERIC_TO_INT64, BNumericToInt64, minVersion = numeric), BuiltinFunctionInfo(FOLDL, BFoldl), BuiltinFunctionInfo(FOLDR, BFoldr), - BuiltinFunctionInfo(WITH_AUTHORITY, BWithAuthority), BuiltinFunctionInfo(TEXTMAP_EMPTY, BTextMapEmpty), BuiltinFunctionInfo(TEXTMAP_INSERT, BTextMapInsert), BuiltinFunctionInfo(TEXTMAP_LOOKUP, BTextMapLookup), diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala index 98dce9c85fe6..1052994b5782 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala @@ -2509,8 +2509,8 @@ class EngineTest case Right((_, _)) => } } - - "authority required; not granted" in { + /* + "authority required; not granted" in { // TODO #15882 -- rework required inside(run(mkCommand(party1 = alice, party2 = bob), grantNeedAuthority = false)) { case Left( Interpretation( @@ -2523,11 +2523,12 @@ class EngineTest } } - "authority required; granted" in { + "authority required; granted" in { // TODO #15882 -- rework required inside(run(mkCommand(party1 = alice, party2 = bob), grantNeedAuthority = true)) { case Right((_, _)) => } } + */ } } diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/PhaseOne.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/PhaseOne.scala index b49784528e62..2d7bd274fb01 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/PhaseOne.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/PhaseOne.scala @@ -472,9 +472,6 @@ private[lf] final class PhaseOne( case BFoldr => SBFoldr case BEqualList => SBEqualList - // Authority functions - case BWithAuthority => SBWithAuthority - // Errors case BError => SBUserError diff --git a/daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/WithAuthorityTest.scala b/daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/WithAuthorityTest.scala deleted file mode 100644 index bdbc40b3959a..000000000000 --- a/daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/WithAuthorityTest.scala +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package com.daml.lf -package speedy - -import com.daml.lf.data.FrontStack -import com.daml.lf.data.ImmArray -import com.daml.lf.data.Ref.Party -import com.daml.lf.interpretation.Error.FailedAuthorization -import com.daml.lf.ledger.FailedAuthorization.CreateMissingAuthorization -import com.daml.lf.speedy.SError.SError -import com.daml.lf.speedy.SExpr.SEApp -import com.daml.lf.speedy.SValue.{SList, SParty} -import com.daml.lf.testing.parser.Implicits._ -import com.daml.lf.transaction.Node -import com.daml.lf.transaction.NodeId -import com.daml.lf.transaction.SubmittedTransaction -import com.daml.lf.value.Value.{ValueRecord, ValueParty} - -import org.scalatest.Inside -import org.scalatest.freespec.AnyFreeSpec -import org.scalatest.matchers.should.Matchers._ - -class WithAuthorityTest extends AnyFreeSpec with Inside { - - val a = Party.assertFromString("Alice") - val b = Party.assertFromString("Bob") - val c = Party.assertFromString("Charlie") - - import WithAuthorityTest._ - import SpeedyTestLib.AuthRequest - - "Single" - { - - "single (auth changed): A->{B}->A [FAIL]" in { - inside(makeSingle(committers = Set(a), required = Set(b), signed = a)) { case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(b) - cma.requiredParties shouldBe Set(a) - } - } - } - } - "single (auth changed): A->{B}->B [OK]" in { - inside(makeSingle(committers = Set(a), required = Set(b), signed = b)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(b), List(Create(b)))) - shape shouldBe expected - ars shouldBe List(AuthRequest(holding = Set(a), requesting = Set(b))) - } - } - "single (auth restricted/extended) {A,B}->{B,C}->A [FAIL]" in { - inside(makeSingle(committers = Set(a, b), required = Set(b, c), signed = a)) { - case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(b, c) - cma.requiredParties shouldBe Set(a) - } - } - } - } - "single (auth restricted/extended) {A,B}->{B,C}->B [OK]" in { - inside(makeSingle(committers = Set(a, b), required = Set(b, c), signed = b)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(b, c), List(Create(b)))) - shape shouldBe expected - ars shouldBe List(AuthRequest(holding = Set(a, b), requesting = Set(c))) - } - } - "single (auth restricted/extended) {A,B}->{B,C}->C [OK]" in { - inside(makeSingle(committers = Set(a, b), required = Set(b, c), signed = c)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(b, c), List(Create(c)))) - shape shouldBe expected - ars shouldBe List(AuthRequest(holding = Set(a, b), requesting = Set(c))) - } - } - "single (auth unchanged) A->{A}->A [OK; no auth-node]" in { - inside(makeSingle(committers = Set(a), required = Set(a), signed = a)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Create(a)) - shape shouldBe expected - ars shouldBe List() - } - } - "single (auth restricted) {A,B}->{B}->B [OK; no auth-node]" in { - inside(makeSingle(committers = Set(a, b), required = Set(b), signed = b)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Create(b)) - shape shouldBe expected - ars shouldBe List() - } - } - "single (auth restricted) {A,B}->{B}->A [FAIL]" in { - inside(makeSingle(committers = Set(a, b), required = Set(b), signed = a)) { case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(b) - cma.requiredParties shouldBe Set(a) - } - } - } - } - } - - "Sequence1" - { - - "sequence1: A-> ( {B}->B ; ->A ) [OK]" in { - inside( - makeSequence1( - committers = Set(a), - required = Set(b), - signed1 = b, - signed2 = a, - ) - ) { case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List[Shape](Authority(Set(b), List(Create(b))), Create(a)) - shape shouldBe expected - ars shouldBe List(AuthRequest(holding = Set(a), requesting = Set(b))) - } - } - "sequence1: A-> ( {B}->B ; ->B ) [FAIL]" in { - inside( - makeSequence1( - committers = Set(a), - required = Set(b), - signed1 = b, - signed2 = b, - ) - ) { case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(a) - cma.requiredParties shouldBe Set(b) - } - } - } - } - "sequence1: A-> ( {A}->A ; ->A ) [OK; no auth-node]" in { - inside( - makeSequence1( - committers = Set(a), - required = Set(a), - signed1 = a, - signed2 = a, - ) - ) { case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List[Shape](Create(a), Create(a)) - shape shouldBe expected - ars shouldBe List() - } - } - "sequence1: {A,B}-> ( {B}->B ; ->A ) [OK; no auth-node]" in { - inside( - makeSequence1( - committers = Set(a, b), - required = Set(b), - signed1 = b, - signed2 = a, - ) - ) { case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List[Shape](Create(b), Create(a)) - shape shouldBe expected - ars shouldBe List() - } - } - "sequence1: {A,B}-> ( {B}->B ; ->B ) [OK; no auth-node]" in { - inside( - makeSequence1( - committers = Set(a, b), - required = Set(b), - signed1 = b, - signed2 = b, - ) - ) { case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List[Shape](Create(b), Create(b)) - shape shouldBe expected - ars shouldBe List() - } - } - - } - - "Sequence2" - { - - "sequence2: A-> ( {B}->B ; {C}->C ) [OK; 2 auth nodes]" in { - inside( - makeSequence2( - committers = Set(a), - required1 = Set(b), - signed1 = b, - required2 = Set(c), - signed2 = c, - ) - ) { case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(b), List(Create(b))), Authority(Set(c), List(Create(c)))) - shape shouldBe expected - ars shouldBe List( - AuthRequest(holding = Set(a), requesting = Set(b)), - AuthRequest(holding = Set(a), requesting = Set(c)), - ) - } - } - "sequence2: A-> ( {B}->B ; {B}->B ) [OK; 2 auth nodes]" in { - inside( - makeSequence2( - committers = Set(a), - required1 = Set(b), - signed1 = b, - required2 = Set(b), - signed2 = b, - ) - ) { case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(b), List(Create(b))), Authority(Set(b), List(Create(b)))) - shape shouldBe expected - ars shouldBe List( - AuthRequest(holding = Set(a), requesting = Set(b)), - AuthRequest(holding = Set(a), requesting = Set(b)), - ) - } - } - "sequence2: A-> ( {B}->B ; {A}->A ) [OK; only 1 auth node]" in { - inside( - makeSequence2( - committers = Set(a), - required1 = Set(b), - signed1 = b, - required2 = Set(a), - signed2 = a, - ) - ) { case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List[Shape](Authority(Set(b), List(Create(b))), Create(a)) - shape shouldBe expected - ars shouldBe List(AuthRequest(holding = Set(a), requesting = Set(b))) - } - } - "sequence2: A-> ( {B}->B ; {C}->A ) [FAIL]" in { - inside( - makeSequence2( - committers = Set(a), - required1 = Set(b), - signed1 = b, - required2 = Set(c), - signed2 = a, - ) - ) { case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(c) - cma.requiredParties shouldBe Set(a) - } - } - } - } - "sequence2: A-> ( {B}->B ; {C}->B ) [FAIL]" in { - inside( - makeSequence2( - committers = Set(a), - required1 = Set(b), - signed1 = b, - required2 = Set(c), - signed2 = b, - ) - ) { case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(c) - cma.requiredParties shouldBe Set(b) - } - } - } - } - } - - "Nested" - { - - "nested: A->{B}->{C}->C [OK]" in { - inside(makeNested(committers = Set(a), outer = Set(b), inner = Set(c), signed = c)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(b), List(Authority(Set(c), List(Create(c)))))) - shape shouldBe expected - ars shouldBe List( - AuthRequest(holding = Set(a), requesting = Set(b)), - AuthRequest(holding = Set(b), requesting = Set(c)), - ) - } - } - "nested: A->{B}->{C}->A [FAIL]" in { - inside(makeNested(committers = Set(a), outer = Set(b), inner = Set(c), signed = a)) { - case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(c) - cma.requiredParties shouldBe Set(a) - } - } - } - } - "nested: A->{B}->{C}->B [FAIL]" in { - inside(makeNested(committers = Set(a), outer = Set(b), inner = Set(c), signed = b)) { - case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(c) - cma.requiredParties shouldBe Set(b) - } - } - } - } - "nested: A->{A}->{C}->C [OK; 1 auth-node]" in { - inside(makeNested(committers = Set(a), outer = Set(a), inner = Set(c), signed = c)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(c), List(Create(c)))) - shape shouldBe expected - ars shouldBe List(AuthRequest(holding = Set(a), requesting = Set(c))) - } - } - "nested: A->{A}->{C}->A [FAIL]" in { - inside(makeNested(committers = Set(a), outer = Set(a), inner = Set(c), signed = a)) { - case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(c) - cma.requiredParties shouldBe Set(a) - } - } - } - } - "nested: A->{C}->{C}->C [OK; 1 auth-node]" in { - inside(makeNested(committers = Set(a), outer = Set(c), inner = Set(c), signed = c)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(c), List(Create(c)))) - shape shouldBe expected - ars shouldBe List(AuthRequest(holding = Set(a), requesting = Set(c))) - } - } - "nested: A->{C}->{C}->A [FAIL]" in { - inside(makeNested(committers = Set(a), outer = Set(c), inner = Set(c), signed = a)) { - case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(c) - cma.requiredParties shouldBe Set(a) - } - } - } - } - "nested: A->{A,B}->{B,C}->C [OK]" in { - inside(makeNested(committers = Set(a), outer = Set(a, b), inner = Set(b, c), signed = c)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(a, b), List(Authority(Set(b, c), List(Create(c)))))) - shape shouldBe expected - ars shouldBe List( - AuthRequest(holding = Set(a), requesting = Set(b)), - AuthRequest(holding = Set(a, b), requesting = Set(c)), - ) - } - } - "nested: A->{A,B}->{B,C}->B [OK]" in { - inside(makeNested(committers = Set(a), outer = Set(a, b), inner = Set(b, c), signed = b)) { - case Right((tx, ars)) => - val shape = shapeOfTransaction(tx) - val expected = List(Authority(Set(a, b), List(Authority(Set(b, c), List(Create(b)))))) - shape shouldBe expected - ars shouldBe List( - AuthRequest(holding = Set(a), requesting = Set(b)), - AuthRequest(holding = Set(a, b), requesting = Set(c)), - ) - } - } - "nested: A->{A,B}->{B,C}->A [FAIL]" in { - inside(makeNested(committers = Set(a), outer = Set(a, b), inner = Set(b, c), signed = a)) { - case Left(err) => - inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) => - inside(why) { case cma: CreateMissingAuthorization => - cma.authorizingParties shouldBe Set(b, c) - cma.requiredParties shouldBe Set(a) - } - } - } - } - } - - // TODO #15882 -- test interaction between Authority and Exercise/Rollback nodes - -} - -object WithAuthorityTest { - - import SpeedyTestLib.loggingContext - import SpeedyTestLib.AuthRequest - - val transactionSeed = crypto.Hash.hashPrivateKey("WithAuthorityTest.scala") - - val pkgs: PureCompiledPackages = SpeedyTestLib.typeAndCompile(p""" - module M { - - record @serializable T1 = { signed: Party, info: Int64 } ; - template (record : T1) = { - precondition True; - signatories Cons @Party [M:T1 {signed} record] (Nil @Party); - observers Nil @Party; - agreement "Agreement"; - }; - - val single : List Party -> Party -> Update Unit = - \(requested: List Party) -> \(signed: Party) -> - WITH_AUTHORITY @Unit requested - (ubind x1: ContractId M:T1 <- create @M:T1 M:T1 { signed = signed, info = 100 } - in upure @Unit ()); - - val nested : List Party -> List Party -> Party -> Update Unit = - \(outer: List Party) -> \(inner: List Party) -> \(signed: Party) -> - WITH_AUTHORITY @Unit outer - (WITH_AUTHORITY @Unit inner - (ubind x1: ContractId M:T1 <- create @M:T1 M:T1 { signed = signed, info = 100 } - in upure @Unit ())); - - val sequence1 : List Party -> Party -> Party -> Update Unit = - \(required1: List Party) -> \(signed1: Party) -> \(signed2: Party) -> - ubind - u: Unit <- - WITH_AUTHORITY @Unit required1 - (ubind x1: ContractId M:T1 <- create @M:T1 M:T1 { signed = signed1, info = 100 } - in upure @Unit ()); - x2: ContractId M:T1 <- create @M:T1 M:T1 { signed = signed2, info = 100 } - in upure @Unit (); - - val sequence2 : List Party -> Party -> List Party -> Party -> Update Unit = - \(required1: List Party) -> \(signed1: Party) -> \(required2: List Party) -> \(signed2: Party) -> - ubind - u: Unit <- - WITH_AUTHORITY @Unit required1 - (ubind x1: ContractId M:T1 <- create @M:T1 M:T1 { signed = signed1, info = 100 } - in upure @Unit ()); - u: Unit <- - WITH_AUTHORITY @Unit required2 - (ubind x2: ContractId M:T1 <- create @M:T1 M:T1 { signed = signed2, info = 100 } - in upure @Unit ()) - in upure @Unit (); - } - """) - - def makeSetPartyValue(set: Set[Party]): SValue = { - SList(FrontStack(set.toList.map(SParty(_)): _*)) - } - - type Success = (SubmittedTransaction, List[AuthRequest]) - - def makeSingle( - committers: Set[Party], - required: Set[Party], - signed: Party, - ): Either[SError, Success] = { - val requiredV = makeSetPartyValue(required) - val signedV = SParty(signed) - val example = SEApp(pkgs.compiler.unsafeCompile(e"M:single"), Array(requiredV, signedV)) - val machine = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, example, committers) - SpeedyTestLib.buildTransactionCollectAuthRequests(machine) - } - - def makeSequence1( - committers: Set[Party], - required: Set[Party], - signed1: Party, - signed2: Party, - ): Either[SError, Success] = { - val requiredV = makeSetPartyValue(required) - val signed1V = SParty(signed1) - val signed2V = SParty(signed2) - val example = SEApp( - pkgs.compiler.unsafeCompile(e"M:sequence1"), - Array(requiredV, signed1V, signed2V), - ) - val machine = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, example, committers) - SpeedyTestLib.buildTransactionCollectAuthRequests(machine) - } - - def makeSequence2( - committers: Set[Party], - required1: Set[Party], - signed1: Party, - required2: Set[Party], - signed2: Party, - ): Either[SError, Success] = { - val required1V = makeSetPartyValue(required1) - val signed1V = SParty(signed1) - val required2V = makeSetPartyValue(required2) - val signed2V = SParty(signed2) - val example = SEApp( - pkgs.compiler.unsafeCompile(e"M:sequence2"), - Array(required1V, signed1V, required2V, signed2V), - ) - val machine = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, example, committers) - SpeedyTestLib.buildTransactionCollectAuthRequests(machine) - } - - def makeNested( - committers: Set[Party], - outer: Set[Party], - inner: Set[Party], - signed: Party, - ): Either[SError, Success] = { - val outerV = makeSetPartyValue(outer) - val innerV = makeSetPartyValue(inner) - val signedV = SParty(signed) - val example = SEApp(pkgs.compiler.unsafeCompile(e"M:nested"), Array(outerV, innerV, signedV)) - val machine = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, example, committers) - SpeedyTestLib.buildTransactionCollectAuthRequests(machine) - } - - sealed trait Shape // minimal transaction tree, for purposes of writing test expectation - final case class Create(signed: Party) extends Shape - final case class Exercise(x: List[Shape]) extends Shape - final case class Rollback(x: List[Shape]) extends Shape - final case class Authority(obtained: Set[Party], x: List[Shape]) extends Shape - - private def shapeOfTransaction(tx: SubmittedTransaction): List[Shape] = { - def trees(nid: NodeId): List[Shape] = { - tx.nodes(nid) match { - case create: Node.Create => - create.arg match { - case ValueRecord(_, ImmArray((None, ValueParty(signed)), _)) => - List(Create(signed)) - case _ => - sys.error(s"unexpected create.arg: ${create.arg}") - } - case _: Node.LeafOnlyAction => - Nil - case node: Node.Exercise => - List(Exercise(node.children.toList.flatMap(nid => trees(nid)))) - case node: Node.Rollback => - List(Rollback(node.children.toList.flatMap(nid => trees(nid)))) - case node: Node.Authority => - List(Authority(node.obtained, node.children.toList.flatMap(nid => trees(nid)))) - } - } - tx.roots.toList.flatMap(nid => trees(nid)) - } -} diff --git a/daml-lf/language/src/main/scala/com/digitalasset/daml/lf/language/Ast.scala b/daml-lf/language/src/main/scala/com/digitalasset/daml/lf/language/Ast.scala index a2b6fe4defa3..2454bf566e2c 100644 --- a/daml-lf/language/src/main/scala/com/digitalasset/daml/lf/language/Ast.scala +++ b/daml-lf/language/src/main/scala/com/digitalasset/daml/lf/language/Ast.scala @@ -457,10 +457,6 @@ object Ast { final case object BFoldl extends BuiltinFunction // : ∀a b. (b → a → b) → b → List a → b final case object BFoldr extends BuiltinFunction // : ∀a b. (a → b → b) → b → List a → b - // Authority - final case object BWithAuthority - extends BuiltinFunction // : ∀ a. List Party → Update a → Update a - // Maps final case object BTextMapEmpty extends BuiltinFunction // : ∀ a. TextMap a final case object BTextMapInsert diff --git a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala index a9be97b5a5fa..3091d7c16e47 100644 --- a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala +++ b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala @@ -338,7 +338,6 @@ private[parser] class ExprParser[P](parserParameters: ParserParameters[P]) { "UNIX_MICROSECONDS_TO_TIMESTAMP" -> BUnixMicrosecondsToTimestamp, "FOLDL" -> BFoldl, "FOLDR" -> BFoldr, - "WITH_AUTHORITY" -> BWithAuthority, "TEXTMAP_EMPTY" -> BTextMapEmpty, "TEXTMAP_INSERT" -> BTextMapInsert, "TEXTMAP_LOOKUP" -> BTextMapLookup, diff --git a/daml-lf/parser/src/test/scala/com/digitalasset/daml/lf/testing/parser/ParsersSpec.scala b/daml-lf/parser/src/test/scala/com/digitalasset/daml/lf/testing/parser/ParsersSpec.scala index b35e045be188..a8a4f1f3201e 100644 --- a/daml-lf/parser/src/test/scala/com/digitalasset/daml/lf/testing/parser/ParsersSpec.scala +++ b/daml-lf/parser/src/test/scala/com/digitalasset/daml/lf/testing/parser/ParsersSpec.scala @@ -209,7 +209,6 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher "UNIX_MICROSECONDS_TO_TIMESTAMP" -> BUnixMicrosecondsToTimestamp, "FOLDL" -> BFoldl, "FOLDR" -> BFoldr, - "WITH_AUTHORITY" -> BWithAuthority, "EXPLODE_TEXT" -> BExplodeText, "IMPLODE_TEXT" -> BImplodeText, "APPEND_TEXT" -> BAppendText, diff --git a/daml-lf/spec/daml-lf-1.rst b/daml-lf/spec/daml-lf-1.rst index abe03574e26c..03535093ce57 100644 --- a/daml-lf/spec/daml-lf-1.rst +++ b/daml-lf/spec/daml-lf-1.rst @@ -4557,15 +4557,6 @@ List functions predicate give as first argument. -Authority functions -~~~~~~~~~~~~~~~~~~~ - -* ``WITH_AUTHORITY : ∀ (α : ⋆) . 'List' 'Party' → 'Update' α → 'Update' α`` - - Request authorization from the ledger for the scope of an update operation. - - [*Available in versions >= 1.dev*] - Text map functions ~~~~~~~~~~~~~~~~~~ diff --git a/daml-lf/tests/WithAuthority.daml b/daml-lf/tests/WithAuthority.daml index bfb2dfde5e3f..94dd29041ea6 100644 --- a/daml-lf/tests/WithAuthority.daml +++ b/daml-lf/tests/WithAuthority.daml @@ -22,3 +22,7 @@ template T withAuthorityOf [party2] $ do create (HaveAuthority party2) pure () + + +withAuthorityOf : [Party] -> Update a -> Update a +withAuthorityOf _ u = u -- TODO #15882 -- require rework diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala index 1e12331f2114..79ab09884218 100644 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala @@ -137,12 +137,6 @@ private[validation] object Typing { alpha.name -> KStar, TForall(beta.name -> KStar, (alpha ->: beta ->: beta) ->: beta ->: TList(alpha) ->: beta), ), - // Authority - BWithAuthority -> - TForall( - alpha.name -> KStar, - TList(TParty) ->: TUpdate(alpha) ->: TUpdate(alpha), - ), // Maps BTextMapEmpty -> TForall( diff --git a/daml-script/test/daml/TestWithAuthority.daml b/daml-script/test/daml/TestWithAuthority.daml index b08c1920af50..fda06c1d85c8 100644 --- a/daml-script/test/daml/TestWithAuthority.daml +++ b/daml-script/test/daml/TestWithAuthority.daml @@ -32,6 +32,8 @@ template ProposeConsortiumAuthority withAuthorityOf [consortiumParty] $ do create HasConsortiumAutority with consortiumParty +withAuthorityOf : [Party] -> Update a -> Update a +withAuthorityOf _ u = u -- TODO #15882 -- require rework test : Script () test = do @@ -46,7 +48,8 @@ test = do proposer = alice accepted = [] obs = [bob,charlie] - consortiumParty = org + --consortiumParty = org -- TODO #15882 -- require rework + consortiumParty = alice prop <- submit bob do exerciseCmd prop Accept with who = bob prop <- submit charlie do exerciseCmd prop Accept with who = charlie