Sandbox Classic: Privatize everything. (#7130)

* sandbox-classic: Split out `LedgerBackedWriteService`.

* sandbox-classic: Privatize everything.

CHANGELOG_BEGIN
CHANGELOG_END
This commit is contained in:
Samir Talwar 2020-08-14 10:39:52 +02:00 committed by GitHub
parent 66ae38da6c
commit dcb21dc358
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 160 additions and 135 deletions

View File

@ -9,7 +9,7 @@ import com.daml.ledger.api.domain.LedgerId
import com.daml.platform.sandbox.config.LedgerName
import scalaz.syntax.tag._
class LedgerIdGenerator(name: LedgerName) {
private[sandbox] final class LedgerIdGenerator(name: LedgerName) {
def generateRandomId(): LedgerId =
LedgerId(s"${name.unwrap.toLowerCase()}-${UUID.randomUUID().toString}")
}

View File

@ -18,13 +18,13 @@ import com.daml.platform.store.Contract.{ActiveContract, DivulgedContract}
import com.daml.platform.store._
import scalaz.syntax.std.map._
case class InMemoryActiveLedgerState(
private[sandbox] case class InMemoryActiveLedgerState(
activeContracts: Map[ContractId, ActiveContract],
divulgedContracts: Map[ContractId, DivulgedContract],
keys: Map[GlobalKey, ContractId],
reverseKeys: Map[ContractId, GlobalKey],
parties: Map[Party, PartyDetails])
extends ActiveLedgerState[InMemoryActiveLedgerState] {
parties: Map[Party, PartyDetails],
) extends ActiveLedgerState[InMemoryActiveLedgerState] {
def isVisibleForDivulgees(contractId: ContractId, forParty: Party): Boolean =
activeContracts
@ -174,7 +174,7 @@ case class InMemoryActiveLedgerState(
}
}
object InMemoryActiveLedgerState {
private[sandbox] object InMemoryActiveLedgerState {
def empty: InMemoryActiveLedgerState =
InMemoryActiveLedgerState(Map.empty, Map.empty, Map.empty, Map.empty, Map.empty)
}

View File

@ -0,0 +1,97 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.platform.sandbox.stores
import java.util.concurrent.CompletionStage
import com.daml.api.util.TimeProvider
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger.api.health.HealthStatus
import com.daml.ledger.participant.state.v1.{
Configuration,
SubmissionId,
SubmissionResult,
SubmittedTransaction,
SubmitterInfo,
TransactionMeta,
WriteService
}
import com.daml.lf.data.Ref.Party
import com.daml.lf.data.Time
import com.daml.logging.LoggingContext
import com.daml.logging.LoggingContext.withEnrichedLoggingContext
import com.daml.platform.sandbox.stores.ledger.{Ledger, PartyIdGenerator}
import scala.compat.java8.FutureConverters
private[stores] final class LedgerBackedWriteService(ledger: Ledger, timeProvider: TimeProvider)(
implicit loggingContext: LoggingContext,
) extends WriteService {
override def currentHealth(): HealthStatus = ledger.currentHealth()
override def submitTransaction(
submitterInfo: SubmitterInfo,
transactionMeta: TransactionMeta,
transaction: SubmittedTransaction,
): CompletionStage[SubmissionResult] =
withEnrichedLoggingContext(
"submitter" -> submitterInfo.submitter,
"applicationId" -> submitterInfo.applicationId,
"commandId" -> submitterInfo.commandId,
"deduplicateUntil" -> submitterInfo.deduplicateUntil.toString,
"submissionTime" -> transactionMeta.submissionTime.toInstant.toString,
"workflowId" -> transactionMeta.workflowId.getOrElse(""),
"ledgerTime" -> transactionMeta.ledgerEffectiveTime.toInstant.toString,
) { implicit loggingContext =>
FutureConverters.toJava(
ledger.publishTransaction(submitterInfo, transactionMeta, transaction)
)
}
override def allocateParty(
hint: Option[Party],
displayName: Option[String],
submissionId: SubmissionId,
): CompletionStage[SubmissionResult] = {
val party = hint.getOrElse(PartyIdGenerator.generateRandomId())
withEnrichedLoggingContext(
"party" -> party,
"submissionId" -> submissionId,
) { implicit loggingContext =>
FutureConverters.toJava(ledger.publishPartyAllocation(submissionId, party, displayName))
}
}
// WritePackagesService
override def uploadPackages(
submissionId: SubmissionId,
payload: List[Archive],
sourceDescription: Option[String]
): CompletionStage[SubmissionResult] =
withEnrichedLoggingContext(
"submissionId" -> submissionId,
"description" -> sourceDescription.getOrElse(""),
"packageHashes" -> payload.iterator.map(_.getHash).mkString(","),
) { implicit loggingContext =>
FutureConverters.toJava(
ledger
.uploadPackages(submissionId, timeProvider.getCurrentTime, sourceDescription, payload))
}
// WriteConfigService
override def submitConfiguration(
maxRecordTime: Time.Timestamp,
submissionId: SubmissionId,
config: Configuration,
): CompletionStage[SubmissionResult] =
withEnrichedLoggingContext(
"maxRecordTime" -> maxRecordTime.toInstant.toString,
"submissionId" -> submissionId,
"configGeneration" -> config.generation.toString,
"configMaxDeduplicationTime" -> config.maxDeduplicationTime.toString,
) { implicit loggingContext =>
FutureConverters.toJava(ledger.publishConfiguration(maxRecordTime, submissionId, config))
}
}

View File

@ -4,26 +4,15 @@
package com.daml.platform.sandbox.stores
import java.time.Instant
import java.util.concurrent.CompletionStage
import akka.stream.Materializer
import akka.stream.scaladsl.{Sink, Source}
import com.daml.api.util.TimeProvider
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger.api.health.HealthStatus
import com.daml.ledger.participant.state.index.v2._
import com.daml.ledger.participant.state.v1.{
ApplicationId => _,
LedgerId => _,
TransactionId => _,
_
}
import com.daml.ledger.participant.state.{v1 => ParticipantState}
import com.daml.lf.data.Ref.Party
import com.daml.lf.data.{ImmArray, Time}
import com.daml.ledger.participant.state.index.v2.IndexService
import com.daml.ledger.participant.state.v1.{ParticipantId, WriteService}
import com.daml.lf.data.ImmArray
import com.daml.lf.transaction.TransactionCommitter
import com.daml.logging.LoggingContext
import com.daml.logging.LoggingContext.withEnrichedLoggingContext
import com.daml.metrics.Metrics
import com.daml.platform.common.LedgerIdMode
import com.daml.platform.configuration.ServerRole
@ -32,24 +21,23 @@ import com.daml.platform.packages.InMemoryPackageStore
import com.daml.platform.sandbox.LedgerIdGenerator
import com.daml.platform.sandbox.config.LedgerName
import com.daml.platform.sandbox.stores.ledger.ScenarioLoader.LedgerEntryOrBump
import com.daml.platform.sandbox.stores.ledger._
import com.daml.platform.sandbox.stores.ledger.inmemory.InMemoryLedger
import com.daml.platform.sandbox.stores.ledger.sql.{SqlLedger, SqlStartMode}
import com.daml.platform.sandbox.stores.ledger.{Ledger, MeteredLedger}
import com.daml.platform.store.dao.events.LfValueTranslation
import com.daml.resources.{Resource, ResourceOwner}
import org.slf4j.LoggerFactory
import scala.compat.java8.FutureConverters
import scala.concurrent.duration._
import scala.concurrent.duration.{DurationInt, FiniteDuration}
import scala.concurrent.{ExecutionContext, Future}
trait IndexAndWriteService {
private[sandbox] trait IndexAndWriteService {
def indexService: IndexService
def writeService: WriteService
}
object SandboxIndexAndWriteService {
private[sandbox] object SandboxIndexAndWriteService {
//TODO: internalise the template store as well
private val logger = LoggerFactory.getLogger(SandboxIndexAndWriteService.getClass)
@ -172,72 +160,3 @@ object SandboxIndexAndWriteService {
}
}
}
final class LedgerBackedWriteService(ledger: Ledger, timeProvider: TimeProvider)(
implicit loggingContext: LoggingContext,
) extends WriteService {
override def currentHealth(): HealthStatus = ledger.currentHealth()
override def submitTransaction(
submitterInfo: ParticipantState.SubmitterInfo,
transactionMeta: ParticipantState.TransactionMeta,
transaction: SubmittedTransaction,
): CompletionStage[ParticipantState.SubmissionResult] =
withEnrichedLoggingContext(
"submitter" -> submitterInfo.submitter,
"applicationId" -> submitterInfo.applicationId,
"commandId" -> submitterInfo.commandId,
"deduplicateUntil" -> submitterInfo.deduplicateUntil.toString,
"submissionTime" -> transactionMeta.submissionTime.toInstant.toString,
"workflowId" -> transactionMeta.workflowId.getOrElse(""),
"ledgerTime" -> transactionMeta.ledgerEffectiveTime.toInstant.toString,
) { implicit loggingContext =>
FutureConverters.toJava(
ledger.publishTransaction(submitterInfo, transactionMeta, transaction)
)
}
override def allocateParty(
hint: Option[Party],
displayName: Option[String],
submissionId: SubmissionId): CompletionStage[SubmissionResult] = {
val party = hint.getOrElse(PartyIdGenerator.generateRandomId())
withEnrichedLoggingContext(
"party" -> party,
"submissionId" -> submissionId,
) { implicit loggingContext =>
FutureConverters.toJava(ledger.publishPartyAllocation(submissionId, party, displayName))
}
}
// WritePackagesService
override def uploadPackages(
submissionId: SubmissionId,
payload: List[Archive],
sourceDescription: Option[String]
): CompletionStage[SubmissionResult] =
withEnrichedLoggingContext(
"submissionId" -> submissionId,
"description" -> sourceDescription.getOrElse(""),
"packageHashes" -> payload.iterator.map(_.getHash).mkString(","),
) { implicit loggingContext =>
FutureConverters.toJava(
ledger
.uploadPackages(submissionId, timeProvider.getCurrentTime, sourceDescription, payload))
}
// WriteConfigService
override def submitConfiguration(
maxRecordTime: Time.Timestamp,
submissionId: SubmissionId,
config: Configuration): CompletionStage[SubmissionResult] =
withEnrichedLoggingContext(
"maxRecordTime" -> maxRecordTime.toInstant.toString,
"submissionId" -> submissionId,
"configGeneration" -> config.generation.toString,
"configMaxDeduplicationTime" -> config.maxDeduplicationTime.toString,
) { implicit loggingContext =>
FutureConverters.toJava(ledger.publishConfiguration(maxRecordTime, submissionId, config))
}
}

View File

@ -18,7 +18,7 @@ import com.daml.platform.store.ReadOnlyLedger
import scala.concurrent.Future
trait Ledger extends ReadOnlyLedger {
private[sandbox] trait Ledger extends ReadOnlyLedger {
def publishTransaction(
submitterInfo: SubmitterInfo,
@ -50,7 +50,7 @@ trait Ledger extends ReadOnlyLedger {
}
object Ledger {
private[sandbox] object Ledger {
type Divulgence = Relation[ContractId, Party]

View File

@ -62,6 +62,6 @@ private class MeteredLedger(ledger: Ledger, metrics: Metrics)
}
object MeteredLedger {
private[sandbox] object MeteredLedger {
def apply(ledger: Ledger, metrics: Metrics): Ledger = new MeteredLedger(ledger, metrics)
}

View File

@ -7,7 +7,7 @@ import java.util.UUID
import com.daml.lf.data.Ref
object PartyIdGenerator {
private[stores] object PartyIdGenerator {
def generateRandomId(): Ref.Party =
Ref.Party.assertFromString(s"party-${UUID.randomUUID().toString.take(8)}")
}

View File

@ -9,7 +9,7 @@ import com.daml.ledger.participant.state.v1.Offset
// This utility object makes sure that the offset representation is always
// padded with zeros up to 8 bytes.
// This should only be used in SqlLedger and InMemoryLedger.
object SandboxOffset {
private[ledger] object SandboxOffset {
def numBytes = 8

View File

@ -19,7 +19,7 @@ import scala.annotation.tailrec
import scala.collection.breakOut
import scala.collection.mutable.ArrayBuffer
object ScenarioLoader {
private[sandbox] object ScenarioLoader {
/** When loading from the scenario, we also specify by how much to bump the
* ledger end after each entry. This is because in the scenario transaction

View File

@ -8,25 +8,7 @@ import java.util.concurrent.atomic.AtomicReference
import akka.NotUsed
import akka.stream.scaladsl.Source
import com.daml.ledger.participant.state.index.v2.{
CommandDeduplicationDuplicate,
CommandDeduplicationNew,
CommandDeduplicationResult,
PackageDetails
}
import com.daml.ledger.participant.state.v1.{
ApplicationId => _,
LedgerId => _,
TransactionId => _,
_
}
import com.daml.api.util.TimeProvider
import com.daml.lf.data.Ref.{LedgerString, PackageId, Party}
import com.daml.lf.data.{ImmArray, Ref, Time}
import com.daml.lf.language.Ast
import com.daml.lf.transaction.{GlobalKey, TransactionCommitter}
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger
import com.daml.ledger.api.domain.{
@ -50,6 +32,24 @@ import com.daml.ledger.api.v1.transaction_service.{
GetTransactionTreesResponse,
GetTransactionsResponse
}
import com.daml.ledger.participant.state.index.v2.{
CommandDeduplicationDuplicate,
CommandDeduplicationNew,
CommandDeduplicationResult,
PackageDetails
}
import com.daml.ledger.participant.state.v1.{
ApplicationId => _,
LedgerId => _,
TransactionId => _,
_
}
import com.daml.lf.data.Ref.{LedgerString, PackageId, Party}
import com.daml.lf.data.{ImmArray, Ref, Time}
import com.daml.lf.language.Ast
import com.daml.lf.transaction.{GlobalKey, TransactionCommitter}
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.logging.{ContextualizedLogger, LoggingContext}
import com.daml.platform.index.TransactionConversion
import com.daml.platform.packages.InMemoryPackageStore
@ -57,6 +57,8 @@ import com.daml.platform.participant.util.LfEngineToApi
import com.daml.platform.sandbox.stores.InMemoryActiveLedgerState
import com.daml.platform.sandbox.stores.ledger.Ledger
import com.daml.platform.sandbox.stores.ledger.ScenarioLoader.LedgerEntryOrBump
import com.daml.platform.sandbox.stores.ledger.inmemory.InMemoryLedger._
import com.daml.platform.store.CompletionFromTransaction
import com.daml.platform.store.Contract.ActiveContract
import com.daml.platform.store.entries.{
ConfigurationEntry,
@ -64,28 +66,16 @@ import com.daml.platform.store.entries.{
PackageLedgerEntry,
PartyLedgerEntry
}
import com.daml.platform.store.CompletionFromTransaction
import com.daml.platform.{ApiOffset, index}
import scalaz.syntax.tag.ToTagOps
import scala.concurrent.Future
import scala.util.Try
sealed trait InMemoryEntry extends Product with Serializable
final case class InMemoryLedgerEntry(entry: LedgerEntry) extends InMemoryEntry
final case class InMemoryConfigEntry(entry: ConfigurationEntry) extends InMemoryEntry
final case class InMemoryPartyEntry(entry: PartyLedgerEntry) extends InMemoryEntry
final case class InMemoryPackageEntry(entry: PackageLedgerEntry) extends InMemoryEntry
final case class CommandDeduplicationEntry(
deduplicationKey: String,
deduplicateUntil: Instant,
)
/** This stores all the mutable data that we need to run a ledger: the PCS, the ACS, and the deduplicator.
*
*/
class InMemoryLedger(
private[sandbox] final class InMemoryLedger(
val ledgerId: LedgerId,
participantId: ParticipantId,
timeProvider: TimeProvider,
@ -645,3 +635,22 @@ class InMemoryLedger(
}
}
}
private[sandbox] object InMemoryLedger {
sealed trait InMemoryEntry extends Product with Serializable
final case class InMemoryLedgerEntry(entry: LedgerEntry) extends InMemoryEntry
final case class InMemoryConfigEntry(entry: ConfigurationEntry) extends InMemoryEntry
final case class InMemoryPartyEntry(entry: PartyLedgerEntry) extends InMemoryEntry
final case class InMemoryPackageEntry(entry: PackageLedgerEntry) extends InMemoryEntry
final case class CommandDeduplicationEntry(
deduplicationKey: String,
deduplicateUntil: Instant,
)
}

View File

@ -17,7 +17,7 @@ import com.daml.platform.sandbox.stores.ledger.SandboxOffset
import scala.collection.immutable.TreeMap
private[ledger] class LedgerEntries[T](identify: T => String) {
private[inmemory] class LedgerEntries[T](identify: T => String) {
private val logger = LoggerFactory.getLogger(this.getClass)

View File

@ -44,7 +44,7 @@ import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal
import scala.util.{Failure, Success}
object SqlLedger {
private[sandbox] object SqlLedger {
private type PersistenceQueue = SourceQueueWithComplete[Offset => Future[Unit]]

View File

@ -3,9 +3,9 @@
package com.daml.platform.sandbox.stores.ledger.sql
sealed abstract class SqlStartMode extends Product with Serializable
private[sandbox] sealed abstract class SqlStartMode extends Product with Serializable
object SqlStartMode {
private[sandbox] object SqlStartMode {
/** Will continue using an initialised ledger, otherwise initialize a new one */
final case object ContinueIfExists extends SqlStartMode

View File

@ -28,7 +28,7 @@ import com.daml.testing.postgresql.PostgresResource
import scala.concurrent.ExecutionContext
object LedgerResource {
private[sandbox] object LedgerResource {
def inMemory(
ledgerId: LedgerId,