Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KV: do not use "Effects" part of InputsAndEffects #9433

Merged
merged 5 commits into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,29 @@ sealed abstract class HasTxNodes[Nid, +Cid] {
globalState
}

final def localContracts[Cid2 >: Cid]: Map[Cid2, Nid] =
fold(Map.empty[Cid2, Nid]) {
final def localContracts[Cid2 >: Cid]: Map[Cid2, (Nid, Node.NodeCreate[Cid2])] =
fold(Map.empty[Cid2, (Nid, Node.NodeCreate[Cid2])]) {
case (acc, (nid, create: Node.NodeCreate[Cid])) =>
acc.updated(create.coid, nid)
acc.updated(create.coid, nid -> create)
case (acc, _) => acc
}

/** Returns the IDs of all the consumed contracts.
* This includes transient contracts but it does not include contracts
* consumed in rollback nodes.
*/
final def consumedContracts[Cid2 >: Cid]: Set[Cid2] =
foldInExecutionOrder(Set.empty[Cid2])(
exerciseBegin = (acc, _, exe) => {
if (exe.consuming) { (acc + exe.targetCoid, true) }
else { (acc, true) }
},
rollbackBegin = (acc, _, _) => (acc, false),
leaf = (acc, _, _) => acc,
exerciseEnd = (acc, _, _) => acc,
rollbackEnd = (acc, _, _) => acc,
)

/** Returns the IDs of all input contracts that are used by this transaction.
*/
final def inputContracts[Cid2 >: Cid]: Set[Cid2] =
Expand Down Expand Up @@ -405,6 +421,37 @@ sealed abstract class HasTxNodes[Nid, +Cid] {
}
}

/** The contract keys created or updated as part of the transaction.
* This includes updates to transient contracts (by mapping them to None)
* but it does not include any updates under rollback nodes.
*/
final def updatedContractKeys(implicit
ev: HasTxNodes[Nid, Cid] <:< HasTxNodes[_, Value.ContractId]
): Map[GlobalKey, Option[Value.ContractId]] = {
ev(this).foldInExecutionOrder(Map.empty[GlobalKey, Option[Value.ContractId]])(
exerciseBegin = {
case (acc, _, exec) if exec.consuming =>
(
exec.key.fold(acc)(key =>
acc.updated(GlobalKey.assertBuild(exec.templateId, key.key), None)
),
true,
)
case (acc, _, _) => (acc, true)
},
rollbackBegin = (acc, _, _) => (acc, false),
leaf = {
case (acc, _, create: Node.NodeCreate[Value.ContractId]) =>
create.key.fold(acc)(key =>
acc.updated(GlobalKey.assertBuild(create.templateId, key.key), Some(create.coid))
)
case (acc, _, _: Node.NodeFetch[_] | _: Node.NodeLookupByKey[_]) => acc
},
exerciseEnd = (acc, _, _) => acc,
rollbackEnd = (acc, _, _) => acc,
)
}

// This method visits to all nodes of the transaction in execution order.
// Exercise/rollback nodes are visited twice: when execution reaches them and when execution leaves their body.
// On the first visit of an execution/rollback node, the caller can prevent traversal of the children
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,82 @@ class TransactionSpec extends AnyFreeSpec with Matchers with ScalaCheckDrivenPro
builder.build().contractKeys shouldBe expectedResults
}
}

def create(builder: TransactionBuilder, parties: Seq[String], key: Option[String] = None) = {
val cid: ContractId = builder.newCid
val node = builder.create(
id = cid,
template = "-pkg-:Mod:T",
argument = V.ValueUnit,
signatories = parties,
observers = Seq(),
key = key.map(V.ValueText(_)),
)
(cid, node)
}
def exercise(
builder: TransactionBuilder,
create: Node.NodeCreate[ContractId],
parties: Seq[String],
consuming: Boolean,
) =
builder.exercise(
contract = create,
choice = "C",
actingParties = parties.toSet,
consuming = consuming,
argument = V.ValueUnit,
byKey = false,
)

"consumedContract" - {
"return the IDs of consumed contracts" in {
val builder = TransactionBuilder()
val parties = Seq("Alice")
val (cid0, create0) = create(builder, parties)
val (_, create1) = create(builder, parties)
val (cid2, create2) = create(builder, parties)
val (_, create3) = create(builder, parties)
builder.add(exercise(builder, create0, parties, true))
builder.add(create1)
builder.add(create2)
val exeNid1 = builder.add(exercise(builder, create1, parties, false))
val exeNid2 = builder.add(exercise(builder, create2, parties, true), exeNid1)
builder.add(exercise(builder, create3, parties, false), exeNid2)
val rollback = builder.add(builder.rollback(), exeNid2)
builder.add(exercise(builder, create3, parties, true), rollback)
builder.build().consumedContracts shouldBe Set(cid0, cid2)
}
}

"updatedContractKeys" - {
"return all the updated contract keys" in {
val builder = TransactionBuilder()
val parties = Seq("Alice")
val (cid0, create0) = create(builder, parties, Some("key0"))
val (_, create1) = create(builder, parties, Some("key1"))
val (_, create2) = create(builder, parties, Some("key2"))
val (cid3, create3) = create(builder, parties, Some("key2"))
val (_, create4) = create(builder, parties, Some("key2"))
val (_, create5) = create(builder, parties, Some("key3"))
builder.add(create0)
builder.add(exercise(builder, create0, parties, false))
builder.add(create1)
val ex = builder.add(exercise(builder, create1, parties, true))
builder.add(create2, ex)
builder.add(exercise(builder, create2, parties, true), ex)
builder.add(create3, ex)
val rollback = builder.add(builder.rollback())
builder.add(exercise(builder, create0, parties, true), rollback)
builder.add(create5, rollback)
builder.add(exercise(builder, create3, parties, true), rollback)
builder.add(create4, rollback)
def key(s: String) =
GlobalKey.assertBuild(Ref.Identifier.assertFromString("-pkg-:Mod:T"), V.ValueText(s))
builder.build().updatedContractKeys shouldBe
Map(key("key0") -> Some(cid0), key("key1") -> None, key("key2") -> Some(cid3))
}
}
}

object TransactionSpec {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ import com.daml.ledger.participant.state.v1.{PackageId, SubmitterInfo}
import com.daml.lf.data.Ref.{Identifier, LedgerString, Party}
import com.daml.lf.data.Relation.Relation
import com.daml.lf.data.Time
import com.daml.lf.transaction.{GlobalKey, _}
import com.daml.lf.transaction.{
BlindingInfo,
miklos-da marked this conversation as resolved.
Show resolved Hide resolved
GlobalKey,
NodeId,
Transaction,
TransactionCoder,
TransactionOuterClass,
}
import com.daml.lf.value.Value.{ContractId, VersionedValue}
import com.daml.lf.value.{Value, ValueCoder, ValueOuterClass}
import com.daml.lf.{crypto, data}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ class KeyValueSubmission(metrics: Metrics) {
*/
def transactionOutputs(tx: SubmittedTransaction): List[DamlStateKey] =
metrics.daml.kvutils.submission.conversion.transactionOutputs.time { () =>
val effects = InputsAndEffects.computeEffects(tx)
effects.createdContracts.map(_._1) ++ effects.consumedContracts
(tx.localContracts.keys ++ tx.consumedContracts).map(Conversions.contractIdToStateKey).toList
}

private def submissionParties(
Expand Down
Loading