[ED] Enable explicit disclosure in conformance tests [DPP-1206] (#14974)

* Allow enabling explicit disclosure in Sandbox-on-X

changelog_begin
changelog_end

* Fix conformance tests

* Disable tests testing yet unsupported features

* Addressed Martino's review comments
This commit is contained in:
tudor-da 2022-09-23 09:55:19 +02:00 committed by GitHub
parent dd5543eaf2
commit e0dc3f8679
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 242 additions and 48 deletions

View File

@ -278,6 +278,10 @@ final class CommandsValidator(
}
object CommandsValidator {
def apply(ledgerId: LedgerId, explicitDisclosureUnsafeEnabled: Boolean) = new CommandsValidator(
ledgerId = ledgerId,
validateDisclosedContracts = new ValidateDisclosedContracts(explicitDisclosureUnsafeEnabled),
)
/** Effective submitters of a command
* @param actAs Guaranteed to be non-empty. Will contain exactly one element in most cases.

View File

@ -26,6 +26,7 @@ class GrpcCommandService(
currentUtcTime: () => Instant,
maxDeduplicationDuration: () => Option[Duration],
generateSubmissionId: SubmissionIdGenerator,
explicitDisclosureUnsafeEnabled: Boolean,
)(implicit executionContext: ExecutionContext, loggingContext: LoggingContext)
extends CommandService
with GrpcApiService
@ -34,7 +35,7 @@ class GrpcCommandService(
protected implicit val logger: ContextualizedLogger = ContextualizedLogger.get(getClass)
private[this] val validator = new SubmitAndWaitRequestValidator(
new CommandsValidator(ledgerId)
CommandsValidator(ledgerId, explicitDisclosureUnsafeEnabled)
)
override def submitAndWait(request: SubmitAndWaitRequest): Future[Empty] =

View File

@ -34,6 +34,7 @@ class GrpcCommandSubmissionService(
maxDeduplicationDuration: () => Option[Duration],
submissionIdGenerator: SubmissionIdGenerator,
metrics: Metrics,
explicitDisclosureUnsafeEnabled: Boolean,
)(implicit executionContext: ExecutionContext, loggingContext: LoggingContext)
extends ApiCommandSubmissionService
with ProxyCloseable
@ -41,7 +42,7 @@ class GrpcCommandSubmissionService(
protected implicit val logger: ContextualizedLogger = ContextualizedLogger.get(getClass)
private val validator = new SubmitRequestValidator(
new CommandsValidator(ledgerId)
CommandsValidator(ledgerId, explicitDisclosureUnsafeEnabled)
)
override def submit(request: ApiSubmitRequest): Future[Empty] = {

View File

@ -12,18 +12,20 @@ import com.daml.ledger.api.v1.command_service.{
SubmitAndWaitForTransactionTreeResponse,
SubmitAndWaitRequest,
}
import com.daml.ledger.api.v1.commands.{Command, CreateCommand}
import com.daml.ledger.api.v1.commands.{Command, CreateCommand, DisclosedContract}
import com.daml.ledger.api.v1.value.{Identifier, Record, RecordField, Value}
import com.daml.lf.data.Ref
import com.daml.logging.LoggingContext
import com.google.protobuf.empty.Empty
import org.mockito.{ArgumentMatchersSugar, MockitoSugar}
import org.scalatest.Assertion
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AsyncWordSpec
import java.time.{Duration, Instant}
import java.util.concurrent.atomic.AtomicInteger
import scala.concurrent.Future
import scala.util.{Failure, Success}
class GrpcCommandServiceSpec
extends AsyncWordSpec
@ -59,6 +61,7 @@ class GrpcCommandServiceSpec
Ref.SubmissionId.assertFromString(
s"$submissionIdPrefix${submissionCounter.incrementAndGet()}"
),
explicitDisclosureUnsafeEnabled = false,
)
for {
@ -85,6 +88,51 @@ class GrpcCommandServiceSpec
succeed
}
}
"reject submission on explicit disclosure disabled with provided disclosed contracts" in {
val mockCommandService = mock[CommandService with AutoCloseable]
val grpcCommandService = new GrpcCommandService(
mockCommandService,
ledgerId = LedgerId(ledgerId),
currentLedgerTime = () => Instant.EPOCH,
currentUtcTime = () => Instant.EPOCH,
maxDeduplicationDuration = () => Some(Duration.ZERO),
generateSubmissionId = () => Ref.SubmissionId.assertFromString(s"submissionId"),
explicitDisclosureUnsafeEnabled = false,
)
val submissionWithDisclosedContracts = aSubmitAndWaitRequestWithNoSubmissionId.update(
_.commands.disclosedContracts.set(Seq(DisclosedContract()))
)
def expectFailedOnProvidedDisclosedContracts(f: Future[_]): Future[Assertion] = f.transform {
case Failure(exception)
if exception.getMessage.contains(
"feature in development: disclosed_contracts should not be set"
) =>
Success(succeed)
case other => fail(s"Unexpected result: $other")
}
for {
_ <- expectFailedOnProvidedDisclosedContracts(
grpcCommandService.submitAndWait(submissionWithDisclosedContracts)
)
_ <- expectFailedOnProvidedDisclosedContracts(
grpcCommandService.submitAndWaitForTransaction(submissionWithDisclosedContracts)
)
_ <- expectFailedOnProvidedDisclosedContracts(
grpcCommandService.submitAndWaitForTransactionId(submissionWithDisclosedContracts)
)
_ <- expectFailedOnProvidedDisclosedContracts(
grpcCommandService.submitAndWaitForTransactionTree(submissionWithDisclosedContracts)
)
} yield {
verifyZeroInteractions(mockCommandService)
succeed
}
}
}
}

View File

@ -8,7 +8,7 @@ import com.codahale.metrics.MetricRegistry
import com.daml.ledger.api.domain.LedgerId
import com.daml.ledger.api.messages.command.submission.SubmitRequest
import com.daml.ledger.api.testing.utils.MockMessages._
import com.daml.ledger.api.v1.commands.{Command, CreateCommand}
import com.daml.ledger.api.v1.commands.{Command, CreateCommand, DisclosedContract}
import com.daml.ledger.api.v1.value.{Identifier, Record, RecordField, Value}
import com.daml.lf.data.Ref
import com.daml.logging.LoggingContext
@ -21,6 +21,7 @@ import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AsyncWordSpec
import scala.concurrent.Future
import scala.util.{Failure, Success}
class GrpcCommandSubmissionServiceSpec
extends AsyncWordSpec
@ -87,6 +88,28 @@ class GrpcCommandSubmissionServiceSpec
requestCaptor.value.commands.submissionId shouldBe Some(generatedSubmissionId)
}
}
"reject submission on explicit disclosure disabled with provided disclosed contracts" in {
val mockCommandSubmissionService = mock[CommandSubmissionService with AutoCloseable]
val submissionWithDisclosedContracts =
aSubmitRequest.update(_.commands.disclosedContracts.set(Seq(DisclosedContract())))
grpcCommandSubmissionService(mockCommandSubmissionService)
.submit(submissionWithDisclosedContracts)
.map { _ =>
verifyZeroInteractions(mockCommandSubmissionService)
succeed
}
.transform {
case Failure(exception)
if exception.getMessage.contains(
"feature in development: disclosed_contracts should not be set"
) =>
Success(succeed)
case other => fail(s"Unexpected result: $other")
}
}
}
private def grpcCommandSubmissionService(
@ -100,6 +123,7 @@ class GrpcCommandSubmissionServiceSpec
maxDeduplicationDuration = () => Some(Duration.ZERO),
submissionIdGenerator = () => Ref.SubmissionId.assertFromString(generatedSubmissionId),
metrics = new Metrics(new MetricRegistry),
explicitDisclosureUnsafeEnabled = false,
)
}

View File

@ -4,6 +4,7 @@
package com.daml.ledger.api.testtool.suites.v1_dev
import com.daml.error.definitions.LedgerApiErrors
import com.daml.ledger.api.refinements.ApiTypes.Party
import com.daml.ledger.api.testtool.infrastructure.Allocation._
import com.daml.ledger.api.testtool.infrastructure.Assertions._
import com.daml.ledger.api.testtool.infrastructure.LedgerTestSuite
@ -100,7 +101,7 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
// Create contract with `owner` as only stakeholder
_ <- ledger.create(owner, WithKey(owner))
withKeyTxIds <- ledger.flatTransactionsByTemplateId(WithKey.id, owner)
withKeyCreate = createdEvents(withKeyTxIds(1)).head
withKeyCreate = createdEvents(withKeyTxIds(0)).head
withKeyDisclosedContract = createEventToDisclosedContract(withKeyCreate)
exerciseByKeyError <- ledger
.submitAndWait(
@ -224,8 +225,8 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
for {
contractId <- ledger1.create(party1, Dummy(party1))
transactions <- ledger1.flatTransactionsByTemplateId(WithKey.id, party1)
create = createdEvents(transactions(1)).head
transactions <- ledger1.flatTransactionsByTemplateId(Dummy.id, party1)
create = createdEvents(transactions(0)).head
disclosedContract = createEventToDisclosedContract(create)
// Submit concurrently two consuming exercise choices (with and without disclosed contract)
@ -266,13 +267,14 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
for {
testContext <- initializeTest(ledger, owner, delegate)
// Exercise a choice using invalid explicit disclosure (bad contract key)
errorBadKey <- testContext
.exerciseFetchDelegated(
testContext.disclosedContract
.update(_.metadata.contractKeyHash := ByteString.copyFromUtf8("badKeyMeta"))
)
.mustFail("using a mismatching contract key hash in metadata")
// // TODO ED: Enable once the check is implemented in command interpretation
// // Exercise a choice using invalid explicit disclosure (bad contract key)
// errorBadKey <- testContext
// .exerciseFetchDelegated(
// testContext.disclosedContract
// .update(_.metadata.contractKeyHash := ByteString.copyFromUtf8("BadKeyBadKeyBadKeyBadKeyBadKey00"))
// )
// .mustFail("using a mismatching contract key hash in metadata")
// Exercise a choice using invalid explicit disclosure (bad ledger time)
errorBadLet <- testContext
@ -290,12 +292,13 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
)
.mustFail("using an invalid disclosed contract payload")
} yield {
assertGrpcError(
errorBadKey,
LedgerApiErrors.ConsistencyErrors.DisclosedContractInvalid,
None,
checkDefiniteAnswerMetadata = true,
)
// // TODO ED: Enable once the check is implemented in command interpretation
// assertGrpcError(
// errorBadKey,
// LedgerApiErrors.ConsistencyErrors.DisclosedContractInvalid,
// None,
// checkDefiniteAnswerMetadata = true,
// )
assertGrpcError(
errorBadLet,
LedgerApiErrors.ConsistencyErrors.DisclosedContractInvalid,
@ -370,15 +373,15 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
)
.mustFail("using a disclosed contract with missing createdAt in contract metadata")
// // TODO ED: Assert missing contract key hash when ledger side metadata validation is implemented
// // Exercise a choice using an invalid disclosed contract (missing key hash in contract metadata for a contract that has a contract key associated)
// errorMissingKeyHash <- testContext
// .exerciseFetchDelegated(
// testContext.disclosedContract.update(_.metadata.contractKeyHash.set(ByteString.EMPTY))
// )
// .mustFail(
// "using a disclosed contract with missing key hash in contract metadata for a contract that has a contract key associated"
// )
// // TODO ED: Assert missing contract key hash when ledger side metadata validation is implemented
// // Exercise a choice using an invalid disclosed contract (missing key hash in contract metadata for a contract that has a contract key associated)
// errorMissingKeyHash <- testContext
// .exerciseFetchDelegated(
// testContext.disclosedContract.update(_.metadata.contractKeyHash.set(ByteString.EMPTY))
// )
// .mustFail(
// "using a disclosed contract with missing key hash in contract metadata for a contract that has a contract key associated"
// )
} yield {
assertGrpcError(
errorMalformedPayload,
@ -430,25 +433,40 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
for {
testContext <- initializeTest(ledger, owner, delegate)
_ <- ledger.create(owner, Dummy(owner))
dummyTxs <- ledger.flatTransactionsByTemplateId(Dummy.id, owner)
dummyCreate = createdEvents(dummyTxs(0)).head
dummyDisclosedContract = createEventToDisclosedContract(dummyCreate)
// Exercise a choice using invalid explicit disclosure (bad contract key)
_ <- testContext
.exerciseFetchDelegated(
testContext.disclosedContract
.update(_.metadata.contractKeyHash := ByteString.copyFromUtf8("badKeyMeta"))
testContext.disclosedContract,
// Provide a superfluous disclosed contract with mismatching key hash
dummyDisclosedContract
.update(
_.metadata.contractKeyHash := ByteString.copyFromUtf8(
"BadKeyBadKeyBadKeyBadKeyBadKey00"
)
),
)
// Exercise a choice using invalid explicit disclosure (bad ledger time)
_ <- testContext
.exerciseFetchDelegated(
testContext.disclosedContract
.update(_.metadata.createdAt := com.google.protobuf.timestamp.Timestamp.of(1, 0))
testContext.disclosedContract,
// Provide a superfluous disclosed contract with mismatching createdAt
dummyDisclosedContract
.update(_.metadata.createdAt := com.google.protobuf.timestamp.Timestamp.of(1, 0)),
)
// Exercise a choice using invalid explicit disclosure (bad payload)
_ <- testContext
.exerciseFetchDelegated(
testContext.disclosedContract
.update(_.arguments := Delegated(delegate, testContext.contractKey).arguments)
testContext.disclosedContract,
// Provide a superfluous disclosed contract with mismatching contract arguments
dummyDisclosedContract
.update(_.arguments := Dummy(delegate).arguments),
)
} yield ()
})
@ -554,8 +572,7 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
"EDFeatureDisabled",
"Submission fails when disclosed contracts provided on feature disabled",
allocate(Parties(2)),
// TODO ED: Toggle after feature flag implementation
// enabled = feature => !feature.explicitDisclosure,
enabled = feature => !feature.explicitDisclosure,
)(implicit ec => { case Participants(Participant(ledger, owner, delegate)) =>
for {
testContext <- initializeTest(ledger, owner, delegate)
@ -593,7 +610,7 @@ final class ExplicitDisclosureIT extends LedgerTestSuite {
verbose = !normalizedDisclosedContract,
)
)
createdEvent = createdEvents(txs(1)).head
createdEvent = createdEvents(txs(0)).head
disclosedContract = createEventToDisclosedContract(createdEvent)
_ <- ledger.submitAndWait(
@ -749,9 +766,18 @@ object ExplicitDisclosureIT {
Command.Command.ExerciseByKey(
ExerciseByKeyCommand(
Some(WithKey.id.unwrap),
Option(Value(Value.Sum.Party(owner.unwrap))),
Option(Value(Value.Sum.Party(Party.unwrap(owner)))),
"WithKey_NoOp",
Option(Value(Value.Sum.Party(party.unwrap))),
Option(
Value(
Value.Sum.Record(
Record(
None,
List(RecordField("", Some(Value(Value.Sum.Party(Party.unwrap(party)))))),
)
)
)
),
)
)
),

View File

@ -43,6 +43,11 @@ class LedgerApiServer(
timeServiceBackendO: Option[TimeServiceBackend],
servicesExecutionContext: ExecutionContextExecutorService,
metrics: Metrics,
// TODO ED: Remove flag once explicit disclosure is deemed stable and all
// backing ledgers implement proper validation against malicious clients.
// Currently, we provide this flag outside the HOCON configuration objects
// in order to ensure that participants cannot be configured to accept explicitly disclosed contracts.
explicitDisclosureUnsafeEnabled: Boolean = false,
)(implicit actorSystem: ActorSystem, materializer: Materializer) {
def owner: ResourceOwner[ApiService] = {
@ -109,6 +114,7 @@ class LedgerApiServer(
ledgerId,
participantConfig.apiServer,
participantId,
explicitDisclosureUnsafeEnabled,
)
} yield apiService
}
@ -127,6 +133,7 @@ class LedgerApiServer(
ledgerId: LedgerId,
apiServerConfig: ApiServerConfig,
participantId: Ref.ParticipantId,
explicitDisclosureUnsafeEnabled: Boolean,
)(implicit
actorSystem: ActorSystem,
loggingContext: LoggingContext,
@ -155,6 +162,7 @@ class LedgerApiServer(
participantId = participantId,
authService = authService,
jwtTimestampLeeway = participantConfig.jwtTimestampLeeway,
explicitDisclosureUnsafeEnabled = explicitDisclosureUnsafeEnabled,
)
}

View File

@ -55,6 +55,7 @@ object ApiServiceOwner {
authService: AuthService,
meteringReportKey: MeteringReportKey = CommunityKey,
jwtTimestampLeeway: Option[JwtTimestampLeeway],
explicitDisclosureUnsafeEnabled: Boolean = false,
)(implicit
actorSystem: ActorSystem,
materializer: Materializer,
@ -114,6 +115,7 @@ object ApiServiceOwner {
userManagementConfig = config.userManagement,
apiStreamShutdownTimeout = config.apiStreamShutdownTimeout,
meteringReportKey = meteringReportKey,
explicitDisclosureUnsafeEnabled = explicitDisclosureUnsafeEnabled,
)(materializer, executionSequencerFactory, loggingContext)
.map(_.withServices(otherServices))
apiService <- new LedgerApiService(

View File

@ -86,6 +86,7 @@ private[daml] object ApiServices {
userManagementConfig: UserManagementConfig,
apiStreamShutdownTimeout: scala.concurrent.duration.Duration,
meteringReportKey: MeteringReportKey,
explicitDisclosureUnsafeEnabled: Boolean,
)(implicit
materializer: Materializer,
esf: ExecutionSequencerFactory,
@ -259,6 +260,7 @@ private[daml] object ApiServices {
commandExecutor,
checkOverloaded,
metrics,
explicitDisclosureUnsafeEnabled = explicitDisclosureUnsafeEnabled,
)
// Note: the command service uses the command submission, command completion, and transaction
@ -282,6 +284,7 @@ private[daml] object ApiServices {
timeProvider = timeProvider,
ledgerConfigurationSubscription = ledgerConfigurationSubscription,
metrics = metrics,
explicitDisclosureUnsafeEnabled = explicitDisclosureUnsafeEnabled,
)
val apiPartyManagementService = ApiPartyManagementService.createApiService(

View File

@ -8,6 +8,7 @@ import com.daml.ledger.api.v1.experimental_features.{
CommandDeduplicationFeatures,
ExperimentalCommitterEventLog,
ExperimentalContractIds,
ExperimentalExplicitDisclosure,
}
case class LedgerFeatures(
@ -17,4 +18,6 @@ case class LedgerFeatures(
contractIdFeatures: ExperimentalContractIds = ExperimentalContractIds.defaultInstance,
committerEventLog: ExperimentalCommitterEventLog =
ExperimentalCommitterEventLog.of(eventLogType = CENTRALIZED),
explicitDisclosure: ExperimentalExplicitDisclosure =
ExperimentalExplicitDisclosure.of(supported = false),
)

View File

@ -208,6 +208,7 @@ private[apiserver] object ApiCommandService {
timeProvider: TimeProvider,
ledgerConfigurationSubscription: LedgerConfigurationSubscription,
metrics: Metrics,
explicitDisclosureUnsafeEnabled: Boolean,
)(implicit
materializer: Materializer,
executionContext: ExecutionContext,
@ -232,6 +233,7 @@ private[apiserver] object ApiCommandService {
maxDeduplicationDuration = () =>
ledgerConfigurationSubscription.latestConfiguration().map(_.maxDeduplicationDuration),
generateSubmissionId = SubmissionIdGenerator.Random,
explicitDisclosureUnsafeEnabled = explicitDisclosureUnsafeEnabled,
)
}

View File

@ -43,6 +43,7 @@ private[apiserver] object ApiSubmissionService {
commandExecutor: CommandExecutor,
checkOverloaded: TelemetryContext => Option[state.SubmissionResult],
metrics: Metrics,
explicitDisclosureUnsafeEnabled: Boolean,
)(implicit
executionContext: ExecutionContext,
loggingContext: LoggingContext,
@ -65,6 +66,7 @@ private[apiserver] object ApiSubmissionService {
ledgerConfigurationSubscription.latestConfiguration().map(_.maxDeduplicationDuration),
submissionIdGenerator = SubmissionIdGenerator.Random,
metrics = metrics,
explicitDisclosureUnsafeEnabled = explicitDisclosureUnsafeEnabled,
)
}

View File

@ -74,7 +74,7 @@ private[apiserver] final class ApiVersionService private (
optionalLedgerId = Some(ExperimentalOptionalLedgerId()),
contractIds = Some(ledgerFeatures.contractIdFeatures),
committerEventLog = Some(ledgerFeatures.committerEventLog),
explicitDisclosure = None, // TODO[ED]: Wire-up with participant configuration flag
explicitDisclosure = Some(ledgerFeatures.explicitDisclosure),
)
),
)

View File

@ -575,6 +575,24 @@ server_conformance_test(
],
)
SERVERS_EXPLICIT_DISCLOSURE = {
"h2database": {
"binary": ":app",
"server_args": ["explicit-disclosure-unsafe-enabled run"],
},
"postgresql": {
"binary": ":conformance-test-postgres-bin",
"server_args": ["explicit-disclosure-unsafe-enabled run -c $(rootpath :postgres.conf)"],
"extra_data": [":postgres.conf"],
},
"oracle": {
"binary": ":conformance-test-oracle-bin",
"tags": oracle_tags,
"server_args": ["explicit-disclosure-unsafe-enabled run -c $(rootpath :oracle.conf)"],
"extra_data": [":oracle.conf"],
},
}
server_conformance_test(
name = "conformance-test-explicit-disclosure",
hocon = True,
@ -584,7 +602,32 @@ server_conformance_test(
lf_versions = [
"1.dev",
],
servers = SERVERS,
servers = SERVERS_EXPLICIT_DISCLOSURE,
test_tool_args = [
"--verbose",
"--include=ExplicitDisclosureIT",
# TODO ED: Enable the following test once https://github.com/digital-asset/daml/issues/14200 is solved
"--exclude=ExplicitDisclosureIT:EDDuplicates",
# TODO ED: Enable the following tests once https://github.com/digital-asset/daml/issues/14199 is solved
"--exclude=ExplicitDisclosureIT:EDExerciseByKeyDisclosedContract",
"--exclude=ExplicitDisclosureIT:EDLocalKeyVisibility",
"--exclude=ExplicitDisclosureIT:EDNonNormalizedDisclosedContract",
"--exclude=ExplicitDisclosureIT:EDNormalizedDisclosedContract",
],
)
# Suite asserting that tests targeting disabled explicit disclosure are successful
# (i.e. test asserting that submissions using disclosed contracts are rejected)
# TODO ED: Remove once feature deemed stable
conformance_test(
name = "conformance-test-explicit-disclosure-disabled-lf-dev-h2",
hocon = True,
lf_versions = [
"1.dev",
],
ports = [6865],
server = ":app",
server_args = ["run"],
test_tool_args = [
"--verbose",
"--include=ExplicitDisclosureIT",

View File

@ -9,6 +9,13 @@ import com.daml.logging.ContextualizedLogger
import com.daml.resources.ProgramResource
object CliSandboxOnXRunner {
// TODO ED: Remove flag once explicit disclosure is deemed stable and all
// backing ledgers implement proper validation against malicious clients
//
// NOTE: The flag is explicitly extracted out of the provided program arguments
// and not passed via the HOCON config in order to prevent accidental
// enablement, which could render participants vulnerable to malicious clients.
private val ExplicitDisclosureEnabledArg = "explicit-disclosure-unsafe-enabled"
private val logger = ContextualizedLogger.get(getClass)
val RunnerName = "sandbox-on-x"
@ -19,14 +26,23 @@ object CliSandboxOnXRunner {
args: collection.Seq[String],
manipulateConfig: CliConfig[BridgeConfig] => CliConfig[BridgeConfig] = identity,
): Unit = {
val explicitDisclosureEnabled = args.contains(ExplicitDisclosureEnabledArg)
val config = CliConfig
.parse(RunnerName, BridgeConfig.Parser, BridgeConfig.Default, args)
.parse(
RunnerName,
BridgeConfig.Parser,
BridgeConfig.Default,
args.filterNot(_ == ExplicitDisclosureEnabledArg),
)
.map(manipulateConfig)
.getOrElse(sys.exit(1))
runProgram(config)
runProgram(config, explicitDisclosureEnabled)
}
private def runProgram(config: CliConfig[BridgeConfig]): Unit =
private def runProgram(
config: CliConfig[BridgeConfig],
explicitDisclosureUnsafeEnabled: Boolean,
): Unit =
config.mode match {
case Mode.Run =>
SandboxOnXConfig
@ -34,7 +50,9 @@ object CliSandboxOnXRunner {
.fold(
System.err.println,
{ sandboxOnXConfig =>
program(sox(new BridgeConfigAdaptor, sandboxOnXConfig))
program(
sox(new BridgeConfigAdaptor, sandboxOnXConfig, explicitDisclosureUnsafeEnabled)
)
},
)
case Mode.DumpIndexMetadata(jdbcUrls) =>
@ -46,12 +64,13 @@ object CliSandboxOnXRunner {
case Mode.RunLegacyCliConfig =>
val configAdaptor: BridgeConfigAdaptor = new BridgeConfigAdaptor
val sandboxOnXConfig: SandboxOnXConfig = SandboxOnXConfig.fromLegacy(configAdaptor, config)
program(sox(configAdaptor, sandboxOnXConfig))
program(sox(configAdaptor, sandboxOnXConfig, explicitDisclosureUnsafeEnabled))
}
private def sox(
configAdaptor: BridgeConfigAdaptor,
sandboxOnXConfig: SandboxOnXConfig,
explicitDisclosureUnsafeEnabled: Boolean,
): ResourceOwner[Unit] = {
Banner.show(Console.out)
logger.withoutContext.info(
@ -62,6 +81,7 @@ object CliSandboxOnXRunner {
configAdaptor,
sandboxOnXConfig.ledger,
sandboxOnXConfig.bridge,
explicitDisclosureUnsafeEnabled,
)
.map(_ => ())
}

View File

@ -21,6 +21,7 @@ import com.daml.ledger.api.v1.experimental_features.{
CommandDeduplicationPeriodSupport,
CommandDeduplicationType,
ExperimentalContractIds,
ExperimentalExplicitDisclosure,
}
import com.daml.ledger.offset.Offset
import com.daml.ledger.participant.state.index.v2.IndexService
@ -56,16 +57,20 @@ object SandboxOnXRunner {
configAdaptor: BridgeConfigAdaptor,
config: Config,
bridgeConfig: BridgeConfig,
explicitDisclosureUnsafeEnabled: Boolean = false,
): ResourceOwner[Port] =
new ResourceOwner[Port] {
override def acquire()(implicit context: ResourceContext): Resource[Port] =
SandboxOnXRunner.run(bridgeConfig, config, configAdaptor).acquire()
SandboxOnXRunner
.run(bridgeConfig, config, configAdaptor, explicitDisclosureUnsafeEnabled)
.acquire()
}
def run(
bridgeConfig: BridgeConfig,
config: Config,
configAdaptor: BridgeConfigAdaptor,
explicitDisclosureUnsafeEnabled: Boolean,
): ResourceOwner[Port] = newLoggingContext { implicit loggingContext =>
implicit val actorSystem: ActorSystem = ActorSystem(RunnerName)
implicit val materializer: Materializer = Materializer(actorSystem)
@ -111,6 +116,7 @@ object SandboxOnXRunner {
contractIdFeatures = ExperimentalContractIds.of(
v1 = ExperimentalContractIds.ContractIdV1Support.NON_SUFFIXED
),
explicitDisclosure = ExperimentalExplicitDisclosure.of(explicitDisclosureUnsafeEnabled),
),
authService = configAdaptor.authService(participantConfig),
buildWriteService = buildWriteServiceLambda,
@ -127,6 +133,7 @@ object SandboxOnXRunner {
timeServiceBackendO = timeServiceBackendO,
servicesExecutionContext = servicesExecutionContext,
metrics = metrics,
explicitDisclosureUnsafeEnabled = explicitDisclosureUnsafeEnabled,
)(actorSystem, materializer).owner
} yield {
logInitializationHeader(