[engine] kill Daml withAuthority / LF WITH_AUTHORITY (#16548)

This commit is contained in:
nickchapman-da 2023-04-17 16:50:10 +01:00 committed by GitHub
parent e1a96bc543
commit ac68bdf416
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 16 additions and 620 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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*

View File

@ -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),

View File

@ -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((_, _)) =>
}
}
*/
}
}

View File

@ -472,9 +472,6 @@ private[lf] final class PhaseOne(
case BFoldr => SBFoldr
case BEqualList => SBEqualList
// Authority functions
case BWithAuthority => SBWithAuthority
// Errors
case BError => SBUserError

View File

@ -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))
}
}

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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
~~~~~~~~~~~~~~~~~~

View File

@ -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

View File

@ -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(

View File

@ -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