mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-19 16:57:40 +03:00
update canton to 20240709.13636.vd03d4972 (#19547)
Co-authored-by: Azure Pipelines Daml Build <support@digitalasset.com> Co-authored-by: Remy Haemmerle <Remy.Haemmerle@daml.com>
This commit is contained in:
parent
2d6b7f87bc
commit
5078d1e043
@ -11,7 +11,7 @@ import "scalapb/scalapb.proto";
|
|||||||
|
|
||||||
// Schema definition for the exported ACS snapshot
|
// Schema definition for the exported ACS snapshot
|
||||||
message ActiveContract {
|
message ActiveContract {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// The ID of the domain where the contract was assigned at the time of the export
|
// The ID of the domain where the contract was assigned at the time of the export
|
||||||
// Required
|
// Required
|
||||||
|
@ -5,8 +5,8 @@ object ProtocolVersionAnnotation {
|
|||||||
/** Type-level marker for whether a protocol version is stable */
|
/** Type-level marker for whether a protocol version is stable */
|
||||||
sealed trait Status
|
sealed trait Status
|
||||||
|
|
||||||
/** Marker for unstable protocol versions */
|
/** Marker for alpha protocol versions */
|
||||||
sealed trait Unstable extends Status
|
sealed trait Alpha extends Status
|
||||||
|
|
||||||
/** Marker for stable protocol versions */
|
/** Marker for stable protocol versions */
|
||||||
sealed trait Stable extends Status
|
sealed trait Stable extends Status
|
||||||
@ -19,17 +19,17 @@ object ProtocolVersionAnnotation {
|
|||||||
* that are used in some stable protocol versions
|
* that are used in some stable protocol versions
|
||||||
*
|
*
|
||||||
* Implements both [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Stable]] and
|
* Implements both [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Stable]] and
|
||||||
* [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Unstable]] means that [[StableProtoVersion]]
|
* [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Alpha]] means that [[StableProtoVersion]]
|
||||||
* messages can be used in stable and unstable protocol versions.
|
* messages can be used in stable and alpha protocol versions.
|
||||||
*/
|
*/
|
||||||
trait StableProtoVersion
|
trait StableProtoVersion
|
||||||
extends ProtocolVersionAnnotation.Stable
|
extends ProtocolVersionAnnotation.Stable
|
||||||
with ProtocolVersionAnnotation.Unstable
|
with ProtocolVersionAnnotation.Alpha
|
||||||
|
|
||||||
/** Marker trait for Protobuf messages generated by scalapb
|
/** Marker trait for Protobuf messages generated by scalapb
|
||||||
* that are used only unstable protocol versions
|
* that are used only alpha protocol versions
|
||||||
*/
|
*/
|
||||||
trait UnstableProtoVersion extends ProtocolVersionAnnotation.Unstable
|
trait AlphaProtoVersion extends ProtocolVersionAnnotation.Alpha
|
||||||
|
|
||||||
/** Marker trait for Protobuf messages generated by scalapb
|
/** Marker trait for Protobuf messages generated by scalapb
|
||||||
* that are used only to persist data in node storage.
|
* that are used only to persist data in node storage.
|
||||||
|
@ -4,12 +4,23 @@
|
|||||||
package com.digitalasset.canton.admin.api.client.commands
|
package com.digitalasset.canton.admin.api.client.commands
|
||||||
|
|
||||||
import com.digitalasset.canton.domain.sequencing.sequencer.block.bftordering.admin.EnterpriseSequencerBftAdminData.{
|
import com.digitalasset.canton.domain.sequencing.sequencer.block.bftordering.admin.EnterpriseSequencerBftAdminData.{
|
||||||
|
OrderingTopology,
|
||||||
PeerNetworkStatus,
|
PeerNetworkStatus,
|
||||||
endpointToProto,
|
endpointToProto,
|
||||||
}
|
}
|
||||||
import com.digitalasset.canton.networking.Endpoint
|
import com.digitalasset.canton.networking.Endpoint
|
||||||
import com.digitalasset.canton.sequencer.admin.v30
|
import com.digitalasset.canton.sequencer.admin.v30.SequencerBftAdministrationServiceGrpc.SequencerBftAdministrationServiceStub
|
||||||
import com.digitalasset.canton.sequencer.admin.v30.*
|
import com.digitalasset.canton.sequencer.admin.v30.{
|
||||||
|
AddPeerEndpointRequest,
|
||||||
|
AddPeerEndpointResponse,
|
||||||
|
GetOrderingTopologyRequest,
|
||||||
|
GetOrderingTopologyResponse,
|
||||||
|
GetPeerNetworkStatusRequest,
|
||||||
|
GetPeerNetworkStatusResponse,
|
||||||
|
RemovePeerEndpointRequest,
|
||||||
|
RemovePeerEndpointResponse,
|
||||||
|
SequencerBftAdministrationServiceGrpc,
|
||||||
|
}
|
||||||
import io.grpc.ManagedChannel
|
import io.grpc.ManagedChannel
|
||||||
|
|
||||||
import scala.concurrent.Future
|
import scala.concurrent.Future
|
||||||
@ -19,11 +30,11 @@ object EnterpriseSequencerBftAdminCommands {
|
|||||||
abstract class BaseSequencerBftAdministrationCommand[Req, Rep, Res]
|
abstract class BaseSequencerBftAdministrationCommand[Req, Rep, Res]
|
||||||
extends GrpcAdminCommand[Req, Rep, Res] {
|
extends GrpcAdminCommand[Req, Rep, Res] {
|
||||||
override type Svc =
|
override type Svc =
|
||||||
v30.SequencerBftAdministrationServiceGrpc.SequencerBftAdministrationServiceStub
|
SequencerBftAdministrationServiceStub
|
||||||
override def createService(
|
override def createService(
|
||||||
channel: ManagedChannel
|
channel: ManagedChannel
|
||||||
): v30.SequencerBftAdministrationServiceGrpc.SequencerBftAdministrationServiceStub =
|
): SequencerBftAdministrationServiceStub =
|
||||||
v30.SequencerBftAdministrationServiceGrpc.stub(channel)
|
SequencerBftAdministrationServiceGrpc.stub(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class AddPeerEndpoint(endpoint: Endpoint)
|
final case class AddPeerEndpoint(endpoint: Endpoint)
|
||||||
@ -38,7 +49,7 @@ object EnterpriseSequencerBftAdminCommands {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override def submitRequest(
|
override def submitRequest(
|
||||||
service: v30.SequencerBftAdministrationServiceGrpc.SequencerBftAdministrationServiceStub,
|
service: SequencerBftAdministrationServiceStub,
|
||||||
request: AddPeerEndpointRequest,
|
request: AddPeerEndpointRequest,
|
||||||
): Future[AddPeerEndpointResponse] =
|
): Future[AddPeerEndpointResponse] =
|
||||||
service.addPeerEndpoint(request)
|
service.addPeerEndpoint(request)
|
||||||
@ -61,7 +72,7 @@ object EnterpriseSequencerBftAdminCommands {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override def submitRequest(
|
override def submitRequest(
|
||||||
service: v30.SequencerBftAdministrationServiceGrpc.SequencerBftAdministrationServiceStub,
|
service: SequencerBftAdministrationServiceStub,
|
||||||
request: RemovePeerEndpointRequest,
|
request: RemovePeerEndpointRequest,
|
||||||
): Future[RemovePeerEndpointResponse] =
|
): Future[RemovePeerEndpointResponse] =
|
||||||
service.removePeerEndpoint(request)
|
service.removePeerEndpoint(request)
|
||||||
@ -84,7 +95,7 @@ object EnterpriseSequencerBftAdminCommands {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override def submitRequest(
|
override def submitRequest(
|
||||||
service: v30.SequencerBftAdministrationServiceGrpc.SequencerBftAdministrationServiceStub,
|
service: SequencerBftAdministrationServiceStub,
|
||||||
request: GetPeerNetworkStatusRequest,
|
request: GetPeerNetworkStatusRequest,
|
||||||
): Future[GetPeerNetworkStatusResponse] =
|
): Future[GetPeerNetworkStatusResponse] =
|
||||||
service.getPeerNetworkStatus(request)
|
service.getPeerNetworkStatus(request)
|
||||||
@ -94,4 +105,27 @@ object EnterpriseSequencerBftAdminCommands {
|
|||||||
): Either[String, PeerNetworkStatus] =
|
): Either[String, PeerNetworkStatus] =
|
||||||
PeerNetworkStatus.fromProto(response)
|
PeerNetworkStatus.fromProto(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final case class GetOrderingTopology()
|
||||||
|
extends BaseSequencerBftAdministrationCommand[
|
||||||
|
GetOrderingTopologyRequest,
|
||||||
|
GetOrderingTopologyResponse,
|
||||||
|
OrderingTopology,
|
||||||
|
] {
|
||||||
|
|
||||||
|
override def createRequest(): Either[String, GetOrderingTopologyRequest] = Right(
|
||||||
|
GetOrderingTopologyRequest.of()
|
||||||
|
)
|
||||||
|
|
||||||
|
override def submitRequest(
|
||||||
|
service: SequencerBftAdministrationServiceStub,
|
||||||
|
request: GetOrderingTopologyRequest,
|
||||||
|
): Future[GetOrderingTopologyResponse] =
|
||||||
|
service.getOrderingTopology(request)
|
||||||
|
|
||||||
|
override def handleResponse(
|
||||||
|
response: GetOrderingTopologyResponse
|
||||||
|
): Either[String, OrderingTopology] =
|
||||||
|
OrderingTopology.fromProto(response)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ final case class RetentionPeriodDefaults(
|
|||||||
* @param manualStart If set to true, the nodes have to be manually started via console (default false)
|
* @param manualStart If set to true, the nodes have to be manually started via console (default false)
|
||||||
* @param startupParallelism Start up to N nodes in parallel (default is num-threads)
|
* @param startupParallelism Start up to N nodes in parallel (default is num-threads)
|
||||||
* @param nonStandardConfig don't fail config validation on non-standard configuration settings
|
* @param nonStandardConfig don't fail config validation on non-standard configuration settings
|
||||||
* @param devVersionSupport If true, allow domain nodes to use unstable protocol versions and participant nodes to connect to such domains
|
* @param alphaVersionSupport If true, allow domain nodes to use alpha protocol versions and participant nodes to connect to such domains
|
||||||
* @param betaVersionSupport If true, allow domain nodes to use beta protocol versions and participant nodes to connect to such domains
|
* @param betaVersionSupport If true, allow domain nodes to use beta protocol versions and participant nodes to connect to such domains
|
||||||
* @param timeouts Sets the timeouts used for processing and console
|
* @param timeouts Sets the timeouts used for processing and console
|
||||||
* @param portsFile A ports file name, where the ports of all participants will be written to after startup
|
* @param portsFile A ports file name, where the ports of all participants will be written to after startup
|
||||||
@ -252,7 +252,7 @@ final case class CantonParameters(
|
|||||||
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
||||||
nonStandardConfig: Boolean = true,
|
nonStandardConfig: Boolean = true,
|
||||||
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
||||||
devVersionSupport: Boolean = true,
|
alphaVersionSupport: Boolean = true,
|
||||||
betaVersionSupport: Boolean = false,
|
betaVersionSupport: Boolean = false,
|
||||||
portsFile: Option[String] = None,
|
portsFile: Option[String] = None,
|
||||||
timeouts: TimeoutSettings = TimeoutSettings(),
|
timeouts: TimeoutSettings = TimeoutSettings(),
|
||||||
@ -380,7 +380,7 @@ trait CantonConfig {
|
|||||||
participantParameters.transferTimeProofFreshnessProportion,
|
participantParameters.transferTimeProofFreshnessProportion,
|
||||||
protocolConfig = ParticipantProtocolConfig(
|
protocolConfig = ParticipantProtocolConfig(
|
||||||
minimumProtocolVersion = participantParameters.minimumProtocolVersion.map(_.unwrap),
|
minimumProtocolVersion = participantParameters.minimumProtocolVersion.map(_.unwrap),
|
||||||
devVersionSupport = participantParameters.devVersionSupport,
|
alphaVersionSupport = participantParameters.alphaVersionSupport,
|
||||||
betaVersionSupport = participantParameters.BetaVersionSupport,
|
betaVersionSupport = participantParameters.BetaVersionSupport,
|
||||||
dontWarnOnDeprecatedPV = participantParameters.dontWarnOnDeprecatedPV,
|
dontWarnOnDeprecatedPV = participantParameters.dontWarnOnDeprecatedPV,
|
||||||
),
|
),
|
||||||
@ -523,7 +523,7 @@ private[canton] object CantonNodeParameterConverter {
|
|||||||
|
|
||||||
def protocol(parent: CantonConfig, config: ProtocolConfig): CantonNodeParameters.Protocol =
|
def protocol(parent: CantonConfig, config: ProtocolConfig): CantonNodeParameters.Protocol =
|
||||||
CantonNodeParameters.Protocol.Impl(
|
CantonNodeParameters.Protocol.Impl(
|
||||||
devVersionSupport = parent.parameters.devVersionSupport || config.devVersionSupport,
|
alphaVersionSupport = parent.parameters.alphaVersionSupport || config.alphaVersionSupport,
|
||||||
betaVersionSupport = parent.parameters.betaVersionSupport || config.betaVersionSupport,
|
betaVersionSupport = parent.parameters.betaVersionSupport || config.betaVersionSupport,
|
||||||
dontWarnOnDeprecatedPV = config.dontWarnOnDeprecatedPV,
|
dontWarnOnDeprecatedPV = config.dontWarnOnDeprecatedPV,
|
||||||
)
|
)
|
||||||
|
@ -184,14 +184,14 @@ object CommunityConfigValidations
|
|||||||
name: String,
|
name: String,
|
||||||
nodeTypeName: String,
|
nodeTypeName: String,
|
||||||
nonStandardConfig: Boolean,
|
nonStandardConfig: Boolean,
|
||||||
devVersionSupport: Boolean,
|
alphaVersionSupport: Boolean,
|
||||||
): Validated[NonEmpty[Seq[String]], Unit] = {
|
): Validated[NonEmpty[Seq[String]], Unit] = {
|
||||||
Validated.cond(
|
Validated.cond(
|
||||||
nonStandardConfig || !devVersionSupport,
|
nonStandardConfig || !alphaVersionSupport,
|
||||||
(),
|
(),
|
||||||
NonEmpty(
|
NonEmpty(
|
||||||
Seq,
|
Seq,
|
||||||
s"Enabling dev-version-support for $nodeTypeName $name requires you to explicitly set canton.parameters.non-standard-config = yes",
|
s"Enabling alpha-version-support for $nodeTypeName $name requires you to explicitly set canton.parameters.non-standard-config = yes",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ object CommunityConfigValidations
|
|||||||
name = name.unwrap,
|
name = name.unwrap,
|
||||||
nodeTypeName = nodeConfig.nodeTypeName,
|
nodeTypeName = nodeConfig.nodeTypeName,
|
||||||
nonStandardConfig = config.parameters.nonStandardConfig,
|
nonStandardConfig = config.parameters.nonStandardConfig,
|
||||||
devVersionSupport = nodeConfig.parameters.devVersionSupport,
|
alphaVersionSupport = nodeConfig.parameters.alphaVersionSupport,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,10 @@ import com.digitalasset.canton.domain.sequencing.config.{
|
|||||||
RemoteSequencerConfig,
|
RemoteSequencerConfig,
|
||||||
SequencerNodeConfigCommon,
|
SequencerNodeConfigCommon,
|
||||||
}
|
}
|
||||||
import com.digitalasset.canton.domain.sequencing.sequencer.block.bftordering.admin.EnterpriseSequencerBftAdminData.PeerNetworkStatus
|
import com.digitalasset.canton.domain.sequencing.sequencer.block.bftordering.admin.EnterpriseSequencerBftAdminData.{
|
||||||
|
OrderingTopology,
|
||||||
|
PeerNetworkStatus,
|
||||||
|
}
|
||||||
import com.digitalasset.canton.domain.sequencing.sequencer.{
|
import com.digitalasset.canton.domain.sequencing.sequencer.{
|
||||||
SequencerClients,
|
SequencerClients,
|
||||||
SequencerPruningStatus,
|
SequencerPruningStatus,
|
||||||
@ -1162,6 +1165,12 @@ abstract class SequencerReference(
|
|||||||
consoleEnvironment.run {
|
consoleEnvironment.run {
|
||||||
runner.adminCommand(EnterpriseSequencerBftAdminCommands.GetPeerNetworkStatus(endpoints))
|
runner.adminCommand(EnterpriseSequencerBftAdminCommands.GetPeerNetworkStatus(endpoints))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Help.Summary("Get the currently active ordering topology")
|
||||||
|
def get_ordering_topology(): OrderingTopology =
|
||||||
|
consoleEnvironment.run {
|
||||||
|
runner.adminCommand(EnterpriseSequencerBftAdminCommands.GetOrderingTopology())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,9 +562,7 @@ class LocalSecretKeyAdministration(
|
|||||||
.leftMap(err => s"Error retrieving private key [$fingerprint] $err")
|
.leftMap(err => s"Error retrieving private key [$fingerprint] $err")
|
||||||
publicKey <- crypto.cryptoPublicStore
|
publicKey <- crypto.cryptoPublicStore
|
||||||
.publicKey(fingerprint)
|
.publicKey(fingerprint)
|
||||||
.leftMap(_.toString)
|
.toRight(s"Error retrieving public key [$fingerprint]: no public key found")
|
||||||
.subflatMap(_.toRight(s"no public key found for [$fingerprint]"))
|
|
||||||
.leftMap(err => s"Error retrieving public key [$fingerprint] $err")
|
|
||||||
keyPair: CryptoKeyPair[PublicKey, PrivateKey] = (publicKey, privateKey) match {
|
keyPair: CryptoKeyPair[PublicKey, PrivateKey] = (publicKey, privateKey) match {
|
||||||
case (pub: SigningPublicKey, pkey: SigningPrivateKey) =>
|
case (pub: SigningPublicKey, pkey: SigningPrivateKey) =>
|
||||||
new SigningKeyPair(pub, pkey)
|
new SigningKeyPair(pub, pkey)
|
||||||
|
@ -206,7 +206,7 @@ class ManagedNodes[
|
|||||||
for {
|
for {
|
||||||
cAndP <- configAndParams(name)
|
cAndP <- configAndParams(name)
|
||||||
(config, params) = cAndP
|
(config, params) = cAndP
|
||||||
_ <- runMigration(name, config.storage, params.devVersionSupport)
|
_ <- runMigration(name, config.storage, params.alphaVersionSupport)
|
||||||
} yield ()
|
} yield ()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -216,7 +216,7 @@ class ManagedNodes[
|
|||||||
for {
|
for {
|
||||||
cAndP <- configAndParams(name)
|
cAndP <- configAndParams(name)
|
||||||
(config, params) = cAndP
|
(config, params) = cAndP
|
||||||
_ <- runRepairMigration(name, config.storage, params.devVersionSupport)
|
_ <- runRepairMigration(name, config.storage, params.alphaVersionSupport)
|
||||||
} yield ()
|
} yield ()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -299,7 +299,7 @@ class ManagedNodes[
|
|||||||
params: CantonNodeParameters,
|
params: CantonNodeParameters,
|
||||||
): Either[StartupError, Unit] =
|
): Either[StartupError, Unit] =
|
||||||
runIfUsingDatabase[Id](storageConfig) { dbConfig =>
|
runIfUsingDatabase[Id](storageConfig) { dbConfig =>
|
||||||
val migrations = migrationsFactory.create(dbConfig, name, params.devVersionSupport)
|
val migrations = migrationsFactory.create(dbConfig, name, params.alphaVersionSupport)
|
||||||
import TraceContext.Implicits.Empty.*
|
import TraceContext.Implicits.Empty.*
|
||||||
logger.info(s"Setting up database schemas for $name")
|
logger.info(s"Setting up database schemas for $name")
|
||||||
|
|
||||||
@ -332,11 +332,11 @@ class ManagedNodes[
|
|||||||
private def runMigration(
|
private def runMigration(
|
||||||
name: InstanceName,
|
name: InstanceName,
|
||||||
storageConfig: StorageConfig,
|
storageConfig: StorageConfig,
|
||||||
devVersionSupport: Boolean,
|
alphaVersionSupport: Boolean,
|
||||||
): Either[StartupError, Unit] =
|
): Either[StartupError, Unit] =
|
||||||
runIfUsingDatabase[Id](storageConfig) { dbConfig =>
|
runIfUsingDatabase[Id](storageConfig) { dbConfig =>
|
||||||
migrationsFactory
|
migrationsFactory
|
||||||
.create(dbConfig, name, devVersionSupport)
|
.create(dbConfig, name, alphaVersionSupport)
|
||||||
.migrateDatabase()
|
.migrateDatabase()
|
||||||
.leftMap(FailedDatabaseMigration(name, _))
|
.leftMap(FailedDatabaseMigration(name, _))
|
||||||
.value
|
.value
|
||||||
@ -346,11 +346,11 @@ class ManagedNodes[
|
|||||||
private def runRepairMigration(
|
private def runRepairMigration(
|
||||||
name: InstanceName,
|
name: InstanceName,
|
||||||
storageConfig: StorageConfig,
|
storageConfig: StorageConfig,
|
||||||
devVersionSupport: Boolean,
|
alphaVersionSupport: Boolean,
|
||||||
): Either[StartupError, Unit] =
|
): Either[StartupError, Unit] =
|
||||||
runIfUsingDatabase[Id](storageConfig) { dbConfig =>
|
runIfUsingDatabase[Id](storageConfig) { dbConfig =>
|
||||||
migrationsFactory
|
migrationsFactory
|
||||||
.create(dbConfig, name, devVersionSupport)
|
.create(dbConfig, name, alphaVersionSupport)
|
||||||
.repairFlywayMigration()
|
.repairFlywayMigration()
|
||||||
.leftMap(FailedDatabaseRepairMigration(name, _))
|
.leftMap(FailedDatabaseRepairMigration(name, _))
|
||||||
.value
|
.value
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
// anymore.
|
// anymore.
|
||||||
_shared {
|
_shared {
|
||||||
participant-dev-params = {
|
participant-dev-params = {
|
||||||
dev-version-support = true
|
alpha-version-support = true
|
||||||
}
|
}
|
||||||
// domain parameters config
|
// domain parameters config
|
||||||
domain-dev-params = {
|
domain-dev-params = {
|
||||||
dev-version-support = true
|
alpha-version-support = true
|
||||||
protocol-version = dev
|
protocol-version = dev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
canton.parameters {
|
canton.parameters {
|
||||||
non-standard-config = yes
|
non-standard-config = yes
|
||||||
dev-version-support = yes
|
alpha-version-support = yes
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
canton.parameters {
|
||||||
|
# turn on non-standard configuration support
|
||||||
|
non-standard-config = yes
|
||||||
|
|
||||||
|
# turn on support of alpha version support for domain nodes
|
||||||
|
alpha-version-support = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
canton.participants.participant1.parameters = {
|
||||||
|
# enable alpha version support on the participant (this will allow the participant to connect to a domain running protocol version dev or any other alpha protocol)
|
||||||
|
# and it will turn on support for unsafe daml lf dev versions
|
||||||
|
# not to be used in production and requires you to define non-standard-config = yes
|
||||||
|
alpha-version-support = yes
|
||||||
|
}
|
@ -2,13 +2,13 @@ canton.parameters {
|
|||||||
# turn on non-standard configuration support
|
# turn on non-standard configuration support
|
||||||
non-standard-config = yes
|
non-standard-config = yes
|
||||||
|
|
||||||
# turn on support of development version support for domain nodes
|
# turn on support of alpha version support for domain nodes
|
||||||
dev-version-support = yes
|
alpha-version-support = yes
|
||||||
}
|
}
|
||||||
|
|
||||||
canton.participants.participant1.parameters = {
|
canton.participants.participant1.parameters = {
|
||||||
# enable dev version on the participant (this will allow the participant to connect to a domain with dev protocol version)
|
# enable alpha version support on the participant (this will allow the participant to connect to a domain with dev protocol version)
|
||||||
# and it will turn on support for unsafe daml lf dev versions
|
# and it will turn on support for unsafe daml lf dev versions
|
||||||
# not to be used in production and requires you to define non-standard-config = yes
|
# not to be used in production and requires you to define non-standard-config = yes
|
||||||
dev-version-support = yes
|
alpha-version-support = yes
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ class NodesTest extends FixtureAnyWordSpec with BaseTest with HasExecutionContex
|
|||||||
override def batching: BatchingConfig = BatchingConfig()
|
override def batching: BatchingConfig = BatchingConfig()
|
||||||
override def caching: CachingConfigs = CachingConfigs()
|
override def caching: CachingConfigs = CachingConfigs()
|
||||||
override def useUnifiedSequencer: Boolean = false
|
override def useUnifiedSequencer: Boolean = false
|
||||||
override def devVersionSupport: Boolean = false
|
override def alphaVersionSupport: Boolean = false
|
||||||
override def watchdog: Option[WatchdogConfig] = None
|
override def watchdog: Option[WatchdogConfig] = None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ class NodesTest extends FixtureAnyWordSpec with BaseTest with HasExecutionContex
|
|||||||
nonStandardConfig: Boolean = false,
|
nonStandardConfig: Boolean = false,
|
||||||
dbMigrateAndStart: Boolean = false,
|
dbMigrateAndStart: Boolean = false,
|
||||||
disableUpgradeValidation: Boolean = false,
|
disableUpgradeValidation: Boolean = false,
|
||||||
devVersionSupport: Boolean = false,
|
alphaVersionSupport: Boolean = false,
|
||||||
betaVersionSupport: Boolean = false,
|
betaVersionSupport: Boolean = false,
|
||||||
dontWarnOnDeprecatedPV: Boolean = false,
|
dontWarnOnDeprecatedPV: Boolean = false,
|
||||||
initialProtocolVersion: ProtocolVersion = testedProtocolVersion,
|
initialProtocolVersion: ProtocolVersion = testedProtocolVersion,
|
||||||
|
@ -202,7 +202,7 @@ message AcknowledgeSignedRequest {
|
|||||||
message AcknowledgeSignedResponse {}
|
message AcknowledgeSignedResponse {}
|
||||||
|
|
||||||
message DownloadTopologyStateForInitRequest {
|
message DownloadTopologyStateForInitRequest {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
string member = 1;
|
string member = 1;
|
||||||
}
|
}
|
||||||
@ -212,7 +212,7 @@ message DownloadTopologyStateForInitResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message GetTrafficStateForMemberRequest {
|
message GetTrafficStateForMemberRequest {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// Member for which to get the traffic state
|
// Member for which to get the traffic state
|
||||||
string member = 1;
|
string member = 1;
|
||||||
@ -221,7 +221,7 @@ message GetTrafficStateForMemberRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message GetTrafficStateForMemberResponse {
|
message GetTrafficStateForMemberResponse {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.protocol.v30.TrafficState traffic_state = 1;
|
com.digitalasset.canton.protocol.v30.TrafficState traffic_state = 1;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ message GlobalKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message AggregationRule {
|
message AggregationRule {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// Members who are allowed to send a request for the underlying aggregation.
|
// Members who are allowed to send a request for the underlying aggregation.
|
||||||
// Must contain SubmissionRequest.sender, otherwise the request is rejected.
|
// Must contain SubmissionRequest.sender, otherwise the request is rejected.
|
||||||
|
@ -11,7 +11,7 @@ import "scalapb/scalapb.proto";
|
|||||||
// Definition of the ConfirmationResponse message which is shared between the transaction and transfer protocol
|
// Definition of the ConfirmationResponse message which is shared between the transaction and transfer protocol
|
||||||
|
|
||||||
message LocalVerdict {
|
message LocalVerdict {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
VerdictCode code = 1;
|
VerdictCode code = 1;
|
||||||
google.rpc.Status reason = 2; // ok iff code is approve
|
google.rpc.Status reason = 2; // ok iff code is approve
|
||||||
@ -25,7 +25,7 @@ message LocalVerdict {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message ConfirmationResponse {
|
message ConfirmationResponse {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
int64 request_id = 1; // in microseconds of UTC time since Unix epoch
|
int64 request_id = 1; // in microseconds of UTC time since Unix epoch
|
||||||
string sender = 2;
|
string sender = 2;
|
||||||
|
@ -47,7 +47,7 @@ enum OnboardingRestriction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message DynamicDomainParameters {
|
message DynamicDomainParameters {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
google.protobuf.Duration confirmation_response_timeout = 1;
|
google.protobuf.Duration confirmation_response_timeout = 1;
|
||||||
google.protobuf.Duration mediator_reaction_timeout = 2;
|
google.protobuf.Duration mediator_reaction_timeout = 2;
|
||||||
|
@ -35,7 +35,7 @@ message MediatorReject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message Verdict {
|
message Verdict {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
oneof some_verdict {
|
oneof some_verdict {
|
||||||
google.protobuf.Empty approve = 1;
|
google.protobuf.Empty approve = 1;
|
||||||
@ -46,7 +46,7 @@ message Verdict {
|
|||||||
|
|
||||||
// This covers transactions and transfers
|
// This covers transactions and transfers
|
||||||
message ConfirmationResultMessage {
|
message ConfirmationResultMessage {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
string domain_id = 1;
|
string domain_id = 1;
|
||||||
com.digitalasset.canton.protocol.v30.ViewType view_type = 2;
|
com.digitalasset.canton.protocol.v30.ViewType view_type = 2;
|
||||||
|
@ -9,7 +9,7 @@ import "google/protobuf/wrappers.proto";
|
|||||||
import "scalapb/scalapb.proto";
|
import "scalapb/scalapb.proto";
|
||||||
|
|
||||||
message OrderingRequest {
|
message OrderingRequest {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
string sequencer_uid = 1; // UID of the sequencer requesting ordering of the request
|
string sequencer_uid = 1; // UID of the sequencer requesting ordering of the request
|
||||||
google.protobuf.BytesValue content = 2; // Content of the request to be ordered
|
google.protobuf.BytesValue content = 2; // Content of the request to be ordered
|
||||||
|
@ -63,7 +63,7 @@ message ViewCommonData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message Informee {
|
message Informee {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
string party = 1;
|
string party = 1;
|
||||||
int32 weight = 2; // optional: only set if party is confirming
|
int32 weight = 2; // optional: only set if party is confirming
|
||||||
@ -87,14 +87,14 @@ message ViewParticipantMessage {
|
|||||||
// InformeeMessage
|
// InformeeMessage
|
||||||
|
|
||||||
message InformeeMessage {
|
message InformeeMessage {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
FullInformeeTree full_informee_tree = 1;
|
FullInformeeTree full_informee_tree = 1;
|
||||||
com.digitalasset.canton.crypto.v30.Signature submitting_participant_signature = 2;
|
com.digitalasset.canton.crypto.v30.Signature submitting_participant_signature = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LightTransactionViewTree {
|
message LightTransactionViewTree {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
GenTransactionTree tree = 1;
|
GenTransactionTree tree = 1;
|
||||||
repeated bytes subview_hashes = 2;
|
repeated bytes subview_hashes = 2;
|
||||||
@ -118,7 +118,7 @@ message InputContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message CommonMetadata {
|
message CommonMetadata {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
||||||
// this used to contain a confirmation policy (Signatory or VIP) that no longer exists
|
// this used to contain a confirmation policy (Signatory or VIP) that no longer exists
|
||||||
@ -129,7 +129,7 @@ message CommonMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SubmitterMetadata {
|
message SubmitterMetadata {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
||||||
repeated string act_as = 2;
|
repeated string act_as = 2;
|
||||||
@ -153,7 +153,7 @@ message SessionKeyLookup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message EncryptedViewMessage {
|
message EncryptedViewMessage {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
bytes view_tree = 1;
|
bytes view_tree = 1;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ message TransferId {
|
|||||||
// Messages sent by a participant as part of the transfer protocol
|
// Messages sent by a participant as part of the transfer protocol
|
||||||
|
|
||||||
message TransferOutCommonData {
|
message TransferOutCommonData {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
||||||
string source_domain = 2;
|
string source_domain = 2;
|
||||||
@ -33,7 +33,7 @@ message TransferOutCommonData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message TransferViewTree {
|
message TransferViewTree {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
bytes common_data = 1;
|
bytes common_data = 1;
|
||||||
BlindableNode participant_data = 2;
|
BlindableNode participant_data = 2;
|
||||||
@ -47,14 +47,14 @@ message TransferInMediatorMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message TransferOutMediatorMessage {
|
message TransferOutMediatorMessage {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
TransferViewTree tree = 1;
|
TransferViewTree tree = 1;
|
||||||
com.digitalasset.canton.crypto.v30.Signature submitting_participant_signature = 2;
|
com.digitalasset.canton.crypto.v30.Signature submitting_participant_signature = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TransferInCommonData {
|
message TransferInCommonData {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
||||||
string target_domain = 2;
|
string target_domain = 2;
|
||||||
@ -65,7 +65,7 @@ message TransferInCommonData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message TransferSubmitterMetadata {
|
message TransferSubmitterMetadata {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
string submitter = 1;
|
string submitter = 1;
|
||||||
string submitting_participant_uid = 2;
|
string submitting_participant_uid = 2;
|
||||||
@ -76,7 +76,7 @@ message TransferSubmitterMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message TransferOutView {
|
message TransferOutView {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
||||||
string target_domain = 3;
|
string target_domain = 3;
|
||||||
@ -88,7 +88,7 @@ message TransferOutView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message TransferInView {
|
message TransferInView {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
com.digitalasset.canton.crypto.v30.Salt salt = 1;
|
||||||
v30.SerializableContract contract = 3;
|
v30.SerializableContract contract = 3;
|
||||||
|
@ -73,7 +73,7 @@ message Handshake {
|
|||||||
|
|
||||||
// Submission cost computed by the sender for a SubmissionRequest
|
// Submission cost computed by the sender for a SubmissionRequest
|
||||||
message SequencingSubmissionCost {
|
message SequencingSubmissionCost {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
// Computed cost
|
// Computed cost
|
||||||
int64 cost = 1;
|
int64 cost = 1;
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ message StaticDomainParameters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message Envelope {
|
message Envelope {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// Contains a v30.EnvelopeContent if signatures are empty and a v30.TypedSignedProtocolMessageContent otherwise
|
// Contains a v30.EnvelopeContent if signatures are empty and a v30.TypedSignedProtocolMessageContent otherwise
|
||||||
bytes content = 1;
|
bytes content = 1;
|
||||||
@ -102,13 +102,13 @@ message Envelope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message Batch {
|
message Batch {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
repeated Envelope envelopes = 1;
|
repeated Envelope envelopes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CompressedBatch {
|
message CompressedBatch {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
enum CompressionAlgorithm {
|
enum CompressionAlgorithm {
|
||||||
COMPRESSION_ALGORITHM_UNSPECIFIED = 0;
|
COMPRESSION_ALGORITHM_UNSPECIFIED = 0;
|
||||||
@ -121,7 +121,7 @@ message CompressedBatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SequencedEvent {
|
message SequencedEvent {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// A sequence number for all events emitted to a subscriber. Starting at 0.
|
// A sequence number for all events emitted to a subscriber. Starting at 0.
|
||||||
// The same event may have different counter values for different recipients.
|
// The same event may have different counter values for different recipients.
|
||||||
@ -158,7 +158,7 @@ message SequencedEvent {
|
|||||||
|
|
||||||
// Messages used for synchronization between sequencer nodes
|
// Messages used for synchronization between sequencer nodes
|
||||||
message SubmissionRequest {
|
message SubmissionRequest {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// Sender of the request.
|
// Sender of the request.
|
||||||
// This request must be wrapped in a SignedContent and
|
// This request must be wrapped in a SignedContent and
|
||||||
|
@ -8,7 +8,7 @@ package com.digitalasset.canton.protocol.v30;
|
|||||||
import "scalapb/scalapb.proto";
|
import "scalapb/scalapb.proto";
|
||||||
|
|
||||||
message DynamicSequencingParameters {
|
message DynamicSequencingParameters {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// Sequencing dynamic domain parameters can only be interpreted by a sequencer implementation
|
// Sequencing dynamic domain parameters can only be interpreted by a sequencer implementation
|
||||||
// and are opaque to the rest of the domain.
|
// and are opaque to the rest of the domain.
|
||||||
|
@ -10,7 +10,7 @@ import "google/protobuf/wrappers.proto";
|
|||||||
import "scalapb/scalapb.proto";
|
import "scalapb/scalapb.proto";
|
||||||
|
|
||||||
message SignedContent {
|
message SignedContent {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
google.protobuf.BytesValue content = 1;
|
google.protobuf.BytesValue content = 1;
|
||||||
repeated com.digitalasset.canton.crypto.v30.Signature signatures = 2;
|
repeated com.digitalasset.canton.crypto.v30.Signature signatures = 2;
|
||||||
|
@ -14,7 +14,7 @@ import "scalapb/scalapb.proto";
|
|||||||
// Messages depending on both participant_transaction.proto and participant_transfer.proto.
|
// Messages depending on both participant_transaction.proto and participant_transfer.proto.
|
||||||
|
|
||||||
message TypedSignedProtocolMessageContent {
|
message TypedSignedProtocolMessageContent {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
oneof some_signed_protocol_message {
|
oneof some_signed_protocol_message {
|
||||||
bytes confirmation_response = 2;
|
bytes confirmation_response = 2;
|
||||||
@ -25,14 +25,14 @@ message TypedSignedProtocolMessageContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SignedProtocolMessage {
|
message SignedProtocolMessage {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
repeated com.digitalasset.canton.crypto.v30.Signature signature = 1;
|
repeated com.digitalasset.canton.crypto.v30.Signature signature = 1;
|
||||||
bytes typed_signed_protocol_message_content = 2;
|
bytes typed_signed_protocol_message_content = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message EnvelopeContent {
|
message EnvelopeContent {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
oneof some_envelope_content {
|
oneof some_envelope_content {
|
||||||
v30.InformeeMessage informee_message = 1;
|
v30.InformeeMessage informee_message = 1;
|
||||||
|
@ -323,7 +323,7 @@ message TopologyMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message TopologyTransaction {
|
message TopologyTransaction {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
Enums.TopologyChangeOp operation = 1;
|
Enums.TopologyChangeOp operation = 1;
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ message TopologyTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SignedTopologyTransaction {
|
message SignedTopologyTransaction {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// serialized topology transaction (protobuf bytestring)
|
// serialized topology transaction (protobuf bytestring)
|
||||||
bytes transaction = 1;
|
bytes transaction = 1;
|
||||||
@ -359,7 +359,7 @@ message SignedTopologyTransaction {
|
|||||||
* including the member the submitted the broadcast.
|
* including the member the submitted the broadcast.
|
||||||
*/
|
*/
|
||||||
message TopologyTransactionsBroadcast {
|
message TopologyTransactionsBroadcast {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
message Broadcast {
|
message Broadcast {
|
||||||
string broadcast_id = 1;
|
string broadcast_id = 1;
|
||||||
|
@ -10,7 +10,7 @@ import "google/protobuf/wrappers.proto";
|
|||||||
import "scalapb/scalapb.proto";
|
import "scalapb/scalapb.proto";
|
||||||
|
|
||||||
message TrafficControlParameters {
|
message TrafficControlParameters {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// In bytes, the maximum amount of base traffic that can be accumulated
|
// In bytes, the maximum amount of base traffic that can be accumulated
|
||||||
uint64 max_base_traffic_amount = 1;
|
uint64 max_base_traffic_amount = 1;
|
||||||
@ -34,7 +34,7 @@ message TrafficControlParameters {
|
|||||||
// Message representing a traffic receipt included in SequencedEvent receipts to update sender about
|
// Message representing a traffic receipt included in SequencedEvent receipts to update sender about
|
||||||
// the traffic consumed state after sequencing of the event
|
// the traffic consumed state after sequencing of the event
|
||||||
message TrafficReceipt {
|
message TrafficReceipt {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
// Cost effectively consumed by this specific event
|
// Cost effectively consumed by this specific event
|
||||||
uint64 consumed_cost = 1;
|
uint64 consumed_cost = 1;
|
||||||
// Total amount of extra traffic consumed
|
// Total amount of extra traffic consumed
|
||||||
@ -45,7 +45,7 @@ message TrafficReceipt {
|
|||||||
|
|
||||||
// Message representing traffic consumed by a member at a given point in time
|
// Message representing traffic consumed by a member at a given point in time
|
||||||
message TrafficConsumed {
|
message TrafficConsumed {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
// Member consuming the traffic
|
// Member consuming the traffic
|
||||||
string member = 1;
|
string member = 1;
|
||||||
// Total extra traffic consumed
|
// Total extra traffic consumed
|
||||||
@ -60,7 +60,7 @@ message TrafficConsumed {
|
|||||||
|
|
||||||
// Message representing a traffic purchase made on behalf of a member
|
// Message representing a traffic purchase made on behalf of a member
|
||||||
message TrafficPurchased {
|
message TrafficPurchased {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
// Member receiving the traffic
|
// Member receiving the traffic
|
||||||
string member = 1;
|
string member = 1;
|
||||||
// Serial of the update
|
// Serial of the update
|
||||||
@ -88,7 +88,7 @@ message TrafficState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SetTrafficPurchasedMessage {
|
message SetTrafficPurchasedMessage {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
// Member to update the balance for
|
// Member to update the balance for
|
||||||
string member = 1;
|
string member = 1;
|
||||||
|
@ -242,10 +242,10 @@ object CommunityStorageConfig {
|
|||||||
trait DbConfig extends StorageConfig with PrettyPrinting {
|
trait DbConfig extends StorageConfig with PrettyPrinting {
|
||||||
|
|
||||||
/** Function to combine the defined migration path together with dev version changes */
|
/** Function to combine the defined migration path together with dev version changes */
|
||||||
final def buildMigrationsPaths(devVersionSupport: Boolean): Seq[String] = {
|
final def buildMigrationsPaths(alphaVersionSupport: Boolean): Seq[String] = {
|
||||||
if (parameters.migrationsPaths.nonEmpty)
|
if (parameters.migrationsPaths.nonEmpty)
|
||||||
parameters.migrationsPaths
|
parameters.migrationsPaths
|
||||||
else if (devVersionSupport)
|
else if (alphaVersionSupport)
|
||||||
Seq(stableMigrationPath, devMigrationPath)
|
Seq(stableMigrationPath, devMigrationPath)
|
||||||
else Seq(stableMigrationPath)
|
else Seq(stableMigrationPath)
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,7 @@ class Crypto(
|
|||||||
): EitherT[FutureUnlessShutdown, SigningKeyGenerationError, SigningPublicKey] =
|
): EitherT[FutureUnlessShutdown, SigningKeyGenerationError, SigningPublicKey] =
|
||||||
for {
|
for {
|
||||||
publicKey <- privateCrypto.generateSigningKey(scheme, name)
|
publicKey <- privateCrypto.generateSigningKey(scheme, name)
|
||||||
_ <- cryptoPublicStore
|
_ <- EitherT.right(cryptoPublicStore.storeSigningKey(publicKey, name))
|
||||||
.storeSigningKey(publicKey, name)
|
|
||||||
.leftMap[SigningKeyGenerationError](SigningKeyGenerationError.SigningPublicStoreError)
|
|
||||||
} yield publicKey
|
} yield publicKey
|
||||||
|
|
||||||
/** Helper method to generate a new encryption key pair and store the public key in the public store as well. */
|
/** Helper method to generate a new encryption key pair and store the public key in the public store as well. */
|
||||||
@ -60,11 +58,7 @@ class Crypto(
|
|||||||
): EitherT[FutureUnlessShutdown, EncryptionKeyGenerationError, EncryptionPublicKey] =
|
): EitherT[FutureUnlessShutdown, EncryptionKeyGenerationError, EncryptionPublicKey] =
|
||||||
for {
|
for {
|
||||||
publicKey <- privateCrypto.generateEncryptionKey(scheme, name)
|
publicKey <- privateCrypto.generateEncryptionKey(scheme, name)
|
||||||
_ <- cryptoPublicStore
|
_ <- EitherT.right(cryptoPublicStore.storeEncryptionKey(publicKey, name))
|
||||||
.storeEncryptionKey(publicKey, name)
|
|
||||||
.leftMap[EncryptionKeyGenerationError](
|
|
||||||
EncryptionKeyGenerationError.EncryptionPublicStoreError
|
|
||||||
)
|
|
||||||
} yield publicKey
|
} yield publicKey
|
||||||
|
|
||||||
override def onClosed(): Unit =
|
override def onClosed(): Unit =
|
||||||
|
@ -457,9 +457,15 @@ object EncryptionPublicKey
|
|||||||
final case class EncryptionPublicKeyWithName(
|
final case class EncryptionPublicKeyWithName(
|
||||||
override val publicKey: EncryptionPublicKey,
|
override val publicKey: EncryptionPublicKey,
|
||||||
override val name: Option[KeyName],
|
override val name: Option[KeyName],
|
||||||
) extends PublicKeyWithName {
|
) extends PublicKeyWithName
|
||||||
|
with PrettyPrinting {
|
||||||
|
|
||||||
type K = EncryptionPublicKey
|
type K = EncryptionPublicKey
|
||||||
|
|
||||||
override val id: Fingerprint = publicKey.id
|
override val id: Fingerprint = publicKey.id
|
||||||
|
|
||||||
|
override def pretty: Pretty[EncryptionPublicKeyWithName] =
|
||||||
|
prettyOfClass(param("publicKey", _.publicKey), param("name", _.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
object EncryptionPublicKeyWithName {
|
object EncryptionPublicKeyWithName {
|
||||||
|
@ -387,9 +387,15 @@ object SigningPublicKey
|
|||||||
final case class SigningPublicKeyWithName(
|
final case class SigningPublicKeyWithName(
|
||||||
override val publicKey: SigningPublicKey,
|
override val publicKey: SigningPublicKey,
|
||||||
override val name: Option[KeyName],
|
override val name: Option[KeyName],
|
||||||
) extends PublicKeyWithName {
|
) extends PublicKeyWithName
|
||||||
|
with PrettyPrinting {
|
||||||
|
|
||||||
type K = SigningPublicKey
|
type K = SigningPublicKey
|
||||||
|
|
||||||
override val id: Fingerprint = publicKey.id
|
override val id: Fingerprint = publicKey.id
|
||||||
|
|
||||||
|
override def pretty: Pretty[SigningPublicKeyWithName] =
|
||||||
|
prettyOfClass(param("publicKey", _.publicKey), param("name", _.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
object SigningPublicKeyWithName {
|
object SigningPublicKeyWithName {
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
package com.digitalasset.canton.crypto.store
|
package com.digitalasset.canton.crypto.store
|
||||||
|
|
||||||
import cats.data.EitherT
|
import cats.data.OptionT
|
||||||
import cats.syntax.functor.*
|
import cats.syntax.functor.*
|
||||||
import com.daml.error.{ErrorCategory, ErrorCode, Explanation, Resolution}
|
import com.daml.error.{ErrorCategory, ErrorCode, Explanation, Resolution}
|
||||||
import com.digitalasset.canton.config.ProcessingTimeout
|
import com.digitalasset.canton.config.ProcessingTimeout
|
||||||
import com.digitalasset.canton.crypto.store.db.DbCryptoPublicStore
|
import com.digitalasset.canton.crypto.store.db.DbCryptoPublicStore
|
||||||
import com.digitalasset.canton.crypto.store.memory.InMemoryCryptoPublicStore
|
import com.digitalasset.canton.crypto.store.memory.InMemoryCryptoPublicStore
|
||||||
import com.digitalasset.canton.crypto.{KeyName, *}
|
import com.digitalasset.canton.crypto.{KeyName, *}
|
||||||
|
import com.digitalasset.canton.discard.Implicits.DiscardOps
|
||||||
import com.digitalasset.canton.error.{BaseCantonError, CantonErrorGroups}
|
import com.digitalasset.canton.error.{BaseCantonError, CantonErrorGroups}
|
||||||
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
||||||
import com.digitalasset.canton.logging.NamedLoggerFactory
|
import com.digitalasset.canton.logging.NamedLoggerFactory
|
||||||
@ -34,31 +35,25 @@ trait CryptoPublicStore extends AutoCloseable {
|
|||||||
// Write methods that the underlying store has to implement for the caching
|
// Write methods that the underlying store has to implement for the caching
|
||||||
protected def writeSigningKey(key: SigningPublicKey, name: Option[KeyName])(implicit
|
protected def writeSigningKey(key: SigningPublicKey, name: Option[KeyName])(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit]
|
): FutureUnlessShutdown[Unit]
|
||||||
|
|
||||||
protected def writeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName])(implicit
|
protected def writeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName])(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit]
|
): FutureUnlessShutdown[Unit]
|
||||||
|
|
||||||
protected[crypto] def listAllKeyFingerprints(implicit
|
|
||||||
traceContext: TraceContext
|
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[Fingerprint]] =
|
|
||||||
for {
|
|
||||||
signingKeys <- listSigningKeys
|
|
||||||
encryptionKeys <- listEncryptionKeys
|
|
||||||
} yield signingKeys.map(_.publicKey.id) ++ encryptionKeys.map(_.publicKey.id)
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
private[store] def listSigningKeys(implicit
|
private[store] def listSigningKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[SigningPublicKeyWithName]]
|
): FutureUnlessShutdown[Set[SigningPublicKeyWithName]]
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
private[store] def listEncryptionKeys(implicit
|
private[store] def listEncryptionKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[EncryptionPublicKeyWithName]]
|
): FutureUnlessShutdown[Set[EncryptionPublicKeyWithName]]
|
||||||
|
|
||||||
def storePublicKey(publicKey: PublicKey, name: Option[KeyName])(implicit
|
def storePublicKey(publicKey: PublicKey, name: Option[KeyName])(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] =
|
): FutureUnlessShutdown[Unit] =
|
||||||
(publicKey: @unchecked) match {
|
(publicKey: @unchecked) match {
|
||||||
case sigKey: SigningPublicKey => storeSigningKey(sigKey, name)
|
case sigKey: SigningPublicKey => storeSigningKey(sigKey, name)
|
||||||
case encKey: EncryptionPublicKey => storeEncryptionKey(encKey, name)
|
case encKey: EncryptionPublicKey => storeEncryptionKey(encKey, name)
|
||||||
@ -66,50 +61,35 @@ trait CryptoPublicStore extends AutoCloseable {
|
|||||||
|
|
||||||
def publicKey(keyId: Fingerprint)(implicit
|
def publicKey(keyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[PublicKey]] =
|
): OptionT[FutureUnlessShutdown, PublicKey] =
|
||||||
publicKeyWithName(keyId).map(_.map(_.publicKey))
|
readSigningKey(keyId)
|
||||||
|
.widen[PublicKeyWithName]
|
||||||
def publicKeyWithName(keyId: Fingerprint)(implicit
|
.orElse(readEncryptionKey(keyId).widen[PublicKeyWithName])
|
||||||
traceContext: TraceContext
|
.map(_.publicKey)
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[PublicKeyWithName]] =
|
|
||||||
for {
|
|
||||||
sigKeyOption <- readSigningKey(keyId)
|
|
||||||
pubKeyOption <- sigKeyOption.fold(readEncryptionKey(keyId).widen[Option[PublicKeyWithName]])(
|
|
||||||
key => EitherT.rightT(Some(key))
|
|
||||||
)
|
|
||||||
} yield pubKeyOption
|
|
||||||
|
|
||||||
def existsPublicKey(keyId: Fingerprint, purpose: KeyPurpose)(implicit
|
|
||||||
traceContext: TraceContext
|
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Boolean] =
|
|
||||||
purpose match {
|
|
||||||
case KeyPurpose.Signing => signingKey(keyId).map(_.nonEmpty)
|
|
||||||
case KeyPurpose.Encryption => encryptionKey(keyId).map(_.nonEmpty)
|
|
||||||
}
|
|
||||||
|
|
||||||
def findSigningKeyIdByName(keyName: KeyName)(implicit
|
def findSigningKeyIdByName(keyName: KeyName)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[SigningPublicKey]] =
|
): OptionT[FutureUnlessShutdown, SigningPublicKey] =
|
||||||
listSigningKeys.map(_.find(_.name.contains(keyName)).map(_.publicKey))
|
OptionT(listSigningKeys.map(_.find(_.name.contains(keyName)).map(_.publicKey)))
|
||||||
|
|
||||||
def findSigningKeyIdByFingerprint(fingerprint: Fingerprint)(implicit
|
def findSigningKeyIdByFingerprint(fingerprint: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[SigningPublicKey]] =
|
): OptionT[FutureUnlessShutdown, SigningPublicKey] =
|
||||||
listSigningKeys.map(_.find(_.publicKey.fingerprint == fingerprint).map(_.publicKey))
|
OptionT(listSigningKeys.map(_.find(_.publicKey.fingerprint == fingerprint).map(_.publicKey)))
|
||||||
|
|
||||||
def findEncryptionKeyIdByName(keyName: KeyName)(implicit
|
def findEncryptionKeyIdByName(keyName: KeyName)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[EncryptionPublicKey]] =
|
): OptionT[FutureUnlessShutdown, EncryptionPublicKey] =
|
||||||
listEncryptionKeys.map(_.find(_.name.contains(keyName)).map(_.publicKey))
|
OptionT(listEncryptionKeys.map(_.find(_.name.contains(keyName)).map(_.publicKey)))
|
||||||
|
|
||||||
def findEncryptionKeyIdByFingerprint(fingerprint: Fingerprint)(implicit
|
def findEncryptionKeyIdByFingerprint(fingerprint: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[EncryptionPublicKey]] =
|
): OptionT[FutureUnlessShutdown, EncryptionPublicKey] =
|
||||||
listEncryptionKeys.map(_.find(_.publicKey.fingerprint == fingerprint).map(_.publicKey))
|
OptionT(listEncryptionKeys.map(_.find(_.publicKey.fingerprint == fingerprint).map(_.publicKey)))
|
||||||
|
|
||||||
def publicKeysWithName(implicit
|
def publicKeysWithName(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[PublicKeyWithName]] =
|
): FutureUnlessShutdown[Set[PublicKeyWithName]] =
|
||||||
for {
|
for {
|
||||||
sigKeys <- listSigningKeys
|
sigKeys <- listSigningKeys
|
||||||
encKeys <- listEncryptionKeys
|
encKeys <- listEncryptionKeys
|
||||||
@ -117,64 +97,68 @@ trait CryptoPublicStore extends AutoCloseable {
|
|||||||
|
|
||||||
def signingKey(signingKeyId: Fingerprint)(implicit
|
def signingKey(signingKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[SigningPublicKey]] =
|
): OptionT[FutureUnlessShutdown, SigningPublicKey] =
|
||||||
retrieveKeyAndUpdateCache(signingKeyMap, readSigningKey(_))(signingKeyId)
|
retrieveKeyAndUpdateCache(signingKeyMap, readSigningKey(_))(signingKeyId)
|
||||||
|
|
||||||
protected def readSigningKey(signingKeyId: Fingerprint)(implicit
|
protected def readSigningKey(signingKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[SigningPublicKeyWithName]]
|
): OptionT[FutureUnlessShutdown, SigningPublicKeyWithName]
|
||||||
|
|
||||||
def signingKeys(implicit
|
def signingKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[SigningPublicKey]] =
|
): FutureUnlessShutdown[Set[SigningPublicKey]] =
|
||||||
retrieveKeysAndUpdateCache(listSigningKeys, signingKeyMap)
|
retrieveKeysAndUpdateCache(listSigningKeys, signingKeyMap)
|
||||||
|
|
||||||
def storeSigningKey(key: SigningPublicKey, name: Option[KeyName] = None)(implicit
|
def storeSigningKey(key: SigningPublicKey, name: Option[KeyName] = None)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] =
|
): FutureUnlessShutdown[Unit] =
|
||||||
writeSigningKey(key, name).map { _ =>
|
writeSigningKey(key, name).map { _ =>
|
||||||
val _ = signingKeyMap.put(key.id, SigningPublicKeyWithName(key, name))
|
signingKeyMap.put(key.id, SigningPublicKeyWithName(key, name)).discard
|
||||||
}
|
}
|
||||||
|
|
||||||
def encryptionKey(encryptionKeyId: Fingerprint)(implicit
|
def encryptionKey(encryptionKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[EncryptionPublicKey]] =
|
): OptionT[FutureUnlessShutdown, EncryptionPublicKey] =
|
||||||
retrieveKeyAndUpdateCache(encryptionKeyMap, readEncryptionKey(_))(encryptionKeyId)
|
retrieveKeyAndUpdateCache(encryptionKeyMap, readEncryptionKey(_))(encryptionKeyId)
|
||||||
|
|
||||||
protected def readEncryptionKey(encryptionKeyId: Fingerprint)(implicit
|
protected def readEncryptionKey(encryptionKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[EncryptionPublicKeyWithName]]
|
): OptionT[FutureUnlessShutdown, EncryptionPublicKeyWithName]
|
||||||
|
|
||||||
def encryptionKeys(implicit
|
def encryptionKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[EncryptionPublicKey]] =
|
): FutureUnlessShutdown[Set[EncryptionPublicKey]] =
|
||||||
retrieveKeysAndUpdateCache(listEncryptionKeys, encryptionKeyMap)
|
retrieveKeysAndUpdateCache(listEncryptionKeys, encryptionKeyMap)
|
||||||
|
|
||||||
def storeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName] = None)(implicit
|
def storeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName] = None)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] =
|
): FutureUnlessShutdown[Unit] =
|
||||||
writeEncryptionKey(key, name)
|
writeEncryptionKey(key, name)
|
||||||
.map { _ =>
|
.map { _ =>
|
||||||
val _ = encryptionKeyMap.put(key.id, EncryptionPublicKeyWithName(key, name))
|
encryptionKeyMap.put(key.id, EncryptionPublicKeyWithName(key, name)).discard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private[crypto] def deleteKey(keyId: Fingerprint)(implicit
|
||||||
|
traceContext: TraceContext
|
||||||
|
): FutureUnlessShutdown[Unit]
|
||||||
|
|
||||||
private def retrieveKeyAndUpdateCache[KN <: PublicKeyWithName](
|
private def retrieveKeyAndUpdateCache[KN <: PublicKeyWithName](
|
||||||
cache: TrieMap[Fingerprint, KN],
|
cache: TrieMap[Fingerprint, KN],
|
||||||
readKey: Fingerprint => EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[KN]],
|
readKey: Fingerprint => OptionT[FutureUnlessShutdown, KN],
|
||||||
)(keyId: Fingerprint): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[KN#K]] =
|
)(keyId: Fingerprint): OptionT[FutureUnlessShutdown, KN#K] =
|
||||||
cache.get(keyId) match {
|
cache.get(keyId) match {
|
||||||
case Some(value) => EitherT.rightT(Some(value.publicKey))
|
case Some(key) => OptionT.some(key.publicKey)
|
||||||
case None =>
|
case None =>
|
||||||
readKey(keyId).map { keyOption =>
|
readKey(keyId).map { key =>
|
||||||
keyOption.foreach(key => cache.putIfAbsent(keyId, key))
|
cache.putIfAbsent(keyId, key).discard
|
||||||
keyOption.map(_.publicKey)
|
key.publicKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def retrieveKeysAndUpdateCache[KN <: PublicKeyWithName](
|
private def retrieveKeysAndUpdateCache[KN <: PublicKeyWithName](
|
||||||
keysFromDb: EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[KN]],
|
keysFromDb: FutureUnlessShutdown[Set[KN]],
|
||||||
cache: TrieMap[Fingerprint, KN],
|
cache: TrieMap[Fingerprint, KN],
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[KN#K]] =
|
): FutureUnlessShutdown[Set[KN#K]] =
|
||||||
for {
|
for {
|
||||||
// we always rebuild the cache here just in case new keys have been added by another process
|
// we always rebuild the cache here just in case new keys have been added by another process
|
||||||
// this should not be a problem since these operations to get all keys are infrequent and typically
|
// this should not be a problem since these operations to get all keys are infrequent and typically
|
||||||
@ -194,7 +178,7 @@ object CryptoPublicStore {
|
|||||||
ec: ExecutionContext
|
ec: ExecutionContext
|
||||||
): CryptoPublicStore = {
|
): CryptoPublicStore = {
|
||||||
storage match {
|
storage match {
|
||||||
case _: MemoryStorage => new InMemoryCryptoPublicStore
|
case _: MemoryStorage => new InMemoryCryptoPublicStore(loggerFactory)
|
||||||
case dbStorage: DbStorage =>
|
case dbStorage: DbStorage =>
|
||||||
new DbCryptoPublicStore(dbStorage, releaseProtocolVersion, timeouts, loggerFactory)
|
new DbCryptoPublicStore(dbStorage, releaseProtocolVersion, timeouts, loggerFactory)
|
||||||
}
|
}
|
||||||
@ -218,27 +202,22 @@ object CryptoPublicStoreError extends CantonErrorGroups.CommandErrorGroup {
|
|||||||
extends BaseCantonError.Impl(cause = "An error occurred with the public crypto store")
|
extends BaseCantonError.Impl(cause = "An error occurred with the public crypto store")
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class FailedToListKeys(reason: String) extends CryptoPublicStoreError {
|
|
||||||
override def pretty: Pretty[FailedToListKeys] = prettyOfClass(unnamedParam(_.reason.unquoted))
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class FailedToReadKey(keyId: Fingerprint, reason: String)
|
|
||||||
extends CryptoPublicStoreError {
|
|
||||||
override def pretty: Pretty[FailedToReadKey] = prettyOfClass(unnamedParam(_.reason.unquoted))
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class FailedToInsertKey(keyId: Fingerprint, reason: String)
|
final case class FailedToInsertKey(keyId: Fingerprint, reason: String)
|
||||||
extends CryptoPublicStoreError {
|
extends CryptoPublicStoreError {
|
||||||
override def pretty: Pretty[FailedToInsertKey] =
|
override def pretty: Pretty[FailedToInsertKey] =
|
||||||
prettyOfClass(param("keyId", _.keyId), param("reason", _.reason.unquoted))
|
prettyOfClass(param("keyId", _.keyId), param("reason", _.reason.unquoted))
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class KeyAlreadyExists(keyId: Fingerprint, existingKeyName: Option[String])
|
final case class KeyAlreadyExists[K <: PublicKeyWithName: Pretty](
|
||||||
extends CryptoPublicStoreError {
|
keyId: Fingerprint,
|
||||||
override def pretty: Pretty[KeyAlreadyExists] =
|
existingPublicKey: K,
|
||||||
|
newPublicKey: K,
|
||||||
|
) extends CryptoPublicStoreError {
|
||||||
|
override def pretty: Pretty[KeyAlreadyExists[K]] =
|
||||||
prettyOfClass(
|
prettyOfClass(
|
||||||
param("keyId", _.keyId),
|
param("keyId", _.keyId),
|
||||||
param("existingKeyName", _.existingKeyName.getOrElse("").unquoted),
|
param("existingPublicKey", _.existingPublicKey),
|
||||||
|
param("newPublicKey", _.newPublicKey),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ import com.digitalasset.canton.resource.DbStorage.DbAction
|
|||||||
import com.digitalasset.canton.resource.DbStorage.Implicits.*
|
import com.digitalasset.canton.resource.DbStorage.Implicits.*
|
||||||
import com.digitalasset.canton.resource.{DbStorage, DbStore}
|
import com.digitalasset.canton.resource.{DbStorage, DbStore}
|
||||||
import com.digitalasset.canton.tracing.TraceContext
|
import com.digitalasset.canton.tracing.TraceContext
|
||||||
import com.digitalasset.canton.util.EitherTUtil
|
|
||||||
import com.digitalasset.canton.version.ReleaseProtocolVersion
|
import com.digitalasset.canton.version.ReleaseProtocolVersion
|
||||||
import com.google.common.annotations.VisibleForTesting
|
import com.google.common.annotations.VisibleForTesting
|
||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
@ -149,18 +148,16 @@ class DbCryptoPrivateStore(
|
|||||||
purpose: KeyPurpose,
|
purpose: KeyPurpose,
|
||||||
)(implicit
|
)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Option[StoredPrivateKey]] =
|
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Option[StoredPrivateKey]] = {
|
||||||
EitherTUtil
|
EitherT.right(
|
||||||
.fromFuture[CryptoPrivateStoreError, Option[StoredPrivateKey]](
|
storage
|
||||||
storage
|
.querySingleUnlessShutdown(
|
||||||
.querySingle(
|
queryKey(keyId, purpose),
|
||||||
queryKey(keyId, purpose),
|
functionFullName,
|
||||||
functionFullName,
|
)
|
||||||
)
|
.value
|
||||||
.value,
|
)
|
||||||
err => CryptoPrivateStoreError.FailedToReadKey(keyId, err.toString),
|
}
|
||||||
)
|
|
||||||
.mapK(FutureUnlessShutdown.outcomeK)
|
|
||||||
|
|
||||||
private[crypto] def writePrivateKey(
|
private[crypto] def writePrivateKey(
|
||||||
key: StoredPrivateKey
|
key: StoredPrivateKey
|
||||||
@ -172,15 +169,13 @@ class DbCryptoPrivateStore(
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
private[canton] def listPrivateKeys(purpose: KeyPurpose, encrypted: Boolean)(implicit
|
private[canton] def listPrivateKeys(purpose: KeyPurpose, encrypted: Boolean)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Set[StoredPrivateKey]] =
|
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Set[StoredPrivateKey]] = {
|
||||||
EitherTUtil
|
EitherT.right(
|
||||||
.fromFuture[CryptoPrivateStoreError, Set[StoredPrivateKey]](
|
storage
|
||||||
storage
|
.queryUnlessShutdown(queryKeys(purpose), functionFullName)
|
||||||
.query(queryKeys(purpose), functionFullName)
|
.map(keys => keys.filter(_.isEncrypted == encrypted))
|
||||||
.map(keys => keys.filter(_.isEncrypted == encrypted)),
|
)
|
||||||
err => CryptoPrivateStoreError.FailedToListKeys(err.toString),
|
}
|
||||||
)
|
|
||||||
.mapK(FutureUnlessShutdown.outcomeK)
|
|
||||||
|
|
||||||
private def deleteKey(keyId: Fingerprint): SqlAction[Int, NoStream, Effect.Write] =
|
private def deleteKey(keyId: Fingerprint): SqlAction[Int, NoStream, Effect.Write] =
|
||||||
sqlu"delete from common_crypto_private_keys where key_id = $keyId"
|
sqlu"delete from common_crypto_private_keys where key_id = $keyId"
|
||||||
@ -191,28 +186,24 @@ class DbCryptoPrivateStore(
|
|||||||
private[crypto] def replaceStoredPrivateKeys(newKeys: Seq[StoredPrivateKey])(implicit
|
private[crypto] def replaceStoredPrivateKeys(newKeys: Seq[StoredPrivateKey])(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Unit] =
|
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Unit] =
|
||||||
EitherTUtil
|
EitherT.right(
|
||||||
.fromFuture[CryptoPrivateStoreError, Unit](
|
storage
|
||||||
storage
|
.updateUnlessShutdown_(
|
||||||
.update_(
|
DBIOAction
|
||||||
DBIOAction
|
.sequence(
|
||||||
.sequence(
|
newKeys.map(key => deleteKey(key.id).andThen(insertKeyUpdate(key)))
|
||||||
newKeys.map(key => deleteKey(key.id).andThen(insertKeyUpdate(key)))
|
)
|
||||||
)
|
.transactionally,
|
||||||
.transactionally,
|
functionFullName,
|
||||||
functionFullName,
|
)
|
||||||
),
|
)
|
||||||
err => CryptoPrivateStoreError.FailedToReplaceKeys(newKeys.map(_.id), err.toString),
|
|
||||||
)
|
|
||||||
.mapK(FutureUnlessShutdown.outcomeK)
|
|
||||||
|
|
||||||
private[crypto] def deletePrivateKey(keyId: Fingerprint)(implicit
|
private[crypto] def deletePrivateKey(keyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Unit] =
|
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Unit] =
|
||||||
EitherTUtil.fromFuture(
|
EitherT.right(
|
||||||
storage
|
storage
|
||||||
.updateUnlessShutdown_(deleteKey(keyId), functionFullName),
|
.updateUnlessShutdown_(deleteKey(keyId), functionFullName)
|
||||||
err => CryptoPrivateStoreError.FailedToDeleteKey(keyId, err.toString),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private[crypto] def encrypted(
|
private[crypto] def encrypted(
|
||||||
@ -235,27 +226,23 @@ class DbCryptoPrivateStore(
|
|||||||
private[crypto] def getWrapperKeyId()(implicit
|
private[crypto] def getWrapperKeyId()(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Option[String300]] =
|
): EitherT[FutureUnlessShutdown, CryptoPrivateStoreError, Option[String300]] =
|
||||||
EitherTUtil
|
EitherT
|
||||||
.fromFuture(
|
.right(
|
||||||
storage.queryUnlessShutdown(
|
storage
|
||||||
{
|
.queryUnlessShutdown(
|
||||||
sql"select distinct wrapper_key_id from common_crypto_private_keys"
|
sql"select distinct wrapper_key_id from common_crypto_private_keys"
|
||||||
.as[Option[String300]]
|
.as[Option[String300]]
|
||||||
.map(_.toSeq)
|
.map(_.toSeq),
|
||||||
},
|
functionFullName,
|
||||||
functionFullName,
|
)
|
||||||
),
|
|
||||||
err => CryptoPrivateStoreError.FailedToGetWrapperKeyId(err.toString),
|
|
||||||
)
|
)
|
||||||
.transform {
|
.subflatMap { wrapperKeys =>
|
||||||
case Left(err) => Left(err)
|
if (wrapperKeys.size > 1)
|
||||||
case Right(wrapper_keys) =>
|
Left(
|
||||||
if (wrapper_keys.size > 1)
|
CryptoPrivateStoreError
|
||||||
Left(
|
.FailedToGetWrapperKeyId("Found more than one distinct wrapper_key_id")
|
||||||
CryptoPrivateStoreError
|
)
|
||||||
.FailedToGetWrapperKeyId("Found more than one distinct wrapper_key_id")
|
else
|
||||||
)
|
Right(wrapperKeys.flatten.headOption)
|
||||||
else
|
|
||||||
Right(wrapper_keys.flatten.headOption)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
|
|
||||||
package com.digitalasset.canton.crypto.store.db
|
package com.digitalasset.canton.crypto.store.db
|
||||||
|
|
||||||
import cats.data.EitherT
|
import cats.data.OptionT
|
||||||
import cats.syntax.bifunctor.*
|
|
||||||
import com.daml.nameof.NameOf.functionFullName
|
import com.daml.nameof.NameOf.functionFullName
|
||||||
import com.digitalasset.canton.config.ProcessingTimeout
|
import com.digitalasset.canton.config.ProcessingTimeout
|
||||||
import com.digitalasset.canton.crypto.*
|
import com.digitalasset.canton.crypto.*
|
||||||
@ -12,9 +11,8 @@ import com.digitalasset.canton.crypto.store.*
|
|||||||
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
||||||
import com.digitalasset.canton.logging.NamedLoggerFactory
|
import com.digitalasset.canton.logging.NamedLoggerFactory
|
||||||
import com.digitalasset.canton.resource.DbStorage.DbAction
|
import com.digitalasset.canton.resource.DbStorage.DbAction
|
||||||
import com.digitalasset.canton.resource.{DbStorage, DbStore}
|
import com.digitalasset.canton.resource.{DbStorage, DbStore, IdempotentInsert}
|
||||||
import com.digitalasset.canton.tracing.TraceContext
|
import com.digitalasset.canton.tracing.TraceContext
|
||||||
import com.digitalasset.canton.util.EitherTUtil
|
|
||||||
import com.digitalasset.canton.version.ReleaseProtocolVersion
|
import com.digitalasset.canton.version.ReleaseProtocolVersion
|
||||||
import slick.jdbc.{GetResult, SetParameter}
|
import slick.jdbc.{GetResult, SetParameter}
|
||||||
|
|
||||||
@ -42,7 +40,7 @@ class DbCryptoPublicStore(
|
|||||||
.as[K]
|
.as[K]
|
||||||
.map(_.toSet)
|
.map(_.toSet)
|
||||||
|
|
||||||
private def queryKey[K <: PublicKeyWithName: GetResult](
|
private def queryKeyO[K <: PublicKeyWithName: GetResult](
|
||||||
keyId: Fingerprint,
|
keyId: Fingerprint,
|
||||||
purpose: KeyPurpose,
|
purpose: KeyPurpose,
|
||||||
): DbAction.ReadOnly[Option[K]] =
|
): DbAction.ReadOnly[Option[K]] =
|
||||||
@ -50,109 +48,86 @@ class DbCryptoPublicStore(
|
|||||||
.as[K]
|
.as[K]
|
||||||
.headOption
|
.headOption
|
||||||
|
|
||||||
private def insertKeyUpdate[K <: PublicKey: SetParameter, KN <: PublicKeyWithName: GetResult](
|
private def queryKey[K <: PublicKeyWithName: GetResult](
|
||||||
key: K,
|
keyId: Fingerprint,
|
||||||
name: Option[KeyName],
|
purpose: KeyPurpose,
|
||||||
): DbAction.WriteOnly[Int] =
|
): DbAction.ReadOnly[K] =
|
||||||
storage.profile match {
|
sql"select data, name from common_crypto_public_keys where key_id = $keyId and purpose = $purpose"
|
||||||
case _: DbStorage.Profile.Oracle =>
|
.as[K]
|
||||||
sqlu"""insert
|
.head
|
||||||
/*+ IGNORE_ROW_ON_DUPKEY_INDEX ( common_crypto_public_keys ( key_id ) ) */
|
|
||||||
into common_crypto_public_keys (key_id, purpose, data, name)
|
|
||||||
values (${key.id}, ${key.purpose}, $key, $name)"""
|
|
||||||
case _ =>
|
|
||||||
sqlu"""insert into common_crypto_public_keys (key_id, purpose, data, name)
|
|
||||||
values (${key.id}, ${key.purpose}, $key, $name)
|
|
||||||
on conflict do nothing"""
|
|
||||||
}
|
|
||||||
|
|
||||||
private def insertKey[K <: PublicKey: SetParameter, KN <: PublicKeyWithName: GetResult](
|
private def insertKey[K <: PublicKey: SetParameter, KN <: PublicKeyWithName: GetResult](
|
||||||
key: K,
|
key: K,
|
||||||
name: Option[KeyName],
|
name: Option[KeyName],
|
||||||
)(implicit
|
)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] =
|
): FutureUnlessShutdown[Unit] = {
|
||||||
for {
|
storage.queryAndUpdateUnlessShutdown(
|
||||||
inserted <- EitherT.right(
|
IdempotentInsert.insertVerifyingConflicts(
|
||||||
storage.updateUnlessShutdown(insertKeyUpdate(key, name), functionFullName)
|
storage,
|
||||||
)
|
"common_crypto_public_keys ( key_id )",
|
||||||
res <-
|
sql"common_crypto_public_keys (key_id, purpose, data, name) values (${key.id}, ${key.purpose}, $key, $name)",
|
||||||
if (inserted == 0) {
|
queryKey(key.id, key.purpose),
|
||||||
// If no key was inserted by the insert query, check that the existing value matches
|
)(
|
||||||
storage
|
existingKey => existingKey.publicKey == key && existingKey.name == name,
|
||||||
.querySingleUnlessShutdown(queryKey(key.id, key.purpose), functionFullName)
|
_ => s"Existing public key for ${key.id} is different than inserted key",
|
||||||
.toRight(
|
),
|
||||||
CryptoPublicStoreError.FailedToInsertKey(key.id, "No key inserted and no key found")
|
functionFullName,
|
||||||
)
|
)
|
||||||
.flatMap { existingKey =>
|
}
|
||||||
EitherT
|
|
||||||
.cond[FutureUnlessShutdown](
|
|
||||||
existingKey.publicKey == key && existingKey.name == name,
|
|
||||||
(),
|
|
||||||
CryptoPublicStoreError.KeyAlreadyExists(key.id, existingKey.name.map(_.unwrap)),
|
|
||||||
)
|
|
||||||
.leftWiden[CryptoPublicStoreError]
|
|
||||||
}
|
|
||||||
} else EitherT.rightT[FutureUnlessShutdown, CryptoPublicStoreError](())
|
|
||||||
} yield res
|
|
||||||
|
|
||||||
override def readSigningKey(signingKeyId: Fingerprint)(implicit
|
override def readSigningKey(signingKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[SigningPublicKeyWithName]] =
|
): OptionT[FutureUnlessShutdown, SigningPublicKeyWithName] =
|
||||||
EitherTUtil.fromFuture(
|
storage
|
||||||
storage
|
.querySingleUnlessShutdown(
|
||||||
.querySingleUnlessShutdown(
|
queryKeyO[SigningPublicKeyWithName](signingKeyId, KeyPurpose.Signing),
|
||||||
queryKey[SigningPublicKeyWithName](signingKeyId, KeyPurpose.Signing),
|
functionFullName,
|
||||||
functionFullName,
|
)
|
||||||
)
|
|
||||||
.value,
|
|
||||||
err => CryptoPublicStoreError.FailedToReadKey(signingKeyId, err.toString),
|
|
||||||
)
|
|
||||||
|
|
||||||
override def readEncryptionKey(encryptionKeyId: Fingerprint)(implicit
|
override def readEncryptionKey(encryptionKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[EncryptionPublicKeyWithName]] =
|
): OptionT[FutureUnlessShutdown, EncryptionPublicKeyWithName] =
|
||||||
EitherTUtil.fromFuture(
|
storage
|
||||||
storage
|
.querySingleUnlessShutdown(
|
||||||
.querySingleUnlessShutdown(
|
queryKeyO[EncryptionPublicKeyWithName](encryptionKeyId, KeyPurpose.Encryption),
|
||||||
queryKey[EncryptionPublicKeyWithName](encryptionKeyId, KeyPurpose.Encryption),
|
functionFullName,
|
||||||
functionFullName,
|
)
|
||||||
)
|
|
||||||
.value,
|
|
||||||
err => CryptoPublicStoreError.FailedToReadKey(encryptionKeyId, err.toString),
|
|
||||||
)
|
|
||||||
|
|
||||||
override protected def writeSigningKey(key: SigningPublicKey, name: Option[KeyName])(implicit
|
override protected def writeSigningKey(key: SigningPublicKey, name: Option[KeyName])(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] =
|
): FutureUnlessShutdown[Unit] =
|
||||||
insertKey[SigningPublicKey, SigningPublicKeyWithName](key, name)
|
insertKey[SigningPublicKey, SigningPublicKeyWithName](key, name)
|
||||||
|
|
||||||
override protected def writeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName])(
|
override protected def writeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName])(
|
||||||
implicit traceContext: TraceContext
|
implicit traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] =
|
): FutureUnlessShutdown[Unit] =
|
||||||
insertKey[EncryptionPublicKey, EncryptionPublicKeyWithName](key, name)
|
insertKey[EncryptionPublicKey, EncryptionPublicKeyWithName](key, name)
|
||||||
|
|
||||||
override private[store] def listSigningKeys(implicit
|
override private[store] def listSigningKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[SigningPublicKeyWithName]] =
|
): FutureUnlessShutdown[Set[SigningPublicKeyWithName]] =
|
||||||
EitherTUtil.fromFuture(
|
storage.queryUnlessShutdown(
|
||||||
storage.queryUnlessShutdown(
|
queryKeys[SigningPublicKeyWithName](KeyPurpose.Signing),
|
||||||
queryKeys[SigningPublicKeyWithName](KeyPurpose.Signing),
|
functionFullName,
|
||||||
functionFullName,
|
|
||||||
),
|
|
||||||
err => CryptoPublicStoreError.FailedToListKeys(err.toString),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override private[store] def listEncryptionKeys(implicit
|
override private[store] def listEncryptionKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[EncryptionPublicKeyWithName]] =
|
): FutureUnlessShutdown[Set[EncryptionPublicKeyWithName]] =
|
||||||
EitherTUtil
|
storage
|
||||||
.fromFuture(
|
.queryUnlessShutdown(
|
||||||
storage
|
queryKeys[EncryptionPublicKeyWithName](KeyPurpose.Encryption),
|
||||||
.queryUnlessShutdown(
|
functionFullName,
|
||||||
queryKeys[EncryptionPublicKeyWithName](KeyPurpose.Encryption),
|
|
||||||
functionFullName,
|
|
||||||
),
|
|
||||||
err => CryptoPublicStoreError.FailedToListKeys(err.toString),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override private[crypto] def deleteKey(
|
||||||
|
keyId: Fingerprint
|
||||||
|
)(implicit traceContext: TraceContext): FutureUnlessShutdown[Unit] = {
|
||||||
|
storage
|
||||||
|
.updateUnlessShutdown_(
|
||||||
|
sqlu"delete from common_crypto_public_keys where key_id = $keyId",
|
||||||
|
functionFullName,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,76 +3,102 @@
|
|||||||
|
|
||||||
package com.digitalasset.canton.crypto.store.memory
|
package com.digitalasset.canton.crypto.store.memory
|
||||||
|
|
||||||
import cats.data.EitherT
|
import cats.data.OptionT
|
||||||
import cats.syntax.either.*
|
import cats.syntax.either.*
|
||||||
import com.digitalasset.canton.crypto.store.{CryptoPublicStore, CryptoPublicStoreError}
|
import com.digitalasset.canton.crypto.store.{CryptoPublicStore, CryptoPublicStoreError}
|
||||||
import com.digitalasset.canton.crypto.{KeyName, *}
|
import com.digitalasset.canton.crypto.{KeyName, *}
|
||||||
|
import com.digitalasset.canton.discard.Implicits.DiscardOps
|
||||||
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
||||||
|
import com.digitalasset.canton.logging.pretty.Pretty
|
||||||
|
import com.digitalasset.canton.logging.{NamedLoggerFactory, NamedLogging}
|
||||||
import com.digitalasset.canton.tracing.TraceContext
|
import com.digitalasset.canton.tracing.TraceContext
|
||||||
import com.digitalasset.canton.util.TrieMapUtil
|
import com.digitalasset.canton.util.{ErrorUtil, TrieMapUtil}
|
||||||
|
|
||||||
import scala.collection.concurrent.TrieMap
|
import scala.collection.concurrent.TrieMap
|
||||||
import scala.concurrent.ExecutionContext
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
class InMemoryCryptoPublicStore(override implicit val ec: ExecutionContext)
|
class InMemoryCryptoPublicStore(override protected val loggerFactory: NamedLoggerFactory)(
|
||||||
extends CryptoPublicStore {
|
override implicit val ec: ExecutionContext
|
||||||
|
) extends CryptoPublicStore
|
||||||
|
with NamedLogging {
|
||||||
|
|
||||||
private val storedSigningKeyMap: TrieMap[Fingerprint, SigningPublicKeyWithName] = TrieMap.empty
|
private val storedSigningKeyMap: TrieMap[Fingerprint, SigningPublicKeyWithName] = TrieMap.empty
|
||||||
private val storedEncryptionKeyMap: TrieMap[Fingerprint, EncryptionPublicKeyWithName] =
|
private val storedEncryptionKeyMap: TrieMap[Fingerprint, EncryptionPublicKeyWithName] =
|
||||||
TrieMap.empty
|
TrieMap.empty
|
||||||
|
|
||||||
private def errorKeyDuplicate[K <: PublicKeyWithName](
|
private def errorKeyDuplicate[K <: PublicKeyWithName: Pretty](
|
||||||
keyId: Fingerprint,
|
keyId: Fingerprint,
|
||||||
oldKey: K,
|
oldKey: K,
|
||||||
newKey: K,
|
newKey: K,
|
||||||
): CryptoPublicStoreError =
|
): CryptoPublicStoreError =
|
||||||
CryptoPublicStoreError.KeyAlreadyExists(keyId, oldKey.name.map(_.unwrap))
|
CryptoPublicStoreError.KeyAlreadyExists(keyId, oldKey, newKey)
|
||||||
|
|
||||||
override protected def writeSigningKey(key: SigningPublicKey, name: Option[KeyName])(implicit
|
override protected def writeSigningKey(key: SigningPublicKey, name: Option[KeyName])(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] = {
|
): FutureUnlessShutdown[Unit] = {
|
||||||
TrieMapUtil
|
FutureUnlessShutdown.wrap {
|
||||||
.insertIfAbsent(
|
TrieMapUtil
|
||||||
storedSigningKeyMap,
|
.insertIfAbsent(
|
||||||
key.id,
|
storedSigningKeyMap,
|
||||||
SigningPublicKeyWithName(key, name),
|
key.id,
|
||||||
errorKeyDuplicate[SigningPublicKeyWithName] _,
|
SigningPublicKeyWithName(key, name),
|
||||||
)
|
errorKeyDuplicate[SigningPublicKeyWithName] _,
|
||||||
.toEitherT
|
)
|
||||||
|
.valueOr { err =>
|
||||||
|
ErrorUtil.invalidState(
|
||||||
|
s"Existing public key for ${key.id} is different than inserted key: $err"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def readSigningKey(signingKeyId: Fingerprint)(implicit
|
override def readSigningKey(signingKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[SigningPublicKeyWithName]] =
|
): OptionT[FutureUnlessShutdown, SigningPublicKeyWithName] =
|
||||||
EitherT.rightT(storedSigningKeyMap.get(signingKeyId))
|
OptionT.fromOption(storedSigningKeyMap.get(signingKeyId))
|
||||||
|
|
||||||
override def readEncryptionKey(encryptionKeyId: Fingerprint)(implicit
|
override def readEncryptionKey(encryptionKeyId: Fingerprint)(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[EncryptionPublicKeyWithName]] =
|
): OptionT[FutureUnlessShutdown, EncryptionPublicKeyWithName] =
|
||||||
EitherT.rightT(storedEncryptionKeyMap.get(encryptionKeyId))
|
OptionT.fromOption(storedEncryptionKeyMap.get(encryptionKeyId))
|
||||||
|
|
||||||
override protected def writeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName])(
|
override protected def writeEncryptionKey(key: EncryptionPublicKey, name: Option[KeyName])(
|
||||||
implicit traceContext: TraceContext
|
implicit traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Unit] = {
|
): FutureUnlessShutdown[Unit] = {
|
||||||
TrieMapUtil
|
FutureUnlessShutdown.wrap {
|
||||||
.insertIfAbsent(
|
TrieMapUtil
|
||||||
storedEncryptionKeyMap,
|
.insertIfAbsent(
|
||||||
key.id,
|
storedEncryptionKeyMap,
|
||||||
EncryptionPublicKeyWithName(key, name),
|
key.id,
|
||||||
errorKeyDuplicate[EncryptionPublicKeyWithName] _,
|
EncryptionPublicKeyWithName(key, name),
|
||||||
)
|
errorKeyDuplicate[EncryptionPublicKeyWithName] _,
|
||||||
.toEitherT
|
)
|
||||||
|
.valueOr { _ =>
|
||||||
|
ErrorUtil.invalidState(
|
||||||
|
s"Existing public key for ${key.id} is different than inserted key"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override private[store] def listSigningKeys(implicit
|
override private[store] def listSigningKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[SigningPublicKeyWithName]] =
|
): FutureUnlessShutdown[Set[SigningPublicKeyWithName]] =
|
||||||
EitherT.rightT(storedSigningKeyMap.values.toSet)
|
FutureUnlessShutdown.pure(storedSigningKeyMap.values.toSet)
|
||||||
|
|
||||||
override private[store] def listEncryptionKeys(implicit
|
override private[store] def listEncryptionKeys(implicit
|
||||||
traceContext: TraceContext
|
traceContext: TraceContext
|
||||||
): EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Set[EncryptionPublicKeyWithName]] =
|
): FutureUnlessShutdown[Set[EncryptionPublicKeyWithName]] =
|
||||||
EitherT.rightT(storedEncryptionKeyMap.values.toSet)
|
FutureUnlessShutdown.pure(storedEncryptionKeyMap.values.toSet)
|
||||||
|
|
||||||
|
override private[crypto] def deleteKey(
|
||||||
|
keyId: Fingerprint
|
||||||
|
)(implicit traceContext: TraceContext): FutureUnlessShutdown[Unit] = {
|
||||||
|
storedSigningKeyMap.remove(keyId).discard
|
||||||
|
storedEncryptionKeyMap.remove(keyId).discard
|
||||||
|
FutureUnlessShutdown.unit
|
||||||
|
}
|
||||||
|
|
||||||
override def close(): Unit = ()
|
override def close(): Unit = ()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,14 @@ object CantonNodeParameters {
|
|||||||
) extends CantonNodeParameters.General
|
) extends CantonNodeParameters.General
|
||||||
}
|
}
|
||||||
trait Protocol {
|
trait Protocol {
|
||||||
def devVersionSupport: Boolean
|
def alphaVersionSupport: Boolean
|
||||||
def betaVersionSupport: Boolean
|
def betaVersionSupport: Boolean
|
||||||
def dontWarnOnDeprecatedPV: Boolean
|
def dontWarnOnDeprecatedPV: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
object Protocol {
|
object Protocol {
|
||||||
final case class Impl(
|
final case class Impl(
|
||||||
devVersionSupport: Boolean,
|
alphaVersionSupport: Boolean,
|
||||||
betaVersionSupport: Boolean,
|
betaVersionSupport: Boolean,
|
||||||
dontWarnOnDeprecatedPV: Boolean,
|
dontWarnOnDeprecatedPV: Boolean,
|
||||||
) extends CantonNodeParameters.Protocol
|
) extends CantonNodeParameters.Protocol
|
||||||
@ -95,7 +95,7 @@ trait HasProtocolCantonNodeParameters extends CantonNodeParameters.Protocol {
|
|||||||
|
|
||||||
protected def protocol: CantonNodeParameters.Protocol
|
protected def protocol: CantonNodeParameters.Protocol
|
||||||
|
|
||||||
def devVersionSupport: Boolean = protocol.devVersionSupport
|
def alphaVersionSupport: Boolean = protocol.alphaVersionSupport
|
||||||
def betaVersionSupport: Boolean = protocol.betaVersionSupport
|
def betaVersionSupport: Boolean = protocol.betaVersionSupport
|
||||||
def dontWarnOnDeprecatedPV: Boolean = protocol.dontWarnOnDeprecatedPV
|
def dontWarnOnDeprecatedPV: Boolean = protocol.dontWarnOnDeprecatedPV
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,10 @@ object FutureUnlessShutdown {
|
|||||||
Future.successful(x)
|
Future.successful(x)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** Analog to Future.apply that handles an exception of `x` as a failed future. */
|
||||||
|
def wrap[A](x: => A)(implicit ec: ExecutionContext): FutureUnlessShutdown[A] =
|
||||||
|
FutureUnlessShutdown.outcomeF(Future(x))
|
||||||
|
|
||||||
/** Wraps the result of a [[scala.concurrent.Future]] into an [[UnlessShutdown.Outcome]] */
|
/** Wraps the result of a [[scala.concurrent.Future]] into an [[UnlessShutdown.Outcome]] */
|
||||||
def outcomeF[A](f: Future[A])(implicit ec: ExecutionContext): FutureUnlessShutdown[A] =
|
def outcomeF[A](f: Future[A])(implicit ec: ExecutionContext): FutureUnlessShutdown[A] =
|
||||||
FutureUnlessShutdown(f.map(UnlessShutdown.Outcome(_)))
|
FutureUnlessShutdown(f.map(UnlessShutdown.Outcome(_)))
|
||||||
|
@ -154,9 +154,11 @@ object EncryptedView {
|
|||||||
traceContext: TraceContext,
|
traceContext: TraceContext,
|
||||||
): EitherT[FutureUnlessShutdown, InvalidEncryptionKey, Unit] =
|
): EitherT[FutureUnlessShutdown, InvalidEncryptionKey, Unit] =
|
||||||
for {
|
for {
|
||||||
encryptionKey <- cryptoPublicStore
|
encryptionKey <- EitherT.right(
|
||||||
.findEncryptionKeyIdByFingerprint(keyId)
|
cryptoPublicStore
|
||||||
.leftMap(err => DecryptionError.InvalidEncryptionKey(err.show))
|
.findEncryptionKeyIdByFingerprint(keyId)
|
||||||
|
.value
|
||||||
|
)
|
||||||
_ <- encryptionKey match {
|
_ <- encryptionKey match {
|
||||||
case Some(encPubKey) =>
|
case Some(encPubKey) =>
|
||||||
EitherT.cond[FutureUnlessShutdown](
|
EitherT.cond[FutureUnlessShutdown](
|
||||||
|
@ -49,14 +49,14 @@ trait DbMigrations { this: NamedLogging =>
|
|||||||
* A user that does that, won't be able to upgrade to new Canton versions, as we reserve our right to just
|
* A user that does that, won't be able to upgrade to new Canton versions, as we reserve our right to just
|
||||||
* modify the dev version files in any way we like.
|
* modify the dev version files in any way we like.
|
||||||
*/
|
*/
|
||||||
protected def devVersionSupport: Boolean
|
protected def alphaVersionSupport: Boolean
|
||||||
|
|
||||||
/** Database is migrated using Flyway, which looks at the migration files at
|
/** Database is migrated using Flyway, which looks at the migration files at
|
||||||
* src/main/resources/db/migration/canton as explained at https://flywaydb.org/documentation/getstarted/firststeps/api
|
* src/main/resources/db/migration/canton as explained at https://flywaydb.org/documentation/getstarted/firststeps/api
|
||||||
*/
|
*/
|
||||||
protected def createFlyway(dataSource: DataSource): Flyway = {
|
protected def createFlyway(dataSource: DataSource): Flyway = {
|
||||||
Flyway.configure
|
Flyway.configure
|
||||||
.locations(dbConfig.buildMigrationsPaths(devVersionSupport)*)
|
.locations(dbConfig.buildMigrationsPaths(alphaVersionSupport)*)
|
||||||
.dataSource(dataSource)
|
.dataSource(dataSource)
|
||||||
.cleanDisabled(!dbConfig.parameters.unsafeCleanOnValidationError)
|
.cleanDisabled(!dbConfig.parameters.unsafeCleanOnValidationError)
|
||||||
.cleanOnValidationError(dbConfig.parameters.unsafeCleanOnValidationError)
|
.cleanOnValidationError(dbConfig.parameters.unsafeCleanOnValidationError)
|
||||||
@ -298,7 +298,7 @@ class CommunityDbMigrationsFactory(loggerFactory: NamedLoggerFactory) extends Db
|
|||||||
|
|
||||||
class CommunityDbMigrations(
|
class CommunityDbMigrations(
|
||||||
protected val dbConfig: DbConfig,
|
protected val dbConfig: DbConfig,
|
||||||
protected val devVersionSupport: Boolean,
|
protected val alphaVersionSupport: Boolean,
|
||||||
protected val loggerFactory: NamedLoggerFactory,
|
protected val loggerFactory: NamedLoggerFactory,
|
||||||
)(implicit override protected val closeContext: CloseContext)
|
)(implicit override protected val closeContext: CloseContext)
|
||||||
extends DbMigrations
|
extends DbMigrations
|
||||||
|
@ -10,12 +10,12 @@ import com.digitalasset.canton.buildinfo.BuildInfo
|
|||||||
import com.digitalasset.canton.logging.pretty.{Pretty, PrettyPrinting}
|
import com.digitalasset.canton.logging.pretty.{Pretty, PrettyPrinting}
|
||||||
import com.digitalasset.canton.serialization.ProtoConverter.ParsingResult
|
import com.digitalasset.canton.serialization.ProtoConverter.ParsingResult
|
||||||
import com.digitalasset.canton.version.ProtocolVersion.{
|
import com.digitalasset.canton.version.ProtocolVersion.{
|
||||||
|
alpha,
|
||||||
beta,
|
beta,
|
||||||
deleted,
|
deleted,
|
||||||
deprecated,
|
deprecated,
|
||||||
stable,
|
stable,
|
||||||
supported,
|
supported,
|
||||||
unstable,
|
|
||||||
}
|
}
|
||||||
import pureconfig.error.FailureReason
|
import pureconfig.error.FailureReason
|
||||||
import pureconfig.{ConfigReader, ConfigWriter}
|
import pureconfig.{ConfigReader, ConfigWriter}
|
||||||
@ -38,11 +38,11 @@ import slick.jdbc.{GetResult, PositionedParameters, SetParameter}
|
|||||||
*
|
*
|
||||||
* How to add a new protocol version `N`:
|
* How to add a new protocol version `N`:
|
||||||
* - Define a new constant `v<N>` in the [[ProtocolVersion$]] object via
|
* - Define a new constant `v<N>` in the [[ProtocolVersion$]] object via
|
||||||
* {{{lazy val v<N>: ProtocolVersionWithStatus[Unstable] = ProtocolVersion.unstable(<N>)}}}
|
* {{{lazy val v<N>: ProtocolVersionWithStatus[Alpha] = ProtocolVersion.alpha(<N>)}}}
|
||||||
*
|
*
|
||||||
* - The new protocol version should be declared as unstable until it is released:
|
* - The new protocol version should be declared as alpha until it is released:
|
||||||
* Define it with type argument [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Unstable]]
|
* Define it with type argument [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Alpha]]
|
||||||
* and add it to the list in [[com.digitalasset.canton.version.ProtocolVersion.unstable]].
|
* and add it to the list in [[com.digitalasset.canton.version.ProtocolVersion.alpha]].
|
||||||
*
|
*
|
||||||
* - Add a new test job for the protocol version `N` to the canton_build workflow.
|
* - Add a new test job for the protocol version `N` to the canton_build workflow.
|
||||||
* Make a sensible decision how often it should run.
|
* Make a sensible decision how often it should run.
|
||||||
@ -51,16 +51,16 @@ import slick.jdbc.{GetResult, PositionedParameters, SetParameter}
|
|||||||
*
|
*
|
||||||
* How to release a protocol version `N`:
|
* How to release a protocol version `N`:
|
||||||
* - Switch the type parameter of the protocol version constant `v<N>` from
|
* - Switch the type parameter of the protocol version constant `v<N>` from
|
||||||
* [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Unstable]] to [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Stable]]
|
* [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Alpha]] to [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Stable]]
|
||||||
* As a result, you may have to modify a couple of protobuf definitions and mark them as stable as well.
|
* As a result, you may have to modify a couple of protobuf definitions and mark them as stable as well.
|
||||||
*
|
*
|
||||||
* - Remove `v<N>` from [[com.digitalasset.canton.version.ProtocolVersion.unstable]]
|
* - Remove `v<N>` from [[com.digitalasset.canton.version.ProtocolVersion.alpha]]
|
||||||
* and add it to [[com.digitalasset.canton.buildinfo.BuildInfo.stableProtocolVersions]].
|
* and add it to [[com.digitalasset.canton.buildinfo.BuildInfo.stableProtocolVersions]].
|
||||||
*
|
*
|
||||||
* How to release a protocol version `N` as Beta:
|
* How to release a protocol version `N` as Beta:
|
||||||
* - Switch the type parameter of the protocol version constant `v<N>` from
|
* - Switch the type parameter of the protocol version constant `v<N>` from
|
||||||
* [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Unstable]] to [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Beta]]
|
* [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Alpha]] to [[com.digitalasset.canton.version.ProtocolVersionAnnotation.Beta]]
|
||||||
* - Remove `v<N>` from [[com.digitalasset.canton.version.ProtocolVersion.unstable]]
|
* - Remove `v<N>` from [[com.digitalasset.canton.version.ProtocolVersion.alpha]]
|
||||||
* and add it to [[com.digitalasset.canton.buildinfo.BuildInfo.betaProtocolVersions]].
|
* and add it to [[com.digitalasset.canton.buildinfo.BuildInfo.betaProtocolVersions]].
|
||||||
*
|
*
|
||||||
* - Check the test jobs for protocol versions:
|
* - Check the test jobs for protocol versions:
|
||||||
@ -79,7 +79,7 @@ sealed case class ProtocolVersion private[version] (v: Int)
|
|||||||
|
|
||||||
def isDeprecated: Boolean = deprecated.contains(this)
|
def isDeprecated: Boolean = deprecated.contains(this)
|
||||||
|
|
||||||
def isUnstable: Boolean = unstable.contains(this)
|
def isUnstable: Boolean = alpha.contains(this)
|
||||||
|
|
||||||
def isBeta: Boolean = beta.contains(this)
|
def isBeta: Boolean = beta.contains(this)
|
||||||
|
|
||||||
@ -110,10 +110,11 @@ object ProtocolVersion {
|
|||||||
v: Int
|
v: Int
|
||||||
): ProtocolVersionWithStatus[ProtocolVersionAnnotation.Stable] =
|
): ProtocolVersionWithStatus[ProtocolVersionAnnotation.Stable] =
|
||||||
createWithStatus[ProtocolVersionAnnotation.Stable](v)
|
createWithStatus[ProtocolVersionAnnotation.Stable](v)
|
||||||
private[version] def createUnstable(
|
|
||||||
|
private[version] def createAlpha(
|
||||||
v: Int
|
v: Int
|
||||||
): ProtocolVersionWithStatus[ProtocolVersionAnnotation.Unstable] =
|
): ProtocolVersionWithStatus[ProtocolVersionAnnotation.Alpha] =
|
||||||
createWithStatus[ProtocolVersionAnnotation.Unstable](v)
|
createWithStatus[ProtocolVersionAnnotation.Alpha](v)
|
||||||
private[version] def createBeta(
|
private[version] def createBeta(
|
||||||
v: Int
|
v: Int
|
||||||
): ProtocolVersionWithStatus[ProtocolVersionAnnotation.Beta] =
|
): ProtocolVersionWithStatus[ProtocolVersionAnnotation.Beta] =
|
||||||
@ -236,31 +237,31 @@ object ProtocolVersion {
|
|||||||
ProtocolVersion(30),
|
ProtocolVersion(30),
|
||||||
)
|
)
|
||||||
|
|
||||||
val unstable: NonEmpty[List[ProtocolVersionWithStatus[ProtocolVersionAnnotation.Unstable]]] =
|
val alpha: NonEmpty[List[ProtocolVersionWithStatus[ProtocolVersionAnnotation.Alpha]]] =
|
||||||
NonEmpty.mk(List, ProtocolVersion.v31, ProtocolVersion.dev)
|
NonEmpty.mk(List, ProtocolVersion.v31, ProtocolVersion.dev)
|
||||||
|
|
||||||
val beta: List[ProtocolVersionWithStatus[ProtocolVersionAnnotation.Beta]] =
|
val beta: List[ProtocolVersionWithStatus[ProtocolVersionAnnotation.Beta]] =
|
||||||
parseFromBuildInfo(BuildInfo.betaProtocolVersions.toSeq)
|
parseFromBuildInfo(BuildInfo.betaProtocolVersions.toSeq)
|
||||||
.map(pv => ProtocolVersion.createBeta(pv.v))
|
.map(pv => ProtocolVersion.createBeta(pv.v))
|
||||||
|
|
||||||
val supported: NonEmpty[List[ProtocolVersion]] = (unstable ++ beta ++ stable).sorted
|
val supported: NonEmpty[List[ProtocolVersion]] = (alpha ++ beta ++ stable).sorted
|
||||||
|
|
||||||
private val allProtocolVersions = deprecated ++ deleted ++ unstable ++ beta ++ stable
|
private val allProtocolVersions = deprecated ++ deleted ++ alpha ++ beta ++ stable
|
||||||
|
|
||||||
require(
|
require(
|
||||||
allProtocolVersions.sizeCompare(allProtocolVersions.distinct) == 0,
|
allProtocolVersions.sizeCompare(allProtocolVersions.distinct) == 0,
|
||||||
s"All the protocol versions should be distinct." +
|
s"All the protocol versions should be distinct." +
|
||||||
s"Found: ${Map("deprecated" -> deprecated, "deleted" -> deleted, "unstable" -> unstable, "stable" -> stable)}",
|
s"Found: ${Map("deprecated" -> deprecated, "deleted" -> deleted, "alpha" -> alpha, "stable" -> stable)}",
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(i15561): change back to `stableAndSupported.max1` once there is a stable Daml 3 protocol version
|
// TODO(i15561): change back to `stableAndSupported.max1` once there is a stable Daml 3 protocol version
|
||||||
val latest: ProtocolVersion = stable.lastOption.getOrElse(unstable.head1)
|
val latest: ProtocolVersion = stable.lastOption.getOrElse(alpha.head1)
|
||||||
|
|
||||||
lazy val dev: ProtocolVersionWithStatus[ProtocolVersionAnnotation.Unstable] =
|
lazy val dev: ProtocolVersionWithStatus[ProtocolVersionAnnotation.Alpha] =
|
||||||
ProtocolVersion.createUnstable(Int.MaxValue)
|
ProtocolVersion.createAlpha(Int.MaxValue)
|
||||||
|
|
||||||
lazy val v31: ProtocolVersionWithStatus[ProtocolVersionAnnotation.Unstable] =
|
lazy val v31: ProtocolVersionWithStatus[ProtocolVersionAnnotation.Alpha] =
|
||||||
ProtocolVersion.createUnstable(31)
|
ProtocolVersion.createAlpha(31)
|
||||||
|
|
||||||
// Minimum stable protocol version introduced
|
// Minimum stable protocol version introduced
|
||||||
lazy val minimum: ProtocolVersion = v31
|
lazy val minimum: ProtocolVersion = v31
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: CantonExamples
|
name: CantonExamples
|
||||||
|
@ -32,7 +32,7 @@ trait LocalNodeParametersConfig {
|
|||||||
/** Various cache sizes */
|
/** Various cache sizes */
|
||||||
def caching: CachingConfigs
|
def caching: CachingConfigs
|
||||||
def useUnifiedSequencer: Boolean
|
def useUnifiedSequencer: Boolean
|
||||||
def devVersionSupport: Boolean
|
def alphaVersionSupport: Boolean
|
||||||
def watchdog: Option[WatchdogConfig]
|
def watchdog: Option[WatchdogConfig]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
package com.digitalasset.canton.config
|
package com.digitalasset.canton.config
|
||||||
|
|
||||||
trait ProtocolConfig {
|
trait ProtocolConfig {
|
||||||
def devVersionSupport: Boolean
|
def alphaVersionSupport: Boolean
|
||||||
def betaVersionSupport: Boolean
|
def betaVersionSupport: Boolean
|
||||||
def dontWarnOnDeprecatedPV: Boolean
|
def dontWarnOnDeprecatedPV: Boolean
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.digitalasset.canton.ProtoDeserializationError.ProtoDeserializationFai
|
|||||||
import com.digitalasset.canton.config.CantonRequireTypes.String300
|
import com.digitalasset.canton.config.CantonRequireTypes.String300
|
||||||
import com.digitalasset.canton.config.ProcessingTimeout
|
import com.digitalasset.canton.config.ProcessingTimeout
|
||||||
import com.digitalasset.canton.crypto.admin.v30
|
import com.digitalasset.canton.crypto.admin.v30
|
||||||
import com.digitalasset.canton.crypto.store.{CryptoPrivateStoreError, CryptoPublicStoreError}
|
import com.digitalasset.canton.crypto.store.CryptoPrivateStoreError
|
||||||
import com.digitalasset.canton.crypto.{v30 as cryptoproto, *}
|
import com.digitalasset.canton.crypto.{v30 as cryptoproto, *}
|
||||||
import com.digitalasset.canton.error.BaseCantonError
|
import com.digitalasset.canton.error.BaseCantonError
|
||||||
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
import com.digitalasset.canton.lifecycle.FutureUnlessShutdown
|
||||||
@ -59,11 +59,7 @@ class GrpcVaultService(
|
|||||||
override def listMyKeys(request: v30.ListMyKeysRequest): Future[v30.ListMyKeysResponse] = {
|
override def listMyKeys(request: v30.ListMyKeysRequest): Future[v30.ListMyKeysResponse] = {
|
||||||
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
||||||
val result = for {
|
val result = for {
|
||||||
keys <- crypto.cryptoPublicStore.publicKeysWithName
|
keys <- EitherT.right(crypto.cryptoPublicStore.publicKeysWithName)
|
||||||
.leftMap[BaseCantonError] { err =>
|
|
||||||
CryptoPublicStoreError.ErrorCode
|
|
||||||
.WrapStr(s"Failed to retrieve public keys: $err")
|
|
||||||
}
|
|
||||||
publicKeys <-
|
publicKeys <-
|
||||||
keys.toList.parFilterA(pk =>
|
keys.toList.parFilterA(pk =>
|
||||||
crypto.cryptoPrivateStore
|
crypto.cryptoPrivateStore
|
||||||
@ -100,7 +96,7 @@ class GrpcVaultService(
|
|||||||
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
||||||
for {
|
for {
|
||||||
publicKey <-
|
publicKey <-
|
||||||
FutureUnlessShutdown.pure(
|
FutureUnlessShutdown.wrap(
|
||||||
ProtoConverter
|
ProtoConverter
|
||||||
.parse(
|
.parse(
|
||||||
cryptoproto.PublicKey.parseFrom,
|
cryptoproto.PublicKey.parseFrom,
|
||||||
@ -109,14 +105,12 @@ class GrpcVaultService(
|
|||||||
)
|
)
|
||||||
.valueOr(err => throw ProtoDeserializationFailure.WrapNoLogging(err).asGrpcError)
|
.valueOr(err => throw ProtoDeserializationFailure.WrapNoLogging(err).asGrpcError)
|
||||||
)
|
)
|
||||||
name <- FutureUnlessShutdown.pure(
|
name <- FutureUnlessShutdown.wrap(
|
||||||
KeyName
|
KeyName
|
||||||
.fromProtoPrimitive(request.name)
|
.fromProtoPrimitive(request.name)
|
||||||
.valueOr(err => throw ProtoDeserializationFailure.WrapNoLogging(err).asGrpcError)
|
.valueOr(err => throw ProtoDeserializationFailure.WrapNoLogging(err).asGrpcError)
|
||||||
)
|
)
|
||||||
_ <- crypto.cryptoPublicStore
|
_ <- crypto.cryptoPublicStore.storePublicKey(publicKey, name.emptyStringAsNone)
|
||||||
.storePublicKey(publicKey, name.emptyStringAsNone)
|
|
||||||
.valueOr(err => throw CryptoPublicStoreError.ErrorCode.Wrap(err).asGrpcError)
|
|
||||||
} yield v30.ImportPublicKeyResponse(fingerprint = publicKey.fingerprint.unwrap)
|
} yield v30.ImportPublicKeyResponse(fingerprint = publicKey.fingerprint.unwrap)
|
||||||
}.failOnShutdownTo(AbortedDueToShutdown.Error().asGrpcError)
|
}.failOnShutdownTo(AbortedDueToShutdown.Error().asGrpcError)
|
||||||
|
|
||||||
@ -125,15 +119,11 @@ class GrpcVaultService(
|
|||||||
): Future[v30.ListPublicKeysResponse] = {
|
): Future[v30.ListPublicKeysResponse] = {
|
||||||
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
||||||
crypto.cryptoPublicStore.publicKeysWithName
|
crypto.cryptoPublicStore.publicKeysWithName
|
||||||
.map(keys =>
|
.map { keys =>
|
||||||
v30.ListPublicKeysResponse(listPublicKeys(request.filters, keys).map(_.toProtoV30))
|
v30.ListPublicKeysResponse(listPublicKeys(request.filters, keys).map(_.toProtoV30))
|
||||||
)
|
}
|
||||||
.valueOr(err =>
|
.failOnShutdownTo(AbortedDueToShutdown.Error().asGrpcError)
|
||||||
throw CryptoPublicStoreError.ErrorCode
|
}
|
||||||
.WrapStr(s"Failed to retrieve public keys: $err")
|
|
||||||
.asGrpcError
|
|
||||||
)
|
|
||||||
}.failOnShutdownTo(AbortedDueToShutdown.Error().asGrpcError)
|
|
||||||
|
|
||||||
override def generateSigningKey(
|
override def generateSigningKey(
|
||||||
request: v30.GenerateSigningKeyRequest
|
request: v30.GenerateSigningKeyRequest
|
||||||
@ -232,7 +222,7 @@ class GrpcVaultService(
|
|||||||
.asRuntimeException()
|
.asRuntimeException()
|
||||||
)
|
)
|
||||||
cryptoPrivateStore <-
|
cryptoPrivateStore <-
|
||||||
FutureUnlessShutdown.pure(
|
FutureUnlessShutdown.wrap(
|
||||||
crypto.cryptoPrivateStore.toExtended.getOrElse(
|
crypto.cryptoPrivateStore.toExtended.getOrElse(
|
||||||
throw Status.FAILED_PRECONDITION
|
throw Status.FAILED_PRECONDITION
|
||||||
.withDescription(
|
.withDescription(
|
||||||
@ -242,7 +232,7 @@ class GrpcVaultService(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
fingerprint <-
|
fingerprint <-
|
||||||
FutureUnlessShutdown.pure(
|
FutureUnlessShutdown.wrap(
|
||||||
Fingerprint
|
Fingerprint
|
||||||
.fromProtoPrimitive(request.fingerprint)
|
.fromProtoPrimitive(request.fingerprint)
|
||||||
.valueOr(err =>
|
.valueOr(err =>
|
||||||
@ -252,7 +242,7 @@ class GrpcVaultService(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
protocolVersion <-
|
protocolVersion <-
|
||||||
FutureUnlessShutdown.pure(
|
FutureUnlessShutdown.wrap(
|
||||||
ProtocolVersion
|
ProtocolVersion
|
||||||
.fromProtoPrimitive(request.protocolVersion)
|
.fromProtoPrimitive(request.protocolVersion)
|
||||||
.valueOr(err =>
|
.valueOr(err =>
|
||||||
@ -276,8 +266,7 @@ class GrpcVaultService(
|
|||||||
publicKey <- EitherTUtil.toFutureUnlessShutdown(
|
publicKey <- EitherTUtil.toFutureUnlessShutdown(
|
||||||
crypto.cryptoPublicStore
|
crypto.cryptoPublicStore
|
||||||
.publicKey(fingerprint)
|
.publicKey(fingerprint)
|
||||||
.leftMap(_.toString)
|
.toRight(s"no public key found for [$fingerprint]")
|
||||||
.subflatMap(_.toRight(s"no public key found for [$fingerprint]"))
|
|
||||||
.leftMap(err =>
|
.leftMap(err =>
|
||||||
Status.FAILED_PRECONDITION
|
Status.FAILED_PRECONDITION
|
||||||
.withDescription(s"Error retrieving public key [$fingerprint] $err")
|
.withDescription(s"Error retrieving public key [$fingerprint] $err")
|
||||||
@ -351,7 +340,7 @@ class GrpcVaultService(
|
|||||||
keyPair: CryptoKeyPair[PublicKey, PrivateKey],
|
keyPair: CryptoKeyPair[PublicKey, PrivateKey],
|
||||||
)(implicit traceContext: TraceContext): FutureUnlessShutdown[Unit] =
|
)(implicit traceContext: TraceContext): FutureUnlessShutdown[Unit] =
|
||||||
for {
|
for {
|
||||||
cryptoPrivateStore <- FutureUnlessShutdown.pure(
|
cryptoPrivateStore <- FutureUnlessShutdown.wrap(
|
||||||
crypto.cryptoPrivateStore.toExtended.getOrElse(
|
crypto.cryptoPrivateStore.toExtended.getOrElse(
|
||||||
throw Status.FAILED_PRECONDITION
|
throw Status.FAILED_PRECONDITION
|
||||||
.withDescription(
|
.withDescription(
|
||||||
@ -360,20 +349,7 @@ class GrpcVaultService(
|
|||||||
.asRuntimeException()
|
.asRuntimeException()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
_ <- crypto.cryptoPublicStore
|
_ <- crypto.cryptoPublicStore.storePublicKey(keyPair.publicKey, validatedName)
|
||||||
.storePublicKey(keyPair.publicKey, validatedName)
|
|
||||||
.recoverWith {
|
|
||||||
// if the existing key is the same, then ignore error
|
|
||||||
case error: CryptoPublicStoreError.KeyAlreadyExists =>
|
|
||||||
for {
|
|
||||||
existing <- crypto.cryptoPublicStore.publicKey(keyPair.publicKey.fingerprint)
|
|
||||||
_ <-
|
|
||||||
if (existing.contains(keyPair.publicKey))
|
|
||||||
EitherT.rightT[FutureUnlessShutdown, CryptoPublicStoreError](())
|
|
||||||
else EitherT.leftT[FutureUnlessShutdown, Unit](error: CryptoPublicStoreError)
|
|
||||||
} yield ()
|
|
||||||
}
|
|
||||||
.valueOr(err => throw CryptoPublicStoreError.ErrorCode.Wrap(err).asGrpcError)
|
|
||||||
_ = logger.info(s"Uploading key ${validatedName}")
|
_ = logger.info(s"Uploading key ${validatedName}")
|
||||||
_ <- cryptoPrivateStore
|
_ <- cryptoPrivateStore
|
||||||
.storePrivateKey(keyPair.privateKey, validatedName)
|
.storePrivateKey(keyPair.privateKey, validatedName)
|
||||||
@ -381,7 +357,7 @@ class GrpcVaultService(
|
|||||||
} yield ()
|
} yield ()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
validatedName <- FutureUnlessShutdown.pure(
|
validatedName <- FutureUnlessShutdown.wrap(
|
||||||
OptionUtil
|
OptionUtil
|
||||||
.emptyStringAsNone(request.name)
|
.emptyStringAsNone(request.name)
|
||||||
.traverse(KeyName.create)
|
.traverse(KeyName.create)
|
||||||
@ -423,24 +399,25 @@ class GrpcVaultService(
|
|||||||
): Future[v30.DeleteKeyPairResponse] = {
|
): Future[v30.DeleteKeyPairResponse] = {
|
||||||
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
implicit val traceContext: TraceContext = TraceContextGrpc.fromGrpcContext
|
||||||
for {
|
for {
|
||||||
fingerprint <- Future(
|
fingerprint <- FutureUnlessShutdown.wrap(
|
||||||
Fingerprint
|
Fingerprint
|
||||||
.fromProtoPrimitive(request.fingerprint)
|
.fromProtoPrimitive(request.fingerprint)
|
||||||
.valueOr(err =>
|
.valueOr { err =>
|
||||||
throw ProtoDeserializationFailure
|
throw ProtoDeserializationFailure
|
||||||
.WrapNoLoggingStr(s"Failed to parse key fingerprint: $err")
|
.WrapNoLoggingStr(s"Failed to parse key fingerprint: $err")
|
||||||
.asGrpcError
|
.asGrpcError
|
||||||
)
|
}
|
||||||
)
|
)
|
||||||
_ <- CantonGrpcUtil.mapErrNewEUS {
|
_ <- crypto.cryptoPrivateStore
|
||||||
crypto.cryptoPrivateStore
|
.removePrivateKey(fingerprint)
|
||||||
.removePrivateKey(fingerprint)
|
.valueOr { err =>
|
||||||
.leftMap(err =>
|
throw Status.FAILED_PRECONDITION
|
||||||
ProtoDeserializationFailure.WrapNoLoggingStr(s"Failed to remove private key: $err")
|
.withDescription(s"Failed to remove private key: $err")
|
||||||
)
|
.asRuntimeException()
|
||||||
}
|
}
|
||||||
|
_ <- crypto.cryptoPublicStore.deleteKey(fingerprint)
|
||||||
} yield v30.DeleteKeyPairResponse()
|
} yield v30.DeleteKeyPairResponse()
|
||||||
}
|
}.failOnShutdownTo(AbortedDueToShutdown.Error().asGrpcError)
|
||||||
}
|
}
|
||||||
|
|
||||||
object GrpcVaultService {
|
object GrpcVaultService {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
package com.digitalasset.canton.environment
|
package com.digitalasset.canton.environment
|
||||||
|
|
||||||
import better.files.File
|
import better.files.File
|
||||||
import cats.data.EitherT
|
import cats.data.{EitherT, OptionT}
|
||||||
import cats.syntax.functorFilter.*
|
import cats.syntax.functorFilter.*
|
||||||
import com.daml.metrics.HealthMetrics
|
import com.daml.metrics.HealthMetrics
|
||||||
import com.daml.metrics.api.MetricHandle.LabeledMetricsFactory
|
import com.daml.metrics.api.MetricHandle.LabeledMetricsFactory
|
||||||
@ -29,7 +29,7 @@ import com.digitalasset.canton.crypto.*
|
|||||||
import com.digitalasset.canton.crypto.admin.grpc.GrpcVaultService.GrpcVaultServiceFactory
|
import com.digitalasset.canton.crypto.admin.grpc.GrpcVaultService.GrpcVaultServiceFactory
|
||||||
import com.digitalasset.canton.crypto.admin.v30.VaultServiceGrpc
|
import com.digitalasset.canton.crypto.admin.v30.VaultServiceGrpc
|
||||||
import com.digitalasset.canton.crypto.store.CryptoPrivateStore.CryptoPrivateStoreFactory
|
import com.digitalasset.canton.crypto.store.CryptoPrivateStore.CryptoPrivateStoreFactory
|
||||||
import com.digitalasset.canton.crypto.store.{CryptoPrivateStoreError, CryptoPublicStoreError}
|
import com.digitalasset.canton.crypto.store.CryptoPrivateStoreError
|
||||||
import com.digitalasset.canton.data.CantonTimestamp
|
import com.digitalasset.canton.data.CantonTimestamp
|
||||||
import com.digitalasset.canton.discard.Implicits.DiscardOps
|
import com.digitalasset.canton.discard.Implicits.DiscardOps
|
||||||
import com.digitalasset.canton.environment.CantonNodeBootstrap.HealthDumpFunction
|
import com.digitalasset.canton.environment.CantonNodeBootstrap.HealthDumpFunction
|
||||||
@ -697,14 +697,11 @@ abstract class CantonNodeBootstrapImpl[
|
|||||||
override protected def autoCompleteStage()
|
override protected def autoCompleteStage()
|
||||||
: EitherT[FutureUnlessShutdown, String, Option[Unit]] = {
|
: EitherT[FutureUnlessShutdown, String, Option[Unit]] = {
|
||||||
for {
|
for {
|
||||||
namespaceKeyO <- crypto.cryptoPublicStore
|
namespaceKey <- crypto.cryptoPublicStore
|
||||||
.signingKey(nodeId.fingerprint)
|
.signingKey(nodeId.fingerprint)
|
||||||
.leftMap(_.toString)
|
.toRight(
|
||||||
namespaceKey <- EitherT.fromEither[FutureUnlessShutdown](
|
|
||||||
namespaceKeyO.toRight(
|
|
||||||
s"Performing auto-init but can't find key ${nodeId.fingerprint} from previous step"
|
s"Performing auto-init but can't find key ${nodeId.fingerprint} from previous step"
|
||||||
)
|
)
|
||||||
)
|
|
||||||
// init topology manager
|
// init topology manager
|
||||||
nsd <- EitherT.fromEither[FutureUnlessShutdown](
|
nsd <- EitherT.fromEither[FutureUnlessShutdown](
|
||||||
NamespaceDelegation.create(
|
NamespaceDelegation.create(
|
||||||
@ -820,46 +817,34 @@ object CantonNodeBootstrapImpl {
|
|||||||
|
|
||||||
private def getKeyByFingerprint[P <: PublicKey](
|
private def getKeyByFingerprint[P <: PublicKey](
|
||||||
typ: String,
|
typ: String,
|
||||||
findPubKeyIdByFingerprint: Fingerprint => EitherT[
|
findPubKeyIdByFingerprint: Fingerprint => OptionT[FutureUnlessShutdown, P],
|
||||||
FutureUnlessShutdown,
|
|
||||||
CryptoPublicStoreError,
|
|
||||||
Option[P],
|
|
||||||
],
|
|
||||||
existPrivateKeyByFp: Fingerprint => EitherT[
|
existPrivateKeyByFp: Fingerprint => EitherT[
|
||||||
FutureUnlessShutdown,
|
FutureUnlessShutdown,
|
||||||
CryptoPrivateStoreError,
|
CryptoPrivateStoreError,
|
||||||
Boolean,
|
Boolean,
|
||||||
],
|
],
|
||||||
fingerprint: Fingerprint,
|
fingerprint: Fingerprint,
|
||||||
)(implicit ec: ExecutionContext): EitherT[FutureUnlessShutdown, String, P] = for {
|
)(implicit ec: ExecutionContext): EitherT[FutureUnlessShutdown, String, P] = {
|
||||||
keyIdO <- findPubKeyIdByFingerprint(fingerprint)
|
findPubKeyIdByFingerprint(fingerprint)
|
||||||
.leftMap(err =>
|
.toRight(s"$typ key with fingerprint $fingerprint does not exist")
|
||||||
s"Failure while looking for $typ fingerprint $fingerprint in public store: $err"
|
.flatMap { keyWithFingerprint =>
|
||||||
)
|
val fingerprint = keyWithFingerprint.fingerprint
|
||||||
pubKey <- keyIdO.fold(
|
existPrivateKeyByFp(fingerprint)
|
||||||
EitherT.leftT[FutureUnlessShutdown, P](
|
.leftMap(err =>
|
||||||
s"$typ key with fingerprint $fingerprint does not exist"
|
s"Failure while looking for $typ key $fingerprint in private key store: $err"
|
||||||
)
|
)
|
||||||
) { keyWithFingerprint =>
|
.transform {
|
||||||
val fingerprint = keyWithFingerprint.fingerprint
|
case Right(true) => Right(keyWithFingerprint)
|
||||||
existPrivateKeyByFp(fingerprint)
|
case Right(false) =>
|
||||||
.leftMap(err =>
|
Left(s"Broken private key store: Could not find $typ key $fingerprint")
|
||||||
s"Failure while looking for $typ key $fingerprint in private key store: $err"
|
case Left(err) => Left(err)
|
||||||
)
|
}
|
||||||
.transform {
|
}
|
||||||
case Right(true) => Right(keyWithFingerprint)
|
}
|
||||||
case Right(false) =>
|
|
||||||
Left(s"Broken private key store: Could not find $typ key $fingerprint")
|
|
||||||
case Left(err) => Left(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} yield pubKey
|
|
||||||
|
|
||||||
private def getOrCreateKey[P <: PublicKey](
|
private def getOrCreateKey[P <: PublicKey](
|
||||||
typ: String,
|
typ: String,
|
||||||
findPubKeyIdByName: KeyName => EitherT[FutureUnlessShutdown, CryptoPublicStoreError, Option[
|
findPubKeyIdByName: KeyName => OptionT[FutureUnlessShutdown, P],
|
||||||
P
|
|
||||||
]],
|
|
||||||
generateKey: Option[KeyName] => EitherT[FutureUnlessShutdown, String, P],
|
generateKey: Option[KeyName] => EitherT[FutureUnlessShutdown, String, P],
|
||||||
existPrivateKeyByFp: Fingerprint => EitherT[
|
existPrivateKeyByFp: Fingerprint => EitherT[
|
||||||
FutureUnlessShutdown,
|
FutureUnlessShutdown,
|
||||||
@ -869,8 +854,7 @@ object CantonNodeBootstrapImpl {
|
|||||||
name: String,
|
name: String,
|
||||||
)(implicit ec: ExecutionContext): EitherT[FutureUnlessShutdown, String, P] = for {
|
)(implicit ec: ExecutionContext): EitherT[FutureUnlessShutdown, String, P] = for {
|
||||||
keyName <- EitherT.fromEither[FutureUnlessShutdown](KeyName.create(name))
|
keyName <- EitherT.fromEither[FutureUnlessShutdown](KeyName.create(name))
|
||||||
keyIdO <- findPubKeyIdByName(keyName)
|
keyIdO <- EitherT.right(findPubKeyIdByName(keyName).value)
|
||||||
.leftMap(err => s"Failure while looking for $typ key $name in public store: $err")
|
|
||||||
pubKey <- keyIdO.fold(
|
pubKey <- keyIdO.fold(
|
||||||
generateKey(Some(keyName))
|
generateKey(Some(keyName))
|
||||||
.leftMap(err => s"Failure while generating $typ key for $name: $err")
|
.leftMap(err => s"Failure while generating $typ key for $name: $err")
|
||||||
|
@ -27,8 +27,8 @@ object ProtocolVersionCompatibility {
|
|||||||
release: ReleaseVersion = ReleaseVersion.current,
|
release: ReleaseVersion = ReleaseVersion.current,
|
||||||
): NonEmpty[List[ProtocolVersion]] = {
|
): NonEmpty[List[ProtocolVersion]] = {
|
||||||
val unstableAndBeta =
|
val unstableAndBeta =
|
||||||
if (cantonNodeParameters.devVersionSupport && cantonNodeParameters.nonStandardConfig)
|
if (cantonNodeParameters.alphaVersionSupport && cantonNodeParameters.nonStandardConfig)
|
||||||
ProtocolVersion.unstable.forgetNE ++ ReleaseVersionToProtocolVersions
|
ProtocolVersion.alpha.forgetNE ++ ReleaseVersionToProtocolVersions
|
||||||
.getBetaProtocolVersions(release)
|
.getBetaProtocolVersions(release)
|
||||||
else if (cantonNodeParameters.betaVersionSupport)
|
else if (cantonNodeParameters.betaVersionSupport)
|
||||||
ReleaseVersionToProtocolVersions.getBetaProtocolVersions(release)
|
ReleaseVersionToProtocolVersions.getBetaProtocolVersions(release)
|
||||||
@ -58,7 +58,7 @@ object ProtocolVersionCompatibility {
|
|||||||
|
|
||||||
val unstable =
|
val unstable =
|
||||||
if (includeUnstableVersions)
|
if (includeUnstableVersions)
|
||||||
ProtocolVersion.unstable.forgetNE
|
ProtocolVersion.alpha.forgetNE
|
||||||
else List.empty
|
else List.empty
|
||||||
|
|
||||||
ReleaseVersionToProtocolVersions.getOrElse(
|
ReleaseVersionToProtocolVersions.getOrElse(
|
||||||
@ -77,8 +77,8 @@ object ProtocolVersionCompatibility {
|
|||||||
release: ReleaseVersion = ReleaseVersion.current,
|
release: ReleaseVersion = ReleaseVersion.current,
|
||||||
): NonEmpty[List[ProtocolVersion]] = {
|
): NonEmpty[List[ProtocolVersion]] = {
|
||||||
val unstableAndBeta =
|
val unstableAndBeta =
|
||||||
if (cantonNodeParameters.devVersionSupport && cantonNodeParameters.nonStandardConfig)
|
if (cantonNodeParameters.alphaVersionSupport && cantonNodeParameters.nonStandardConfig)
|
||||||
ProtocolVersion.unstable.forgetNE ++ ReleaseVersionToProtocolVersions
|
ProtocolVersion.alpha.forgetNE ++ ReleaseVersionToProtocolVersions
|
||||||
.getBetaProtocolVersions(release)
|
.getBetaProtocolVersions(release)
|
||||||
else if (cantonNodeParameters.betaVersionSupport)
|
else if (cantonNodeParameters.betaVersionSupport)
|
||||||
ReleaseVersionToProtocolVersions.getBetaProtocolVersions(release)
|
ReleaseVersionToProtocolVersions.getBetaProtocolVersions(release)
|
||||||
@ -108,7 +108,7 @@ object ProtocolVersionCompatibility {
|
|||||||
|
|
||||||
val unstable =
|
val unstable =
|
||||||
if (includeUnstableVersions)
|
if (includeUnstableVersions)
|
||||||
ProtocolVersion.unstable.forgetNE
|
ProtocolVersion.alpha.forgetNE
|
||||||
else List.empty
|
else List.empty
|
||||||
|
|
||||||
ReleaseVersionToProtocolVersions.getOrElse(
|
ReleaseVersionToProtocolVersions.getOrElse(
|
||||||
|
@ -19,7 +19,7 @@ message VersionedMessageV1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message VersionedMessageV2 {
|
message VersionedMessageV2 {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
string msg = 1;
|
string msg = 1;
|
||||||
int32 iValue = 2;
|
int32 iValue = 2;
|
||||||
double dValue = 3;
|
double dValue = 3;
|
||||||
|
@ -29,10 +29,10 @@ trait CryptoPublicStoreTest extends BaseTest { this: AsyncWordSpec =>
|
|||||||
"save encryption keys correctly when added incrementally" in {
|
"save encryption keys correctly when added incrementally" in {
|
||||||
val store = newStore
|
val store = newStore
|
||||||
for {
|
for {
|
||||||
_ <- store.storeEncryptionKey(encKey1, encKey1WithName.name).valueOrFail("store encKey1")
|
_ <- store.storeEncryptionKey(encKey1, encKey1WithName.name)
|
||||||
_ <- store.storeEncryptionKey(encKey2, None).valueOrFail("store encKey2")
|
_ <- store.storeEncryptionKey(encKey2, None)
|
||||||
result <- store.encryptionKeys.valueOrFail("get encryption keys")
|
result <- store.encryptionKeys
|
||||||
result2 <- store.listEncryptionKeys.valueOrFail("list keys")
|
result2 <- store.listEncryptionKeys
|
||||||
} yield {
|
} yield {
|
||||||
result shouldEqual Set(encKey1, encKey2)
|
result shouldEqual Set(encKey1, encKey2)
|
||||||
result2 shouldEqual Set(encKey1WithName, encKey2WithName)
|
result2 shouldEqual Set(encKey1WithName, encKey2WithName)
|
||||||
@ -44,15 +44,15 @@ trait CryptoPublicStoreTest extends BaseTest { this: AsyncWordSpec =>
|
|||||||
val store = newStore
|
val store = newStore
|
||||||
val separateStore = newStore
|
val separateStore = newStore
|
||||||
for {
|
for {
|
||||||
_ <- store.storeEncryptionKey(encKey1, encKey1WithName.name).valueOrFail("store encKey1")
|
_ <- store.storeEncryptionKey(encKey1, encKey1WithName.name)
|
||||||
_ <- store.storeEncryptionKey(encKey2, None).valueOrFail("store encKey2")
|
_ <- store.storeEncryptionKey(encKey2, None)
|
||||||
result1 <- separateStore.encryptionKey(encKey1.fingerprint).valueOrFail("read encKey1")
|
result1 <- separateStore.encryptionKey(encKey1.fingerprint).value
|
||||||
result2 <- separateStore.encryptionKey(encKey2.fingerprint).valueOrFail("read encKey2")
|
result2 <- separateStore.encryptionKey(encKey2.fingerprint).value
|
||||||
|
|
||||||
_ <- store.storeSigningKey(sigKey1, sigKey1WithName.name).valueOrFail("store sigKey1")
|
_ <- store.storeSigningKey(sigKey1, sigKey1WithName.name)
|
||||||
_ <- store.storeSigningKey(sigKey2, None).valueOrFail("store sigKey2")
|
_ <- store.storeSigningKey(sigKey2, None)
|
||||||
result3 <- separateStore.signingKey(sigKey1.fingerprint).valueOrFail("read sigKey1")
|
result3 <- separateStore.signingKey(sigKey1.fingerprint).value
|
||||||
result4 <- separateStore.signingKey(sigKey2.fingerprint).valueOrFail("read sigKey2")
|
result4 <- separateStore.signingKey(sigKey2.fingerprint).value
|
||||||
} yield {
|
} yield {
|
||||||
result1 shouldEqual Some(encKey1)
|
result1 shouldEqual Some(encKey1)
|
||||||
result2 shouldEqual Some(encKey2)
|
result2 shouldEqual Some(encKey2)
|
||||||
@ -66,34 +66,46 @@ trait CryptoPublicStoreTest extends BaseTest { this: AsyncWordSpec =>
|
|||||||
"save signing keys correctly when added incrementally" in {
|
"save signing keys correctly when added incrementally" in {
|
||||||
val store = newStore
|
val store = newStore
|
||||||
for {
|
for {
|
||||||
_ <- store.storeSigningKey(sigKey1, sigKey1WithName.name).valueOrFail("store sigKey1")
|
_ <- store.storeSigningKey(sigKey1, sigKey1WithName.name)
|
||||||
_ <- store.storeSigningKey(sigKey2, None).valueOrFail("store sigKey2")
|
_ <- store.storeSigningKey(sigKey2, None)
|
||||||
result <- store.signingKeys.valueOrFail("list keys")
|
result <- store.signingKeys
|
||||||
result2 <- store.listSigningKeys.valueOrFail("list keys")
|
result2 <- store.listSigningKeys
|
||||||
} yield {
|
} yield {
|
||||||
result shouldEqual Set(sigKey1, sigKey2)
|
result shouldEqual Set(sigKey1, sigKey2)
|
||||||
result2 shouldEqual Set(sigKey1WithName, sigKey2WithName)
|
result2 shouldEqual Set(sigKey1WithName, sigKey2WithName)
|
||||||
}
|
}
|
||||||
}.failOnShutdown
|
}.failOnShutdown
|
||||||
|
|
||||||
|
"delete public keys" in {
|
||||||
|
val store = newStore
|
||||||
|
for {
|
||||||
|
_ <- store.storeSigningKey(sigKey1, sigKey1WithName.name)
|
||||||
|
result1 <- store.signingKeys
|
||||||
|
_ <- store.deleteKey(sigKey1.id)
|
||||||
|
result2 <- store.signingKeys
|
||||||
|
_ <- store.storeSigningKey(sigKey1, None)
|
||||||
|
} yield {
|
||||||
|
result1 shouldEqual Set(sigKey1)
|
||||||
|
result2 shouldEqual Set()
|
||||||
|
}
|
||||||
|
}.failOnShutdown
|
||||||
|
|
||||||
"idempotent store of encryption keys" in {
|
"idempotent store of encryption keys" in {
|
||||||
val store = newStore
|
val store = newStore
|
||||||
for {
|
for {
|
||||||
_ <- store
|
_ <- store.storeEncryptionKey(encKey1, encKey1WithName.name)
|
||||||
.storeEncryptionKey(encKey1, encKey1WithName.name)
|
|
||||||
.valueOrFail("store key 1 with name")
|
|
||||||
|
|
||||||
// Should succeed
|
// Should succeed
|
||||||
_ <- store
|
_ <- store.storeEncryptionKey(encKey1, encKey1WithName.name)
|
||||||
.storeEncryptionKey(encKey1, encKey1WithName.name)
|
|
||||||
.valueOrFail("store key 1 with name again")
|
|
||||||
|
|
||||||
// Should fail due to different name
|
// Should fail due to different name
|
||||||
failedInsert <- store.storeEncryptionKey(encKey1, None).value
|
_failedInsert <- loggerFactory.assertInternalErrorAsyncUS[IllegalStateException](
|
||||||
|
store.storeEncryptionKey(encKey1, None),
|
||||||
|
_.getMessage shouldBe s"Existing public key for ${encKey1.id} is different than inserted key",
|
||||||
|
)
|
||||||
|
|
||||||
result <- store.listEncryptionKeys.valueOrFail("listing encryption keys")
|
result <- store.listEncryptionKeys
|
||||||
} yield {
|
} yield {
|
||||||
failedInsert.left.value shouldBe a[CryptoPublicStoreError]
|
|
||||||
result shouldEqual Set(encKey1WithName)
|
result shouldEqual Set(encKey1WithName)
|
||||||
}
|
}
|
||||||
}.failOnShutdown
|
}.failOnShutdown
|
||||||
@ -103,19 +115,21 @@ trait CryptoPublicStoreTest extends BaseTest { this: AsyncWordSpec =>
|
|||||||
for {
|
for {
|
||||||
_ <- store
|
_ <- store
|
||||||
.storeSigningKey(sigKey1, sigKey1WithName.name)
|
.storeSigningKey(sigKey1, sigKey1WithName.name)
|
||||||
.valueOrFail("store key 1 with name")
|
|
||||||
|
|
||||||
// Should succeed
|
// Should succeed
|
||||||
_ <- store
|
_ <- store
|
||||||
.storeSigningKey(sigKey1, sigKey1WithName.name)
|
.storeSigningKey(sigKey1, sigKey1WithName.name)
|
||||||
.valueOrFail("store key 1 with name again")
|
|
||||||
|
|
||||||
// Should fail due to different name
|
// Should fail due to different name
|
||||||
failedInsert <- store.storeSigningKey(sigKey1, None).value
|
_failedInsert <- loggerFactory.assertInternalErrorAsyncUS[IllegalStateException](
|
||||||
|
store.storeSigningKey(sigKey1, None),
|
||||||
|
_.getMessage should startWith(
|
||||||
|
s"Existing public key for ${sigKey1.id} is different than inserted key"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
result <- store.listSigningKeys.valueOrFail("listing encryption keys")
|
result <- store.listSigningKeys
|
||||||
} yield {
|
} yield {
|
||||||
failedInsert.left.value shouldBe a[CryptoPublicStoreError]
|
|
||||||
result shouldEqual Set(sigKey1WithName)
|
result shouldEqual Set(sigKey1WithName)
|
||||||
}
|
}
|
||||||
}.failOnShutdown
|
}.failOnShutdown
|
||||||
|
@ -8,6 +8,9 @@ import org.scalatest.wordspec.AsyncWordSpec
|
|||||||
|
|
||||||
class CryptoPublicStoreTestInMemory extends AsyncWordSpec with CryptoPublicStoreTest {
|
class CryptoPublicStoreTestInMemory extends AsyncWordSpec with CryptoPublicStoreTest {
|
||||||
"InMemoryCryptoPublicStore" should {
|
"InMemoryCryptoPublicStore" should {
|
||||||
behave like cryptoPublicStore(new InMemoryCryptoPublicStore, backedByDatabase = false)
|
behave like cryptoPublicStore(
|
||||||
|
new InMemoryCryptoPublicStore(loggerFactory),
|
||||||
|
backedByDatabase = false,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ class HasProtocolVersionedWrapperTest extends AnyWordSpec with BaseTest {
|
|||||||
|
|
||||||
// Used by the compiled string below
|
// Used by the compiled string below
|
||||||
val stablePV = ProtocolVersion.createStable(10)
|
val stablePV = ProtocolVersion.createStable(10)
|
||||||
val unstablePV = ProtocolVersion.createUnstable(11)
|
val alphaPV = ProtocolVersion.createAlpha(11)
|
||||||
|
|
||||||
def name: String = "message"
|
def name: String = "message"
|
||||||
|
|
||||||
@ -139,27 +139,27 @@ class HasProtocolVersionedWrapperTest extends AnyWordSpec with BaseTest {
|
|||||||
): Assertion
|
): Assertion
|
||||||
}
|
}
|
||||||
|
|
||||||
clue("can use a stable proto message in an unstable protocol version") {
|
clue("can use a stable proto message in an alpha protocol version") {
|
||||||
assertCompiles(
|
assertCompiles(
|
||||||
"""
|
"""
|
||||||
val _ = VersionedProtoConverter(unstablePV)(VersionedMessageV1)(
|
val _ = VersionedProtoConverter(alphaPV)(VersionedMessageV1)(
|
||||||
supportedProtoVersionMemoized(_)(fromProtoV1),
|
supportedProtoVersionMemoized(_)(fromProtoV1),
|
||||||
_.toProtoV1.toByteString
|
_.toProtoV1.toByteString
|
||||||
)"""
|
)"""
|
||||||
): Assertion
|
): Assertion
|
||||||
}
|
}
|
||||||
|
|
||||||
clue("can use an unstable proto message in an unstable protocol version") {
|
clue("can use an alpha proto message in an alpha protocol version") {
|
||||||
assertCompiles(
|
assertCompiles(
|
||||||
"""
|
"""
|
||||||
val _ = VersionedProtoConverter(unstablePV)(VersionedMessageV2)(
|
val _ = VersionedProtoConverter(alphaPV)(VersionedMessageV2)(
|
||||||
supportedProtoVersionMemoized(_)(fromProtoV2),
|
supportedProtoVersionMemoized(_)(fromProtoV2),
|
||||||
_.toProtoV2.toByteString
|
_.toProtoV2.toByteString
|
||||||
)"""
|
)"""
|
||||||
): Assertion
|
): Assertion
|
||||||
}
|
}
|
||||||
|
|
||||||
clue("can not use an unstable proto message in a stable protocol version") {
|
clue("can not use an alpha proto message in a stable protocol version") {
|
||||||
assertTypeError(
|
assertTypeError(
|
||||||
"""
|
"""
|
||||||
val _ = VersionedProtoConverter(stablePV)(VersionedMessageV2)(
|
val _ = VersionedProtoConverter(stablePV)(VersionedMessageV2)(
|
||||||
@ -213,7 +213,7 @@ object HasProtocolVersionedWrapperTest {
|
|||||||
protocolVersion 30 31 32 33 34 ...
|
protocolVersion 30 31 32 33 34 ...
|
||||||
*/
|
*/
|
||||||
override val supportedProtoVersions = SupportedProtoVersions(
|
override val supportedProtoVersions = SupportedProtoVersions(
|
||||||
ProtoVersion(1) -> VersionedProtoConverter(ProtocolVersion.createUnstable((basePV + 2).v))(
|
ProtoVersion(1) -> VersionedProtoConverter(ProtocolVersion.createAlpha((basePV + 2).v))(
|
||||||
VersionedMessageV1
|
VersionedMessageV1
|
||||||
)(
|
)(
|
||||||
supportedProtoVersionMemoized(_)(fromProtoV1),
|
supportedProtoVersionMemoized(_)(fromProtoV1),
|
||||||
@ -226,9 +226,9 @@ object HasProtocolVersionedWrapperTest {
|
|||||||
supportedProtoVersionMemoized(_)(fromProtoV0),
|
supportedProtoVersionMemoized(_)(fromProtoV0),
|
||||||
_.toProtoV0.toByteString,
|
_.toProtoV0.toByteString,
|
||||||
),
|
),
|
||||||
// Can use an unstable Protobuf message in an unstable protocol version
|
// Can use an alpha Protobuf message in an alpha protocol version
|
||||||
ProtoVersion(2) -> VersionedProtoConverter(
|
ProtoVersion(2) -> VersionedProtoConverter(
|
||||||
ProtocolVersion.createUnstable((basePV + 3).v)
|
ProtocolVersion.createAlpha((basePV + 3).v)
|
||||||
)(VersionedMessageV2)(
|
)(VersionedMessageV2)(
|
||||||
supportedProtoVersionMemoized(_)(fromProtoV2),
|
supportedProtoVersionMemoized(_)(fromProtoV2),
|
||||||
_.toProtoV2.toByteString,
|
_.toProtoV2.toByteString,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: ai-analysis
|
name: ai-analysis
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: bank
|
name: bank
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: doctor
|
name: doctor
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: health-insurance
|
name: health-insurance
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: medical-records
|
name: medical-records
|
||||||
|
@ -122,7 +122,7 @@ message OnboardingStateResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message OnboardingStateForSequencer {
|
message OnboardingStateForSequencer {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
com.digitalasset.canton.topology.admin.v30.TopologyTransactions topology_snapshot = 1;
|
com.digitalasset.canton.topology.admin.v30.TopologyTransactions topology_snapshot = 1;
|
||||||
com.digitalasset.canton.protocol.v30.StaticDomainParameters static_domain_parameters = 2;
|
com.digitalasset.canton.protocol.v30.StaticDomainParameters static_domain_parameters = 2;
|
||||||
|
@ -11,6 +11,7 @@ service SequencerBftAdministrationService {
|
|||||||
rpc AddPeerEndpoint(AddPeerEndpointRequest) returns (AddPeerEndpointResponse);
|
rpc AddPeerEndpoint(AddPeerEndpointRequest) returns (AddPeerEndpointResponse);
|
||||||
rpc RemovePeerEndpoint(RemovePeerEndpointRequest) returns (RemovePeerEndpointResponse);
|
rpc RemovePeerEndpoint(RemovePeerEndpointRequest) returns (RemovePeerEndpointResponse);
|
||||||
rpc GetPeerNetworkStatus(GetPeerNetworkStatusRequest) returns (GetPeerNetworkStatusResponse);
|
rpc GetPeerNetworkStatus(GetPeerNetworkStatusRequest) returns (GetPeerNetworkStatusResponse);
|
||||||
|
rpc GetOrderingTopology(GetOrderingTopologyRequest) returns (GetOrderingTopologyResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddPeerEndpointRequest {
|
message AddPeerEndpointRequest {
|
||||||
@ -60,3 +61,12 @@ message GetPeerNetworkStatusRequest {
|
|||||||
message GetPeerNetworkStatusResponse {
|
message GetPeerNetworkStatusResponse {
|
||||||
repeated PeerEndpointStatus statuses = 1;
|
repeated PeerEndpointStatus statuses = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetOrderingTopologyRequest {}
|
||||||
|
|
||||||
|
message GetOrderingTopologyResponse {
|
||||||
|
// The current epoch, through which the topology is valid.
|
||||||
|
int64 current_epoch = 1;
|
||||||
|
// The sequencer IDs of the active BFT ordering nodes in the network.
|
||||||
|
repeated string sequencer_ids = 2;
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ import "google/protobuf/wrappers.proto";
|
|||||||
import "scalapb/scalapb.proto";
|
import "scalapb/scalapb.proto";
|
||||||
|
|
||||||
message SequencerSnapshot {
|
message SequencerSnapshot {
|
||||||
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.UnstableProtoVersion";
|
option (scalapb.message).companion_extends = "com.digitalasset.canton.version.AlphaProtoVersion";
|
||||||
|
|
||||||
int64 latest_timestamp = 1; // in microseconds of UTC time since Unix epoch
|
int64 latest_timestamp = 1; // in microseconds of UTC time since Unix epoch
|
||||||
uint64 last_block_height = 2;
|
uint64 last_block_height = 2;
|
||||||
|
@ -36,7 +36,7 @@ final case class DomainParametersConfig(
|
|||||||
requiredHashAlgorithms: Option[NonEmpty[Set[HashAlgorithm]]] = None,
|
requiredHashAlgorithms: Option[NonEmpty[Set[HashAlgorithm]]] = None,
|
||||||
requiredCryptoKeyFormats: Option[NonEmpty[Set[CryptoKeyFormat]]] = None,
|
requiredCryptoKeyFormats: Option[NonEmpty[Set[CryptoKeyFormat]]] = None,
|
||||||
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
||||||
override val devVersionSupport: Boolean = true,
|
override val alphaVersionSupport: Boolean = true,
|
||||||
override val betaVersionSupport: Boolean = false,
|
override val betaVersionSupport: Boolean = false,
|
||||||
override val dontWarnOnDeprecatedPV: Boolean = false,
|
override val dontWarnOnDeprecatedPV: Boolean = false,
|
||||||
) extends ProtocolConfig
|
) extends ProtocolConfig
|
||||||
@ -48,7 +48,8 @@ final case class DomainParametersConfig(
|
|||||||
param("requiredSymmetricKeySchemes", _.requiredSymmetricKeySchemes),
|
param("requiredSymmetricKeySchemes", _.requiredSymmetricKeySchemes),
|
||||||
param("requiredHashAlgorithms", _.requiredHashAlgorithms),
|
param("requiredHashAlgorithms", _.requiredHashAlgorithms),
|
||||||
param("requiredCryptoKeyFormats", _.requiredCryptoKeyFormats),
|
param("requiredCryptoKeyFormats", _.requiredCryptoKeyFormats),
|
||||||
param("devVersionSupport", _.devVersionSupport),
|
param("alphaVersionSupport", _.alphaVersionSupport),
|
||||||
|
param("betaVersionSupport", _.betaVersionSupport),
|
||||||
param("dontWarnOnDeprecatedPV", _.dontWarnOnDeprecatedPV),
|
param("dontWarnOnDeprecatedPV", _.dontWarnOnDeprecatedPV),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ abstract class MediatorNodeConfigCommon(
|
|||||||
*/
|
*/
|
||||||
final case class MediatorNodeParameterConfig(
|
final case class MediatorNodeParameterConfig(
|
||||||
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
||||||
override val devVersionSupport: Boolean = true,
|
override val alphaVersionSupport: Boolean = true,
|
||||||
override val betaVersionSupport: Boolean = false,
|
override val betaVersionSupport: Boolean = false,
|
||||||
override val dontWarnOnDeprecatedPV: Boolean = false,
|
override val dontWarnOnDeprecatedPV: Boolean = false,
|
||||||
override val batching: BatchingConfig = BatchingConfig(),
|
override val batching: BatchingConfig = BatchingConfig(),
|
||||||
@ -488,7 +488,7 @@ class MediatorNodeBootstrap(
|
|||||||
timeouts = timeouts,
|
timeouts = timeouts,
|
||||||
traceContextPropagation = parameters.tracing.propagation,
|
traceContextPropagation = parameters.tracing.propagation,
|
||||||
clientProtocolVersions =
|
clientProtocolVersions =
|
||||||
if (parameterConfig.devVersionSupport) ProtocolVersion.supported
|
if (parameterConfig.alphaVersionSupport) ProtocolVersion.supported
|
||||||
else
|
else
|
||||||
// TODO(#15561) Remove NonEmpty construct once stableAndSupported is NonEmpty again
|
// TODO(#15561) Remove NonEmpty construct once stableAndSupported is NonEmpty again
|
||||||
NonEmpty
|
NonEmpty
|
||||||
|
@ -125,7 +125,7 @@ class BftOrderingMetrics(
|
|||||||
|
|
||||||
val batchesOrdered: Meter = openTelemetryMetricsFactory.meter(
|
val batchesOrdered: Meter = openTelemetryMetricsFactory.meter(
|
||||||
MetricInfo(
|
MetricInfo(
|
||||||
prefix :+ s"ordered-batches",
|
prefix :+ "ordered-batches",
|
||||||
summary = "Batches ordered",
|
summary = "Batches ordered",
|
||||||
description = "Measures the total batches ordered.",
|
description = "Measures the total batches ordered.",
|
||||||
qualification = MetricQualification.Traffic,
|
qualification = MetricQualification.Traffic,
|
||||||
@ -134,7 +134,7 @@ class BftOrderingMetrics(
|
|||||||
|
|
||||||
val blocksOrdered: Meter = openTelemetryMetricsFactory.meter(
|
val blocksOrdered: Meter = openTelemetryMetricsFactory.meter(
|
||||||
MetricInfo(
|
MetricInfo(
|
||||||
prefix :+ s"ordered-blocks",
|
prefix :+ "ordered-blocks",
|
||||||
summary = "Blocks ordered",
|
summary = "Blocks ordered",
|
||||||
description = "Measures the total blocks ordered.",
|
description = "Measures the total blocks ordered.",
|
||||||
qualification = MetricQualification.Traffic,
|
qualification = MetricQualification.Traffic,
|
||||||
|
@ -14,13 +14,13 @@ import com.digitalasset.canton.config.{
|
|||||||
|
|
||||||
/** Various parameters for non-standard sequencer settings
|
/** Various parameters for non-standard sequencer settings
|
||||||
*
|
*
|
||||||
* @param devVersionSupport if true, then dev version will be turned on, but we will brick this sequencer node if it is used for production.
|
* @param alphaVersionSupport if true, then dev version will be turned on, but we will brick this sequencer node if it is used for production.
|
||||||
* @param dontWarnOnDeprecatedPV if true, then this sequencer will not emit a warning when configured to use protocol version 2.0.0.
|
* @param dontWarnOnDeprecatedPV if true, then this sequencer will not emit a warning when configured to use protocol version 2.0.0.
|
||||||
* @param maxConfirmationRequestsBurstFactor how forgiving the rate limit is in case of bursts (so rate limit starts after observing an initial burst of factor * max_rate commands)
|
* @param maxConfirmationRequestsBurstFactor how forgiving the rate limit is in case of bursts (so rate limit starts after observing an initial burst of factor * max_rate commands)
|
||||||
*/
|
*/
|
||||||
final case class SequencerNodeParameterConfig(
|
final case class SequencerNodeParameterConfig(
|
||||||
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
||||||
override val devVersionSupport: Boolean = true,
|
override val alphaVersionSupport: Boolean = true,
|
||||||
override val betaVersionSupport: Boolean = false,
|
override val betaVersionSupport: Boolean = false,
|
||||||
override val dontWarnOnDeprecatedPV: Boolean = false,
|
override val dontWarnOnDeprecatedPV: Boolean = false,
|
||||||
maxConfirmationRequestsBurstFactor: PositiveDouble = PositiveDouble.tryCreate(0.5),
|
maxConfirmationRequestsBurstFactor: PositiveDouble = PositiveDouble.tryCreate(0.5),
|
||||||
|
@ -7,12 +7,14 @@ import cats.implicits.*
|
|||||||
import com.digitalasset.canton.config.RequireTypes.Port
|
import com.digitalasset.canton.config.RequireTypes.Port
|
||||||
import com.digitalasset.canton.networking.Endpoint
|
import com.digitalasset.canton.networking.Endpoint
|
||||||
import com.digitalasset.canton.sequencer.admin.v30.{
|
import com.digitalasset.canton.sequencer.admin.v30.{
|
||||||
|
GetOrderingTopologyResponse,
|
||||||
GetPeerNetworkStatusResponse,
|
GetPeerNetworkStatusResponse,
|
||||||
PeerEndpoint,
|
PeerEndpoint,
|
||||||
PeerEndpointHealth as ProtoPeerEndpointHealth,
|
PeerEndpointHealth as ProtoPeerEndpointHealth,
|
||||||
PeerEndpointHealthStatus as ProtoPeerEndpointHealthStatus,
|
PeerEndpointHealthStatus as ProtoPeerEndpointHealthStatus,
|
||||||
PeerEndpointStatus as ProtoPeerEndpointStatus,
|
PeerEndpointStatus as ProtoPeerEndpointStatus,
|
||||||
}
|
}
|
||||||
|
import com.digitalasset.canton.topology.SequencerId
|
||||||
|
|
||||||
object EnterpriseSequencerBftAdminData {
|
object EnterpriseSequencerBftAdminData {
|
||||||
|
|
||||||
@ -89,4 +91,24 @@ object EnterpriseSequencerBftAdminData {
|
|||||||
.sequence
|
.sequence
|
||||||
.map(PeerNetworkStatus(_))
|
.map(PeerNetworkStatus(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final case class OrderingTopology(currentEpoch: Long, sequencerIds: Seq[SequencerId]) {
|
||||||
|
|
||||||
|
def toProto: GetOrderingTopologyResponse =
|
||||||
|
GetOrderingTopologyResponse.of(currentEpoch, sequencerIds.map(_.toProtoPrimitive))
|
||||||
|
}
|
||||||
|
|
||||||
|
object OrderingTopology {
|
||||||
|
def fromProto(response: GetOrderingTopologyResponse): Either[String, OrderingTopology] =
|
||||||
|
response.sequencerIds
|
||||||
|
.map { sequencerIdString =>
|
||||||
|
for {
|
||||||
|
sequencerId <- SequencerId
|
||||||
|
.fromProtoPrimitive(sequencerIdString, "sequencerId")
|
||||||
|
.leftMap(_.toString)
|
||||||
|
} yield sequencerId
|
||||||
|
}
|
||||||
|
.sequence
|
||||||
|
.map(OrderingTopology(response.currentEpoch, _))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import cats.Order.*
|
|||||||
import cats.data.EitherT
|
import cats.data.EitherT
|
||||||
import cats.kernel.Order
|
import cats.kernel.Order
|
||||||
import cats.syntax.either.*
|
import cats.syntax.either.*
|
||||||
import cats.syntax.functor.*
|
|
||||||
import cats.syntax.parallel.*
|
import cats.syntax.parallel.*
|
||||||
import cats.{Functor, Show}
|
import cats.{Functor, Show}
|
||||||
import com.daml.nonempty.NonEmpty
|
import com.daml.nonempty.NonEmpty
|
||||||
@ -29,7 +28,7 @@ import com.digitalasset.canton.tracing.{HasTraceContext, TraceContext, Traced}
|
|||||||
import com.digitalasset.canton.util.EitherTUtil.condUnitET
|
import com.digitalasset.canton.util.EitherTUtil.condUnitET
|
||||||
import com.digitalasset.canton.util.FutureInstances.*
|
import com.digitalasset.canton.util.FutureInstances.*
|
||||||
import com.digitalasset.canton.util.ShowUtil.*
|
import com.digitalasset.canton.util.ShowUtil.*
|
||||||
import com.digitalasset.canton.util.retry
|
import com.digitalasset.canton.util.{ErrorUtil, retry}
|
||||||
import com.digitalasset.canton.version.ProtocolVersion
|
import com.digitalasset.canton.version.ProtocolVersion
|
||||||
import com.digitalasset.canton.{ProtoDeserializationError, SequencerCounter}
|
import com.digitalasset.canton.{ProtoDeserializationError, SequencerCounter}
|
||||||
import com.google.common.annotations.VisibleForTesting
|
import com.google.common.annotations.VisibleForTesting
|
||||||
@ -668,14 +667,15 @@ trait SequencerStore extends SequencerMemberValidator with NamedLogging with Aut
|
|||||||
def saveRecentCheckpoints(): Future[Unit] = for {
|
def saveRecentCheckpoints(): Future[Unit] = for {
|
||||||
checkpoints <- checkpointsAtTimestamp(requestedTimestamp.immediatePredecessor)
|
checkpoints <- checkpointsAtTimestamp(requestedTimestamp.immediatePredecessor)
|
||||||
_ <- checkpoints.toList.parTraverse { case (member, checkpoint) =>
|
_ <- checkpoints.toList.parTraverse { case (member, checkpoint) =>
|
||||||
lookupMember(member).map {
|
for {
|
||||||
case Some(RegisteredMember(memberId, _)) =>
|
memberId <- lookupMember(member).map(
|
||||||
saveCounterCheckpoint(
|
_.fold(ErrorUtil.invalidState(s"Member $member should be registered"))(_.memberId)
|
||||||
memberId,
|
)
|
||||||
checkpoint,
|
_ <- saveCounterCheckpoint(
|
||||||
).value
|
memberId,
|
||||||
case _ => Right(())
|
checkpoint,
|
||||||
}
|
).value
|
||||||
|
} yield ()
|
||||||
}
|
}
|
||||||
} yield ()
|
} yield ()
|
||||||
|
|
||||||
|
@ -17,13 +17,7 @@ import com.digitalasset.canton.lifecycle.{FlagCloseable, HasCloseContext}
|
|||||||
import com.digitalasset.canton.sequencing.protocol.{MessageId, SequencerErrors}
|
import com.digitalasset.canton.sequencing.protocol.{MessageId, SequencerErrors}
|
||||||
import com.digitalasset.canton.store.db.DbTest
|
import com.digitalasset.canton.store.db.DbTest
|
||||||
import com.digitalasset.canton.time.NonNegativeFiniteDuration
|
import com.digitalasset.canton.time.NonNegativeFiniteDuration
|
||||||
import com.digitalasset.canton.topology.{
|
import com.digitalasset.canton.topology.{DefaultTestIdentities, Member, ParticipantId}
|
||||||
DefaultTestIdentities,
|
|
||||||
Member,
|
|
||||||
ParticipantId,
|
|
||||||
SequencerId,
|
|
||||||
UniqueIdentifier,
|
|
||||||
}
|
|
||||||
import com.digitalasset.canton.util.FutureInstances.*
|
import com.digitalasset.canton.util.FutureInstances.*
|
||||||
import com.digitalasset.canton.{BaseTest, ProtocolVersionChecksAsyncWordSpec, SequencerCounter}
|
import com.digitalasset.canton.{BaseTest, ProtocolVersionChecksAsyncWordSpec, SequencerCounter}
|
||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
@ -43,9 +37,7 @@ trait SequencerStoreTest
|
|||||||
with FlagCloseable
|
with FlagCloseable
|
||||||
with ProtocolVersionChecksAsyncWordSpec {
|
with ProtocolVersionChecksAsyncWordSpec {
|
||||||
|
|
||||||
lazy val sequencerMember: Member = SequencerId(
|
lazy val sequencerMember: Member = DefaultTestIdentities.sequencerId
|
||||||
UniqueIdentifier.tryFromProtoPrimitive("sequencer::namespace")
|
|
||||||
)
|
|
||||||
|
|
||||||
def sequencerStore(mk: () => SequencerStore): Unit = {
|
def sequencerStore(mk: () => SequencerStore): Unit = {
|
||||||
|
|
||||||
|
@ -13,5 +13,5 @@ object TestProtocolVersions {
|
|||||||
|
|
||||||
/** A valid, supported protocol version that is not part of the released protocol versions.
|
/** A valid, supported protocol version that is not part of the released protocol versions.
|
||||||
*/
|
*/
|
||||||
val UnreleasedValidPV: ProtocolVersion = ProtocolVersion.unstable.head
|
val UnreleasedValidPV: ProtocolVersion = ProtocolVersion.alpha.head
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
package com.digitalasset.canton.platform.apiserver.services.admin
|
package com.digitalasset.canton.platform.apiserver.services.admin
|
||||||
|
|
||||||
import cats.data.EitherT
|
import cats.data.EitherT
|
||||||
|
import com.digitalasset.daml.lf.archive.DamlLf.Archive
|
||||||
import com.daml.error.DamlError
|
import com.daml.error.DamlError
|
||||||
import com.daml.logging.entries.LoggingValue.OfString
|
import com.daml.logging.entries.LoggingValue.OfString
|
||||||
import com.digitalasset.canton.ledger.error.PackageServiceErrors.{InternalError, Validation}
|
import com.digitalasset.canton.ledger.error.PackageServiceErrors.{InternalError, Validation}
|
||||||
import com.digitalasset.canton.logging.LoggingContextWithTrace.implicitExtractTraceContext
|
import com.digitalasset.canton.logging.LoggingContextWithTrace.implicitExtractTraceContext
|
||||||
import com.digitalasset.canton.logging.{LoggingContextWithTrace, NamedLoggerFactory, NamedLogging}
|
import com.digitalasset.canton.logging.{LoggingContextWithTrace, NamedLoggerFactory, NamedLogging}
|
||||||
import com.digitalasset.canton.platform.apiserver.services.admin.ApiPackageManagementService.ErrorValidations
|
import com.digitalasset.canton.platform.apiserver.services.admin.ApiPackageManagementService.ErrorValidations
|
||||||
import com.digitalasset.daml.lf.archive.DamlLf.Archive
|
|
||||||
import com.digitalasset.daml.lf.archive.Decode
|
import com.digitalasset.daml.lf.archive.Decode
|
||||||
import com.digitalasset.daml.lf.data.Ref
|
import com.digitalasset.daml.lf.data.Ref
|
||||||
import com.digitalasset.daml.lf.language.Ast
|
import com.digitalasset.daml.lf.language.Ast
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --enable-interfaces=yes
|
- --enable-interfaces=yes
|
||||||
name: carbonv1-tests
|
name: carbonv1-tests
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --enable-interfaces=yes
|
- --enable-interfaces=yes
|
||||||
name: carbonv2-tests
|
name: carbonv2-tests
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
name: experimental-tests
|
name: experimental-tests
|
||||||
source: .
|
source: .
|
||||||
version: 3.1.0
|
version: 3.1.0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --enable-interfaces=yes
|
- --enable-interfaces=yes
|
||||||
name: model-tests
|
name: model-tests
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
name: package-management-tests
|
name: package-management-tests
|
||||||
source: .
|
source: .
|
||||||
version: 3.1.0
|
version: 3.1.0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --enable-interfaces=yes
|
- --enable-interfaces=yes
|
||||||
name: semantic-tests
|
name: semantic-tests
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
name: upgrade-tests
|
name: upgrade-tests
|
||||||
source: .
|
source: .
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
name: upgrade-tests
|
name: upgrade-tests
|
||||||
source: .
|
source: .
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
name: upgrade-tests
|
name: upgrade-tests
|
||||||
source: .
|
source: .
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: JsonEncodingTest
|
name: JsonEncodingTest
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.dev
|
- --target=2.dev
|
||||||
name: JsonEncodingTestDev
|
name: JsonEncodingTestDev
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
sdk-version: 3.1.0-snapshot.20240705.13166.0.v801ce9b3
|
sdk-version: 3.1.0-snapshot.20240708.13168.0.v7ed18470
|
||||||
build-options:
|
build-options:
|
||||||
- --target=2.1
|
- --target=2.1
|
||||||
name: AdminWorkflows
|
name: AdminWorkflows
|
||||||
|
@ -882,7 +882,7 @@ object ParticipantNodeBootstrap {
|
|||||||
|
|
||||||
override protected def createEngine(arguments: Arguments): Engine =
|
override protected def createEngine(arguments: Arguments): Engine =
|
||||||
DAMLe.newEngine(
|
DAMLe.newEngine(
|
||||||
enableLfDev = arguments.parameterConfig.devVersionSupport,
|
enableLfDev = arguments.parameterConfig.alphaVersionSupport,
|
||||||
enableLfBeta = arguments.parameterConfig.betaVersionSupport,
|
enableLfBeta = arguments.parameterConfig.betaVersionSupport,
|
||||||
enableStackTraces = arguments.parameterConfig.engine.enableEngineStackTraces,
|
enableStackTraces = arguments.parameterConfig.engine.enableEngineStackTraces,
|
||||||
iterationsBetweenInterruptions =
|
iterationsBetweenInterruptions =
|
||||||
|
@ -45,7 +45,7 @@ final case class ParticipantNodeParameters(
|
|||||||
) extends CantonNodeParameters
|
) extends CantonNodeParameters
|
||||||
with HasGeneralCantonNodeParameters {
|
with HasGeneralCantonNodeParameters {
|
||||||
override def dontWarnOnDeprecatedPV: Boolean = protocolConfig.dontWarnOnDeprecatedPV
|
override def dontWarnOnDeprecatedPV: Boolean = protocolConfig.dontWarnOnDeprecatedPV
|
||||||
override def devVersionSupport: Boolean = protocolConfig.devVersionSupport
|
override def alphaVersionSupport: Boolean = protocolConfig.alphaVersionSupport
|
||||||
override def betaVersionSupport: Boolean = protocolConfig.betaVersionSupport
|
override def betaVersionSupport: Boolean = protocolConfig.betaVersionSupport
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ object ParticipantNodeParameters {
|
|||||||
protocolConfig = ParticipantProtocolConfig(
|
protocolConfig = ParticipantProtocolConfig(
|
||||||
Some(testedProtocolVersion),
|
Some(testedProtocolVersion),
|
||||||
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
||||||
devVersionSupport = true,
|
alphaVersionSupport = true,
|
||||||
betaVersionSupport = true,
|
betaVersionSupport = true,
|
||||||
dontWarnOnDeprecatedPV = false,
|
dontWarnOnDeprecatedPV = false,
|
||||||
),
|
),
|
||||||
|
@ -95,7 +95,7 @@ object PartyNotificationConfig {
|
|||||||
|
|
||||||
final case class ParticipantProtocolConfig(
|
final case class ParticipantProtocolConfig(
|
||||||
minimumProtocolVersion: Option[ProtocolVersion],
|
minimumProtocolVersion: Option[ProtocolVersion],
|
||||||
override val devVersionSupport: Boolean,
|
override val alphaVersionSupport: Boolean,
|
||||||
override val betaVersionSupport: Boolean,
|
override val betaVersionSupport: Boolean,
|
||||||
override val dontWarnOnDeprecatedPV: Boolean,
|
override val dontWarnOnDeprecatedPV: Boolean,
|
||||||
) extends ProtocolConfig
|
) extends ProtocolConfig
|
||||||
@ -331,7 +331,7 @@ object TestingTimeServiceConfig {
|
|||||||
* Setting to zero will disable reusing recent time proofs and will instead always fetch a new proof.
|
* Setting to zero will disable reusing recent time proofs and will instead always fetch a new proof.
|
||||||
* @param minimumProtocolVersion The minimum protocol version that this participant will speak when connecting to a domain
|
* @param minimumProtocolVersion The minimum protocol version that this participant will speak when connecting to a domain
|
||||||
* @param initialProtocolVersion The initial protocol version used by the participant (default latest), e.g., used to create the initial topology transactions.
|
* @param initialProtocolVersion The initial protocol version used by the participant (default latest), e.g., used to create the initial topology transactions.
|
||||||
* @param devVersionSupport If set to true, will allow the participant to connect to a domain with dev protocol version and will turn on unsafe Daml LF versions.
|
* @param alphaVersionSupport If set to true, will allow the participant to connect to a domain with dev protocol version and will turn on unsafe Daml LF versions.
|
||||||
* @param dontWarnOnDeprecatedPV If true, then this participant will not emit a warning when connecting to a sequencer using a deprecated protocol version (such as 2.0.0).
|
* @param dontWarnOnDeprecatedPV If true, then this participant will not emit a warning when connecting to a sequencer using a deprecated protocol version (such as 2.0.0).
|
||||||
* @param warnIfOverloadedFor If all incoming commands have been rejected due to PARTICIPANT_BACKPRESSURE during this interval, the participant will log a warning.
|
* @param warnIfOverloadedFor If all incoming commands have been rejected due to PARTICIPANT_BACKPRESSURE during this interval, the participant will log a warning.
|
||||||
* @param excludeInfrastructureTransactions If set, infrastructure transactions (i.e. ping, bong and dar distribution) will be excluded from participant metering.
|
* @param excludeInfrastructureTransactions If set, infrastructure transactions (i.e. ping, bong and dar distribution) will be excluded from participant metering.
|
||||||
@ -357,7 +357,7 @@ final case class ParticipantNodeParameterConfig(
|
|||||||
ProtocolVersion.latest
|
ProtocolVersion.latest
|
||||||
),
|
),
|
||||||
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
// TODO(i15561): Revert back to `false` once there is a stable Daml 3 protocol version
|
||||||
devVersionSupport: Boolean = true,
|
alphaVersionSupport: Boolean = true,
|
||||||
BetaVersionSupport: Boolean = false,
|
BetaVersionSupport: Boolean = false,
|
||||||
dontWarnOnDeprecatedPV: Boolean = false,
|
dontWarnOnDeprecatedPV: Boolean = false,
|
||||||
warnIfOverloadedFor: Option[config.NonNegativeFiniteDuration] = Some(
|
warnIfOverloadedFor: Option[config.NonNegativeFiniteDuration] = Some(
|
||||||
|
@ -41,7 +41,7 @@ object MockedNodeParameters {
|
|||||||
|
|
||||||
override def loggingConfig: LoggingConfig = _loggingConfig
|
override def loggingConfig: LoggingConfig = _loggingConfig
|
||||||
|
|
||||||
override def devVersionSupport: Boolean = ???
|
override def alphaVersionSupport: Boolean = ???
|
||||||
|
|
||||||
override def betaVersionSupport: Boolean = ???
|
override def betaVersionSupport: Boolean = ???
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
package com.digitalasset.canton.crypto.provider.symbolic
|
package com.digitalasset.canton.crypto.provider.symbolic
|
||||||
|
|
||||||
import cats.data.EitherT
|
import cats.data.{EitherT, OptionT}
|
||||||
import com.digitalasset.canton.concurrent.DirectExecutionContext
|
import com.digitalasset.canton.concurrent.DirectExecutionContext
|
||||||
import com.digitalasset.canton.config.ProcessingTimeout
|
import com.digitalasset.canton.config.ProcessingTimeout
|
||||||
import com.digitalasset.canton.crypto.*
|
import com.digitalasset.canton.crypto.*
|
||||||
@ -37,27 +37,34 @@ class SymbolicCrypto(
|
|||||||
loggerFactory,
|
loggerFactory,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private def process[E, A](
|
private def processE[E, A](
|
||||||
description: String
|
description: String
|
||||||
)(fn: TraceContext => EitherT[FutureUnlessShutdown, E, A]): A = {
|
)(fn: TraceContext => EitherT[FutureUnlessShutdown, E, A]): A =
|
||||||
|
process(description)(fn(_).valueOr(err => sys.error(s"Failed operation $description: $err")))
|
||||||
|
|
||||||
|
private def processO[A](
|
||||||
|
description: String
|
||||||
|
)(fn: TraceContext => OptionT[FutureUnlessShutdown, A]): Option[A] =
|
||||||
|
process(description)(fn(_).value)
|
||||||
|
|
||||||
|
private def process[A](description: String)(fn: TraceContext => FutureUnlessShutdown[A]): A = {
|
||||||
TraceContext.withNewTraceContext { implicit traceContext =>
|
TraceContext.withNewTraceContext { implicit traceContext =>
|
||||||
timeouts.default.await(description) {
|
timeouts.default.await(description) {
|
||||||
fn(traceContext)
|
fn(traceContext)
|
||||||
.valueOr(err => sys.error(s"Failed operation $description: $err"))
|
|
||||||
.onShutdown(sys.error("aborted due to shutdown"))
|
.onShutdown(sys.error("aborted due to shutdown"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getOrGenerateSymbolicSigningKey(name: String): SigningPublicKey = {
|
def getOrGenerateSymbolicSigningKey(name: String): SigningPublicKey = {
|
||||||
process("get or generate symbolic signing key") { implicit traceContext =>
|
processO("get or generate symbolic signing key") { implicit traceContext =>
|
||||||
cryptoPublicStore
|
cryptoPublicStore
|
||||||
.findSigningKeyIdByName(KeyName.tryCreate(name))
|
.findSigningKeyIdByName(KeyName.tryCreate(name))
|
||||||
}.getOrElse(generateSymbolicSigningKey(Some(name)))
|
}.getOrElse(generateSymbolicSigningKey(Some(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
def getOrGenerateSymbolicEncryptionKey(name: String): EncryptionPublicKey = {
|
def getOrGenerateSymbolicEncryptionKey(name: String): EncryptionPublicKey = {
|
||||||
process("get or generate symbolic encryption key") { implicit traceContext =>
|
processO("get or generate symbolic encryption key") { implicit traceContext =>
|
||||||
cryptoPublicStore
|
cryptoPublicStore
|
||||||
.findEncryptionKeyIdByName(KeyName.tryCreate(name))
|
.findEncryptionKeyIdByName(KeyName.tryCreate(name))
|
||||||
}.getOrElse(generateSymbolicEncryptionKey(Some(name)))
|
}.getOrElse(generateSymbolicEncryptionKey(Some(name)))
|
||||||
@ -67,7 +74,7 @@ class SymbolicCrypto(
|
|||||||
def generateSymbolicSigningKey(
|
def generateSymbolicSigningKey(
|
||||||
name: Option[String] = None
|
name: Option[String] = None
|
||||||
): SigningPublicKey = {
|
): SigningPublicKey = {
|
||||||
process("generate symbolic signing key") { implicit traceContext =>
|
processE("generate symbolic signing key") { implicit traceContext =>
|
||||||
// We don't care about the signing key scheme in symbolic crypto
|
// We don't care about the signing key scheme in symbolic crypto
|
||||||
generateSigningKey(SigningKeyScheme.Ed25519, name.map(KeyName.tryCreate))
|
generateSigningKey(SigningKeyScheme.Ed25519, name.map(KeyName.tryCreate))
|
||||||
}
|
}
|
||||||
@ -75,7 +82,7 @@ class SymbolicCrypto(
|
|||||||
|
|
||||||
/** Generates a new symbolic signing keypair but does not store it in the public store */
|
/** Generates a new symbolic signing keypair but does not store it in the public store */
|
||||||
def newSymbolicSigningKeyPair(): SigningKeyPair = {
|
def newSymbolicSigningKeyPair(): SigningKeyPair = {
|
||||||
process("generate symbolic signing keypair") { implicit traceContext =>
|
processE("generate symbolic signing keypair") { implicit traceContext =>
|
||||||
// We don't care about the signing key scheme in symbolic crypto
|
// We don't care about the signing key scheme in symbolic crypto
|
||||||
privateCrypto
|
privateCrypto
|
||||||
.generateSigningKeypair(SigningKeyScheme.Ed25519)
|
.generateSigningKeypair(SigningKeyScheme.Ed25519)
|
||||||
@ -85,7 +92,7 @@ class SymbolicCrypto(
|
|||||||
def generateSymbolicEncryptionKey(
|
def generateSymbolicEncryptionKey(
|
||||||
name: Option[String] = None
|
name: Option[String] = None
|
||||||
): EncryptionPublicKey =
|
): EncryptionPublicKey =
|
||||||
process("generate symbolic encryption key") { implicit traceContext =>
|
processE("generate symbolic encryption key") { implicit traceContext =>
|
||||||
// We don't care about the encryption key scheme in symbolic crypto
|
// We don't care about the encryption key scheme in symbolic crypto
|
||||||
generateEncryptionKey(
|
generateEncryptionKey(
|
||||||
EncryptionKeyScheme.EciesP256HkdfHmacSha256Aes128Gcm,
|
EncryptionKeyScheme.EciesP256HkdfHmacSha256Aes128Gcm,
|
||||||
@ -94,7 +101,7 @@ class SymbolicCrypto(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def newSymbolicEncryptionKeyPair(): EncryptionKeyPair = {
|
def newSymbolicEncryptionKeyPair(): EncryptionKeyPair = {
|
||||||
process("generate symbolic encryption keypair") { implicit traceContext =>
|
processE("generate symbolic encryption keypair") { implicit traceContext =>
|
||||||
// We don't care about the encryption key scheme in symbolic crypto
|
// We don't care about the encryption key scheme in symbolic crypto
|
||||||
privateCrypto
|
privateCrypto
|
||||||
.generateEncryptionKeypair(EncryptionKeyScheme.EciesP256HkdfHmacSha256Aes128Gcm)
|
.generateEncryptionKeypair(EncryptionKeyScheme.EciesP256HkdfHmacSha256Aes128Gcm)
|
||||||
@ -102,7 +109,7 @@ class SymbolicCrypto(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def sign(hash: Hash, signingKeyId: Fingerprint): Signature =
|
def sign(hash: Hash, signingKeyId: Fingerprint): Signature =
|
||||||
process("symbolic signing") { implicit traceContext =>
|
processE("symbolic signing") { implicit traceContext =>
|
||||||
privateCrypto.sign(hash, signingKeyId)
|
privateCrypto.sign(hash, signingKeyId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +135,7 @@ object SymbolicCrypto {
|
|||||||
DirectExecutionContext(loggerFactory.getLogger(this.getClass))
|
DirectExecutionContext(loggerFactory.getLogger(this.getClass))
|
||||||
|
|
||||||
val pureCrypto = new SymbolicPureCrypto()
|
val pureCrypto = new SymbolicPureCrypto()
|
||||||
val cryptoPublicStore = new InMemoryCryptoPublicStore
|
val cryptoPublicStore = new InMemoryCryptoPublicStore(loggerFactory)
|
||||||
val cryptoPrivateStore = new InMemoryCryptoPrivateStore(releaseProtocolVersion, loggerFactory)
|
val cryptoPrivateStore = new InMemoryCryptoPrivateStore(releaseProtocolVersion, loggerFactory)
|
||||||
val privateCrypto = new SymbolicPrivateCrypto(pureCrypto, cryptoPrivateStore)
|
val privateCrypto = new SymbolicPrivateCrypto(pureCrypto, cryptoPrivateStore)
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import cats.data.{EitherT, OptionT}
|
|||||||
import com.digitalasset.canton.BaseTest
|
import com.digitalasset.canton.BaseTest
|
||||||
import com.digitalasset.canton.concurrent.{DirectExecutionContext, ExecutionContextMonitor}
|
import com.digitalasset.canton.concurrent.{DirectExecutionContext, ExecutionContextMonitor}
|
||||||
import com.digitalasset.canton.discard.Implicits.DiscardOps
|
import com.digitalasset.canton.discard.Implicits.DiscardOps
|
||||||
|
import com.digitalasset.canton.lifecycle.{FutureUnlessShutdown, UnlessShutdown}
|
||||||
import com.digitalasset.canton.logging.SuppressingLogger.LogEntryOptionality
|
import com.digitalasset.canton.logging.SuppressingLogger.LogEntryOptionality
|
||||||
import com.digitalasset.canton.util.ErrorUtil
|
import com.digitalasset.canton.util.ErrorUtil
|
||||||
import com.digitalasset.canton.util.Thereafter.syntax.*
|
import com.digitalasset.canton.util.Thereafter.syntax.*
|
||||||
@ -195,6 +196,20 @@ class SuppressingLogger private[logging] (
|
|||||||
checkLogsInternalError(assertion),
|
checkLogsInternalError(assertion),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def assertInternalErrorAsyncUS[T <: Throwable](
|
||||||
|
within: => FutureUnlessShutdown[_],
|
||||||
|
assertion: T => Assertion,
|
||||||
|
)(implicit c: ClassTag[T], pos: source.Position): FutureUnlessShutdown[Assertion] =
|
||||||
|
assertLogs(
|
||||||
|
within.transform {
|
||||||
|
case Success(_) =>
|
||||||
|
fail(s"An exception of type $c was expected, but no exception was thrown.")
|
||||||
|
case Failure(c(t)) => Success(UnlessShutdown.Outcome(assertion(t)))
|
||||||
|
case Failure(t) => fail(s"Exception has wrong type. Expected type: $c.", t)
|
||||||
|
}(directExecutionContext),
|
||||||
|
checkLogsInternalError(assertion),
|
||||||
|
)
|
||||||
|
|
||||||
/** Asserts that the sequence of logged warnings/errors meets a given sequence of assertions.
|
/** Asserts that the sequence of logged warnings/errors meets a given sequence of assertions.
|
||||||
* Use this if the expected sequence of logged warnings/errors is deterministic.
|
* Use this if the expected sequence of logged warnings/errors is deterministic.
|
||||||
*
|
*
|
||||||
|
@ -1 +1 @@
|
|||||||
20240708.13628.v22bd0def
|
20240709.13636.vd03d4972
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
canton {
|
canton {
|
||||||
parameters {
|
parameters {
|
||||||
non-standard-config = yes
|
non-standard-config = yes
|
||||||
dev-version-support = yes
|
alpha-version-support = yes
|
||||||
}
|
}
|
||||||
participants {
|
participants {
|
||||||
build-and-lint-test {
|
build-and-lint-test {
|
||||||
@ -10,7 +10,7 @@ canton {
|
|||||||
# This test is run in exclusive mode to avoid clashes.
|
# This test is run in exclusive mode to avoid clashes.
|
||||||
ledger-api.port = 5011
|
ledger-api.port = 5011
|
||||||
admin-api.port = 5012
|
admin-api.port = 5012
|
||||||
parameters.dev-version-support = yes
|
parameters.alpha-version-support = yes
|
||||||
http-ledger-api-experimental {
|
http-ledger-api-experimental {
|
||||||
allow-insecure-tokens = true
|
allow-insecure-tokens = true
|
||||||
server {
|
server {
|
||||||
|
@ -185,9 +185,9 @@ getCantonConfig conf@SandboxConfig{..} portFile mCerts (ledgerPort, adminPort, s
|
|||||||
[ "type" Aeson..= ("sim-clock" :: T.Text) ]
|
[ "type" Aeson..= ("sim-clock" :: T.Text) ]
|
||||||
| Static <- [timeMode] ]
|
| Static <- [timeMode] ]
|
||||||
-- TODO(https://github.com/DACH-NY/canton/issues/16458): once ProtocolVersion.latest
|
-- TODO(https://github.com/DACH-NY/canton/issues/16458): once ProtocolVersion.latest
|
||||||
-- is stable, revert dev-version-support and non-standard-config to
|
-- is stable, revert alpha-version-support and non-standard-config to
|
||||||
-- devVersionSupport here and below.
|
-- devVersionSupport here and below.
|
||||||
, [ "dev-version-support" Aeson..= True]
|
, [ "alpha-version-support" Aeson..= True]
|
||||||
, [ "non-standard-config" Aeson..= True]
|
, [ "non-standard-config" Aeson..= True]
|
||||||
] )
|
] )
|
||||||
, "participants" Aeson..= Aeson.object
|
, "participants" Aeson..= Aeson.object
|
||||||
@ -207,7 +207,7 @@ getCantonConfig conf@SandboxConfig{..} portFile mCerts (ledgerPort, adminPort, s
|
|||||||
] ]
|
] ]
|
||||||
| Just secret <- [mbSharedSecret] ]
|
| Just secret <- [mbSharedSecret] ]
|
||||||
)
|
)
|
||||||
, "parameters" Aeson..= Aeson.object [ "dev-version-support" Aeson..= True ]
|
, "parameters" Aeson..= Aeson.object [ "alpha-version-support" Aeson..= True ]
|
||||||
] <>
|
] <>
|
||||||
[ "testing-time" Aeson..= Aeson.object [ "type" Aeson..= ("monotonic-time" :: T.Text) ]
|
[ "testing-time" Aeson..= Aeson.object [ "type" Aeson..= ("monotonic-time" :: T.Text) ]
|
||||||
| Static <- [timeMode]
|
| Static <- [timeMode]
|
||||||
@ -223,13 +223,13 @@ getCantonConfig conf@SandboxConfig{..} portFile mCerts (ledgerPort, adminPort, s
|
|||||||
, storage
|
, storage
|
||||||
, "public-api" Aeson..= port sequencerPublicPort
|
, "public-api" Aeson..= port sequencerPublicPort
|
||||||
, "admin-api" Aeson..= port sequencerAdminPort
|
, "admin-api" Aeson..= port sequencerAdminPort
|
||||||
, "parameters" Aeson..= Aeson.object [ "dev-version-support" Aeson..= True ]
|
, "parameters" Aeson..= Aeson.object [ "alpha-version-support" Aeson..= True ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, "mediators" Aeson..= Aeson.object
|
, "mediators" Aeson..= Aeson.object
|
||||||
[ "mediator1" Aeson..= Aeson.object
|
[ "mediator1" Aeson..= Aeson.object
|
||||||
[ "admin-api" Aeson..= port mediatorAdminPort
|
[ "admin-api" Aeson..= port mediatorAdminPort
|
||||||
, "parameters" Aeson..= Aeson.object [ "dev-version-support" Aeson..= True ]
|
, "parameters" Aeson..= Aeson.object [ "alpha-version-support" Aeson..= True ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -89,7 +89,7 @@ object CantonRunner {
|
|||||||
val (adminPort, ledgerApiPort) = ports(i)
|
val (adminPort, ledgerApiPort) = ports(i)
|
||||||
val participantId = config.participantIds(i)
|
val participantId = config.participantIds(i)
|
||||||
// TODO(https://github.com/DACH-NY/canton/issues/16458): once ProtocolVersion.latest
|
// TODO(https://github.com/DACH-NY/canton/issues/16458): once ProtocolVersion.latest
|
||||||
// is stable, revert dev-version-support and non-standard-config to
|
// is stable, revert alpha-version-support and non-standard-config to
|
||||||
// devMode here and below.
|
// devMode here and below.
|
||||||
s"""${participantId} {
|
s"""${participantId} {
|
||||||
| admin-api.port = ${adminPort.port}
|
| admin-api.port = ${adminPort.port}
|
||||||
@ -102,7 +102,7 @@ object CantonRunner {
|
|||||||
| storage.type = memory
|
| storage.type = memory
|
||||||
| parameters = {
|
| parameters = {
|
||||||
| engine.enable-engine-stack-traces = true
|
| engine.enable-engine-stack-traces = true
|
||||||
| dev-version-support = yes
|
| alpha-version-support = yes
|
||||||
| disable-upgrade-validation = ${config.disableUpgradeValidation}
|
| disable-upgrade-validation = ${config.disableUpgradeValidation}
|
||||||
| }
|
| }
|
||||||
| ${timeType.fold("")(x => "testing-time.type = " + x)}
|
| ${timeType.fold("")(x => "testing-time.type = " + x)}
|
||||||
@ -114,7 +114,7 @@ object CantonRunner {
|
|||||||
s"""canton {
|
s"""canton {
|
||||||
| parameters {
|
| parameters {
|
||||||
| non-standard-config = yes
|
| non-standard-config = yes
|
||||||
| dev-version-support = yes
|
| alpha-version-support = yes
|
||||||
| ports-file = ${toJson(files.portsFile)}
|
| ports-file = ${toJson(files.portsFile)}
|
||||||
| ${clockType.fold("")(x => "clock.type = " + x)}
|
| ${clockType.fold("")(x => "clock.type = " + x)}
|
||||||
| }
|
| }
|
||||||
|
Loading…
Reference in New Issue
Block a user