Skip to content

Commit

Permalink
Switch isInterfaceFetch for interfaceId, put into proto (#19858)
Browse files Browse the repository at this point in the history
* Switch isInterfaceFetch for interfaceId, put into proto

* (may revert) Try pipe interfaceId through ActionDescription

* Add interface id to fetch replay command
Put Action description changes into PV7

* Add interface id to Fetch Node packageIds

* Update Security evidence

* Fix EngineTest compilation

* Update test evidence again

* Move change to ViewParticipantDataV5

* Switch new ViewParticipantData to + ActionDescription to Unstable

* Add interfaceId to pretty on Fetch and Exercise
  • Loading branch information
samuel-williams-da authored Sep 11, 2024
1 parent 02eab57 commit ee1ef99
Show file tree
Hide file tree
Showing 26 changed files with 247 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,25 @@ message ViewParticipantData {
v3.ActionDescription action_description = 6;
v0.ViewParticipantData.RollbackContext rollback_context = 7; // optional; defaults to the empty RollbackContext if omitted.
}

message ActionDescription {
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";

// Compared to v3: Update FetchActionDescription
oneof description {
v0.ActionDescription.CreateActionDescription create = 1;
v3.ActionDescription.ExerciseActionDescription exercise = 2;
FetchActionDescription fetch = 3;
v1.ActionDescription.LookupByKeyActionDescription lookup_by_key = 4;
}

// Compared from v1: Add interfaceId
message FetchActionDescription {
string input_contract_id = 1;
repeated string actors = 2;
bool by_key = 3;
string version = 4;
optional string template_id = 5;
optional string interface_id = 6;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

syntax = "proto3";

package com.digitalasset.canton.protocol.v5;

import "com/digitalasset/canton/crypto/v0/crypto.proto";
import "com/digitalasset/canton/protocol/v0/participant_transaction.proto";
import "com/digitalasset/canton/protocol/v1/participant_transaction.proto";
import "com/digitalasset/canton/protocol/v2/participant_transaction.proto";
import "com/digitalasset/canton/protocol/v3/participant_transaction.proto";
import "com/digitalasset/canton/protocol/v4/participant_transaction.proto";
import "scalapb/scalapb.proto";

// Compared to v4: action_description changed type from v3.ActionDescription to v4.ActionDescription
message ViewParticipantData {
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
com.digitalasset.canton.crypto.v0.Salt salt = 1;
repeated v2.InputContract core_inputs = 2;
repeated v2.CreatedContract created_core = 3;
repeated string created_in_subview_archived_in_core = 4; // ids of contracts created in a subview and archived in the core
repeated v1.ResolvedKey resolved_keys = 5;
v4.ActionDescription action_description = 6;
v0.ViewParticipantData.RollbackContext rollback_context = 7; // optional; defaults to the empty RollbackContext if omitted.
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.digitalasset.canton.protocol.{
v1,
v2,
v3,
v4,
}
import com.digitalasset.canton.serialization.ProtoConverter
import com.digitalasset.canton.serialization.ProtoConverter.ParsingResult
Expand Down Expand Up @@ -74,6 +75,7 @@ sealed trait ActionDescription
protected def toProtoDescriptionV1: v1.ActionDescription.Description
protected def toProtoDescriptionV2: v2.ActionDescription.Description
protected def toProtoDescriptionV3: v3.ActionDescription.Description
protected def toProtoDescriptionV4: v4.ActionDescription.Description

def toProtoV0: v0.ActionDescription =
v0.ActionDescription(description = toProtoDescriptionV0)
Expand All @@ -87,6 +89,8 @@ sealed trait ActionDescription
def toProtoV3: v3.ActionDescription =
v3.ActionDescription(description = toProtoDescriptionV3)

def toProtoV4: v4.ActionDescription =
v4.ActionDescription(description = toProtoDescriptionV4)
}

object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription] {
Expand All @@ -109,6 +113,10 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
supportedProtoVersion(_)(fromProtoV3),
_.toProtoV3.toByteString,
),
ProtoVersion(4) -> VersionedProtoConverter(ProtocolVersion.v7)(v4.ActionDescription)(
supportedProtoVersion(_)(fromProtoV4),
_.toProtoV4.toByteString,
),
)

final case class InvalidActionDescription(message: String)
Expand Down Expand Up @@ -202,8 +210,8 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
_stakeholders,
_key,
byKey,
interfaceId,
version,
_byInterface,
) =>
for {
_ <- Either.cond(
Expand All @@ -222,6 +230,7 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
byKey,
version,
Option.when(protocolVersion >= ProtocolVersion.v6)(templateId),
interfaceId.filter(_ => protocolVersion >= ProtocolVersion.v7),
protocolVersionRepresentativeFor(protocolVersion),
)
} yield actionDescription
Expand Down Expand Up @@ -481,7 +490,7 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
actors <- actorsP.traverse(ProtoConverter.parseLfPartyId).map(_.toSet)
version <- lfVersionFromProtoVersioned(versionP)
actionDescription <- FetchActionDescription
.create(inputContractId, actors, byKey, version, None, pv)
.create(inputContractId, actors, byKey, version, None, None, pv)
.leftMap(err => OtherError(err.message))
} yield actionDescription
}
Expand All @@ -503,7 +512,31 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
version <- lfVersionFromProtoVersioned(versionP)
templateId <- templateIdP.traverse(RefIdentifierSyntax.fromProtoPrimitive)
actionDescription <- FetchActionDescription
.create(inputContractId, actors, byKey, version, templateId, pv)
.create(inputContractId, actors, byKey, version, templateId, None, pv)
.leftMap(err => OtherError(err.message))
} yield actionDescription
}

