mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 09:17:43 +03:00
Support upgrades in daml-script submissions (#17676)
* Support upgrades in daml-script submissions * Fix export client test
This commit is contained in:
parent
29aa0f537c
commit
c899320718
@ -130,6 +130,7 @@ object ExampleExportClient {
|
||||
maxInboundMessageSize = RunnerMainConfig.DefaultMaxInboundMessageSize,
|
||||
applicationId = None,
|
||||
uploadDar = false,
|
||||
enableContractUpgrading = false,
|
||||
)
|
||||
val adminClient = LedgerClient.singleHost(
|
||||
hostIp,
|
||||
|
@ -167,11 +167,17 @@ abstract class ConverterMethods(stablePackages: StablePackages) {
|
||||
interfaceId: Option[Identifier],
|
||||
choiceName: ChoiceName,
|
||||
argument: Value,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
): Either[String, SValue] = {
|
||||
for {
|
||||
choice <- lookupChoice(templateId, interfaceId, choiceName)
|
||||
translated <- translator
|
||||
.strictTranslateValue(choice.argBinder._2, argument)
|
||||
.translateValue(
|
||||
choice.argBinder._2,
|
||||
argument,
|
||||
if (enableContractUpgrading) preprocessing.ValueTranslator.Config.Upgradeable
|
||||
else preprocessing.ValueTranslator.Config.Strict,
|
||||
)
|
||||
.left
|
||||
.map(err => s"Failed to translate exercise argument: $err")
|
||||
} yield record(
|
||||
|
@ -126,6 +126,7 @@ object RunnerMain {
|
||||
config.timeMode,
|
||||
traceLog,
|
||||
warningLog,
|
||||
enableContractUpgrading = config.enableContractUpgrading,
|
||||
)
|
||||
_ <- Future {
|
||||
outputFile.foreach { outputFile =>
|
||||
|
@ -24,6 +24,7 @@ case class RunnerMainConfig(
|
||||
// and specifying the default for better error messages.
|
||||
applicationId: Option[ApplicationId],
|
||||
uploadDar: Boolean,
|
||||
enableContractUpgrading: Boolean,
|
||||
)
|
||||
|
||||
object RunnerMainConfig {
|
||||
@ -76,6 +77,7 @@ private[script] case class RunnerMainConfigIntermediate(
|
||||
// Legacy behaviour is to upload the dar when using --all and over grpc. None represents that behaviour
|
||||
// We will drop this for daml3, such that we default to not uploading.
|
||||
uploadDar: Option[Boolean],
|
||||
enableContractUpgrading: Boolean,
|
||||
) {
|
||||
import RunnerMainConfigIntermediate._
|
||||
|
||||
@ -133,6 +135,7 @@ private[script] case class RunnerMainConfigIntermediate(
|
||||
maxInboundMessageSize = maxInboundMessageSize,
|
||||
applicationId = applicationId,
|
||||
uploadDar = resolvedUploadDar,
|
||||
enableContractUpgrading = enableContractUpgrading,
|
||||
)
|
||||
} yield config
|
||||
|
||||
@ -263,6 +266,15 @@ private[script] object RunnerMainConfigIntermediate {
|
||||
s"Uploads the dar before running. Only available over GRPC. Default behaviour is to upload with --all, not with --script-name."
|
||||
)
|
||||
|
||||
opt[Unit]("enable-contract-upgrading")
|
||||
.hidden()
|
||||
.action { (_, c) =>
|
||||
c.copy(enableContractUpgrading = true)
|
||||
}
|
||||
.text(
|
||||
"Experimental: Enables daml3-script upgrades support."
|
||||
)
|
||||
|
||||
help("help").text("Print this usage text")
|
||||
|
||||
checkConfig(c => {
|
||||
@ -327,6 +339,7 @@ private[script] object RunnerMainConfigIntermediate {
|
||||
maxInboundMessageSize = RunnerMainConfig.DefaultMaxInboundMessageSize,
|
||||
applicationId = None,
|
||||
uploadDar = None,
|
||||
enableContractUpgrading = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -33,12 +33,18 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
) => Either[String, TemplateChoiceSignature],
|
||||
translator: preprocessing.ValueTranslator,
|
||||
result: ScriptLedgerClient.ExerciseResult,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
) = {
|
||||
for {
|
||||
choice <- Name.fromString(result.choice)
|
||||
c <- lookupChoice(result.templateId, result.interfaceId, choice)
|
||||
translated <- translator
|
||||
.strictTranslateValue(c.returnType, result.result)
|
||||
.translateValue(
|
||||
c.returnType,
|
||||
result.result,
|
||||
if (enableContractUpgrading) preprocessing.ValueTranslator.Config.Upgradeable
|
||||
else preprocessing.ValueTranslator.Config.Strict,
|
||||
)
|
||||
.left
|
||||
.map(err => s"Failed to translate exercise result: $err")
|
||||
} yield translated
|
||||
@ -53,12 +59,13 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
translator: preprocessing.ValueTranslator,
|
||||
scriptIds: ScriptIds,
|
||||
tree: ScriptLedgerClient.TransactionTree,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
): Either[String, SValue] = {
|
||||
def damlTree(s: String) = scriptIds.damlScriptModule("Daml.Script.Questions.TransactionTree", s)
|
||||
def translateTreeEvent(ev: ScriptLedgerClient.TreeEvent): Either[String, SValue] = ev match {
|
||||
case ScriptLedgerClient.Created(tplId, contractId, argument) =>
|
||||
for {
|
||||
anyTemplate <- fromAnyTemplate(translator, tplId, argument)
|
||||
anyTemplate <- fromAnyTemplate(translator, tplId, argument, enableContractUpgrading)
|
||||
} yield SVariant(
|
||||
damlTree("TreeEvent"),
|
||||
Name.assertFromString("CreatedEvent"),
|
||||
@ -79,7 +86,15 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
) =>
|
||||
for {
|
||||
evs <- childEvents.traverse(translateTreeEvent(_))
|
||||
anyChoice <- fromAnyChoice(lookupChoice, translator, tplId, ifaceId, choiceName, arg)
|
||||
anyChoice <- fromAnyChoice(
|
||||
lookupChoice,
|
||||
translator,
|
||||
tplId,
|
||||
ifaceId,
|
||||
choiceName,
|
||||
arg,
|
||||
enableContractUpgrading,
|
||||
)
|
||||
} yield SVariant(
|
||||
damlTree("TreeEvent"),
|
||||
Name.assertFromString("ExercisedEvent"),
|
||||
@ -110,6 +125,7 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
translator: preprocessing.ValueTranslator,
|
||||
scriptIds: ScriptIds,
|
||||
commandResult: ScriptLedgerClient.CommandResult,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
): Either[String, SValue] = {
|
||||
def scriptCommands(s: String) = scriptIds.damlScriptModule("Daml.Script.Commands", s)
|
||||
commandResult match {
|
||||
@ -124,7 +140,12 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
)
|
||||
case r: ScriptLedgerClient.ExerciseResult =>
|
||||
for {
|
||||
translated <- translateExerciseResult(lookupChoice, translator, r)
|
||||
translated <- translateExerciseResult(
|
||||
lookupChoice,
|
||||
translator,
|
||||
r,
|
||||
enableContractUpgrading,
|
||||
)
|
||||
} yield SVariant(
|
||||
scriptCommands("CommandResult"),
|
||||
Ref.Name.assertFromString("ExerciseResult"),
|
||||
@ -144,11 +165,14 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
translateError: T => SValue,
|
||||
scriptIds: ScriptIds,
|
||||
submitResult: Either[T, Seq[ScriptLedgerClient.CommandResult]],
|
||||
enableContractUpgrading: Boolean = false,
|
||||
): Either[String, SValue] = submitResult match {
|
||||
case Right(commandResults) =>
|
||||
commandResults
|
||||
.to(FrontStack)
|
||||
.traverse(fromCommandResult(lookupChoice, translator, scriptIds, _))
|
||||
.traverse(
|
||||
fromCommandResult(lookupChoice, translator, scriptIds, _, enableContractUpgrading)
|
||||
)
|
||||
.map { rs =>
|
||||
SVariant(
|
||||
StablePackagesV2.Either,
|
||||
@ -178,9 +202,19 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
translateError: T => SValue,
|
||||
scriptIds: ScriptIds,
|
||||
submitResultList: List[Either[T, Seq[ScriptLedgerClient.CommandResult]]],
|
||||
enableContractUpgrading: Boolean = false,
|
||||
): Either[String, SValue] =
|
||||
submitResultList
|
||||
.traverse(fromSubmitResult(lookupChoice, translator, translateError, scriptIds, _))
|
||||
.traverse(
|
||||
fromSubmitResult(
|
||||
lookupChoice,
|
||||
translator,
|
||||
translateError,
|
||||
scriptIds,
|
||||
_,
|
||||
enableContractUpgrading,
|
||||
)
|
||||
)
|
||||
.map { xs => SList(xs.to(FrontStack)) }
|
||||
|
||||
// Convert an active contract to AnyTemplate
|
||||
@ -195,9 +229,10 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
def fromCreated(
|
||||
translator: preprocessing.ValueTranslator,
|
||||
contract: ScriptLedgerClient.ActiveContract,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
): Either[String, SValue] = {
|
||||
for {
|
||||
anyTpl <- fromContract(translator, contract)
|
||||
anyTpl <- fromContract(translator, contract, enableContractUpgrading)
|
||||
} yield record(
|
||||
StablePackagesV2.Tuple2,
|
||||
("_1", SContractId(contract.contractId)),
|
||||
@ -206,9 +241,13 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
}
|
||||
|
||||
def fromTransactionTree(
|
||||
tree: TransactionTree
|
||||
tree: TransactionTree,
|
||||
intendedPackageIds: List[PackageId],
|
||||
): Either[String, ScriptLedgerClient.TransactionTree] = {
|
||||
def convEvent(ev: String): Either[String, ScriptLedgerClient.TreeEvent] =
|
||||
def convEvent(
|
||||
ev: String,
|
||||
oIntendedPackageId: Option[PackageId],
|
||||
): Either[String, ScriptLedgerClient.TreeEvent] =
|
||||
tree.eventsById.get(ev).toRight(s"Event id $ev does not exist").flatMap { event =>
|
||||
event.kind match {
|
||||
case TreeEvent.Kind.Created(created) =>
|
||||
@ -221,7 +260,8 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
.left
|
||||
.map(err => s"Failed to validate create argument: $err")
|
||||
} yield ScriptLedgerClient.Created(
|
||||
tplId,
|
||||
oIntendedPackageId
|
||||
.fold(tplId)(intendedPackageId => tplId.copy(packageId = intendedPackageId)),
|
||||
cid,
|
||||
arg,
|
||||
)
|
||||
@ -235,9 +275,10 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
.validateValue(exercised.getChoiceArgument)
|
||||
.left
|
||||
.map(err => s"Failed to validate exercise argument: $err")
|
||||
childEvents <- exercised.childEventIds.toList.traverse(convEvent(_))
|
||||
childEvents <- exercised.childEventIds.toList.traverse(convEvent(_, None))
|
||||
} yield ScriptLedgerClient.Exercised(
|
||||
tplId,
|
||||
oIntendedPackageId
|
||||
.fold(tplId)(intendedPackageId => tplId.copy(packageId = intendedPackageId)),
|
||||
ifaceId,
|
||||
cid,
|
||||
choice,
|
||||
@ -248,7 +289,9 @@ object Converter extends script.ConverterMethods(StablePackagesV2) {
|
||||
}
|
||||
}
|
||||
for {
|
||||
rootEvents <- tree.rootEventIds.toList.traverse(convEvent(_))
|
||||
rootEvents <- tree.rootEventIds.toList.zip(intendedPackageIds).traverse {
|
||||
case (evId, intendedPackageId) => convEvent(evId, Some(intendedPackageId))
|
||||
}
|
||||
} yield {
|
||||
ScriptLedgerClient.TransactionTree(rootEvents)
|
||||
}
|
||||
|
@ -30,19 +30,20 @@ private[lf] class Runner(
|
||||
) {
|
||||
import Free.Result, SExpr.SExpr
|
||||
|
||||
private val initialClientsV1 = initialClients.map(ScriptLedgerClient.realiseScriptLedgerClient)
|
||||
private val initialClientsV2 = initialClients.map(
|
||||
ScriptLedgerClient.realiseScriptLedgerClient(_, unversionedRunner.enableContractUpgrading)
|
||||
)
|
||||
|
||||
private val env =
|
||||
new ScriptF.Env(
|
||||
unversionedRunner.script.scriptIds,
|
||||
unversionedRunner.timeMode,
|
||||
initialClientsV1,
|
||||
initialClientsV2,
|
||||
unversionedRunner.extendedCompiledPackages,
|
||||
unversionedRunner.enableContractUpgrading,
|
||||
)
|
||||
|
||||
private val ideLedgerContext: Option[IdeLedgerContext] =
|
||||
initialClientsV1.default_participant.collect {
|
||||
initialClientsV2.default_participant.collect {
|
||||
case ledgerClient: ledgerinteraction.IdeLedgerClient =>
|
||||
new IdeLedgerContext {
|
||||
override def currentSubmission: Option[ScenarioRunner.CurrentSubmission] =
|
||||
|
@ -70,7 +70,6 @@ object ScriptF {
|
||||
val timeMode: ScriptTimeMode,
|
||||
private var _clients: Participants[ScriptLedgerClient],
|
||||
compiledPackages: CompiledPackages,
|
||||
val enableContractUpgrading: Boolean,
|
||||
) {
|
||||
def clients = _clients
|
||||
val valueTranslator = new ValueTranslator(
|
||||
@ -184,6 +183,7 @@ object ScriptF {
|
||||
_.toDamlSubmitError(env),
|
||||
env.scriptIds,
|
||||
resItems,
|
||||
client.enableContractUpgrading,
|
||||
)
|
||||
)
|
||||
} yield SEValue(res)
|
||||
@ -213,6 +213,7 @@ object ScriptF {
|
||||
_.toDamlSubmitError(env),
|
||||
env.scriptIds,
|
||||
submitRes,
|
||||
client.enableContractUpgrading,
|
||||
)
|
||||
)
|
||||
} yield SEValue(res)
|
||||
@ -240,7 +241,13 @@ object ScriptF {
|
||||
.to(FrontStack)
|
||||
.traverse(
|
||||
Converter
|
||||
.fromCommandResult(env.lookupChoice, env.valueTranslator, env.scriptIds, _)
|
||||
.fromCommandResult(
|
||||
env.lookupChoice,
|
||||
env.valueTranslator,
|
||||
env.scriptIds,
|
||||
_,
|
||||
client.enableContractUpgrading,
|
||||
)
|
||||
)
|
||||
.map(results => SEValue(SList(results)))
|
||||
)
|
||||
@ -298,6 +305,7 @@ object ScriptF {
|
||||
env.valueTranslator,
|
||||
env.scriptIds,
|
||||
submitRes,
|
||||
client.enableContractUpgrading,
|
||||
)
|
||||
)
|
||||
} yield SEValue(res)
|
||||
@ -320,7 +328,7 @@ object ScriptF {
|
||||
.to(FrontStack)
|
||||
.traverse(
|
||||
Converter
|
||||
.fromCreated(env.valueTranslator, _)
|
||||
.fromCreated(env.valueTranslator, _, client.enableContractUpgrading)
|
||||
)
|
||||
)
|
||||
} yield SEValue(SList(res))
|
||||
@ -338,9 +346,11 @@ object ScriptF {
|
||||
): Future[SExpr] =
|
||||
for {
|
||||
client <- Converter.toFuture(env.clients.getPartiesParticipant(parties))
|
||||
optR <- client.queryContractId(parties, tplId, cid, env.enableContractUpgrading)
|
||||
optR <- client.queryContractId(parties, tplId, cid)
|
||||
optR <- Converter.toFuture(
|
||||
optR.traverse(Converter.fromContract(env.valueTranslator, _, env.enableContractUpgrading))
|
||||
optR.traverse(
|
||||
Converter.fromContract(env.valueTranslator, _, client.enableContractUpgrading)
|
||||
)
|
||||
)
|
||||
} yield SEValue(SOptional(optR))
|
||||
}
|
||||
@ -431,7 +441,9 @@ object ScriptF {
|
||||
client <- Converter.toFuture(env.clients.getPartiesParticipant(parties))
|
||||
optR <- client.queryContractKey(parties, tplId, key.key, translateKey(env))
|
||||
optR <- Converter.toFuture(
|
||||
optR.traverse(Converter.fromCreated(env.valueTranslator, _))
|
||||
optR.traverse(
|
||||
Converter.fromCreated(env.valueTranslator, _, client.enableContractUpgrading)
|
||||
)
|
||||
)
|
||||
} yield SEValue(SOptional(optR))
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import com.daml.ledger.api.v1.transaction_filter.{
|
||||
InterfaceFilter,
|
||||
TransactionFilter,
|
||||
}
|
||||
import com.daml.ledger.api.v1.{value => api}
|
||||
import com.daml.ledger.api.validation.NoLoggingValueValidator
|
||||
import com.daml.ledger.client.LedgerClient
|
||||
import com.daml.lf.command
|
||||
@ -52,37 +53,34 @@ import scalaz.syntax.tag._
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: ApplicationId)
|
||||
extends ScriptLedgerClient {
|
||||
class GrpcLedgerClient(
|
||||
val grpcClient: LedgerClient,
|
||||
val applicationId: ApplicationId,
|
||||
override val enableContractUpgrading: Boolean = false,
|
||||
) extends ScriptLedgerClient {
|
||||
override val transport = "gRPC API"
|
||||
|
||||
override def query(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
): Future[Vector[ScriptLedgerClient.ActiveContract]] = {
|
||||
queryWithKey(parties, templateId, enableContractUpgrading).map(_.map(_._1))
|
||||
queryWithKey(parties, templateId).map(_.map(_._1))
|
||||
}
|
||||
|
||||
// Omits the package id on an identifier if contract upgrades are enabled
|
||||
private def toApiIdentifierUpgrades(identifier: Identifier): api.Identifier = {
|
||||
val converted = toApiIdentifier(identifier)
|
||||
if (enableContractUpgrading) converted.copy(packageId = "") else converted
|
||||
}
|
||||
|
||||
private def templateFilter(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
): TransactionFilter = {
|
||||
val filters = Filters(Some(InclusiveFilters(Seq(toApiIdentifier(templateId)))))
|
||||
TransactionFilter(parties.toList.map(p => (p, filters)).toMap)
|
||||
}
|
||||
|
||||
// Template filter with the package id removed, for upgrades
|
||||
private def upgradeableTemplateFilter(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
): TransactionFilter = {
|
||||
val filters = Filters(
|
||||
Some(InclusiveFilters(Seq(toApiIdentifier(templateId).copy(packageId = ""))))
|
||||
)
|
||||
val filters = Filters(Some(InclusiveFilters(Seq(toApiIdentifierUpgrades(templateId)))))
|
||||
TransactionFilter(parties.toList.map(p => (p, filters)).toMap)
|
||||
}
|
||||
|
||||
@ -106,14 +104,11 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
private def queryWithKey(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
): Future[Vector[(ScriptLedgerClient.ActiveContract, Option[Value])]] = {
|
||||
val filter =
|
||||
if (enableContractUpgrading) upgradeableTemplateFilter(parties, templateId)
|
||||
else templateFilter(parties, templateId)
|
||||
val filter = templateFilter(parties, templateId)
|
||||
val acsResponses =
|
||||
grpcClient.activeContractSetClient
|
||||
.getActiveContracts(filter, verbose = false)
|
||||
@ -149,14 +144,13 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
cid: ContractId,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
): Future[Option[ScriptLedgerClient.ActiveContract]] = {
|
||||
// We cannot do better than a linear search over query here.
|
||||
for {
|
||||
activeContracts <- query(parties, templateId, enableContractUpgrading)
|
||||
activeContracts <- query(parties, templateId)
|
||||
} yield {
|
||||
activeContracts.find(c => c.contractId == cid)
|
||||
}
|
||||
@ -305,6 +299,10 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
case Left(err) => throw new ConverterException(err)
|
||||
case Right(cmds) => cmds
|
||||
}
|
||||
// We need to remember the original package ID for each command result, so we can reapply them
|
||||
// after we get the results (for upgrades)
|
||||
val commandResultPackageIds = commands.flatMap(toCommandPackageIds(_))
|
||||
|
||||
val apiCommands = Commands(
|
||||
party = actAs.head,
|
||||
actAs = actAs.toList,
|
||||
@ -322,7 +320,9 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
val events = transactionTree.getTransaction.rootEventIds
|
||||
.map(evId => transactionTree.getTransaction.eventsById(evId))
|
||||
.toList
|
||||
events.traverse(fromTreeEvent(_)) match {
|
||||
events.zip(commandResultPackageIds).traverse { case (event, intendedPackageId) =>
|
||||
fromTreeEvent(event, intendedPackageId)
|
||||
} match {
|
||||
case Left(err) => throw new ConverterException(err)
|
||||
case Right(results) => results
|
||||
}
|
||||
@ -354,6 +354,9 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
import scalaz.syntax.traverse._
|
||||
for {
|
||||
ledgerCommands <- Converter.toFuture(commands.traverse(toCommand(_)))
|
||||
// We need to remember the original package ID for each command result, so we can reapply them
|
||||
// after we get the results (for upgrades)
|
||||
commandResultPackageIds = commands.flatMap(toCommandPackageIds(_))
|
||||
apiCommands = Commands(
|
||||
party = actAs.head,
|
||||
actAs = actAs.toList,
|
||||
@ -366,7 +369,9 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
request = SubmitAndWaitRequest(Some(apiCommands))
|
||||
resp <- grpcClient.commandServiceClient
|
||||
.submitAndWaitForTransactionTree(request)
|
||||
converted <- Converter.toFuture(Converter.fromTransactionTree(resp.getTransaction))
|
||||
converted <- Converter.toFuture(
|
||||
Converter.fromTransactionTree(resp.getTransaction, commandResultPackageIds)
|
||||
)
|
||||
} yield converted
|
||||
}
|
||||
|
||||
@ -417,26 +422,41 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
} yield ()
|
||||
}
|
||||
|
||||
// Note that CreateAndExerciseCommand gives two results, so we duplicate the package id
|
||||
private def toCommandPackageIds(cmd: command.ApiCommand): List[PackageId] =
|
||||
cmd match {
|
||||
case command.CreateAndExerciseCommand(templateId, _, _, _) =>
|
||||
List(templateId.packageId, templateId.packageId)
|
||||
case cmd => List(cmd.typeId.packageId)
|
||||
}
|
||||
|
||||
private def toCommand(cmd: command.ApiCommand): Either[String, Command] =
|
||||
cmd match {
|
||||
case command.CreateCommand(templateId, argument) =>
|
||||
for {
|
||||
arg <- lfValueToApiRecord(true, argument)
|
||||
} yield Command().withCreate(CreateCommand(Some(toApiIdentifier(templateId)), Some(arg)))
|
||||
} yield Command().withCreate(
|
||||
CreateCommand(Some(toApiIdentifierUpgrades(templateId)), Some(arg))
|
||||
)
|
||||
case command.ExerciseCommand(typeId, contractId, choice, argument) =>
|
||||
for {
|
||||
arg <- lfValueToApiValue(true, argument)
|
||||
} yield Command().withExercise(
|
||||
// TODO: https://github.com/digital-asset/daml/issues/14747
|
||||
// Fix once the new field interface_id have been added to the API Exercise Command
|
||||
ExerciseCommand(Some(toApiIdentifier(typeId)), contractId.coid, choice, Some(arg))
|
||||
ExerciseCommand(Some(toApiIdentifierUpgrades(typeId)), contractId.coid, choice, Some(arg))
|
||||
)
|
||||
case command.ExerciseByKeyCommand(templateId, key, choice, argument) =>
|
||||
for {
|
||||
key <- lfValueToApiValue(true, key)
|
||||
argument <- lfValueToApiValue(true, argument)
|
||||
} yield Command().withExerciseByKey(
|
||||
ExerciseByKeyCommand(Some(toApiIdentifier(templateId)), Some(key), choice, Some(argument))
|
||||
ExerciseByKeyCommand(
|
||||
Some(toApiIdentifierUpgrades(templateId)),
|
||||
Some(key),
|
||||
choice,
|
||||
Some(argument),
|
||||
)
|
||||
)
|
||||
case command.CreateAndExerciseCommand(templateId, template, choice, argument) =>
|
||||
for {
|
||||
@ -444,7 +464,7 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
argument <- lfValueToApiValue(true, argument)
|
||||
} yield Command().withCreateAndExercise(
|
||||
CreateAndExerciseCommand(
|
||||
Some(toApiIdentifier(templateId)),
|
||||
Some(toApiIdentifierUpgrades(templateId)),
|
||||
Some(template),
|
||||
choice,
|
||||
Some(argument),
|
||||
@ -452,7 +472,10 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
)
|
||||
}
|
||||
|
||||
private def fromTreeEvent(ev: TreeEvent): Either[String, ScriptLedgerClient.CommandResult] = {
|
||||
private def fromTreeEvent(
|
||||
ev: TreeEvent,
|
||||
intendedPackageId: PackageId,
|
||||
): Either[String, ScriptLedgerClient.CommandResult] = {
|
||||
import scalaz.std.option._
|
||||
import scalaz.syntax.traverse._
|
||||
ev match {
|
||||
@ -469,7 +492,12 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat
|
||||
templateId <- Converter.fromApiIdentifier(exercised.getTemplateId)
|
||||
ifaceId <- exercised.interfaceId.traverse(Converter.fromApiIdentifier)
|
||||
choice <- ChoiceName.fromString(exercised.choice)
|
||||
} yield ScriptLedgerClient.ExerciseResult(templateId, ifaceId, choice, result)
|
||||
} yield ScriptLedgerClient.ExerciseResult(
|
||||
templateId.copy(packageId = intendedPackageId),
|
||||
ifaceId,
|
||||
choice,
|
||||
result,
|
||||
)
|
||||
case TreeEvent(TreeEvent.Kind.Empty) =>
|
||||
throw new ConverterException("Invalid tree event Empty")
|
||||
}
|
||||
|
@ -115,7 +115,6 @@ class IdeLedgerClient(
|
||||
override def query(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
@ -167,7 +166,6 @@ class IdeLedgerClient(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
cid: ContractId,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
|
@ -164,7 +164,6 @@ class JsonLedgerClient(
|
||||
override def query(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
@ -194,7 +193,6 @@ class JsonLedgerClient(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
cid: ContractId,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit ec: ExecutionContext, mat: Materializer) = {
|
||||
for {
|
||||
parties <- validateTokenParties(parties, "queryContractId")
|
||||
|
@ -52,13 +52,20 @@ object ScriptLedgerClient {
|
||||
argument: Value,
|
||||
) extends TreeEvent
|
||||
|
||||
def realiseScriptLedgerClient(ledger: abstractLedgers.ScriptLedgerClient): ScriptLedgerClient =
|
||||
def realiseScriptLedgerClient(
|
||||
ledger: abstractLedgers.ScriptLedgerClient,
|
||||
enableContractUpgrading: Boolean,
|
||||
): ScriptLedgerClient =
|
||||
ledger match {
|
||||
case abstractLedgers.GrpcLedgerClient(grpcClient, applicationId) =>
|
||||
new GrpcLedgerClient(grpcClient, applicationId)
|
||||
new GrpcLedgerClient(grpcClient, applicationId, enableContractUpgrading)
|
||||
case abstractLedgers.JsonLedgerClient(uri, token, envIface, actorSystem) =>
|
||||
if (enableContractUpgrading)
|
||||
throw new IllegalArgumentException("The JSON client does not support Upgrades")
|
||||
new JsonLedgerClient(uri, token, envIface, actorSystem)
|
||||
case abstractLedgers.IdeLedgerClient(compiledPackages, traceLog, warningLog, canceled) =>
|
||||
if (enableContractUpgrading)
|
||||
throw new IllegalArgumentException("The IDE Ledger client does not support Upgrades")
|
||||
new IdeLedgerClient(compiledPackages, traceLog, warningLog, canceled)
|
||||
}
|
||||
|
||||
@ -76,7 +83,6 @@ trait ScriptLedgerClient {
|
||||
def query(
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
@ -84,6 +90,8 @@ trait ScriptLedgerClient {
|
||||
|
||||
protected def transport: String
|
||||
|
||||
val enableContractUpgrading: Boolean = false
|
||||
|
||||
final protected def unsupportedOn(what: String) =
|
||||
Future.failed(
|
||||
new UnsupportedOperationException(
|
||||
@ -95,7 +103,6 @@ trait ScriptLedgerClient {
|
||||
parties: OneAnd[Set, Ref.Party],
|
||||
templateId: Identifier,
|
||||
cid: ContractId,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
mat: Materializer,
|
||||
|
Loading…
Reference in New Issue
Block a user