Add by_interface field in Create, Fetch, & Exercise transaction nodes. (#11576)

* Add by_interface field in tx nodes.

This PR adds an optional `by_interface` field in the Create, Fetch,
and Exercise nodes, as part of #10915. It also updates TransactionCoder
to support these fields.

Setting these fields (in the LF interpreter) is left to a separate PR.

changelog_begin
changelog_end

* update security-evidence.md

* Add version checks in TransactionCoder
This commit is contained in:
Sofia Faro 2021-11-08 16:33:02 +00:00 committed by GitHub
parent 7d68e05f7f
commit cbc3c8c686
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 136 additions and 33 deletions

View File

@ -37,6 +37,7 @@ class AuthorizationSpec extends AnyFreeSpec with Matchers with Inside {
observers = Seq("Carl"),
key = Some(Value.ValueUnit),
maintainers = maintainers,
byInterface = None,
)
"create" - {

View File

@ -103,6 +103,7 @@ class BlindingSpec extends AnyFreeSpec with Matchers {
observers = Seq("Carl"),
key = Some(ValueRecord(None, ImmArray.empty)),
maintainers = Seq("Alice"),
byInterface = None,
)
val lookup = builder.lookupByKey(create, true)
val nodeId = builder.add(lookup)
@ -124,6 +125,7 @@ class BlindingSpec extends AnyFreeSpec with Matchers {
observers = Seq("Carl"),
key = Some(ValueRecord(None, ImmArray.empty)),
maintainers = Seq("Alice"),
byInterface = None,
)
val lookup = builder.lookupByKey(create, false)
val nodeId = builder.add(lookup)

View File

@ -1104,6 +1104,7 @@ class EngineTest
_,
_,
_,
_,
) =>
coid shouldBe originalCoid
consuming shouldBe true
@ -1190,7 +1191,7 @@ class EngineTest
def actFetchActors(n: Node): Set[Party] = {
n match {
case Node.Fetch(_, _, actingParties, _, _, _, _, _) => actingParties
case Node.Fetch(_, _, actingParties, _, _, _, _, _, _) => actingParties
case _ => Set()
}
}
@ -1576,7 +1577,7 @@ class EngineTest
)
tx.transaction.nodes.values.headOption match {
case Some(Node.Fetch(_, _, _, _, _, key, _, _)) =>
case Some(Node.Fetch(_, _, _, _, _, key, _, _, _)) =>
key match {
// just test that the maintainers match here, getting the key out is a bit hairier
case Some(Node.KeyWithMaintainers(_, maintainers)) =>
@ -1800,7 +1801,7 @@ class EngineTest
val stx = suffix(tx)
val ImmArray(_, exeNode1) = tx.transaction.roots
val Node.Exercise(_, _, _, _, _, _, _, _, _, children, _, _, _, _) =
val Node.Exercise(_, _, _, _, _, _, _, _, _, children, _, _, _, _, _) =
tx.transaction.nodes(exeNode1)
val nids = children.toSeq.take(2).toImmArray

View File

@ -485,7 +485,7 @@ object ScenarioLedger {
}
processNodes(mbNewCache2, idsToProcess)
case Node.Fetch(referencedCoid, templateId @ _, _, _, _, _, _, _) =>
case Node.Fetch(referencedCoid, templateId @ _, _, _, _, _, _, _, _) =>
val newCacheP =
newCache.updateLedgerNodeInfo(referencedCoid)(info =>
info.copy(referencedBy = info.referencedBy + eventId)

View File

@ -945,6 +945,7 @@ private[lf] object SBuiltin {
signatories = sigs,
stakeholders = sigs union obs,
key = mbKey,
byInterface = None, // TODO https://github.com/digital-asset/daml/issues/10915
)
machine.addLocalContract(coid, templateId, createArg, sigs, obs, mbKey)
@ -1007,6 +1008,7 @@ private[lf] object SBuiltin {
mbKey = mbKey,
byKey = byKey,
chosenValue = chosenValue,
byInterface = None, // TODO https://github.com/digital-asset/daml/issues/10915
)
checkAborted(onLedger.ptx)
machine.returnValue = SUnit
@ -1217,6 +1219,7 @@ private[lf] object SBuiltin {
stakeholders,
key,
byKey,
None, // TODO https://github.com/digital-asset/daml/issues/10915
)
checkAborted(onLedger.ptx)
machine.returnValue = SUnit

View File

@ -136,6 +136,8 @@ private[lf] object PartialTransaction {
* @param parent The context in which the exercises is
* happening.
* @param byKey True if the exercise is done "by key"
* @param byInterface The interface through which this exercise
* was invoked, if any.
*/
final case class ExercisesContextInfo(
targetId: Value.ContractId,
@ -151,6 +153,7 @@ private[lf] object PartialTransaction {
nodeId: NodeId,
parent: Context,
byKey: Boolean,
byInterface: Option[TypeConName],
) extends ContextInfo {
val actionNodeSeed = parent.nextActionChildSeed
val actionChildSeed = crypto.Hash.deriveNodeSeed(actionNodeSeed, _)
@ -406,6 +409,7 @@ private[speedy] case class PartialTransaction(
signatories: Set[Party],
stakeholders: Set[Party],
key: Option[Node.KeyWithMaintainers[Value]],
byInterface: Option[TypeConName],
): (Value.ContractId, PartialTransaction) = {
val actionNodeSeed = context.nextActionChildSeed
val discriminator =
@ -420,6 +424,7 @@ private[speedy] case class PartialTransaction(
signatories,
stakeholders,
key,
byInterface,
version,
)
val nid = NodeId(nextNodeIdx)
@ -498,6 +503,7 @@ private[speedy] case class PartialTransaction(
stakeholders: Set[Party],
key: Option[Node.KeyWithMaintainers[Value]],
byKey: Boolean,
byInterface: Option[TypeConName],
): PartialTransaction = {
val nid = NodeId(nextNodeIdx)
val version = packageToTransactionVersion(templateId.packageId)
@ -509,6 +515,7 @@ private[speedy] case class PartialTransaction(
stakeholders,
key,
normByKey(version, byKey),
byInterface,
version,
)
mustBeActive(
@ -554,6 +561,7 @@ private[speedy] case class PartialTransaction(
mbKey: Option[Node.KeyWithMaintainers[Value]],
byKey: Boolean,
chosenValue: Value,
byInterface: Option[TypeConName],
): PartialTransaction = {
val nid = NodeId(nextNodeIdx)
val ec =
@ -571,6 +579,7 @@ private[speedy] case class PartialTransaction(
nodeId = nid,
parent = context,
byKey = byKey,
byInterface = byInterface,
)
mustBeActive(
@ -663,6 +672,7 @@ private[speedy] case class PartialTransaction(
exerciseResult = None,
key = ec.contractKey,
byKey = normByKey(version, ec.byKey),
byInterface = ec.byInterface,
version = version,
)
}

View File

@ -301,6 +301,7 @@ object NormalizeRollbackSpec {
signatories = Set.empty,
stakeholders = Set.empty,
key = None,
byInterface = None,
version = TransactionVersion.minVersion,
)
@ -324,6 +325,7 @@ object NormalizeRollbackSpec {
exerciseResult = None,
key = None,
byKey = false,
byInterface = None,
version = TransactionVersion.minVersion,
)
}

View File

@ -53,6 +53,7 @@ class PartialTransactionSpec extends AnyWordSpec with Matchers with Inside {
Set(party),
Set.empty,
None,
None,
)
._2
@ -70,6 +71,7 @@ class PartialTransactionSpec extends AnyWordSpec with Matchers with Inside {
choiceObservers = Set.empty,
mbKey = None,
byKey = false,
byInterface = None,
chosenValue = Value.ValueUnit,
)

View File

@ -84,8 +84,9 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion
signatories: Set[Ref.Party],
observers: Set[Ref.Party],
key: Option[Value] = None,
byInterface: Option[Ref.Identifier] = None,
): Node.Create =
create(id, templateId, argument, signatories, observers, key, signatories)
create(id, templateId, argument, signatories, observers, key, signatories, byInterface)
def create(
id: ContractId,
@ -95,6 +96,7 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion
observers: Set[Ref.Party],
key: Option[Value],
maintainers: Set[Ref.Party],
byInterface: Option[Ref.Identifier],
): Node.Create = {
Node.Create(
coid = id,
@ -104,6 +106,7 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion
signatories = signatories,
stakeholders = signatories | observers,
key = key.map(Node.KeyWithMaintainers(_, maintainers)),
byInterface = byInterface,
version = pkgTxVersion(templateId.packageId),
)
}
@ -117,6 +120,7 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion
result: Option[Value] = None,
choiceObservers: Set[Ref.Party] = Set.empty,
byKey: Boolean = true,
byInterface: Option[Ref.Identifier] = None,
): Node.Exercise =
Node.Exercise(
choiceObservers = choiceObservers,
@ -132,6 +136,7 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion
exerciseResult = result,
key = contract.key,
byKey = byKey,
byInterface = byInterface,
version = pkgTxVersion(contract.templateId.packageId),
)
@ -144,7 +149,11 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion
): Node.Exercise =
exercise(contract, choice, consuming, actingParties, argument, byKey = true)
def fetch(contract: Node.Create, byKey: Boolean = false): Node.Fetch =
def fetch(
contract: Node.Create,
byKey: Boolean = false,
byInterface: Option[Ref.Identifier] = None,
): Node.Fetch =
Node.Fetch(
coid = contract.coid,
templateId = contract.templateId,
@ -153,6 +162,7 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion
stakeholders = contract.stakeholders,
key = contract.key,
byKey = byKey,
byInterface = byInterface,
version = pkgTxVersion(contract.templateId.packageId),
)

View File

@ -316,6 +316,7 @@ object ValueGenerators {
signatories,
stakeholders,
key,
None, // TODO https://github.com/digital-asset/daml/issues/10915
version,
)
}
@ -343,6 +344,7 @@ object ValueGenerators {
stakeholders,
key,
byKey,
None, // TODO https://github.com/digital-asset/daml/issues/10915
version,
)
}
@ -399,6 +401,7 @@ object ValueGenerators {
exerciseResult,
key,
byKey,
None, // TODO https://github.com/digital-asset/daml/issues/10915
version,
)
}

View File

@ -10,8 +10,9 @@
// * 12 -- drop value version in profit of node version
// * 13 -- no change w.r.t. 12
// * 14 -- add rollback nodes
// add byKey flag to fetch and exercise node
// add by_key flag to fetch and exercise node
// * dev -- special staging area for the next version to be released
// add by_interface to fetch and exercise node
syntax = "proto3";
package com.daml.lf.transaction;
@ -72,6 +73,7 @@ message NodeCreate {
repeated string signatories = 4;
KeyWithMaintainers key_with_maintainers = 5;
com.daml.lf.value.ContractId contract_id_struct = 6;
optional com.daml.lf.value.Identifier by_interface = 10; // *since version dev*
}
message NodeFetch {
@ -83,7 +85,8 @@ message NodeFetch {
reserved 5; // was value_version
com.daml.lf.value.ContractId contract_id_struct = 6;
KeyWithMaintainers key_with_maintainers = 8;
bool byKey = 9; // *since version 1.14*
bool by_key = 9; // *since version 1.14*
optional com.daml.lf.value.Identifier by_interface = 10; // *since version dev*
}
message NodeExercise {
@ -108,7 +111,8 @@ message NodeExercise {
reserved 13; // was contract_key
KeyWithMaintainers key_with_maintainers = 14; // optional
repeated string observers = 15; // *since version 11*
bool byKey = 18; // *since version 14*
bool by_key = 18; // *since version 14*
optional com.daml.lf.value.Identifier by_interface = 19; // *since version dev*
}
message NodeLookupByKey {

View File

@ -56,6 +56,8 @@ object Node {
def byKey: Boolean
def byInterface: Option[TypeConName]
protected def versionValue[Cid2 >: ContractId](v: Value): VersionedValue =
VersionedValue(version, v)
}
@ -82,6 +84,7 @@ object Node {
signatories: Set[Party],
stakeholders: Set[Party],
key: Option[KeyWithMaintainers[Value]],
override val byInterface: Option[TypeConName],
// For the sake of consistency between types with a version field, keep this field the last.
override val version: TransactionVersion,
) extends LeafOnlyAction
@ -121,6 +124,7 @@ object Node {
stakeholders: Set[Party],
key: Option[KeyWithMaintainers[Value]],
override val byKey: Boolean, // invariant (!byKey || exerciseResult.isDefined)
override val byInterface: Option[TypeConName],
// For the sake of consistency between types with a version field, keep this field the last.
override val version: TransactionVersion,
) extends LeafOnlyAction
@ -160,6 +164,7 @@ object Node {
exerciseResult: Option[Value],
key: Option[KeyWithMaintainers[Value]],
override val byKey: Boolean, // invariant (!byKey || exerciseResult.isDefined)
override val byInterface: Option[TypeConName],
// For the sake of consistency between types with a version field, keep this field the last.
override val version: TransactionVersion,
) extends Action
@ -210,6 +215,7 @@ object Node {
override def keyMaintainers: Set[Party] = key.maintainers
override def hasResult: Boolean = result.isDefined
override def byKey: Boolean = true
override def byInterface: Option[TypeConName] = None
override private[lf] def updateVersion(version: TransactionVersion): Node.LookupByKey =
copy(version = version)

View File

@ -437,9 +437,9 @@ sealed abstract class HasTxNodes {
*/
final def inputContracts[Cid2 >: ContractId]: Set[Cid2] =
fold(Set.empty[Cid2]) {
case (acc, (_, Node.Exercise(coid, _, _, _, _, _, _, _, _, _, _, _, _, _))) =>
case (acc, (_, Node.Exercise(coid, _, _, _, _, _, _, _, _, _, _, _, _, _, _))) =>
acc + coid
case (acc, (_, Node.Fetch(coid, _, _, _, _, _, _, _))) =>
case (acc, (_, Node.Fetch(coid, _, _, _, _, _, _, _, _))) =>
acc + coid
case (acc, (_, Node.LookupByKey(_, _, Some(coid), _))) =>
acc + coid
@ -763,13 +763,13 @@ object GenTransaction {
tx.fold(State(Set.empty, Set.empty)) { case (state, (_, node)) =>
node match {
case Node.Create(_, tmplId, _, _, _, _, Some(key), _) =>
case Node.Create(_, tmplId, _, _, _, _, Some(key), _, _) =>
state.created(globalKey(tmplId, key.key))
case Node.Exercise(_, tmplId, _, true, _, _, _, _, _, _, _, Some(key), _, _) =>
case Node.Exercise(_, tmplId, _, true, _, _, _, _, _, _, _, Some(key), _, _, _) =>
state.consumed(globalKey(tmplId, key.key))
case Node.Exercise(_, tmplId, _, false, _, _, _, _, _, _, _, Some(key), _, _) =>
case Node.Exercise(_, tmplId, _, false, _, _, _, _, _, _, _, Some(key), _, _, _) =>
state.referenced(globalKey(tmplId, key.key))
case Node.Fetch(_, tmplId, _, _, _, Some(key), _, _) =>
case Node.Fetch(_, tmplId, _, _, _, Some(key), _, _, _) =>
state.referenced(globalKey(tmplId, key.key))
case Node.LookupByKey(tmplId, key, Some(_), _) =>
state.referenced(globalKey(tmplId, key.key))

View File

@ -277,11 +277,16 @@ object TransactionCoder {
node match {
case nc @ Node.Create(_, _, _, _, _, _, _, _) =>
case nc @ Node.Create(_, _, _, _, _, _, _, _, _) =>
val builder = TransactionOuterClass.NodeCreate.newBuilder()
nc.stakeholders.foreach(builder.addStakeholders)
nc.signatories.foreach(builder.addSignatories)
discard(builder.setContractIdStruct(encodeCid.encode(nc.coid)))
if (nodeVersion >= TransactionVersion.minInterfaces) {
nc.byInterface.foreach(iface =>
builder.setByInterface(ValueCoder.encodeIdentifier(iface))
)
}
for {
_ <-
if (nodeVersion < TransactionVersion.minNoVersionValue) {
@ -309,7 +314,7 @@ object TransactionCoder {
)
} yield nodeBuilder.setCreate(builder).build()
case nf @ Node.Fetch(_, _, _, _, _, _, _, _) =>
case nf @ Node.Fetch(_, _, _, _, _, _, _, _, _) =>
val builder = TransactionOuterClass.NodeFetch.newBuilder()
discard(builder.setTemplateId(ValueCoder.encodeIdentifier(nf.templateId)))
nf.stakeholders.foreach(builder.addStakeholders)
@ -319,6 +324,11 @@ object TransactionCoder {
discard(builder.setByKey(nf.byKey))
}
nf.actingParties.foreach(builder.addActors)
if (nodeVersion >= TransactionVersion.minInterfaces) {
nf.byInterface.foreach(iface =>
builder.setByInterface(ValueCoder.encodeIdentifier(iface))
)
}
for {
_ <- encodeAndSetContractKey(
encodeCid,
@ -328,7 +338,7 @@ object TransactionCoder {
)
} yield nodeBuilder.setFetch(builder).build()
case ne @ Node.Exercise(_, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
case ne @ Node.Exercise(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
val builder = TransactionOuterClass.NodeExercise.newBuilder()
discard(
builder
@ -345,6 +355,11 @@ object TransactionCoder {
if (nodeVersion >= TransactionVersion.minByKey) {
discard(builder.setByKey(ne.byKey))
}
if (nodeVersion >= TransactionVersion.minInterfaces) {
ne.byInterface.foreach(iface =>
builder.setByInterface(ValueCoder.encodeIdentifier(iface))
)
}
for {
_ <- Either.cond(
test = ne.version >= TransactionVersion.minChoiceObservers ||
@ -515,6 +530,12 @@ object TransactionCoder {
nodeVersion,
protoCreate.getKeyWithMaintainers,
)
byInterface <-
if (nodeVersion >= TransactionVersion.minInterfaces && protoCreate.hasByInterface) {
ValueCoder.decodeIdentifier(protoCreate.getByInterface).map(Some(_))
} else {
Right(None)
}
} yield ni -> Node.Create(
c,
ci.template,
@ -523,6 +544,7 @@ object TransactionCoder {
signatories,
stakeholders,
key,
byInterface,
nodeVersion,
)
case NodeTypeCase.FETCH =>
@ -543,6 +565,12 @@ object TransactionCoder {
if (nodeVersion >= TransactionVersion.minByKey)
protoFetch.getByKey
else false
byInterface <-
if (nodeVersion >= TransactionVersion.minInterfaces && protoFetch.hasByInterface) {
ValueCoder.decodeIdentifier(protoFetch.getByInterface).map(Some(_))
} else {
Right(None)
}
} yield ni -> Node.Fetch(
coid = c,
templateId = templateId,
@ -551,6 +579,7 @@ object TransactionCoder {
stakeholders = stakeholders,
key = key,
byKey = byKey,
byInterface = byInterface,
version = nodeVersion,
)
@ -600,6 +629,12 @@ object TransactionCoder {
if (nodeVersion >= TransactionVersion.minByKey)
protoExe.getByKey
else false
byInterface <-
if (nodeVersion >= TransactionVersion.minInterfaces && protoExe.hasByInterface) {
ValueCoder.decodeIdentifier(protoExe.getByInterface).map(Some(_))
} else {
Right(None)
}
} yield ni -> Node.Exercise(
targetCoid = targetCoid,
templateId = templateId,
@ -614,6 +649,7 @@ object TransactionCoder {
exerciseResult = rvOpt,
key = keyWithMaintainers,
byKey = byKey,
byInterface = byInterface,
version = nodeVersion,
)
case NodeTypeCase.LOOKUP_BY_KEY =>

View File

@ -49,6 +49,7 @@ object TransactionVersion {
//nothing was added in V13, so there are no vals: "minSomething = V13"
private[lf] val minExceptions = V14
private[lf] val minByKey = V14
private[lf] val minInterfaces = VDev
private[lf] val assignNodeVersion: LanguageVersion => TransactionVersion = {
import LanguageVersion._

View File

@ -230,6 +230,7 @@ class TransactionCoderSpec
signatories = Set(Party.assertFromString("alice")),
stakeholders = Set(Party.assertFromString("alice"), Party.assertFromString("bob")),
key = None,
byInterface = None,
version = TransactionVersion.minVersion,
)

View File

@ -679,6 +679,7 @@ object TransactionSpec {
exerciseResult = if (hasExerciseResult) Some(V.ValueUnit) else None,
key = None,
byKey = false,
byInterface = None,
version = TransactionVersion.minVersion,
)
@ -691,6 +692,7 @@ object TransactionSpec {
signatories = Set.empty,
stakeholders = Set.empty,
key = None,
byInterface = None,
version = TransactionVersion.minVersion,
)

View File

@ -96,6 +96,7 @@ class ValidationSpec extends AnyFreeSpec with Matchers with TableDrivenPropertyC
signatories = samParties1,
stakeholders = samParties2,
key = key,
byInterface = None, // TODO https://github.com/digital-asset/daml/issues/10915
version = version,
)
@ -112,6 +113,7 @@ class ValidationSpec extends AnyFreeSpec with Matchers with TableDrivenPropertyC
stakeholders = samParties3,
key = key,
byKey = samBool1,
byInterface = None, // TODO https://github.com/digital-asset/daml/issues/10915
version = version,
)
@ -145,6 +147,7 @@ class ValidationSpec extends AnyFreeSpec with Matchers with TableDrivenPropertyC
exerciseResult = exerciseResult,
key = key,
byKey = samBool2,
byInterface = None, // TODO https://github.com/digital-asset/daml/issues/10915
version = version,
)

View File

@ -52,7 +52,7 @@ private[migration] class V10_1__Populate_Event_Data extends BaseJavaMigration {
val txs = loadTransactions(conn)
val data = txs.flatMap { case (txId, tx) =>
tx.nodes.collect {
case (nodeId, Node.Create(cid, _, _, _, signatories, stakeholders, _, _)) =>
case (nodeId, Node.Create(cid, _, _, _, signatories, stakeholders, _, _, _)) =>
(cid, EventId(txId, nodeId), signatories, stakeholders -- signatories)
}
}

View File

@ -34,6 +34,7 @@ private[dao] trait JdbcLedgerDaoDivulgenceSpec extends LoneElement with Inside {
signatories = Set(alice),
stakeholders = Set(alice),
key = None,
byInterface = None,
version = TransactionVersion.minVersion,
)
)
@ -53,6 +54,7 @@ private[dao] trait JdbcLedgerDaoDivulgenceSpec extends LoneElement with Inside {
key = Some(
Node.KeyWithMaintainers(someContractKey(bob, "some key"), Set(bob))
),
byInterface = None,
version = TransactionVersion.minVersion,
)
)
@ -77,6 +79,7 @@ private[dao] trait JdbcLedgerDaoDivulgenceSpec extends LoneElement with Inside {
exerciseResult = Some(someChoiceResult),
key = None,
byKey = false,
byInterface = None,
version = TransactionVersion.minVersion,
)
)
@ -91,6 +94,7 @@ private[dao] trait JdbcLedgerDaoDivulgenceSpec extends LoneElement with Inside {
Node.KeyWithMaintainers(ValueParty(bob), Set(bob))
),
byKey = false,
byInterface = None,
version = TransactionVersion.minVersion,
),
parentId = rootExercise,
@ -112,6 +116,7 @@ private[dao] trait JdbcLedgerDaoDivulgenceSpec extends LoneElement with Inside {
Node.KeyWithMaintainers(someContractKey(bob, "some key"), Set(bob))
),
byKey = false,
byInterface = None,
version = TransactionVersion.minVersion,
),
parentId = rootExercise,
@ -127,6 +132,7 @@ private[dao] trait JdbcLedgerDaoDivulgenceSpec extends LoneElement with Inside {
key = Some(
Node.KeyWithMaintainers(someContractKey(bob, "some key"), Set(bob))
),
byInterface = None,
version = TransactionVersion.minVersion,
),
parentId = nestedExercise,

View File

@ -207,6 +207,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
signatories = signatories,
stakeholders = stakeholders,
key = key,
byInterface = None,
version = txVersion,
)
@ -228,6 +229,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
exerciseResult = Some(someChoiceResult),
key = key,
byKey = false,
byInterface = None,
version = txVersion,
)
@ -243,6 +245,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
stakeholders = Set(party),
None,
byKey = false,
byInterface = None,
version = txVersion,
)
@ -384,6 +387,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
exerciseResult = Some(someChoiceResult),
key = None,
byKey = false,
byInterface = None,
version = txVersion,
)
)
@ -396,6 +400,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
stakeholders = Set(alice),
None,
byKey = false,
byInterface = None,
version = txVersion,
),
exerciseId,
@ -710,6 +715,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
signatories = Set(party),
stakeholders = Set(party),
key = Some(Node.KeyWithMaintainers(someContractKey(party, key), Set(party))),
byInterface = None,
version = txVersion,
)
)
@ -750,6 +756,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
exerciseResult = Some(LfValue.ValueUnit),
key = maybeKey.map(k => Node.KeyWithMaintainers(someContractKey(party, k), Set(party))),
byKey = false,
byInterface = None,
version = txVersion,
)
)
@ -810,6 +817,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
stakeholders = Set(party),
None,
byKey = false,
byInterface = None,
version = txVersion,
)
)

View File

@ -23,6 +23,7 @@ class ProjectionsSpec extends AnyWordSpec with Matchers {
signatories = signatories,
stakeholders = stakeholders,
key = None,
byInterface = None,
version = TransactionVersion.minVersion,
)
@ -49,6 +50,7 @@ class ProjectionsSpec extends AnyWordSpec with Matchers {
exerciseResult = None,
key = None,
byKey = false,
byInterface = None,
version = TransactionVersion.minVersion,
)

View File

@ -1,32 +1,32 @@
# Security tests, by category
## Authorization:
- badly-authorized create is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L60)
- badly-authorized exercise is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L158)
- badly-authorized create is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L61)
- badly-authorized exercise is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L159)
- badly-authorized exercise/create (create is unauthorized) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L265)
- badly-authorized exercise/create (exercise is unauthorized) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L233)
- badly-authorized exercise/exercise (no implicit authority from outer exercise) is rejected: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L324)
- badly-authorized fetch is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L95)
- badly-authorized lookup is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L117)
- create with no signatories is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L50)
- create with non-signatory maintainers is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L72)
- exercise with no controllers is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L148)
- well-authorized create is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L43)
- well-authorized exercise is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L141)
- badly-authorized fetch is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L96)
- badly-authorized lookup is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L118)
- create with no signatories is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L51)
- create with non-signatory maintainers is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L73)
- exercise with no controllers is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L149)
- well-authorized create is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L44)
- well-authorized exercise is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L142)
- well-authorized exercise/create is accepted: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L211)
- well-authorized exercise/exercise is accepted: [AuthPropagationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthPropagationSpec.scala#L367)
- well-authorized fetch is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L89)
- well-authorized lookup is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L111)
- well-authorized fetch is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L90)
- well-authorized lookup is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L112)
## Privacy:
- ensure correct privacy for create node: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L32)
- ensure correct privacy for exercise node (consuming): [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L43)
- ensure correct privacy for exercise node (non-consuming): [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L62)
- ensure correct privacy for exercise subtree: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L137)
- ensure correct privacy for exercise subtree: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L139)
- ensure correct privacy for fetch node: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L82)
- ensure correct privacy for lookup-by-key node (found): [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L94)
- ensure correct privacy for lookup-by-key node (not-found): [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L115)
- ensure correct privacy for rollback subtree: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L199)
- ensure correct privacy for lookup-by-key node (not-found): [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L116)
- ensure correct privacy for rollback subtree: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L201)
## Semantics:
- Exceptions, throw/catch.: [ExceptionTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ExceptionTest.scala#L24)