private def fromFetchProtoV4(
f: v4.ActionDescription.FetchActionDescription,
pv: RepresentativeProtocolVersion[ActionDescription.type],
): ParsingResult[FetchActionDescription] = {
val v4.ActionDescription.FetchActionDescription(
inputContractIdP,
actorsP,
byKey,
versionP,
templateIdP,
interfaceIdP,
) = f
for {
inputContractId <- ProtoConverter.parseLfContractId(inputContractIdP)
actors <- actorsP.traverse(ProtoConverter.parseLfPartyId).map(_.toSet)
version <- lfVersionFromProtoVersioned(versionP)
templateId <- templateIdP.traverse(RefIdentifierSyntax.fromProtoPrimitive)
interfaceId <- interfaceIdP.traverse(RefIdentifierSyntax.fromProtoPrimitive)
actionDescription <- FetchActionDescription
.create(inputContractId, actors, byKey, version, templateId, interfaceId, pv)
.leftMap(err => OtherError(err.message))
} yield actionDescription
}
Expand Down Expand Up @@ -575,7 +608,23 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
case Empty => Left(FieldNotSet("description"))
}
}
}

private[data] def fromProtoV4(
actionDescriptionP: v4.ActionDescription
): ParsingResult[ActionDescription] = {
import v4.ActionDescription.Description.*
val v4.ActionDescription(description) = actionDescriptionP

protocolVersionRepresentativeFor(ProtoVersion(4)).flatMap { pv =>
description match {
case Create(create) => fromCreateProtoV0(create, pv)
case Exercise(exercise) => fromExerciseProtoV3(exercise, pv)
case Fetch(fetch) => fromFetchProtoV4(fetch, pv)
case LookupByKey(lookup) => fromLookupByKeyProtoV1(lookup, pv)
case Empty => Left(FieldNotSet("description"))
}
}
}

private def lfVersionFromProtoVersioned(
Expand Down Expand Up @@ -624,6 +673,9 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
override protected def toProtoDescriptionV3: v3.ActionDescription.Description.Create =
v3.ActionDescription.Description.Create(toProtoDescriptionV0.value)

override protected def toProtoDescriptionV4: v4.ActionDescription.Description.Create =
v4.ActionDescription.Description.Create(toProtoDescriptionV0.value)

override def pretty: Pretty[CreateActionDescription] = prettyOfClass(
param("contract Id", _.contractId),
param("seed", _.seed),
Expand Down Expand Up @@ -717,9 +769,13 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
)
)

