mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Ensure out of time bounds entries are set for all rejections [KVL-1412] (#13595)
This commit is contained in:
parent
6b3e7969cf
commit
988b609051
@ -23,7 +23,6 @@ import com.daml.ledger.participant.state.kvutils.store.events.{
|
||||
}
|
||||
import com.daml.ledger.participant.state.kvutils.store.{
|
||||
DamlCommandDedupValue,
|
||||
DamlLogEntry,
|
||||
DamlStateValue,
|
||||
PreExecutionDeduplicationBounds,
|
||||
}
|
||||
@ -71,8 +70,6 @@ private[transaction] object CommandDeduplication {
|
||||
StepContinue(transactionEntry)
|
||||
} else {
|
||||
if (commitContext.preExecute) {
|
||||
// The out of time bounds entry is required in the committer, so we set it to the default value as we stop the steps here with the duplicate rejection
|
||||
commitContext.outOfTimeBoundsLogEntry = Some(DamlLogEntry.getDefaultInstance)
|
||||
preExecutionDuplicateRejection(
|
||||
commitContext,
|
||||
transactionEntry,
|
||||
|
@ -69,12 +69,16 @@ private[kvutils] class TransactionCommitter(
|
||||
private val committerModelConformanceValidator =
|
||||
new CommitterModelConformanceValidator(engine, metrics)
|
||||
|
||||
/** The order of the steps matters
|
||||
*/
|
||||
override protected val steps: Steps[DamlTransactionEntrySummary] = Iterable(
|
||||
"set_context_min_max_record_time" -> TimeBoundBindingStep.setTimeBoundsInContextStep(
|
||||
defaultConfig
|
||||
),
|
||||
"set_context_out_of_time_bounds_entry" -> ledgerTimeValidator.createValidationStep(rejections),
|
||||
"authorize_submitter" -> authorizeSubmitters,
|
||||
"check_informee_parties_allocation" -> checkInformeePartiesAllocation,
|
||||
"set_time_bounds" -> TimeBoundBindingStep.setTimeBoundsInContextStep(defaultConfig),
|
||||
"deduplicate" -> CommandDeduplication.deduplicateCommandStep(rejections),
|
||||
"validate_ledger_time" -> ledgerTimeValidator.createValidationStep(rejections),
|
||||
"validate_committer_model_conformance" -> committerModelConformanceValidator
|
||||
.createValidationStep(rejections),
|
||||
"validate_consistency" -> TransactionConsistencyValidator.createValidationStep(rejections),
|
||||
|
@ -73,6 +73,7 @@ object TestHelpers {
|
||||
DamlSubmitterInfo.newBuilder
|
||||
.setCommandId("commandId")
|
||||
.addAllSubmitters(submitters.asJava)
|
||||
.setDeduplicationDuration(Conversions.buildDuration(Duration.ofSeconds(30)))
|
||||
)
|
||||
.setSubmissionSeed(ByteString.copyFromUtf8("a" * 32))
|
||||
.build
|
||||
|
@ -206,18 +206,6 @@ class CommandDeduplicationSpec
|
||||
deduplicateStepHasTransactionRejectionEntry(commitContext)
|
||||
}
|
||||
|
||||
"set the out of time bounds log entry during rejections" in {
|
||||
val dedupValue = newDedupValue(
|
||||
_.setRecordTimeBounds(buildPreExecutionDeduplicationBounds(timestamp, timestamp))
|
||||
)
|
||||
val commitContext = createCommitContext(None, Map(aDedupKey -> Some(dedupValue)))
|
||||
commitContext.minimumRecordTime = Some(timestamp)
|
||||
commitContext.maximumRecordTime = Some(timestamp)
|
||||
|
||||
deduplicateStepHasTransactionRejectionEntry(commitContext)
|
||||
commitContext.outOfTimeBoundsLogEntry shouldBe 'defined
|
||||
}
|
||||
|
||||
"return the command deduplication duration as deduplication duration when this exceeds the max delta between record times" in {
|
||||
val dedupValue = newDedupValue(
|
||||
_.setRecordTimeBounds(buildPreExecutionDeduplicationBounds(timestamp, timestamp))
|
||||
|
@ -14,11 +14,15 @@ import com.daml.ledger.participant.state.kvutils.store.events.{
|
||||
DamlTransactionRejectionEntry,
|
||||
}
|
||||
import com.daml.ledger.participant.state.kvutils.store.{
|
||||
DamlCommandDedupValue,
|
||||
DamlLogEntry,
|
||||
DamlPartyAllocation,
|
||||
DamlStateKey,
|
||||
DamlStateValue,
|
||||
PreExecutionDeduplicationBounds,
|
||||
}
|
||||
import com.daml.ledger.participant.state.kvutils.{Conversions, Err, committer}
|
||||
import com.daml.ledger.participant.state.kvutils.wire.DamlSubmission
|
||||
import com.daml.ledger.participant.state.kvutils.{Conversions, Err, KeyValueCommitting, committer}
|
||||
import com.daml.lf.data.Time.Timestamp
|
||||
import com.daml.lf.data.{ImmArray, Ref}
|
||||
import com.daml.lf.engine.Engine
|
||||
@ -289,6 +293,78 @@ class TransactionCommitterSpec
|
||||
}
|
||||
}
|
||||
|
||||
"out of time bounds entry" should {
|
||||
|
||||
"be set" when {
|
||||
|
||||
"a submitting party is not known" in {
|
||||
val context = createCommitContext(
|
||||
recordTime = None,
|
||||
inputs = createInputs(
|
||||
Alice -> Some(hostedParty(Alice)),
|
||||
Bob -> None,
|
||||
) + (Conversions.configurationStateKey -> None),
|
||||
participantId = ParticipantId,
|
||||
)
|
||||
val transactionEntry = createEmptyTransactionEntry(List(Alice, Bob))
|
||||
val result = transactionCommitter.preExecute(
|
||||
DamlSubmission.newBuilder().setTransactionEntry(transactionEntry).build(),
|
||||
context,
|
||||
)
|
||||
resultIsRejectedWithPayload(
|
||||
result,
|
||||
DamlTransactionRejectionEntry.ReasonCase.SUBMITTING_PARTY_NOT_KNOWN_ON_LEDGER,
|
||||
)
|
||||
}
|
||||
|
||||
"the command is a duplicate" in {
|
||||
val transactionEntry = createEmptyTransactionEntry(List(Alice))
|
||||
val configurationInput = Conversions.configurationStateKey -> None
|
||||
val commandDeduplicationInput = Conversions.commandDedupKey(
|
||||
transactionEntry.getSubmitterInfo
|
||||
) -> Some(
|
||||
DamlStateValue.newBuilder
|
||||
.setCommandDedup(
|
||||
DamlCommandDedupValue.newBuilder
|
||||
.setRecordTimeBounds(
|
||||
PreExecutionDeduplicationBounds
|
||||
.newBuilder()
|
||||
.setMaxRecordTime(transactionEntry.getSubmissionTime)
|
||||
.setMinRecordTime(transactionEntry.getSubmissionTime)
|
||||
)
|
||||
)
|
||||
.build
|
||||
)
|
||||
val context = createCommitContext(
|
||||
recordTime = None,
|
||||
inputs = createInputs(
|
||||
Alice -> Some(hostedParty(Alice))
|
||||
) + configurationInput + commandDeduplicationInput,
|
||||
participantId = ParticipantId,
|
||||
)
|
||||
val result = transactionCommitter.preExecute(
|
||||
DamlSubmission.newBuilder().setTransactionEntry(transactionEntry).build(),
|
||||
context,
|
||||
)
|
||||
resultIsRejectedWithPayload(
|
||||
result,
|
||||
DamlTransactionRejectionEntry.ReasonCase.DUPLICATE_COMMAND,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def resultIsRejectedWithPayload(
|
||||
result: KeyValueCommitting.PreExecutionResult,
|
||||
transactionRejectionReason: DamlTransactionRejectionEntry.ReasonCase,
|
||||
) = {
|
||||
result.outOfTimeBoundsLogEntry.getPayloadCase shouldBe DamlLogEntry.PayloadCase.OUT_OF_TIME_BOUNDS_ENTRY
|
||||
result.outOfTimeBoundsLogEntry.getOutOfTimeBoundsEntry.getEntry.getPayloadCase shouldBe DamlLogEntry.PayloadCase.TRANSACTION_REJECTION_ENTRY
|
||||
result.outOfTimeBoundsLogEntry.getOutOfTimeBoundsEntry.getEntry.getTransactionRejectionEntry.getReasonCase shouldBe DamlTransactionRejectionEntry.ReasonCase.RECORD_TIME_OUT_OF_RANGE
|
||||
result.successfulLogEntry.getPayloadCase shouldBe DamlLogEntry.PayloadCase.TRANSACTION_REJECTION_ENTRY
|
||||
result.successfulLogEntry.getTransactionRejectionEntry.getReasonCase shouldBe transactionRejectionReason
|
||||
}
|
||||
}
|
||||
|
||||
private def createTransactionCommitter(
|
||||
defaultConfig: Configuration = theDefaultConfig
|
||||
): committer.transaction.TransactionCommitter =
|
||||
|
Loading…
Reference in New Issue
Block a user