Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ledger-configuration: Extract the configuration from participant-state. [KVL-1002] #10279

Merged
merged 9 commits into from
Jul 15, 2021
Merged
2 changes: 2 additions & 0 deletions ledger/indexer-benchmark/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ da_scala_library(
"//language-support/scala/bindings",
"//ledger/ledger-api-common",
"//ledger/ledger-api-health",
"//ledger/ledger-configuration",
"//ledger/ledger-resources",
"//ledger/metrics",
"//ledger/participant-integration-api",
Expand Down Expand Up @@ -61,6 +62,7 @@ da_scala_library(
"//language-support/scala/bindings",
"//ledger/ledger-api-common",
"//ledger/ledger-api-health",
"//ledger/ledger-configuration",
"//ledger/metrics",
"//ledger/participant-state",
"//ledger/participant-state/kvutils",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import akka.stream.scaladsl.{Sink, Source}
import com.codahale.metrics.MetricRegistry
import com.daml.dec.DirectExecutionContext
import com.daml.ledger.api.health.HealthStatus
import com.daml.ledger.participant.state.kvutils.{OffsetBuilder, Raw}
import com.daml.ledger.participant.state.kvutils.`export`.ProtobufBasedLedgerDataImporter
import com.daml.ledger.configuration.LedgerId
import com.daml.ledger.participant.state.kvutils.api.{
KeyValueParticipantStateReader,
LedgerReader,
LedgerRecord,
}
import com.daml.ledger.participant.state.v1.{LedgerId, Offset, Update}
import com.daml.ledger.participant.state.kvutils.export.ProtobufBasedLedgerDataImporter
import com.daml.ledger.participant.state.kvutils.{OffsetBuilder, Raw}
import com.daml.ledger.participant.state.v1.{Offset, Update}
import com.daml.metrics.Metrics

import scala.concurrent.Future
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,8 @@ import akka.stream.scaladsl.Source
import com.codahale.metrics.{MetricRegistry, Snapshot}
import com.daml.dec.DirectExecutionContext
import com.daml.ledger.api.health.HealthStatus
import com.daml.ledger.participant.state.v1.{
Configuration,
LedgerInitialConditions,
Offset,
ReadService,
TimeModel,
Update,
}
import com.daml.ledger.configuration.{Configuration, LedgerInitialConditions, LedgerTimeModel}
import com.daml.ledger.participant.state.v1.{Offset, ReadService, Update}
import com.daml.ledger.resources.{Resource, ResourceContext, ResourceOwner}
import com.daml.lf.data.Time
import com.daml.logging.LoggingContext.newLoggingContext
Expand Down Expand Up @@ -174,7 +168,7 @@ class IndexerBenchmark() {
IndexerBenchmark.LedgerId,
Configuration(
generation = 0,
timeModel = TimeModel.reasonableDefault,
timeModel = LedgerTimeModel.reasonableDefault,
maxDeduplicationTime = java.time.Duration.ofDays(1),
),
Time.Timestamp.Epoch,
Expand Down
2 changes: 1 addition & 1 deletion ledger/ledger-api-domain/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ da_scala_library(
deps = [
"//daml-lf/data",
"//daml-lf/transaction",
"//ledger/participant-state",
"//ledger/ledger-configuration",
"//libs-scala/logging-entries",
"@maven//:io_zipkin_brave_brave",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.time.Instant

import brave.propagation.TraceContext
import com.daml.ledger.api.domain.Event.{CreateOrArchiveEvent, CreateOrExerciseEvent}
import com.daml.ledger.participant.state.v1.Configuration
import com.daml.ledger.configuration.Configuration
import com.daml.lf.command.{Commands => LfCommands}
import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.LedgerString.ordering
Expand Down
52 changes: 52 additions & 0 deletions ledger/ledger-configuration/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

load(
"//bazel_tools:scala.bzl",
"da_scala_library",
"da_scala_test_suite",
)

da_scala_library(
name = "ledger-configuration",
srcs = glob(["src/main/scala/**/*.scala"]),
resources = glob(["src/main/resources/**/*"]),
tags = ["maven_coordinates=com.daml:ledger-configuration:__VERSION__"],
visibility = [
"//visibility:public",
],
exports = [
"//ledger/ledger-configuration/protobuf:ledger_configuration_proto_java",
],
runtime_deps = [],
deps = [
"//daml-lf/data",
"//language-support/scala/bindings",
"//ledger/ledger-configuration/protobuf:ledger_configuration_proto_java",
"@maven//:com_google_protobuf_protobuf_java",
],
)

filegroup(
name = "sources",
srcs = glob(["src/main/scala/**/*.scala"]),
visibility = ["//visibility:public"],
)

da_scala_test_suite(
name = "ledger-configuration-tests",
size = "small",
srcs = glob(["src/test/suite/scala/**/*.scala"]),
resources = glob(["src/test/resources/*"]),
scala_deps = [
"@maven//:org_scalatest_scalatest",
"@maven//:org_scalaz_scalaz_core",
"@maven//:org_scala_lang_modules_scala_collection_compat",
],
deps = [
":ledger-configuration",
"//daml-lf/data",
"//daml-lf/transaction",
"//ledger-api/grpc-definitions:ledger_api_proto_scala",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ proto_jars(
srcs = ["com/daml/ledger/participant/state/ledger_configuration.proto"],
maven_artifact_prefix = "participant-state-ledger-configuration",
maven_group = "com.daml",
visibility = ["//ledger/participant-state:__subpackages__"],
visibility = [
"//ledger/ledger-configuration:__subpackages__",
"//ledger/participant-state:__subpackages__",
],
deps = [
"@com_google_protobuf//:duration_proto",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ Please read ``daml-lf/spec/transaction.rst`` to understand the rules
we follow for evolving the ledger configuration.

The canonical specification compliant implementation for encoding and
decoding ledger configurations is part of the participant-state package
in ``ledger/participant-state``.
decoding ledger configurations is part of the ledger-configuration
package in ``ledger/ledger-configuration``.

For historical reasons, we have kept the package name as
``com.daml.ledger.participant.state``.
This conversation was marked as resolved.
Show resolved Hide resolved

Version history
^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.participant.state.v1
package com.daml.ledger.configuration

import java.time.Duration

Expand All @@ -10,13 +10,13 @@ import scala.util.Try
/** Ledger configuration describing the ledger's time model.
* Emitted in [[com.daml.ledger.participant.state.v1.Update.ConfigurationChanged]].
*
* @param generation The configuration generation. Monotonically increasing.
* @param timeModel The time model of the ledger. Specifying the time-to-live bounds for Ledger API commands.
* @param generation The configuration generation. Monotonically increasing.
* @param timeModel The time model of the ledger. Specifying the time-to-live bounds for Ledger API commands.
* @param maxDeduplicationTime The maximum time window during which commands can be deduplicated.
*/
final case class Configuration(
generation: Long,
timeModel: TimeModel,
timeModel: LedgerTimeModel,
maxDeduplicationTime: Duration,
)

Expand Down Expand Up @@ -58,8 +58,8 @@ object Configuration {
)
}

def decodeTimeModel(tm: protobuf.LedgerTimeModel): Either[String, TimeModel] =
TimeModel(
def decodeTimeModel(tm: protobuf.LedgerTimeModel): Either[String, LedgerTimeModel] =
LedgerTimeModel(
avgTransactionLatency = parseDuration(tm.getAvgTransactionLatency),
minSkew = parseDuration(tm.getMinSkew),
maxSkew = parseDuration(tm.getMaxSkew),
Expand Down Expand Up @@ -88,8 +88,8 @@ object Configuration {
)
}

def decodeTimeModel(tm: protobuf.LedgerTimeModel): Either[String, TimeModel] =
TimeModel(
def decodeTimeModel(tm: protobuf.LedgerTimeModel): Either[String, LedgerTimeModel] =
LedgerTimeModel(
avgTransactionLatency = parseDuration(tm.getAvgTransactionLatency),
minSkew = parseDuration(tm.getMinSkew),
maxSkew = parseDuration(tm.getMaxSkew),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.participant.state.v2
package com.daml.ledger.configuration

import com.daml.lf.data.Time.Timestamp

/** The initial conditions of the ledger before anything has been committed.
*
* @param ledgerId: The static ledger identifier.
* @param config: The initial ledger configuration
* @param initialRecordTime: The initial record time prior to any [[Update]] event.
* @param ledgerId The static ledger identifier.
* @param config The initial ledger configuration
* @param initialRecordTime The initial record time prior to any update event.
*/
final case class LedgerInitialConditions(
ledgerId: LedgerId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.participant.state.v1
package com.daml.ledger.configuration

import java.time.{Duration, Instant}

import scala.util.Try

/** The ledger time model and associated validations. Some values are given by constructor args; others are derived.
* @param avgTransactionLatency The expected average latency of a transaction, i.e., the average time
* from submitting the transaction to a [[WriteService]] and the transaction
* being assigned a record time.
* @param minSkew The minimimum skew between ledger time and record time: lt_TX >= rt_TX - minSkew
* @param maxSkew The maximum skew between ledger time and record time: lt_TX <= rt_TX + maxSkew
/** The ledger time model and associated validations. Some values are given by constructor args;
* others are derived.
*
* @param avgTransactionLatency The expected average latency of a transaction, i.e., the average
* time from submitting the transaction to a write service and the
* transaction being assigned a record time.
* @param minSkew The minimimum skew between ledger time and record time:
* lt_TX >= rt_TX - minSkew
* @param maxSkew The maximum skew between ledger time and record time:
* lt_TX <= rt_TX + maxSkew
* @throws IllegalArgumentException if the parameters aren't valid
*/
case class TimeModel private (
case class LedgerTimeModel private (
avgTransactionLatency: Duration,
minSkew: Duration,
maxSkew: Duration,
Expand All @@ -37,36 +40,40 @@ case class TimeModel private (
Right(())
}

private[state] def minLedgerTime(recordTime: Instant): Instant =
private[ledger] def minLedgerTime(recordTime: Instant): Instant =
recordTime.minus(minSkew)

private[state] def maxLedgerTime(recordTime: Instant): Instant =
private[ledger] def maxLedgerTime(recordTime: Instant): Instant =
recordTime.plus(maxSkew)

private[state] def minRecordTime(ledgerTime: Instant): Instant =
private[ledger] def minRecordTime(ledgerTime: Instant): Instant =
ledgerTime.minus(maxSkew)

private[state] def maxRecordTime(ledgerTime: Instant): Instant =
private[ledger] def maxRecordTime(ledgerTime: Instant): Instant =
ledgerTime.plus(minSkew)
}

object TimeModel {
object LedgerTimeModel {

/** A default TimeModel that's reasonable for a test or sandbox ledger application.
* Serious applications (viz. ledger) should probably specify their own TimeModel.
*/
val reasonableDefault: TimeModel =
TimeModel(
val reasonableDefault: LedgerTimeModel =
LedgerTimeModel(
avgTransactionLatency = Duration.ofSeconds(0L),
minSkew = Duration.ofSeconds(30L),
maxSkew = Duration.ofSeconds(30L),
).get

def apply(avgTransactionLatency: Duration, minSkew: Duration, maxSkew: Duration): Try[TimeModel] =
def apply(
avgTransactionLatency: Duration,
minSkew: Duration,
maxSkew: Duration,
): Try[LedgerTimeModel] =
Try {
require(!avgTransactionLatency.isNegative, "Negative average transaction latency")
require(!minSkew.isNegative, "Negative min skew")
require(!maxSkew.isNegative, "Negative max skew")
new TimeModel(avgTransactionLatency, minSkew, maxSkew)
new LedgerTimeModel(avgTransactionLatency, minSkew, maxSkew)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger

package object configuration {

/** Identifier for the ledger, MUST match regexp [a-zA-Z0-9-]. */
type LedgerId = String

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.participant.state.v1
package com.daml.ledger.configuration

import java.time._

import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class TimeModelSpec extends AnyWordSpec with Matchers {
class LedgerTimeModelSpec extends AnyWordSpec with Matchers {

private val referenceTime = Instant.EPOCH
private val epsilon = Duration.ofMillis(10L)
private val timeModel =
TimeModel(
LedgerTimeModel(
avgTransactionLatency = Duration.ZERO,
minSkew = Duration.ofSeconds(30L),
maxSkew = Duration.ofSeconds(30L),
Expand Down Expand Up @@ -92,12 +92,11 @@ class TimeModelSpec extends AnyWordSpec with Matchers {
}

"produce a valid error message" in {
val timeModel =
TimeModel(
avgTransactionLatency = Duration.ZERO,
minSkew = Duration.ofSeconds(10L),
maxSkew = Duration.ofSeconds(20L),
).get
val timeModel = LedgerTimeModel(
avgTransactionLatency = Duration.ZERO,
minSkew = Duration.ofSeconds(10L),
maxSkew = Duration.ofSeconds(20L),
).get
val ledgerTime = "2000-01-01T12:00:00Z"
val recordTime = "2000-01-01T12:30:00Z"
val lowerBound = "2000-01-01T12:29:50Z"
Expand All @@ -112,8 +111,8 @@ class TimeModelSpec extends AnyWordSpec with Matchers {
}
}

private def createAsymmetricTimeModel(minSkew: Duration, maxSkew: Duration): TimeModel =
TimeModel(
private def createAsymmetricTimeModel(minSkew: Duration, maxSkew: Duration): LedgerTimeModel =
LedgerTimeModel(
avgTransactionLatency = Duration.ZERO,
minSkew = minSkew,
maxSkew = maxSkew,
Expand Down
3 changes: 3 additions & 0 deletions ledger/ledger-on-memory/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ da_scala_library(
"//ledger/caching",
"//ledger/ledger-api-common",
"//ledger/ledger-api-health",
"//ledger/ledger-configuration",
"//ledger/ledger-resources",
"//ledger/metrics",
"//ledger/participant-state",
Expand Down Expand Up @@ -69,6 +70,7 @@ da_scala_test_suite(
"//ledger/caching",
"//ledger/ledger-api-common",
"//ledger/ledger-api-health",
"//ledger/ledger-configuration",
"//ledger/ledger-resources",
"//ledger/ledger-resources:ledger-resources-test-lib",
"//ledger/metrics",
Expand Down Expand Up @@ -104,6 +106,7 @@ da_scala_library(
"//ledger/ledger-api-auth",
"//ledger/ledger-api-common",
"//ledger/ledger-api-health",
"//ledger/ledger-configuration",
"//ledger/ledger-resources",
"//ledger/metrics",
"//ledger/participant-integration-api",
Expand Down
Loading