diff --git a/docs-main/global-synchronizer/extension-synchronizers/deployment.mdx b/docs-main/global-synchronizer/extension-synchronizers/deployment.mdx index 49e3a2001..8016cbf68 100644 --- a/docs-main/global-synchronizer/extension-synchronizers/deployment.mdx +++ b/docs-main/global-synchronizer/extension-synchronizers/deployment.mdx @@ -1,45 +1,114 @@ --- title: "Deploying a Private Synchronizer" -description: "Step-by-step guide for deploying sequencer and mediator nodes for a private Canton synchronizer" +description: "Step-by-step guide to configure, start, bootstrap, and verify a private Canton synchronizer" --- import CANTON_DOCS_CN_GS_EXTENSION_SYNCHRONIZERS_DEPLOYMENT_0 from "/snippets/external/canton/main/docs-open/target/snippet_json_data/docs-cn/global-synchronizer-extension-synchronizers-deployment-0.mdx"; import CANTON_DOCS_CN_GS_EXTENSION_SYNCHRONIZERS_DEPLOYMENT_1 from "/snippets/external/canton/main/docs-open/target/snippet_json_data/docs-cn/global-synchronizer-extension-synchronizers-deployment-1.mdx"; +This tutorial walks you through deploying a **private synchronizer** (also called an extension synchronizer): configure sequencer and mediator nodes, start them, bootstrap topology, connect validators, and verify the deployment. +It is for operators who run their own synchronizer alongside — or instead of relying solely on — the [Global Synchronizer](/overview/understand/global-synchronizer). It is **not** the Super Validator / Global Synchronizer operator guide. -A private synchronizer requires deploying sequencer and mediator nodes, configuring their database backends, and connecting validators. This guide covers the infrastructure setup for both standalone and hybrid deployments. +For concepts first, see [Private Synchronizers](/global-synchronizer/extension-synchronizers/private-synchronizers). For deep reference (all bootstrap variants, HA, pruning, and so on), use [Synchronizer Operations](/global-synchronizer/extension-synchronizers/synchronizer-operations) — this page is the end-to-end walkthrough; that page is the reference. -## Prerequisites + +**Setup order** -Before you begin: +1. **Configure** — APIs, sequencer backend, TLS, and storage +2. **Start** — Deploy and start sequencer and mediator +3. **Bootstrap** — Initialize synchronizer topology +4. **Connect** — Attach validators / participants +5. **Verify** — Health, topology, and a test transaction +6. **Harden** (optional) — HA, monitoring, backups, and related ops + -- A Kubernetes cluster (1.27+) with Helm 3 installed -- PostgreSQL 14+ (managed service recommended for production) -- TLS certificates for the sequencer endpoint -- Canton release artifacts (Docker images or JARs) -- Familiarity with [Canton's synchronizer architecture](/overview/reference/synchronizer-overview) +## Who this guide is for + +Use this guide when: + +- You need a dedicated synchronizer for privacy, performance, governance, or cost reasons +- A single organization will own and operate the sequencer and mediator (the default path below) +- You may later connect the same validators to the Global Synchronizer ([hybrid pattern](/global-synchronizer/extension-synchronizers/hybrid-synchronizer-pattern)) + +If you only need Canton Network public connectivity and Canton Coin, deploy a [validator on the Global Synchronizer](/global-synchronizer/deployment/deployment-options) instead of standing up your own synchronizer. + +## Choose your topology -## Ordering backends +| Choose… | When… | Then follow… | +|---|---|---| +| **Centralized, single-operator** (default) | One org owns sequencer and mediator | This tutorial | +| **Decentralized / multi-owner** | Distinct operators must co-sign topology | [Decentralized bootstrap](/global-synchronizer/extension-synchronizers/synchronizer-operations#set-up-a-decentralized-synchronizer) | +| **HA / multi-sequencer** | Production redundancy | Finish this tutorial, then [High Availability](/global-synchronizer/extension-synchronizers/synchronizer-operations#high-availability-in-synchronizer) | +| **Hybrid (private + Global Synchronizer)** | Need CN connectivity as well | This tutorial, then [hybrid pattern](/global-synchronizer/extension-synchronizers/hybrid-synchronizer-pattern) and [linking validators](/global-synchronizer/extension-synchronizers/linking-validator-multi-sync) | -The sequencer requires a backend to store and order messages. Canton supports two options: +**Default path for this guide:** one sequencer + one mediator, single owner, [BFT sequencer backend](/global-synchronizer/extension-synchronizers/bft-orderer) (minimal single-node network). Background on the orderer is in [BFT Orderer Architecture](/global-synchronizer/extension-synchronizers/bft-orderer). API, backend, and TLS details are in [Synchronizer Operations — configure](/global-synchronizer/extension-synchronizers/synchronizer-operations#configure-synchronizer-apis). -- **Centralized ordering** — A single ordering node acts as the ordering backend. Simpler to operate, suitable for private synchronizers where a single operator manages the infrastructure. Currently in **Alpha**. -- **Decentralized ordering (BFT with CometBFT)** — Multiple sequencer nodes run BFT consensus. Required when multiple independent parties operate the synchronizer and no single party should control ordering. This is how the Global Synchronizer operates. + +The database sequencer backend is unsupported. Use the BFT sequencer backend for new private synchronizers. Multi-node BFT peer networks and advanced backend options are covered under [Configure Sequencer Backend](/global-synchronizer/extension-synchronizers/synchronizer-operations#configure-sequencer-backend). + + +## Prerequisites + +Before you begin: + +- Familiarity with [Canton's synchronizer architecture](/overview/reference/synchronizer-overview) +- **PostgreSQL 14+** — separate databases for sequencer and mediator; for production, a managed service with automated backups, at least **4 vCPUs / 16 GB memory**, and SSD-backed storage +- **TLS certificates** for the sequencer **public API** (validators connect here) +- Canton release artifacts (container images or JARs) for sequencer and mediator +- Access to the **Canton Console** for the sequencer (and mediator if it runs separately) + +**Kubernetes / Helm (typical production path):** Kubernetes 1.27+ and Helm 3. + +**Local / non-Helm (dev and test):** You can run sequencer and mediator as Canton processes with config files instead of Helm. The configure and bootstrap steps are the same; only how you start the processes changes. See [Deploy and start](#3-deploy-and-start-sequencer-and-mediator) for a short non-Helm note. + +## 1. Configure APIs, backend, and TLS + +Write configuration **before** starting nodes. At minimum you need: + +1. **Sequencer and mediator APIs** — public and admin ports/addresses ([Configure Synchronizer APIs](/global-synchronizer/extension-synchronizers/synchronizer-operations#configure-synchronizer-apis)) +2. **Sequencer backend** — `sequencer.type = BFT` for the default path ([Configure Sequencer Backend](/global-synchronizer/extension-synchronizers/synchronizer-operations#configure-sequencer-backend)) +3. **TLS** on the sequencer public API ([Secure Synchronizer APIs](/global-synchronizer/extension-synchronizers/synchronizer-operations#secure-synchronizer-apis)) +4. **Storage** — Postgres for each node (next section) + +Minimal Canton-style shape (illustrative; map the same settings into Helm values below): + +```scala +sequencers { + sequencer1 { + storage.type = postgres + // ... postgres connection ... + public-api { + port = 5001 + // TLS: see Secure Synchronizer APIs + } + admin-api.port = 5002 + sequencer.type = BFT + } +} + +mediators { + mediator1 { + storage.type = postgres + // ... postgres connection ... + admin-api.port = 5202 + } +} +``` -For most private synchronizer deployments where a single organization controls the infrastructure, the centralized ordering backend is the simpler choice. +For peers, endpoint authentication, dedicated BFT storage, external sequencers, and client authentication, use the operations reference — do not expand this tutorial into those variants. -## Database setup +## 2. Set up databases -You need separate PostgreSQL databases for the sequencer and mediator. Each node stores its own state independently. +Create separate PostgreSQL databases and dedicated users, for example `sequencer_db` / `sequencer_user` and `mediator_db` / `mediator_user`. Each node stores its own state independently. -Create separate databases (`sequencer_db`, `mediator_db`) with dedicated users. For production, use a managed PostgreSQL service (Cloud SQL, RDS, Azure Database for PostgreSQL) with automated backups, high availability, at least 4 vCPUs / 16 GB memory, and SSD-backed storage. +Point the sequencer and mediator storage configuration at those databases before you start the nodes. -## Deploying the sequencer +## 3. Deploy and start sequencer and mediator -### Helm chart configuration +The Helm examples below are **illustrative** packaging of the same settings. Adjust chart names, value keys, and image repositories to match the Canton / CN release artifacts you use. -Create a values file for the sequencer: +### Sequencer (Helm) ```yaml # sequencer-values.yaml @@ -55,24 +124,25 @@ sequencer: user: "sequencer_user" password: "" publicApi: + port: 5001 tls: certChainFile: "/certs/tls.crt" privateKeyFile: "/certs/tls.key" + adminApi: + port: 5002 + sequencer: + type: BFT parameters: synchronizerName: "my-private-sync" ``` -Deploy with Helm: - ```bash helm install sequencer canton/canton-sequencer \ -f sequencer-values.yaml \ --namespace canton-sync ``` -## Deploying the mediator - -Create a values file for the mediator: +### Mediator (Helm) ```yaml # mediator-values.yaml @@ -87,35 +157,53 @@ mediator: databaseName: "mediator_db" user: "mediator_user" password: "" + adminApi: + port: 5202 sequencerConnection: address: "https://sequencer.canton-sync.svc.cluster.local" ``` -Deploy with Helm: - ```bash helm install mediator canton/canton-mediator \ -f mediator-values.yaml \ --namespace canton-sync ``` -## Initializing the synchronizer +### Confirm nodes are healthy + +Before bootstrap: + +- Sequencer and mediator processes/pods are running +- Sequencer health endpoint returns HTTP 200 (when exposed) +- You can open a Canton Console against the sequencer admin API + +### Non-Helm starts + +Start the sequencer and mediator with your Canton distribution and the config files from [Configure](#1-configure-apis-backend-and-tls), then continue with bootstrap. Console commands are the same. -After both nodes are running, initialize the synchronizer topology. Using the Canton Console connected to the sequencer: +## 4. Bootstrap (initialize) the synchronizer +Nodes must be **fresh** (not previously initialized), **started**, and already configured with backend, APIs, TLS, and storage. + +Using the Canton Console connected to the sequencer (default **centralized** bootstrap — single owner, threshold 1): +This creates the synchronizer identity and registers the sequencer and mediator in the synchronizer topology. You should see a physical synchronizer id for `my-private-sync` (or the name you chose). -This creates the synchronizer identity and registers the sequencer and mediator in the synchronizer topology. +Other bootstrap flows (do not inline here): -## Connecting validators +- [Decentralized synchronizer](/global-synchronizer/extension-synchronizers/synchronizer-operations#set-up-a-decentralized-synchronizer) +- [Decentralized with a subset of sequencers as owners](/global-synchronizer/extension-synchronizers/synchronizer-operations#set-up-a-decentralized-synchronizer-with-a-subset-of-sequencers-as-owners) +- [Permissioned synchronizer](/global-synchronizer/extension-synchronizers/synchronizer-operations#bootstrap-a-permissioned-synchronizer) -Once the synchronizer is initialized, validators can connect to it. On each validator's Canton Console: +Full bootstrap reference: [Bootstrap a Synchronizer](/global-synchronizer/extension-synchronizers/synchronizer-operations#bootstrap-a-synchronizer). +## 5. Connect validators - +Once the synchronizer is initialized, connect each validator (participant). On the Canton Console: + Or configure the connection in the validator's Helm values: @@ -126,19 +214,35 @@ participant: sequencerConnection: "https://sequencer.private-sync.example.com" ``` -After connecting, verify the connection with `participant.synchronizers.list_connected()`. +Use a stable **alias** (here `my-private-sync`) consistently in console and Helm. After changing connection config at runtime, disconnect and reconnect the synchronizer on the participant so the update takes effect. + +For validators that also stay on the Global Synchronizer, see [linking a validator to multiple synchronizers](/global-synchronizer/extension-synchronizers/linking-validator-multi-sync). + +## 6. Verify the deployment + +Work through this checklist: -## Verification +1. **Sequencer health** — HTTP health endpoint returns 200 +2. **Mediator in topology** — Mediator is registered on the synchronizer +3. **Participant connected** — `participant.synchronizers.list_connected()` shows your alias +4. **Ping** — Participant can ping across the synchronizer (see bootstrap examples in [Synchronizer Operations](/global-synchronizer/extension-synchronizers/synchronizer-operations#set-up-a-centralized-synchronizer)) +5. **Optional smoke test** — Allocate a test party and create a contract assigned to the private synchronizer -Confirm end-to-end functionality by allocating a test party and creating a contract on the private synchronizer. Check the sequencer health endpoint (HTTP 200 means ready) and verify the mediator is registered in the synchronizer topology. +## Production hardening and next steps -## Production considerations +- **TLS everywhere** — Validators to sequencer public API; prefer TLS for peer and admin paths in production ([Secure Synchronizer APIs](/global-synchronizer/extension-synchronizers/synchronizer-operations#secure-synchronizer-apis)) +- **Network policies** — Restrict sequencer endpoint access to known validator networks +- **Monitoring** — [Synchronizer monitoring](/global-synchronizer/extension-synchronizers/synchronizer-monitoring); reuse your validator metrics stack where possible +- **Backups** — Back up sequencer and mediator databases regularly ([Backup and Restore](/global-synchronizer/extension-synchronizers/synchronizer-operations#backup-and-restore)) +- **HA** — [High Availability in Synchronizer](/global-synchronizer/extension-synchronizers/synchronizer-operations#high-availability-in-synchronizer) +- **Traffic management** — If you enable traffic controls on a private synchronizer, see [Sequencer Traffic Management](/global-synchronizer/extension-synchronizers/synchronizer-operations#sequencer-traffic-management) +- **Pruning** — [Synchronizer Pruning](/global-synchronizer/extension-synchronizers/synchronizer-operations#synchronizer-pruning) -- **TLS everywhere** — Use TLS for all connections between validators and the synchronizer -- **Network policies** — Restrict sequencer endpoint access to known validator IPs -- **Monitoring** — Sequencer and mediator nodes expose Prometheus metrics; use the same monitoring stack as your validators -- **Backups** — Back up sequencer and mediator databases regularly +## Related reference - -The centralized ordering backend (PostgreSQL) is in Alpha. For production workloads, test thoroughly with your expected transaction volume and plan for the possibility of breaking changes in future Canton releases. - +- [Private Synchronizers](/global-synchronizer/extension-synchronizers/private-synchronizers) — Why and when to use them +- [Hybrid Synchronizer Pattern](/global-synchronizer/extension-synchronizers/hybrid-synchronizer-pattern) — Private + Global Synchronizer +- [Linking Validators](/global-synchronizer/extension-synchronizers/linking-validator-multi-sync) — Multi-synchronizer participants +- [Synchronizer Operations](/global-synchronizer/extension-synchronizers/synchronizer-operations) — Configure, bootstrap variants, HA, traffic, pruning, backup +- [BFT Orderer Architecture](/global-synchronizer/extension-synchronizers/bft-orderer) — Ordering backend background +- [Synchronizer Monitoring](/global-synchronizer/extension-synchronizers/synchronizer-monitoring) — Observability diff --git a/docs-main/global-synchronizer/extension-synchronizers/private-synchronizers.mdx b/docs-main/global-synchronizer/extension-synchronizers/private-synchronizers.mdx index 9156394dd..6ec9d8f3b 100644 --- a/docs-main/global-synchronizer/extension-synchronizers/private-synchronizers.mdx +++ b/docs-main/global-synchronizer/extension-synchronizers/private-synchronizers.mdx @@ -96,5 +96,5 @@ Private synchronizers and the Global Synchronizer are complementary: ## Next Steps - [Hybrid Synchronizer Pattern](/global-synchronizer/extension-synchronizers/hybrid-synchronizer-pattern) — Combining public and private synchronizers -- [Deployment](/global-synchronizer/extension-synchronizers/deployment) — Deploying extension synchronizer infrastructure +- [Deploying a Private Synchronizer](/global-synchronizer/extension-synchronizers/deployment) — Configure, start, bootstrap, connect validators, and verify - [Linking Validators](/global-synchronizer/extension-synchronizers/linking-validator-multi-sync) — Multi-synchronizer validator configuration diff --git a/docs-main/global-synchronizer/extension-synchronizers/synchronizer-operations.mdx b/docs-main/global-synchronizer/extension-synchronizers/synchronizer-operations.mdx index 11716abfe..66f34e39d 100644 --- a/docs-main/global-synchronizer/extension-synchronizers/synchronizer-operations.mdx +++ b/docs-main/global-synchronizer/extension-synchronizers/synchronizer-operations.mdx @@ -102,6 +102,10 @@ This page is a reference for configuring, bootstrapping, and operating synchroni # Configure Synchronizer APIs + +For an end-to-end private synchronizer walkthrough that starts with configuration, see [Deploying a Private Synchronizer](/global-synchronizer/extension-synchronizers/deployment). + + A Synchronizer exposes two main APIs, the Admin API and the Public API, while the Participant Node exposes the Ledger API and the Admin API. In this section, we explain what the APIs do and how they can be configured. For details on how to configure endpoints and their addresses, ports, keep alive, and so on, see the general API documentation. @@ -1204,6 +1208,10 @@ val schedule = sequencer1.bft.pruning.get_bft_schedule() # High Availability in Synchronizer + +Complete a basic deployment first ([Deploying a Private Synchronizer](/global-synchronizer/extension-synchronizers/deployment)), then apply HA for production redundancy. + + ## Mediator The mediator service uses a hot standby mechanism with an arbitrary number of replicas. During a mediator fail-over, all in-flight requests get purged. As a result, these requests will timeout at the participants. The applications need to retry the underlying commands.