diff --git a/ledger/participant-state/kvutils/src/main/protobuf/com/daml/ledger/participant/state/kvutils/store/state.proto b/ledger/participant-state/kvutils/src/main/protobuf/com/daml/ledger/participant/state/kvutils/store/state.proto index e6da75aae88b..03f92b71f6c6 100644 --- a/ledger/participant-state/kvutils/src/main/protobuf/com/daml/ledger/participant/state/kvutils/store/state.proto +++ b/ledger/participant-state/kvutils/src/main/protobuf/com/daml/ledger/participant/state/kvutils/store/state.proto @@ -54,9 +54,12 @@ message DamlCommandDedupKey { message DamlCommandDedupValue { reserved 1; // was record_time - // the time until when future commands with the same - // deduplication key will be rejected due to a duplicate submission + // The time until when future commands with the same + // deduplication key will be rejected due to a duplicate submission. google.protobuf.Timestamp deduplicated_until = 2; + // The submission time of the initial command. + // We use submission time because record time is not available during pre-execution. + google.protobuf.Timestamp submission_time = 3; } message DamlSubmissionDedupKey { diff --git a/ledger/participant-state/kvutils/src/main/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitter.scala b/ledger/participant-state/kvutils/src/main/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitter.scala index 7957156bc24e..859734443f65 100644 --- a/ledger/participant-state/kvutils/src/main/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitter.scala +++ b/ledger/participant-state/kvutils/src/main/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitter.scala @@ -329,13 +329,14 @@ private[kvutils] class TransactionCommitter( if (!transactionEntry.submitterInfo.hasDeduplicationDuration) { throw Err.InvalidSubmission("Deduplication duration is not set.") } - val commandDedupBuilder = DamlCommandDedupValue.newBuilder.setDeduplicatedUntil( - Conversions.buildTimestamp( - transactionEntry.submissionTime - .add(parseDuration(transactionEntry.submitterInfo.getDeduplicationDuration)) - .add(config.timeModel.minSkew) - ) + val deduplicateUntil = Conversions.buildTimestamp( + transactionEntry.submissionTime + .add(parseDuration(transactionEntry.submitterInfo.getDeduplicationDuration)) + .add(config.timeModel.minSkew) ) + val commandDedupBuilder = DamlCommandDedupValue.newBuilder + .setDeduplicatedUntil(deduplicateUntil) + .setSubmissionTime(Conversions.buildTimestamp(transactionEntry.submissionTime)) // Set a deduplication entry. commitContext.set( commandDedupKey(transactionEntry.submitterInfo), diff --git a/ledger/participant-state/kvutils/src/test/suite/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitterSpec.scala b/ledger/participant-state/kvutils/src/test/suite/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitterSpec.scala index 1c97dc1e8efb..8494837df9fd 100644 --- a/ledger/participant-state/kvutils/src/test/suite/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitterSpec.scala +++ b/ledger/participant-state/kvutils/src/test/suite/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitterSpec.scala @@ -237,9 +237,9 @@ class TransactionCommitterSpec "setting dedup context" should { val deduplicateUntil = protobuf.Timestamp.newBuilder().setSeconds(30).build() val submissionTime = protobuf.Timestamp.newBuilder().setSeconds(60).build() + val deduplicationDuration = time.Duration.ofSeconds(3) "calculate deduplicate until based on deduplication duration" in { - val deduplicationDuration = time.Duration.ofSeconds(3) val (context, transactionEntrySummary) = buildContextAndTransaction( submissionTime, @@ -257,6 +257,21 @@ class TransactionCommitterSpec .build() } + "set the submission time in the committer context" in { + val (context, transactionEntrySummary) = + buildContextAndTransaction( + submissionTime, + _.setDeduplicationDuration(Conversions.buildDuration(deduplicationDuration)), + ) + transactionCommitter.setDedupEntry(context, transactionEntrySummary) + context + .get(Conversions.commandDedupKey(transactionEntrySummary.submitterInfo)) + .map( + _.getCommandDedup.getSubmissionTime + ) + .value shouldBe submissionTime + } + "throw an error for unsupported deduplication periods" in { forAll( Table[DamlSubmitterInfo.Builder => DamlSubmitterInfo.Builder](