override protected def toProtoDescriptionV4: v4.ActionDescription.Description.Exercise =
v4.ActionDescription.Description.Exercise(toProtoDescriptionV3.value)

override def pretty: Pretty[ExerciseActionDescription] = prettyOfClass(
param("input contract id", _.inputContractId),
param("template id", _.templateId),
param("interface id", _.interfaceId),
param("choice", _.choice.unquoted),
param("chosen value", _.chosenValue),
param("actors", _.actors),
Expand Down Expand Up @@ -828,6 +884,7 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
override val byKey: Boolean,
override val version: LfTransactionVersion,
templateId: Option[LfTemplateId],
interfaceId: Option[LfTemplateId]
)(
override val representativeProtocolVersion: RepresentativeProtocolVersion[
ActionDescription.type
Expand Down Expand Up @@ -864,10 +921,23 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
)
)

override protected def toProtoDescriptionV4: v4.ActionDescription.Description.Fetch =
v4.ActionDescription.Description.Fetch(
v4.ActionDescription.FetchActionDescription(
inputContractId = inputContractId.toProtoPrimitive,
actors = actors.toSeq,
byKey = byKey,
version = version.protoValue,
templateId = templateId.map(i => new RefIdentifierSyntax(i).toProtoPrimitive),
interfaceId = interfaceId.map(i => new RefIdentifierSyntax(i).toProtoPrimitive),
)
)

override def pretty: Pretty[FetchActionDescription] = prettyOfClass(
param("input contract id", _.inputContractId),
param("actors", _.actors),
paramIfTrue("by key", _.byKey),
param("interface id", _.interfaceId),
param("version", _.version),
)
}
Expand All @@ -884,9 +954,10 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
byKey: Boolean,
version: LfTransactionVersion,
templateId: Option[LfTemplateId],
interfaceId: Option[LfInterfaceId],
protocolVersion: RepresentativeProtocolVersion[ActionDescription.type],
): FetchActionDescription =
create(inputContractId, actors, byKey, version, templateId, protocolVersion).valueOr(err =>
create(inputContractId, actors, byKey, version, templateId, interfaceId, protocolVersion).valueOr(err =>
throw err
)

Expand All @@ -896,6 +967,7 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
byKey: Boolean,
version: LfTransactionVersion,
templateId: Option[LfTemplateId],
interfaceId: Option[LfInterfaceId],
protocolVersion: RepresentativeProtocolVersion[ActionDescription.type],
): Either[InvalidActionDescription, FetchActionDescription] = {

Expand All @@ -909,7 +981,7 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
s"Protocol version is equivalent to ${protocolVersion.representative} but template id is supported since protocol version $templateIdSupportedSince"
),
)
} yield new FetchActionDescription(inputContractId, actors, byKey, version, templateId)(
} yield new FetchActionDescription(inputContractId, actors, byKey, version, templateId, interfaceId)(
protocolVersion
)
}
Expand Down Expand Up @@ -949,6 +1021,9 @@ object ActionDescription extends HasProtocolVersionedCompanion[ActionDescription
)
)

override protected def toProtoDescriptionV4: v4.ActionDescription.Description.LookupByKey =
v4.ActionDescription.Description.LookupByKey(toProtoDescriptionV3.value)

