diff --git a/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/config/SpliceConfig.scala b/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/config/SpliceConfig.scala index ca62f0a0f1..fd9535709b 100644 --- a/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/config/SpliceConfig.scala +++ b/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/config/SpliceConfig.scala @@ -711,11 +711,11 @@ object SpliceConfig { ) _ <- Either.cond( conf.domains.global.trustedSynchronizerConfig.forall(c => - c.sequencerNames.length >= c.threshold + c.svNames.length >= c.threshold ), (), ConfigValidationFailed( - "Configuration error: Length of sequencerNames should be greater than or equal to threshold." + "Configuration error: Length of svNames should be greater than or equal to threshold." ), ) _ <- Either.cond( diff --git a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ValidatorSequencerConnectionIntegrationTest.scala b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ValidatorSequencerConnectionIntegrationTest.scala index 1adb7fb642..d97027223b 100644 --- a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ValidatorSequencerConnectionIntegrationTest.scala +++ b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ValidatorSequencerConnectionIntegrationTest.scala @@ -42,7 +42,7 @@ class ValidatorSequencerConnectionIntegrationTest global = c.domains.global.copy( trustedSynchronizerConfig = Some( ValidatorTrustedSynchronizerConfig( - sequencerNames = NonEmptyList.of(getSvName(1), getSvName(2), getSvName(3)), + svNames = NonEmptyList.of(getSvName(1), getSvName(2), getSvName(3)), threshold = 2, ) ) @@ -56,7 +56,7 @@ class ValidatorSequencerConnectionIntegrationTest ) .withManualStart - "validator with 'sequencerNames' set in config connects to specified sequencers and tracks URL changes of sequencers" in { + "validator with 'svNames' set in config connects to specified sequencers and tracks URL changes of sequencers" in { implicit env => startAllSync( sv1Backend, diff --git a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/config/ValidatorAppConfig.scala b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/config/ValidatorAppConfig.scala index 9225a1d7ce..4bd55ae01c 100644 --- a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/config/ValidatorAppConfig.scala +++ b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/config/ValidatorAppConfig.scala @@ -110,9 +110,9 @@ case class ValidatorDecentralizedSynchronizerConfig( case class ValidatorTrustedSynchronizerConfig( /** static list of trusted sequencer names to connect to. - * sequencerNames is mutually exclusive with `url`. + * svNames is mutually exclusive with `url`. */ - sequencerNames: NonEmptyList[String], + svNames: NonEmptyList[String], /** parameter to specify the BFT threshold for the domain connections. * If not specified, f +1 will be used. diff --git a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/domain/DomainConnector.scala b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/domain/DomainConnector.scala index 0163ce5200..1985b7999a 100644 --- a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/domain/DomainConnector.scala +++ b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/domain/DomainConnector.scala @@ -214,7 +214,7 @@ class DomainConnector( ) val svFilteredSequencers = config.domains.global.trustedSynchronizerConfig match { case Some(config) => - val allowedNamesSet = config.sequencerNames.toList.toSet + val allowedNamesSet = config.svNames.toList.toSet logger.debug( s"Filtering sequencers to only include: ${allowedNamesSet.toList.mkString(", ")}" ) diff --git a/cluster/helm/splice-validator/templates/validator.yaml b/cluster/helm/splice-validator/templates/validator.yaml index c5eb53abdd..8b0a1597ba 100644 --- a/cluster/helm/splice-validator/templates/validator.yaml +++ b/cluster/helm/splice-validator/templates/validator.yaml @@ -133,12 +133,14 @@ spec: - name: ADDITIONAL_CONFIG_STATIC_SEQUENCER_URL value: canton.validator-apps.validator_backend.domains.global.url = {{ .Values.decentralizedSynchronizerUrl | quote }} {{ else if .Values.synchronizer -}} - {{- if eq .Values.synchronizer.connectionType "trusted-url" }} + {{- if eq .Values.synchronizer.connectionType "trust-single" }} - name: ADDITIONAL_CONFIG_SYNCHRONIZER_URL value: canton.validator-apps.validator_backend.domains.global.url = {{ .Values.synchronizer.url | quote }} - {{- else if eq .Values.synchronizer.connectionType "trusted-svs" }} - - name: ADDITIONAL_CONFIG_SYNCHRONIZER_NAMES - value: canton.validator-apps.validator_backend.domains.global.sequencer-names = {{ .Values.synchronizer.sequencerNames | toJson}} + {{- else if eq .Values.synchronizer.connectionType "bft-custom" }} + - name: ADDITIONAL_CONFIG_SYNCHRONIZER_TRUSTED + value: | + canton.validator-apps.validator_backend.domains.global.trusted-synchronizer-config.sv-names = {{ .Values.synchronizer.svNames | toJson}} + canton.validator-apps.validator_backend.domains.global.trusted-synchronizer-config.threshold = {{ .Values.synchronizer.threshold }} {{- end }} {{ end }} {{- range $ii, $domain := .Values.extraDomains }} diff --git a/cluster/helm/splice-validator/tests/validator_test.yaml b/cluster/helm/splice-validator/tests/validator_test.yaml index ef1f4b9809..fbcc0d5e98 100644 --- a/cluster/helm/splice-validator/tests/validator_test.yaml +++ b/cluster/helm/splice-validator/tests/validator_test.yaml @@ -236,7 +236,7 @@ tests: - it: "uses synchronizer.url when provided" set: synchronizer: - connectionType: "trusted-url" + connectionType: "trust-single" url: "https://new-sequencer.mock.com" documentSelector: path: kind @@ -246,15 +246,19 @@ tests: path: spec.template.spec.containers[?(@.name=='validator-app')].env[?(@.name=='ADDITIONAL_CONFIG_SYNCHRONIZER_URL')].value pattern: 'canton\.validator-apps\.validator_backend\.domains\.global\.url = "https://new-sequencer\.mock\.com"' - - it: "uses synchronizer.sequencerNames as a JSON array when provided" + - it: "uses synchronizer.svNames as a JSON array when provided" set: synchronizer: - connectionType: "trusted-svs" - sequencerNames: [ "sequencer-1", "sequencer-2" ] + connectionType: "bft-custom" + svNames: [ "sequencer-1", "sequencer-2" ] + threshold: 2 documentSelector: path: kind value: Deployment asserts: - matchRegex: - path: spec.template.spec.containers[?(@.name=='validator-app')].env[?(@.name=='ADDITIONAL_CONFIG_SYNCHRONIZER_NAMES')].value - pattern: 'canton\.validator-apps\.validator_backend\.domains\.global\.sequencer-names = \["sequencer-1","sequencer-2"\]' + path: spec.template.spec.containers[?(@.name=='validator-app')].env[?(@.name=='ADDITIONAL_CONFIG_SYNCHRONIZER_TRUSTED')].value + pattern: 'canton\.validator-apps\.validator_backend\.domains\.global\.trusted-synchronizer-config\.sv-names = \["sequencer-1","sequencer-2"\]' + - matchRegex: + path: spec.template.spec.containers[?(@.name=='validator-app')].env[?(@.name=='ADDITIONAL_CONFIG_SYNCHRONIZER_TRUSTED')].value + pattern: 'canton\.validator-apps\.validator_backend\.domains\.global\.trusted-synchronizer-config\.threshold = 2' diff --git a/cluster/helm/splice-validator/values.schema.json b/cluster/helm/splice-validator/values.schema.json index 08020708a6..ba05f149f8 100644 --- a/cluster/helm/splice-validator/values.schema.json +++ b/cluster/helm/splice-validator/values.schema.json @@ -16,22 +16,27 @@ "connectionType": { "type": "string", "enum": [ - "from-scan", - "trusted-url", - "trusted-svs" + "trust-single", + "bft", + "bft-custom" ] }, - "sequencerNames": { + "url": { + "type": "string", + "description": "Trusted sequencer Url." + }, + "svNames": { "type": "array", "items": { "type": "string" }, "default": [], - "description": "Optional list of trusted sequencer / SV names." + "description": "list of trusted sequencer / SV names. Optional unless connectionType is bft-custom." }, - "url": { - "type": "string", - "description": "Trusted sequencer Url." + "threshold": { + "type": "integer", + "minimum": 0, + "description": "bft-custom threshold. Optional unless connectionType is bft-custom." } } }, @@ -54,7 +59,7 @@ }, "threshold": { "type": "integer", - "default": 0, + "minimum": 0, "description": "bft-custom threshold. Optional unless scan-type is bft-custom." }, "trustedSvs": { @@ -590,52 +595,51 @@ "if": { "required": ["synchronizer"], "properties": { - "synchronizer": { - "required": ["connectionType"] - } + "synchronizer": { "required": ["connectionType"] } } }, "then": { "allOf": [ { "if": { - "properties": { "synchronizer": { "properties": { "connectionType": { "const": "from-scan" } } } } + "properties": { "synchronizer": { "properties": { "connectionType": { "const": "bft" } } } } }, "then": { "properties": { "synchronizer": { - "properties": { - "url": { "not": {} }, - "sequencerNames": { "not": {} } - } + "not": { "required": ["url", "svNames", "threshold"] } } } } }, { "if": { - "properties": { "synchronizer": { "properties": { "connectionType": { "const": "trusted-url" } } } } + "properties": { "synchronizer": { "properties": { "connectionType": { "const": "trust-single" } } } } }, "then": { "properties": { "synchronizer": { "required": ["url"], - "properties": { "sequencerNames": { "not": {} } } + "properties": { + "url": { "minLength": 1 }, + "svNames": false, + "threshold": false + } } } } }, { "if": { - "properties": { "synchronizer": { "properties": { "connectionType": { "const": "trusted-svs" } } } } + "properties": { "synchronizer": { "properties": { "connectionType": { "const": "bft-custom" } } } } }, "then": { "properties": { "synchronizer": { - "required": ["sequencerNames"], + "required": ["svNames", "threshold"], "properties": { - "url": { "not": {} }, - "sequencerNames": { "minItems": 1 } + "url": false, + "svNames": { "minItems": 1 } } } } diff --git a/cluster/pulumi/common-validator/src/config.ts b/cluster/pulumi/common-validator/src/config.ts index 914b145dcd..070ed1b2ab 100644 --- a/cluster/pulumi/common-validator/src/config.ts +++ b/cluster/pulumi/common-validator/src/config.ts @@ -13,19 +13,24 @@ import { z } from 'zod'; export const SynchronizerConfigSchema = z.union([ z .object({ - connectionType: z.literal('trusted-url'), + connectionType: z.literal('trust-single'), url: z.string().min(1), }) .strict(), z .object({ - connectionType: z.literal('trusted-svs'), - sequencerNames: z.array(z.string()).min(1), + connectionType: z.literal('bft-custom'), + svNames: z.array(z.string()).min(1), + threshold: z.number().int().min(1), }) - .strict(), + .strict() + .refine(data => data.svNames.length >= data.threshold, { + message: 'svNames length must be greater than or equal to the threshold', + path: ['threshold'], // Point the error to the threshold field + }), z .object({ - connectionType: z.literal('from-scan').default('from-scan'), + connectionType: z.literal('bft').default('bft'), }) .strict(), ]);