From d90cd2c5425896a0d0c6742691c38b175085251c Mon Sep 17 00:00:00 2001 From: Robert Autenrieth <31539813+rautenrieth-da@users.noreply.github.com> Date: Mon, 16 Mar 2020 16:28:45 +0100 Subject: [PATCH] Output whether command execution depends on time (#5019) CHANGELOG_BEGIN CHANGELOG_END --- .../platform/apiserver/CommandExecutor.scala | 21 ++++++++++++++++++- .../apiserver/CommandExecutorImpl.scala | 12 +++++------ .../services/ApiSubmissionService.scala | 20 +++++------------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutor.scala b/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutor.scala index 259a9d1ab3..75d0f9fe5e 100644 --- a/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutor.scala +++ b/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutor.scala @@ -16,6 +16,25 @@ import com.digitalasset.platform.store.ErrorCause import scala.concurrent.Future +/** + * The result of command execution. + * + * @param submitterInfo The submitter info + * @param transactionMeta The transaction meta-data + * @param dependsOnLedgerTime True if the output of command execution depends in any way + * on the ledger time, as specified through [[Commands.ledgerEffectiveTime]]. + * If this value is false, then the ledger time of the resulting transaction + * ([[TransactionMeta.ledgerEffectiveTime]] can safely be changed after command + * interpretation. + * @param transaction The transaction + */ +final case class CommandExecutionResult( + submitterInfo: SubmitterInfo, + transactionMeta: TransactionMeta, + transaction: Transaction.Transaction, + dependsOnLedgerTime: Boolean, +) + trait CommandExecutor { def execute( @@ -26,5 +45,5 @@ trait CommandExecutor { Option[Value.ContractInst[Transaction.Value[Value.AbsoluteContractId]]]], lookupKey: GlobalKey => Future[Option[AbsoluteContractId]], commands: Commands - ): Future[Either[ErrorCause, (SubmitterInfo, TransactionMeta, Transaction.Transaction)]] + ): Future[Either[ErrorCause, CommandExecutionResult]] } diff --git a/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutorImpl.scala b/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutorImpl.scala index 3ae6b3a6a9..7e5f186c4e 100644 --- a/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutorImpl.scala +++ b/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/CommandExecutorImpl.scala @@ -23,7 +23,6 @@ import com.digitalasset.daml.lf.engine.{ } import com.digitalasset.daml.lf.language.Ast.Package import com.digitalasset.daml.lf.transaction.Node.GlobalKey -import com.digitalasset.daml.lf.transaction.Transaction import com.digitalasset.daml.lf.transaction.Transaction.{Value => TxValue} import com.digitalasset.daml.lf.value.Value import com.digitalasset.daml.lf.value.Value.AbsoluteContractId @@ -49,7 +48,7 @@ class CommandExecutorImpl( Option[Value.ContractInst[TxValue[Value.AbsoluteContractId]]]], lookupKey: GlobalKey => Future[Option[AbsoluteContractId]], commands: Commands, - ): Future[Either[ErrorCause, (SubmitterInfo, TransactionMeta, Transaction.Transaction)]] = { + ): Future[Either[ErrorCause, CommandExecutionResult]] = { consume(engine.submit(commands, participant, submissionSeed))( getPackage, @@ -62,22 +61,23 @@ class CommandExecutorImpl( _ <- Blinding .checkAuthorizationAndBlind(updateTx, Set(submitter)) } yield - ( - SubmitterInfo( + CommandExecutionResult( + submitterInfo = SubmitterInfo( submitted.submitter, submitted.applicationId.unwrap, submitted.commandId.unwrap, Time.Timestamp.assertFromInstant(submitted.maximumRecordTime), submitted.deduplicateUntil, ), - TransactionMeta( + transactionMeta = TransactionMeta( Time.Timestamp.assertFromInstant(submitted.ledgerEffectiveTime), submitted.workflowId.map(_.unwrap), meta.submissionTime, submissionSeed, Some(meta.usedPackages) ), - updateTx, + transaction = updateTx, + dependsOnLedgerTime = meta.dependsOnTime, )).left.map(ErrorCause.DamlLf) } } diff --git a/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/services/ApiSubmissionService.scala b/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/services/ApiSubmissionService.scala index d6a1a9fee4..b618e7f5b9 100644 --- a/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/services/ApiSubmissionService.scala +++ b/ledger/sandbox/src/main/scala/com/digitalasset/platform/apiserver/services/ApiSubmissionService.scala @@ -22,14 +22,7 @@ import com.daml.ledger.participant.state.v1.SubmissionResult.{ NotSupported, Overloaded } -import com.daml.ledger.participant.state.v1.{ - SeedService, - SubmissionResult, - SubmitterInfo, - TimeModel, - TransactionMeta, - WriteService -} +import com.daml.ledger.participant.state.v1.{SeedService, SubmissionResult, TimeModel, WriteService} import com.digitalasset.api.util.TimeProvider import com.digitalasset.daml.lf.crypto import com.digitalasset.daml.lf.data.Ref.Party @@ -42,8 +35,7 @@ import com.digitalasset.ledger.api.messages.command.submission.SubmitRequest import com.digitalasset.logging.LoggingContext.withEnrichedLoggingContext import com.digitalasset.logging.{ContextualizedLogger, LoggingContext} import com.digitalasset.platform.api.grpc.GrpcApiService -import com.digitalasset.platform.apiserver.CommandExecutor -import com.digitalasset.platform.apiserver.services.ApiSubmissionService.TransactionInfo +import com.digitalasset.platform.apiserver.{CommandExecutionResult, CommandExecutor} import com.digitalasset.platform.metrics.timedFuture import com.digitalasset.platform.server.api.services.domain.CommandSubmissionService import com.digitalasset.platform.server.api.services.grpc.GrpcCommandSubmissionService @@ -61,8 +53,6 @@ import scala.util.{Failure, Success, Try} object ApiSubmissionService { - private type TransactionInfo = (SubmitterInfo, TransactionMeta, Transaction.Transaction) - type RecordUpdate = Either[LfError, (Transaction, BlindingInfo)] def create( @@ -231,7 +221,7 @@ final class ApiSubmissionService private ( Metrics.failedInterpretationsMeter.mark() Future.failed(grpcError(toStatus(error))) }, Future.successful) - partyAllocationResults <- allocateMissingInformees(transactionInfo._3) + partyAllocationResults <- allocateMissingInformees(transactionInfo.transaction) submissionResult <- submitTransaction(transactionInfo, partyAllocationResults) } yield submissionResult @@ -263,7 +253,7 @@ final class ApiSubmissionService private ( } private def submitTransaction( - transactionInfo: TransactionInfo, + transactionInfo: CommandExecutionResult, partyAllocationResults: Seq[SubmissionResult], ): Future[SubmissionResult] = partyAllocationResults.find(_ != SubmissionResult.Acknowledged) match { @@ -271,7 +261,7 @@ final class ApiSubmissionService private ( Future.successful(result) case None => transactionInfo match { - case (submitterInfo, transactionMeta, transaction) => + case CommandExecutionResult(submitterInfo, transactionMeta, transaction, _) => timedFuture( Metrics.submittedTransactionsTimer, FutureConverters.toScala(