Skip to content

Commit

Permalink
kvutils: Protos no longer depend on the Daml-LF transaction proto [KV…
Browse files Browse the repository at this point in the history
…L-1166] (#11909)

CHANGELOG_BEGIN

- [Integration Kit] kvutils protos no longer depend on the Daml-LF transaction proto

CHANGELOG_END
  • Loading branch information
hubert-da authored Nov 30, 2021
1 parent 5641948 commit c2c22f8
Show file tree
Hide file tree
Showing 22 changed files with 131 additions and 139 deletions.
1 change: 0 additions & 1 deletion ledger/participant-state/kvutils/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ da_scala_library(
"//daml-lf/engine",
"//daml-lf/language",
"//daml-lf/transaction",
"//daml-lf/transaction:transaction_proto_java",
"//daml-lf/transaction:value_proto_java",
"//daml-lf/transaction-test-lib",
"//ledger-api/grpc-definitions:ledger_api_proto_scala",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ option csharp_namespace = "Com.Daml.Ledger.Participant.State.KVUtils.Store.Event

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "com/daml/lf/transaction.proto";
import "com/daml/ledger/participant/state/kvutils/store/events/rejection_reason.proto";

message DamlSubmitterInfo {
Expand All @@ -40,8 +39,8 @@ message DamlSubmitterInfo {
// with submitter information and metadata (see Ledger API `commands.proto` for
// their source).
message DamlTransactionEntry {
// The original submitted transaction, with relative identifiers.
com.daml.lf.transaction.Transaction transaction = 1;
// The originally submitted transaction (see com.daml.lf.transaction.Transaction).
bytes raw_transaction = 1;

// The submitting party and metadata about the submitted command.
// The submitting party is authorized against the submitting participant
Expand Down Expand Up @@ -87,7 +86,8 @@ message DamlTransactionBlindingInfo {
message DivulgenceEntry {
string contract_id = 1;
repeated string divulged_to_local_parties = 2;
com.daml.lf.transaction.ContractInstance contract_instance = 3;
// The contract instance stored as bytes (see com.daml.lf.transaction.ContractInstance).
bytes raw_contract_instance = 3;
}

// Disclosure, specified in terms of local transaction node IDs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "com/daml/daml_lf_dev/daml_lf.proto";
import "com/daml/ledger/participant/state/kvutils/store/events/configuration.proto";
import "com/daml/lf/transaction.proto";
import "com/daml/lf/value.proto";


Expand Down Expand Up @@ -117,8 +116,8 @@ message DamlContractState {
// The contract key set by the contract. Optional.
DamlContractKey contract_key = 6;

// The contract instance.
com.daml.lf.transaction.ContractInstance contract_instance = 7;
// The contract instance stored as bytes (see com.daml.lf.transaction.ContractInstance).
bytes raw_contract_instance = 7;
}

message DamlContractKey {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,16 @@ private[state] object Conversions {
private def assertEncode[X](context: => String, x: Either[ValueCoder.EncodeError, X]): X =
x.fold(err => throw Err.EncodeError(context, err.errorMessage), identity)

def encodeTransaction(tx: VersionedTransaction): TransactionOuterClass.Transaction =
assertEncode(
def encodeTransaction(tx: VersionedTransaction): Raw.Transaction = {
val transaction = assertEncode(
"Transaction",
TransactionCoder.encodeTransaction(TransactionCoder.NidEncoder, ValueCoder.CidEncoder, tx),
)
Raw.Transaction(transaction.toByteString)
}

def decodeTransaction(tx: TransactionOuterClass.Transaction): VersionedTransaction =
def decodeTransaction(rawTx: Raw.Transaction): VersionedTransaction = {
val tx = TransactionOuterClass.Transaction.parseFrom(rawTx.bytes)
assertDecode(
"Transaction",
TransactionCoder
Expand All @@ -273,6 +276,7 @@ private[state] object Conversions {
tx,
),
)
}

def decodeVersionedValue(protoValue: ValueOuterClass.VersionedValue): VersionedValue =
assertDecode(
Expand All @@ -281,21 +285,26 @@ private[state] object Conversions {
)

def decodeContractInstance(
coinst: TransactionOuterClass.ContractInstance
): Value.VersionedContractInstance =
rawContractInstance: Raw.ContractInstance
): Value.VersionedContractInstance = {
val contractInstance =
TransactionOuterClass.ContractInstance.parseFrom(rawContractInstance.bytes)
assertDecode(
"ContractInstance",
TransactionCoder
.decodeVersionedContractInstance(ValueCoder.CidDecoder, coinst),
.decodeVersionedContractInstance(ValueCoder.CidDecoder, contractInstance),
)
}

def encodeContractInstance(
coinst: Value.VersionedContractInstance
): TransactionOuterClass.ContractInstance =
assertEncode(
): Raw.ContractInstance = {
val contractInstance = assertEncode(
"ContractInstance",
TransactionCoder.encodeContractInstance(ValueCoder.CidEncoder, coinst),
)
Raw.ContractInstance(contractInstance.toByteString)
}

def contractIdStructOrStringToStateKey[A](
coidStruct: ValueOuterClass.ContractId
Expand All @@ -320,7 +329,7 @@ private[state] object Conversions {
*/
def encodeBlindingInfo(
blindingInfo: BlindingInfo,
divulgedContracts: Map[ContractId, TransactionOuterClass.ContractInstance],
divulgedContracts: Map[ContractId, Raw.ContractInstance],
): DamlTransactionBlindingInfo =
DamlTransactionBlindingInfo.newBuilder
.addAllDisclosures(encodeDisclosure(blindingInfo.disclosure).asJava)
Expand Down Expand Up @@ -354,32 +363,32 @@ private[state] object Conversions {

def extractDivulgedContracts(
damlTransactionBlindingInfo: DamlTransactionBlindingInfo
): Either[Seq[String], Map[ContractId, Value.VersionedContractInstance]] = {
): Either[Seq[String], Map[ContractId, Raw.ContractInstance]] = {
val divulgences = damlTransactionBlindingInfo.getDivulgencesList.asScala.toVector
if (divulgences.isEmpty) {
Right(Map.empty)
} else {
val resultAccumulator: Either[Seq[String], mutable.Builder[
(ContractId, Value.VersionedContractInstance),
Map[ContractId, Value.VersionedContractInstance],
(ContractId, Raw.ContractInstance),
Map[ContractId, Raw.ContractInstance],
]] = Right(Map.newBuilder)
divulgences
.foldLeft(resultAccumulator) {
case (Right(contractInstanceIndex), divulgenceEntry) =>
if (divulgenceEntry.hasContractInstance) {
val contractId = decodeContractId(divulgenceEntry.getContractId)
val contractInstance = decodeContractInstance(divulgenceEntry.getContractInstance)
Right(contractInstanceIndex += (contractId -> contractInstance))
} else {
if (divulgenceEntry.getRawContractInstance.isEmpty) {
Left(Vector(divulgenceEntry.getContractId))
} else {
val contractId = decodeContractId(divulgenceEntry.getContractId)
val rawContractInstance = Raw.ContractInstance(divulgenceEntry.getRawContractInstance)
Right(contractInstanceIndex += (contractId -> rawContractInstance))
}
case (Left(missingContracts), divulgenceEntry) =>
// If populated by an older version of the KV WriteService, the contract instances will be missing.
// Hence, we assume that, if one is missing, all are and return the list of missing ids.
if (divulgenceEntry.hasContractInstance) {
Left(missingContracts)
} else {
if (divulgenceEntry.getRawContractInstance.isEmpty) {
Left(missingContracts :+ divulgenceEntry.getContractId)
} else {
Left(missingContracts)
}
}
.map(_.result())
Expand Down Expand Up @@ -554,17 +563,17 @@ private[state] object Conversions {
private def encodeDivulgenceEntry(
contractId: ContractId,
divulgedTo: Set[Ref.Party],
contractInstance: TransactionOuterClass.ContractInstance,
rawContractInstance: Raw.ContractInstance,
): DivulgenceEntry =
DivulgenceEntry.newBuilder
.setContractId(contractIdToString(contractId))
.addAllDivulgedToLocalParties(encodeParties(divulgedTo).asJava)
.setContractInstance(contractInstance)
.setRawContractInstance(rawContractInstance.bytes)
.build

private def encodeDivulgence(
divulgence: Relation[ContractId, Ref.Party],
divulgedContractsIndex: Map[ContractId, TransactionOuterClass.ContractInstance],
divulgedContractsIndex: Map[ContractId, Raw.ContractInstance],
): List[DivulgenceEntry] =
divulgence.toList
.sortBy(_._1.coid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,15 @@ object KeyValueCommitting {
transactionEntry: DamlTransactionEntry
): Set[DamlStateKey] = {
val outputs = Set.newBuilder[DamlStateKey]
val transaction =
TransactionOuterClass.Transaction.parseFrom(transactionEntry.getRawTransaction)
val txVersion =
TransactionCoder.decodeVersion(transactionEntry.getTransaction.getVersion) match {
TransactionCoder.decodeVersion(transaction.getVersion) match {
case Right(value) => value
case Left(err) => throw Err.DecodeError("Transaction", err.errorMessage)
}

transactionEntry.getTransaction.getNodesList.asScala.foreach { node =>
transaction.getNodesList.asScala.foreach { node =>
val nodeVersion = TransactionCoder.decodeNodeVersion(txVersion, node) match {
case Right(value) => value
case Left(err) => throw Err.DecodeError("Node", err.errorMessage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ object KeyValueConsumption {
txEntry: DamlTransactionEntry,
recordTime: Timestamp,
)(implicit loggingContext: LoggingContext): Update.TransactionAccepted = {
val transaction = Conversions.decodeTransaction(txEntry.getTransaction)
val rawTransaction = Raw.Transaction(txEntry.getRawTransaction)
val transaction = Conversions.decodeTransaction(rawTransaction)
val hexTxId = parseLedgerString("TransactionId")(
BaseEncoding.base16.encode(entryId.toByteArray)
)
Expand Down Expand Up @@ -319,7 +320,8 @@ object KeyValueConsumption {
if (!damlTransactionBlindingInfo.getDivulgencesList.isEmpty) {
Conversions.extractDivulgedContracts(damlTransactionBlindingInfo) match {
case Right(divulgedContractsIndex) =>
divulgedContractsIndex.view.map { case (contractId, contractInstance) =>
divulgedContractsIndex.view.map { case (contractId, rawContractInstance) =>
val contractInstance = Conversions.decodeContractInstance(rawContractInstance)
DivulgedContract(contractId, contractInstance)
}.toList
case Left(missingContractIds) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class KeyValueSubmission(metrics: Metrics) {
.addAllInputDamlState(contractKeyStates.asJava)
.setTransactionEntry(
DamlTransactionEntry.newBuilder
.setTransaction(Conversions.encodeTransaction(tx))
.setRawTransaction(Conversions.encodeTransaction(tx).bytes)
.setSubmitterInfo(encodedSubInfo)
.setLedgerEffectiveTime(buildTimestamp(meta.ledgerEffectiveTime))
.setWorkflowId(meta.workflowId.getOrElse(""))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,11 @@ object Raw {

type StateEntry = (StateKey, Envelope)

final case class Transaction(override val bytes: ByteString) extends Bytes

object Transaction extends Companion[Transaction]

final case class ContractInstance(override val bytes: ByteString) extends Bytes

object ContractInstance extends Companion[ContractInstance]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

package com.daml.ledger.participant.state.kvutils.committer.transaction

import com.daml.ledger.participant.state.kvutils.Conversions
import com.daml.ledger.participant.state.kvutils.{Conversions, Raw}
import com.daml.ledger.participant.state.kvutils.Conversions.parseTimestamp
import com.daml.ledger.participant.state.kvutils.store.events.{
DamlSubmitterInfo,
Expand Down Expand Up @@ -44,6 +44,6 @@ private[transaction] object DamlTransactionEntrySummary {
): DamlTransactionEntrySummary =
new DamlTransactionEntrySummary(
submission,
Conversions.decodeTransaction(submission.getTransaction),
Conversions.decodeTransaction(Raw.Transaction(submission.getRawTransaction)),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import com.daml.ledger.participant.state.kvutils.store.{
DamlStateValue,
}
import com.daml.ledger.participant.state.kvutils.wire.DamlSubmission
import com.daml.ledger.participant.state.kvutils.{Conversions, Err}
import com.daml.ledger.participant.state.kvutils.{Conversions, Err, Raw}
import com.daml.lf.data.Ref.Party
import com.daml.lf.engine.{Blinding, Engine}
import com.daml.lf.transaction.{BlindingInfo, TransactionOuterClass}
Expand Down Expand Up @@ -160,7 +160,8 @@ private[kvutils] class TransactionCommitter(
commitContext: CommitContext,
transactionEntry: DamlTransactionEntrySummary,
)(implicit loggingContext: LoggingContext): StepResult[DamlTransactionEntrySummary] = {
val transaction = transactionEntry.submission.getTransaction
val transaction =
TransactionOuterClass.Transaction.parseFrom(transactionEntry.submission.getRawTransaction)
val nodes = transaction.getNodesList.asScala
val nodeMap: Map[String, TransactionOuterClass.Node] =
nodes.view.map(n => n.getNodeId -> n).toMap
Expand Down Expand Up @@ -217,7 +218,7 @@ private[kvutils] class TransactionCommitter(
.build()

val newTransactionEntry = transactionEntry.submission.toBuilder
.setTransaction(newTransaction)
.setRawTransaction(newTransaction.toByteString)
.build()

StepContinue(DamlTransactionEntrySummary(newTransactionEntry))
Expand Down Expand Up @@ -260,7 +261,7 @@ private[kvutils] class TransactionCommitter(
commitContext: CommitContext,
)(implicit
loggingContext: LoggingContext
): Map[ContractId, TransactionOuterClass.ContractInstance] = {
): Map[ContractId, Raw.ContractInstance] = {
val localContracts = transactionEntry.transaction.localContracts
val consumedContracts = transactionEntry.transaction.consumedContracts
val contractKeys = transactionEntry.transaction.updatedContractKeys
Expand All @@ -270,8 +271,8 @@ private[kvutils] class TransactionCommitter(
cs.setActiveAt(buildTimestamp(transactionEntry.ledgerEffectiveTime))
val localDisclosure = blindingInfo.disclosure(nid)
cs.addAllLocallyDisclosedTo((localDisclosure: Iterable[String]).asJava)
cs.setContractInstance(
Conversions.encodeContractInstance(createNode.versionedCoinst)
cs.setRawContractInstance(
Conversions.encodeContractInstance(createNode.versionedCoinst).bytes
)
createNode.key.foreach { keyWithMaintainers =>
cs.setContractKey(
Expand Down Expand Up @@ -299,15 +300,15 @@ private[kvutils] class TransactionCommitter(
}
// Update contract state of divulged contracts.
val divulgedContractsBuilder = {
val builder = Map.newBuilder[ContractId, TransactionOuterClass.ContractInstance]
val builder = Map.newBuilder[ContractId, Raw.ContractInstance]
builder.sizeHint(blindingInfo.divulgence.size)
builder
}

for ((coid, parties) <- blindingInfo.divulgence) {
val key = contractIdToStateKey(coid)
val cs = getContractState(commitContext, key)
divulgedContractsBuilder += (coid -> cs.getContractInstance)
divulgedContractsBuilder += (coid -> Raw.ContractInstance(cs.getRawContractInstance))
val divulged: Set[String] = cs.getDivulgedToList.asScala.toSet
val newDivulgences: Set[String] = parties.toSet[String] -- divulged
if (newDivulgences.nonEmpty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import com.daml.ledger.participant.state.kvutils.committer.transaction.{
}
import com.daml.ledger.participant.state.kvutils.committer.{CommitContext, StepContinue, StepResult}
import com.daml.ledger.participant.state.kvutils.store.{DamlContractState, DamlStateValue}
import com.daml.ledger.participant.state.kvutils.{Conversions, Err}
import com.daml.ledger.participant.state.kvutils.{Conversions, Err, Raw}
import com.daml.lf.archive
import com.daml.lf.data.Ref.PackageId
import com.daml.lf.data.Time.Timestamp
Expand Down Expand Up @@ -146,9 +146,11 @@ private[transaction] class ModelConformanceValidator(engine: Engine, metrics: Me
): Option[Value.VersionedContractInstance] =
commitContext
.read(contractIdToStateKey(contractId))
.map(_.getContractState)
.map(_.getContractInstance)
.map(Conversions.decodeContractInstance)
.map { stateValue =>
val rawContractInstance =
Raw.ContractInstance(stateValue.getContractState.getRawContractInstance)
Conversions.decodeContractInstance(rawContractInstance)
}

// Helper to lookup package from the state. The package contents are stored in the [[DamlLogEntry]],
// which we find by looking up the Daml state entry at `DamlStateKey(packageId = pkgId)`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ object KVTest {
state.damlState
.get(Conversions.contractIdToStateKey(contractId))
.map { v =>
Conversions.decodeContractInstance(v.getContractState.getContractInstance)
Conversions.decodeContractInstance(
Raw.ContractInstance(v.getContractState.getRawContractInstance)
)
},
packages = state.uploadedPackages.get,
keys = globalKey =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ object TestHelpers {
tx: SubmittedTransaction,
): DamlTransactionEntry =
DamlTransactionEntry.newBuilder
.setTransaction(Conversions.encodeTransaction(tx))
.setRawTransaction(Conversions.encodeTransaction(tx).bytes)
.setSubmitterInfo(
DamlSubmitterInfo.newBuilder
.setCommandId("commandId")
Expand Down
Loading

0 comments on commit c2c22f8

Please sign in to comment.