override def pretty: Pretty[LookupByKeyActionDescription] = prettyOfClass(
param("key", _.key),
param("version", _.version),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ final case class ViewParticipantData private (
}
RootAction(cmd, actors, failed, packagePreference)

case FetchActionDescription(inputContractId, actors, byKey, _version, templateIdO) =>
case FetchActionDescription(inputContractId, actors, byKey, _version, templateIdO, interfaceId) =>
val inputContract = coreInputs.getOrElse(
inputContractId,
throw InvalidViewParticipantData(
Expand All @@ -245,7 +245,7 @@ final case class ViewParticipantData private (
)
LfFetchByKeyCommand(templateId = templateId, key = key)
} else {
LfFetchCommand(templateId = templateId, coid = inputContractId)
LfFetchCommand(templateId = templateId, interfaceId = interfaceId, coid = inputContractId)
}
RootAction(cmd, actors, failed = false, packageIdPreference = Set.empty)

Expand Down Expand Up @@ -312,6 +312,16 @@ final case class ViewParticipantData private (
salt = Some(salt.toProtoV0),
)

private[ViewParticipantData] def toProtoV5: v5.ViewParticipantData = v5.ViewParticipantData(
coreInputs = coreInputs.values.map(_.toProtoV2).toSeq,
createdCore = createdCore.map(_.toProtoV2),
createdInSubviewArchivedInCore = createdInSubviewArchivedInCore.toSeq.map(_.toProtoPrimitive),
resolvedKeys = resolvedKeys.toList.map { case (k, res) => ResolvedKey(k, res).toProtoV1 },
actionDescription = Some(actionDescription.toProtoV4),
rollbackContext = if (rollbackContext.isEmpty) None else Some(rollbackContext.toProtoV0),
salt = Some(salt.toProtoV0),
)

override protected[this] def toByteStringUnmemoized: ByteString =
super[HasProtocolVersionedWrapper].toByteString

Expand Down Expand Up @@ -389,6 +399,10 @@ object ViewParticipantData
supportedProtoVersionMemoized(_)(fromProtoV4),
_.toProtoV4.toByteString,
),
ProtoVersion(5) -> VersionedProtoConverter(ProtocolVersion.v7)(v5.ViewParticipantData)(
supportedProtoVersionMemoized(_)(fromProtoV5),
_.toProtoV5.toByteString,
),
)

/** Creates a view participant data.
Expand Down Expand Up @@ -490,7 +504,7 @@ object ViewParticipantData
rbContextP,
) = dataP

fromProtoV1V2V3V4(hashOps, protoVersion)(
fromProtoV1V2V3V4V5(hashOps, protoVersion)(
saltP,
coreInputsP,
createdCoreP,
Expand Down Expand Up @@ -518,7 +532,7 @@ object ViewParticipantData
rbContextP,
) = dataP

fromProtoV1V2V3V4(hashOps, ProtoVersion(2))(
fromProtoV1V2V3V4V5(hashOps, ProtoVersion(2))(
saltP,
coreInputsP,
createdCoreP,
Expand Down Expand Up @@ -546,7 +560,7 @@ object ViewParticipantData
rbContextP,
) = dataP

fromProtoV1V2V3V4(hashOps, ProtoVersion(3))(
fromProtoV1V2V3V4V5(hashOps, ProtoVersion(3))(
saltP,
coreInputsP,
createdCoreP,
Expand Down Expand Up @@ -574,7 +588,7 @@ object ViewParticipantData
rbContextP,
) = dataP

fromProtoV1V2V3V4(hashOps, ProtoVersion(4))(
fromProtoV1V2V3V4V5(hashOps, ProtoVersion(4))(
saltP,
coreInputsP,
createdCoreP,
Expand All @@ -589,7 +603,35 @@ object ViewParticipantData
)(bytes)
}

private def fromProtoV1V2V3V4[
private def fromProtoV5(hashOps: HashOps, dataP: v5.ViewParticipantData)(
bytes: ByteString
): ParsingResult[ViewParticipantData] = {
val v5.ViewParticipantData(
saltP,
coreInputsP,
createdCoreP,
createdInSubviewArchivedInCoreP,
resolvedKeysP,
actionDescriptionP,
rbContextP,
) = dataP

fromProtoV1V2V3V4V5(hashOps, ProtoVersion(5))(
saltP,
coreInputsP,
createdCoreP,
createdInSubviewArchivedInCoreP,
resolvedKeysP,
actionDescriptionP,
ActionDescription.fromProtoV4,
CreatedContract.fromProtoV2,
InputContract.fromProtoV2,
ResolvedKey.fromProtoV1,
rbContextP,
)(bytes)
}

private def fromProtoV1V2V3V4V5[
ActionDescriptionProto,
CreatedContractProto,
InputContractProto,
Expand Down
Loading

0 comments on commit ee1ef99

Please sign in to comment.