diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/admin/http/HttpSvAdminHandler.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/admin/http/HttpSvAdminHandler.scala index 20a30979c1..d4d71560e8 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/admin/http/HttpSvAdminHandler.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/admin/http/HttpSvAdminHandler.scala @@ -58,7 +58,6 @@ import com.digitalasset.canton.time.Clock import com.digitalasset.canton.tracing.TraceContext import com.digitalasset.canton.util.ErrorUtil import io.circe.syntax.EncoderOps -import io.grpc.Status import io.opentelemetry.api.trace.Tracer import org.apache.pekko.stream.Materializer import org.lfdecentralizedtrust.splice.config.{NetworkAppClientConfig, UpgradesConfig} @@ -110,29 +109,18 @@ class HttpSvAdminHandler( // Similar to PublishScanConfigTrigger, this class creates its own scan connection // on demand, because scan might not be available at application startup. - private def createScanConnection(): Future[ScanConnection] = - config.scan match { - case None => - Future.failed( - Status.UNAVAILABLE - .withDescription( - "This application is not configured to connect to a scan service. " + - " Check the application configuration or use the scan API to query votes information." - ) - .asRuntimeException() - ) - case Some(scanConfig) => - implicit val tc: TraceContext = TraceContext.empty - ScanConnection - .singleUncached( - ScanAppClientConfig(NetworkAppClientConfig(scanConfig.internalUrl)), - upgradesConfig, - clock, - retryProvider, - loggerFactory, - retryConnectionOnInitialFailure = true, - ) - } + private def createScanConnection(): Future[ScanConnection] = { + implicit val tc: TraceContext = TraceContext.empty + ScanConnection + .singleUncached( + ScanAppClientConfig(NetworkAppClientConfig(config.scan.internalUrl)), + upgradesConfig, + clock, + retryProvider, + loggerFactory, + retryConnectionOnInitialFailure = true, + ) + } @SuppressWarnings(Array("org.wartremover.warts.Var")) private var scanConnectionV: Option[Future[ScanConnection]] = None private def scanConnectionF: Future[ScanConnection] = blocking { diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/SvDsoAutomationService.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/SvDsoAutomationService.scala index 0a6c543ce6..4a4b44e89f 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/SvDsoAutomationService.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/SvDsoAutomationService.scala @@ -368,17 +368,15 @@ class SvDsoAutomationService( ) ) - config.scan.foreach { scan => - registerTrigger( - new PublishScanConfigTrigger( - triggerContext, - dsoStore, - connection(SpliceLedgerConnectionPriority.Low), - scan, - upgradesConfig, - ) + registerTrigger( + new PublishScanConfigTrigger( + triggerContext, + dsoStore, + connection(SpliceLedgerConnectionPriority.Low), + config.scan, + upgradesConfig, ) - } + ) config.followAmuletConversionRateFeed.foreach { c => registerTrigger( diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/singlesv/SequencerPruningTrigger.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/singlesv/SequencerPruningTrigger.scala index 572f96f26c..0787679615 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/singlesv/SequencerPruningTrigger.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/singlesv/SequencerPruningTrigger.scala @@ -41,7 +41,7 @@ import scala.concurrent.{ExecutionContextExecutor, Future} class SequencerPruningTrigger( override protected val context: TriggerContext, store: SvDsoStore, - scanConfig: Option[SvScanConfig], + scanConfig: SvScanConfig, upgradesConfig: UpgradesConfig, sequencerAdminConnection: SequencerAdminConnection, mediatorAdminConnection: MediatorAdminConnection, @@ -65,27 +65,15 @@ class SequencerPruningTrigger( private def createScanConnection()(implicit tc: TraceContext ): Future[BackfillingScanConnection] = - scanConfig match { - case None => - Future.failed( - Status.UNAVAILABLE - .withDescription( - "This application is not configured to connect to a scan service. " + - " Check the application configuration or use the scan API to query votes information." - ) - .asRuntimeException() - ) - case Some(scanConfig) => - ScanConnection - .singleUncached( - ScanAppClientConfig(NetworkAppClientConfig(scanConfig.internalUrl)), - upgradesConfig, - clock, - context.retryProvider, - loggerFactory, - retryConnectionOnInitialFailure = true, - ) - } + ScanConnection + .singleUncached( + ScanAppClientConfig(NetworkAppClientConfig(scanConfig.internalUrl)), + upgradesConfig, + clock, + context.retryProvider, + loggerFactory, + retryConnectionOnInitialFailure = true, + ) override def performWorkIfAvailable()(implicit traceContext: TraceContext): Future[Boolean] = for { diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/config/SvAppConfig.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/config/SvAppConfig.scala index 58b1a449cb..6235938fef 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/config/SvAppConfig.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/config/SvAppConfig.scala @@ -284,7 +284,7 @@ case class SvAppBackendConfig( initialAmuletPriceVote: Option[BigDecimal] = None, cometBftConfig: Option[SvCometBftConfig] = None, localSynchronizerNode: Option[SvSynchronizerNodeConfig], - scan: Option[SvScanConfig], + scan: SvScanConfig, participantBootstrappingDump: Option[ParticipantBootstrapDumpConfig] = None, identitiesDump: Option[BackupDumpConfig] = None, domainMigrationDumpPath: Option[Path] = None, diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/onboarding/SynchronizerNodeReconciler.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/onboarding/SynchronizerNodeReconciler.scala index 71d6301f24..0cf0f807db 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/onboarding/SynchronizerNodeReconciler.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/onboarding/SynchronizerNodeReconciler.scala @@ -46,7 +46,7 @@ class SynchronizerNodeReconciler( synchronizerId: SynchronizerId, state: SynchronizerNodeState, migrationId: Long, - scan: Option[SvScanConfig], + scanConfig: SvScanConfig, )(implicit ec: ExecutionContext, tc: TraceContext, @@ -54,9 +54,7 @@ class SynchronizerNodeReconciler( def setConfigIfRequired() = for { localSequencerConfig <- SvUtil.getSequencerConfig(synchronizerNode, migrationId) localMediatorConfig <- SvUtil.getMediatorConfig(synchronizerNode) - localScanConfig = scan - .map(scanConfig => new ScanConfig(scanConfig.publicUrl.toString())) - .toJava + localScanConfig = java.util.Optional.of(new ScanConfig(scanConfig.publicUrl.toString())) rulesAndState <- dsoStore.getDsoRulesWithSvNodeState(svParty) nodeState = rulesAndState.svNodeState.payload // TODO(DACH-NY/canton-network-node#4901): do not use default, but reconcile all configured domains diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/util/SvUtil.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/util/SvUtil.scala index 90f6a6a70f..7e061c820f 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/util/SvUtil.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/util/SvUtil.scala @@ -180,7 +180,7 @@ object SvUtil { def getSV1SynchronizerNodeConfig( cometBftNode: Option[CometBftNode], localSynchronizerNode: LocalSynchronizerNode, - scanConfig: Option[SvScanConfig], + scanConfig: SvScanConfig, synchronizerId: SynchronizerId, clock: Clock, migrationId: Long, @@ -234,7 +234,7 @@ object SvUtil { cometBftConfig, sequencerConfig.toJava, mediatorConfig.toJava, - scanConfig.map(c => new ScanConfig(c.publicUrl.toString())).toJava, + Optional.of(new ScanConfig(scanConfig.publicUrl.toString())), Optional.empty(), ) ).asJava diff --git a/cluster/helm/splice-sv-node/values.schema.json b/cluster/helm/splice-sv-node/values.schema.json index 723c72030d..96521950d6 100644 --- a/cluster/helm/splice-sv-node/values.schema.json +++ b/cluster/helm/splice-sv-node/values.schema.json @@ -43,6 +43,7 @@ "defaultJvmOptions", "domain", "imageRepo", + "scan", "nodeIdentifier", "onboardingName", "persistence", @@ -287,7 +288,8 @@ "internalUrl": { "type": "string" } - } + }, + "required": ["publicUrl", "internalUrl"] }, "nodeIdentifier": { "type": "string" diff --git a/docs/src/release_notes.rst b/docs/src/release_notes.rst index 79cbe611f7..cc44a6e570 100644 --- a/docs/src/release_notes.rst +++ b/docs/src/release_notes.rst @@ -25,10 +25,16 @@ Upcoming - Published conversion rates are now clamped to the configured range and the clamped value is published instead of only logging a warning and not publishing an updated value for out of range values. - + - The SV app will no longer store the update history and such, will not be able to answer historical queries. All updates involving the DSO party will still be stored and returned by Scan. + - Deployment + + - The helm values under ``scan``, that is ``publicUrl`` and ``internalUrl`` are now mandatory. + All SVs already deploy scan on DevNet, TestNet and MainNet so this should have no impact. + + 0.4.20 ------