Output whether command execution depends on time (#5019)

CHANGELOG_BEGIN
CHANGELOG_END
This commit is contained in:
Robert Autenrieth 2020-03-16 16:28:45 +01:00 committed by GitHub
parent 9aa68cac4f
commit d90cd2c542
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 22 deletions

View File

@ -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]]
}

View File

@ -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)
}
}

View File

@ -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(