diff --git a/.github/workflows/actions/deploy-terraform-infrastructure/action.yml b/.github/workflows/actions/deploy-terraform-infrastructure/action.yml index 346055b152b..fe3153daab5 100644 --- a/.github/workflows/actions/deploy-terraform-infrastructure/action.yml +++ b/.github/workflows/actions/deploy-terraform-infrastructure/action.yml @@ -125,6 +125,10 @@ inputs: mithril_genesis_verification_key_url: description: Mithril genesis verification key location. required: true + mithril_circuit_verification_key_registry_url: + description: Mithril signed circuit verification key registry location (only for SNARK aggregate signature types). + required: false + default: "" mithril_era_reader_adapter_type: description: Mithril era reader adapter type. required: false @@ -315,6 +319,7 @@ runs: mithril_api_domain = "${{ inputs.mithril_api_domain }}" mithril_image_id = "${{ inputs.mithril_image_id }}" mithril_genesis_verification_key_url = "${{ inputs.mithril_genesis_verification_key_url }}" + mithril_circuit_verification_key_registry_url = "${{ inputs.mithril_circuit_verification_key_registry_url }}" mithril_genesis_secret_key = "${{ inputs.mithril_genesis_secret_key }}" mithril_signers = ${{ fromJSON(inputs.mithril_signers) }} mithril_era_reader_adapter_type = "${{ inputs.mithril_era_reader_adapter_type }}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c622ae014ea..ada5bf048ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -823,6 +823,7 @@ jobs: mithril_signers: ${{ toJSON(matrix.mithril_signers) }} mithril_genesis_secret_key: ${{ secrets.GENESIS_SECRET_KEY }} mithril_genesis_verification_key_url: ${{ vars.GENESIS_VERIFICATION_KEY_URL }} + mithril_circuit_verification_key_registry_url: ${{ vars.CIRCUIT_VERIFICATION_KEY_REGISTRY_URL }} mithril_era_reader_address_url: ${{ vars.ERA_READER_ADDRESS_URL }} mithril_era_reader_verification_key_url: ${{ vars.ERA_READER_VERIFICATION_KEY_URL }} mithril_era_reader_secret_key: ${{ secrets.ERA_READER_SECRET_KEY }} diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 387f5c81efd..226b607eb3d 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -282,6 +282,7 @@ jobs: mithril_signers: ${{ toJSON(matrix.mithril_signers) }} mithril_genesis_secret_key: ${{ secrets.GENESIS_SECRET_KEY }} mithril_genesis_verification_key_url: ${{ vars.GENESIS_VERIFICATION_KEY_URL }} + mithril_circuit_verification_key_registry_url: ${{ vars.CIRCUIT_VERIFICATION_KEY_REGISTRY_URL }} mithril_era_reader_address_url: ${{ vars.ERA_READER_ADDRESS_URL }} mithril_era_reader_verification_key_url: ${{ vars.ERA_READER_VERIFICATION_KEY_URL }} mithril_era_reader_secret_key: ${{ secrets.ERA_READER_SECRET_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 28c7e6dd8d0..76e8c124d9a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -200,6 +200,7 @@ jobs: mithril_image_id: ${{ env.DOCKER_IMAGE_ID }} mithril_signers: ${{ toJSON(matrix.mithril_signers) }} mithril_genesis_verification_key_url: ${{ vars.GENESIS_VERIFICATION_KEY_URL }} + mithril_circuit_verification_key_registry_url: ${{ vars.CIRCUIT_VERIFICATION_KEY_REGISTRY_URL }} mithril_era_reader_address_url: ${{ vars.ERA_READER_ADDRESS_URL }} mithril_era_reader_verification_key_url: ${{ vars.ERA_READER_VERIFICATION_KEY_URL }} mithril_protocol_configuration_reader_address_url: ${{ vars.PROTOCOL_CONFIGURATION_READER_ADDRESS_URL }} diff --git a/.github/workflows/test-deploy-network.yml b/.github/workflows/test-deploy-network.yml index 428dab3e641..502a225fa0f 100644 --- a/.github/workflows/test-deploy-network.yml +++ b/.github/workflows/test-deploy-network.yml @@ -157,6 +157,7 @@ jobs: mithril_signers: ${{ toJSON(matrix.mithril_signers) }} mithril_genesis_secret_key: ${{ secrets.GENESIS_SECRET_KEY }} mithril_genesis_verification_key_url: ${{ vars.GENESIS_VERIFICATION_KEY_URL }} + mithril_circuit_verification_key_registry_url: ${{ vars.CIRCUIT_VERIFICATION_KEY_REGISTRY_URL }} mithril_era_reader_adapter_type: ${{ matrix.mithril_era_reader_adapter_type }} mithril_era_reader_address_url: ${{ vars.ERA_READER_ADDRESS_URL }} mithril_era_reader_verification_key_url: ${{ vars.ERA_READER_VERIFICATION_KEY_URL }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 0801aefbf76..c334921f855 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,10 +21,12 @@ As a minor extension, we have adopted a slightly different versioning convention - Reworked the Mithril aggregator's file archiver to produce byte-stable archives across systems. - Existing archives must be regenerated by the Mithril aggregator to ensure byte stability. - Preliminary support for uploading immutable files to IPFS with the Mithril aggregator and downloading them from IPFS with the Mithril client library and CLI. - - Preliminary support for the circuit verification key registry, a genesis-signed whitelist (with revocations) of the circuit verification keys trusted for SNARK certificates. + - Support for the circuit verification key registry, a genesis-signed whitelist (with revocations) of the circuit verification keys trusted for SNARK certificates. - The registry lives in the new `mithril-circuit-key-registry` crate, holding one entry per circuit verification key, either allowed over an epoch range or revoked for every epoch. - The registry is retrieved over HTTPS and the last verified registry is kept when a refresh fails. - New `circuit-key-registry export`, `whitelist`, `expire`, `revoke` and `sign` commands in the Mithril aggregator to manage the genesis-signed registry of a Mithril network. + - The Mithril aggregator enforces the registry when creating SNARK certificates with the new `circuit_verification_key_registry_url` configuration parameter, refreshing the registry at most once per hour. + - The Mithril client library and CLI verify the circuit verification keys of the SNARK certificates against the registry of their network, resolved from the `networks.json` file, with the new `--circuit-verification-key-registry-path` option of the CLI to read a local registry. - Moved the download of the SRS of the trusted setup from the STM library to the Mithril aggregator, removing the HTTP client and the TLS features from the library and its consumers. - Hardened the SRS download of the Mithril aggregator: a cached SRS is verified against its pinned hash before use, the prover warm-up retries with a doubling delay and gives up on a failure no attempt resolves, and each download attempt is bounded and never leaves HTTPS. - Support for an IVC follower aggregator joining the network at any time, with a new optional `certificate_chain_aggregator_endpoint` configuration parameter of the Mithril aggregator to synchronize the full certificate chain from a distinct aggregator, defaulting to the leader aggregator endpoint. diff --git a/Cargo.lock b/Cargo.lock index 77cbc96bb8d..0b54e87d36a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4214,7 +4214,7 @@ dependencies = [ [[package]] name = "mithril-aggregator" -version = "0.10.12" +version = "0.10.13" dependencies = [ "anyhow", "async-trait", @@ -4444,7 +4444,7 @@ dependencies = [ [[package]] name = "mithril-client" -version = "0.14.27" +version = "0.14.28" dependencies = [ "anyhow", "async-trait", @@ -4461,6 +4461,7 @@ dependencies = [ "mithril-aggregator-client", "mithril-aggregator-discovery", "mithril-cardano-node-internal-database", + "mithril-circuit-key-registry", "mithril-common", "mockall", "rand 0.10.2", @@ -4482,7 +4483,7 @@ dependencies = [ [[package]] name = "mithril-client-cli" -version = "0.13.25" +version = "0.13.26" dependencies = [ "anyhow", "async-trait", @@ -4537,7 +4538,7 @@ dependencies = [ [[package]] name = "mithril-common" -version = "0.7.26" +version = "0.7.27" dependencies = [ "anyhow", "async-trait", @@ -4622,7 +4623,7 @@ dependencies = [ [[package]] name = "mithril-end-to-end" -version = "0.5.20" +version = "0.5.21" dependencies = [ "anyhow", "async-recursion", diff --git a/docs/runbook/README.md b/docs/runbook/README.md index b82dceebd22..b27bad2cb82 100644 --- a/docs/runbook/README.md +++ b/docs/runbook/README.md @@ -6,27 +6,28 @@ This page gathers the available guides to operate a Mithril network. # Guides -| Operation | Location | Description | -| -------------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -| **Genesis manually** | [manual-genesis](./genesis-manually/README.md) | Proceed to manual (re)genesis of the aggregator certificate chain. | -| **Era markers** | [era-markers](./era-markers/README.md) | Create and update era markers on the Cardano chain. | -| **Protocol configuration markers** | [protocol-configuration-markers](./protocol-configuration-markers/README.md) | Create and update protocol configuration markers on the Cardano chain. | -| **Downloads statistics** | [downloads statistics](./statistics/README.md) | Display the number of downloads per day. | -| **Signer registrations monitoring** | [registrations-monitoring](./registrations-monitoring/README.md) | Gather aggregated data about signer registrations (versions, stake, ...). | -| **Recompute certificates hash** | [recompute-certificates-hash](./recompute-certificates-hash/README.md) | Recompute the certificates hash of an aggregator. | -| **Fix terraform lock** | [terraform-lock](./terraform-lock/README.md) | Fix a terraform lock in CD workflows. | -| **Manage SSH access to infrastructure** | [ssh-access](./ssh-access/README.md) | Manage SSH access on the VM of the infrastructure for a user. | -| **Upgrade VM of infrastructure** | [upgrade-vm](./upgrade-vm/README.md) | Upgrade the VM of the infrastructure of a Mithril network. | -| **Create test Docker distribution** | [test-docker-distribution](./test-docker-distribution/README.md) | Create a custom test Docker distribution. | -| **Deploy a test network manually** | [test-deploy-network](./test-deploy-network/README.md) | Manually deploy a test distribution to a test Mithril network. | -| **Publish crates to crates.io manually** | [manual-publish-crates](./manual-publish-crates/README.md) | Manually publish Rust crates to crates.io. | -| **Publish packages to npm manually** | [manual-publish-npm](./manual-publish-npm/README.md) | Manually publish packages to npm registry. | -| **Client multi-platform test** | [test-client-multiplatform](./test-client-multiplatform/README.md) | Run multi-platform client CLI binaries, docker and WASM package tests. | -| **Maintain the networks configuration file** | [maintain-networks-configuration-file](./maintain-networks-configuration-file/README.md) | Maintain the `networks.json` file | -| **Aggregator metrics** | [aggregator-metrics](./aggregator-metrics/README.md) | Display aggregator daily metrics. | -| **Upgrade Cardano node** | [upgrade-cardano-node](./upgrade-cardano-node/README.md) | Upgrade the Cardano node of a Mithril network. | -| **Cardano node warmup** | [warmup-cardano-node](./warmup-cardano-node/README.md) | Warm up a Cardano node from a Mithril snapshot to avoid ledger replay downtime. | -| **Prepare Cardano node artifacts** | [prepare-cardano-node-artifacts](./prepare-cardano-node-artifacts/README.md) | Prepare and publish artifacts for an unreleased Cardano node version. | -| **Cardano Docker bundle** | [cardano-docker-bundle](./cardano-docker-bundle/README.md) | Build and publish a Docker image bundling Cardano node with Mithril. | -| **Update circuits verification keys** | [update-circuit-keys](./update-circuit-keys/README.md) | Update the circuits verification keys after an intentional circuit modification. | -| **GitHub self-hosted runner** | [self-hosted-runner](./self-hosted-runner/README.md) | Set up a GCP virtual machine as a GitHub self-hosted runner for heavy workloads. | +| Operation | Location | Description | +| -------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| **Genesis manually** | [manual-genesis](./genesis-manually/README.md) | Proceed to manual (re)genesis of the aggregator certificate chain. | +| **Era markers** | [era-markers](./era-markers/README.md) | Create and update era markers on the Cardano chain. | +| **Protocol configuration markers** | [protocol-configuration-markers](./protocol-configuration-markers/README.md) | Create and update protocol configuration markers on the Cardano chain. | +| **Downloads statistics** | [downloads statistics](./statistics/README.md) | Display the number of downloads per day. | +| **Signer registrations monitoring** | [registrations-monitoring](./registrations-monitoring/README.md) | Gather aggregated data about signer registrations (versions, stake, ...). | +| **Recompute certificates hash** | [recompute-certificates-hash](./recompute-certificates-hash/README.md) | Recompute the certificates hash of an aggregator. | +| **Fix terraform lock** | [terraform-lock](./terraform-lock/README.md) | Fix a terraform lock in CD workflows. | +| **Manage SSH access to infrastructure** | [ssh-access](./ssh-access/README.md) | Manage SSH access on the VM of the infrastructure for a user. | +| **Upgrade VM of infrastructure** | [upgrade-vm](./upgrade-vm/README.md) | Upgrade the VM of the infrastructure of a Mithril network. | +| **Create test Docker distribution** | [test-docker-distribution](./test-docker-distribution/README.md) | Create a custom test Docker distribution. | +| **Deploy a test network manually** | [test-deploy-network](./test-deploy-network/README.md) | Manually deploy a test distribution to a test Mithril network. | +| **Publish crates to crates.io manually** | [manual-publish-crates](./manual-publish-crates/README.md) | Manually publish Rust crates to crates.io. | +| **Publish packages to npm manually** | [manual-publish-npm](./manual-publish-npm/README.md) | Manually publish packages to npm registry. | +| **Client multi-platform test** | [test-client-multiplatform](./test-client-multiplatform/README.md) | Run multi-platform client CLI binaries, docker and WASM package tests. | +| **Maintain the networks configuration file** | [maintain-networks-configuration-file](./maintain-networks-configuration-file/README.md) | Maintain the `networks.json` file | +| **Aggregator metrics** | [aggregator-metrics](./aggregator-metrics/README.md) | Display aggregator daily metrics. | +| **Upgrade Cardano node** | [upgrade-cardano-node](./upgrade-cardano-node/README.md) | Upgrade the Cardano node of a Mithril network. | +| **Cardano node warmup** | [warmup-cardano-node](./warmup-cardano-node/README.md) | Warm up a Cardano node from a Mithril snapshot to avoid ledger replay downtime. | +| **Prepare Cardano node artifacts** | [prepare-cardano-node-artifacts](./prepare-cardano-node-artifacts/README.md) | Prepare and publish artifacts for an unreleased Cardano node version. | +| **Cardano Docker bundle** | [cardano-docker-bundle](./cardano-docker-bundle/README.md) | Build and publish a Docker image bundling Cardano node with Mithril. | +| **Update circuits verification keys** | [update-circuit-keys](./update-circuit-keys/README.md) | Update the circuits verification keys after an intentional circuit modification. | +| **GitHub self-hosted runner** | [self-hosted-runner](./self-hosted-runner/README.md) | Set up a GCP virtual machine as a GitHub self-hosted runner for heavy workloads. | +| **Circuit verification key registry** | [circuit-key-registry](./circuit-key-registry/README.md) | Publish, rotate and revoke circuit verification keys in the genesis-signed registry. | diff --git a/docs/runbook/circuit-key-registry/README.md b/docs/runbook/circuit-key-registry/README.md new file mode 100644 index 00000000000..058679a8280 --- /dev/null +++ b/docs/runbook/circuit-key-registry/README.md @@ -0,0 +1,320 @@ +# Manage the circuit verification key registry + +## Introduction + +The circuit verification key registry is the list of the circuit verification keys trusted for the +SNARK certificates (`Snark` and `IvcSnark` aggregate signature types) of a Mithril network, signed +with the genesis key of that Mithril network. + +The registry of a Mithril network is published at +`mithril-infra/configuration//circuit-verification-key-registry.json` and +referenced from the Mithril network entry of the [networks.json](../../../networks.json) file: + +```json +"circuit-verification-key-registry": { + "url": "https://raw.githubusercontent.com/IntersectMBO/mithril/main/mithril-infra/configuration/release-mainnet/circuit-verification-key-registry.json" +} +``` + +The nodes reject a SNARK certificate whose circuit verification key digests are not allowed by the +registry: + +- The clients resolve the registry of their Mithril network through `networks.json`, by selecting + the Mithril network entry whose aggregators include their aggregator endpoint, and download it. +- The aggregators download the registry from the URL of their + `circuit_verification_key_registry_url` configuration parameter, set by their deployment (a + `file://` URL reads a local file, for local deployments). + +The nodes refresh the registry when they verify a certificate requiring it, at most once per hour, +keeping the previously verified registry when the refresh fails or would lower the registry +version. + +> [!NOTE] +> The `circuit-key-registry` command and the `circuit_verification_key_registry_url` parameter of +> the aggregator, and the `--circuit-verification-key-registry-path` parameter of the client, only +> exist in binaries built with the `future_snark` feature, which the distributions do not enable +> yet: a deployed Mithril network enforces the registry once its distribution is built with it. + +> [!IMPORTANT] +> `networks.json` only routes the clients to a registry, it is not trusted: a wrong entry can only +> yield a registry that fails the genesis signature verification, or an older registry of the same +> Mithril network. + +## Registry format + +```json +{ + "registry": { + "version": 2, + "entries": [ + { + "digest": "3e5a…9c1f", + "name": "certificate-circuit v1", + "status": "allowed", + "start_epoch": 500, + "end_epoch": null, + "comment": null + }, + { + "digest": "7bd2…04aa", + "name": "ivc-circuit v1", + "status": "revoked", + "start_epoch": 500, + "end_epoch": 520, + "comment": "revoked: soundness issue in the accumulator check" + } + ] + }, + "signature": "…" +} +``` + +| Field | Type | Description | +| ----------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| `registry.version` | integer | Version of the registry, at least `1` and strictly greater than the version of the previously published registry. | +| `registry.entries` | array | One statement per circuit verification key. | +| `entries[].digest` | hex string (64 chars) | Circuit verification key digest the statement is about, unique in the registry. | +| `entries[].name` | string | Label of the circuit verification key, for humans (e.g. `certificate-circuit v1`). | +| `entries[].status` | `allowed` or `revoked` | `allowed`: the key may certify the certificates of the epoch range. `revoked`: the certificates of the key are rejected forever. | +| `entries[].start_epoch` | integer | First epoch (inclusive) at which the key is allowed. | +| `entries[].end_epoch` | integer or `null` | Last epoch (inclusive) at which an allowed key is allowed, `null` when open-ended; epoch of the revocation of a revoked key. | +| `entries[].comment` | string or `null` | Audit trail, e.g. the reason of a revocation. | +| `signature` | hex string | Ed25519 signature of the genesis key of the Mithril network over the `registry` object. | + +The nodes enforce the following rules: + +- A circuit verification key digest without an entry, or whose `allowed` entry does not cover the + epoch of the certificate, is rejected. +- A circuit verification key digest with a `revoked` entry is rejected for every epoch, so a + revocation is retroactive: a forger chooses the epoch its certificate claims. +- A registry refreshed by a running node with a `version` lower than the one it previously + verified is ignored: the node keeps the registry it previously verified. +- A registry signed with the genesis key of another Mithril network is rejected. + +The circuit verification key digests are Poseidon hashes of the transcript representation of the +verification keys, which binds the circuit gates. The two circuits behave differently: + +- The IVC circuit does not depend on the protocol parameters: its circuit verification key digest + is the same for every Mithril network. +- The certificate circuit depends on the `k` and `m` protocol parameters: its circuit verification + key digest changes with them, so a change of `k` or `m` requires whitelisting the new digest, + published before the first epoch certified with the new parameters. + +## Pre-requisites + +- The genesis secret key of the Mithril network, on the air-gapped machine used for signing +- The protocol parameters of the Mithril network +- A `mithril-aggregator` binary built with the `future_snark` feature: + +```bash +cargo build --release -p mithril-aggregator --features future_snark +``` + +## Setup environment variables + +Export the environment variables needed to complete the process: + +```bash +export MITHRIL_AGGREGATOR=**PATH_TO_YOUR_MITHRIL_AGGREGATOR_BINARY** +export MITHRIL_NETWORK=**YOUR_MITHRIL_NETWORK** +export PROTOCOL_PARAMETERS='**YOUR_PROTOCOL_PARAMETERS_JSON**' +export REGISTRY_PATH=mithril-infra/configuration/$MITHRIL_NETWORK/circuit-verification-key-registry.json +``` + +Here is an example for the `release-mainnet` Mithril network: + +```bash +export MITHRIL_AGGREGATOR=./target/release/mithril-aggregator +export MITHRIL_NETWORK=release-mainnet +export PROTOCOL_PARAMETERS='{"k":1944,"m":16948,"phi_f":0.2}' +export REGISTRY_PATH=mithril-infra/configuration/$MITHRIL_NETWORK/circuit-verification-key-registry.json +``` + +On the air-gapped machine holding the genesis secret key, also export: + +```bash +export GENESIS_SECRET_KEY_PATH=**PATH_TO_YOUR_GENESIS_SECRET_KEY_FILE** +``` + +## Export the circuit verification key digests + +Export the circuit verification key digests of the Mithril network: + +```bash +$MITHRIL_AGGREGATOR circuit-key-registry export \ + --protocol-parameters "$PROTOCOL_PARAMETERS" \ + --target-path circuit-verification-key-digests.json +``` + +The command prints the two digests and writes them to the target file: + +```json +{ + "certificate_circuit": "3e5a…9c1f", + "ivc_circuit": "7bd2…04aa" +} +``` + +> The certificate circuit verification key is derived from the trusted setup for the given +> protocol parameters, which is fast for the small `k` of the test networks. Without +> `--protocol-parameters`, the production certificate circuit verification key embedded in +> `mithril-stm` is used. + +## Whitelist a circuit verification key + +Export the circuit verification key digest to whitelist and the first epoch it certifies: + +```bash +export CIRCUIT_VERIFICATION_KEY_DIGEST=**YOUR_CIRCUIT_VERIFICATION_KEY_DIGEST** +export CIRCUIT_VERIFICATION_KEY_NAME=**YOUR_CIRCUIT_VERIFICATION_KEY_NAME** +export START_EPOCH=**YOUR_START_EPOCH** +``` + +On the air-gapped machine, add the `allowed` entry to the registry and sign it: + +```bash +$MITHRIL_AGGREGATOR circuit-key-registry whitelist \ + --registry-path $REGISTRY_PATH \ + --genesis-secret-key-path $GENESIS_SECRET_KEY_PATH \ + --digest $CIRCUIT_VERIFICATION_KEY_DIGEST \ + --name "$CIRCUIT_VERIFICATION_KEY_NAME" \ + --start-epoch $START_EPOCH +``` + +The command verifies the signature of the current registry, appends the entry, increments the +`version`, signs the registry and writes it in place. + +> When the registry file does not exist, the command creates it at version `1`: make sure +> `$REGISTRY_PATH` points to the published registry of the Mithril network, otherwise the +> previously published entries are dropped. The command fails when the key already has an entry. + +> Add `--end-epoch **YOUR_END_EPOCH**` to close the range of the key, and `--comment "…"` to +> record the reason of the entry. + +## Expire a circuit verification key + +Export the circuit verification key digest to expire, which must have an `allowed` entry, and the +last epoch at which it certifies: + +```bash +export CIRCUIT_VERIFICATION_KEY_DIGEST=**YOUR_CIRCUIT_VERIFICATION_KEY_DIGEST** +export END_EPOCH=**YOUR_END_EPOCH** +``` + +On the air-gapped machine, expire the key in the registry and sign it: + +```bash +$MITHRIL_AGGREGATOR circuit-key-registry expire \ + --registry-path $REGISTRY_PATH \ + --genesis-secret-key-path $GENESIS_SECRET_KEY_PATH \ + --digest $CIRCUIT_VERIFICATION_KEY_DIGEST \ + --end-epoch $END_EPOCH +``` + +The command verifies the signature of the current registry, closes the range of the `allowed` +entry of the key at the end epoch, increments the `version`, signs the registry and writes it in +place. The certificates of the key up to the end epoch keep verifying. + +> [!IMPORTANT] +> The end epoch must not precede the last epoch certified with the key, the one preceding the +> re-genesis or the protocol parameters change retiring it, otherwise the certificates of the last +> epochs are rejected. + +> Add `--comment "…"` to record the reason of the expiration. + +## Revoke a circuit verification key + +Export the circuit verification key digest to revoke, which must have an `allowed` entry, the epoch +of the revocation and its reason: + +```bash +export CIRCUIT_VERIFICATION_KEY_DIGEST=**YOUR_CIRCUIT_VERIFICATION_KEY_DIGEST** +export REVOCATION_EPOCH=**YOUR_REVOCATION_EPOCH** +export REVOCATION_COMMENT=**YOUR_REVOCATION_COMMENT** +``` + +On the air-gapped machine, revoke the key in the registry and sign it: + +```bash +$MITHRIL_AGGREGATOR circuit-key-registry revoke \ + --registry-path $REGISTRY_PATH \ + --genesis-secret-key-path $GENESIS_SECRET_KEY_PATH \ + --digest $CIRCUIT_VERIFICATION_KEY_DIGEST \ + --revocation-epoch $REVOCATION_EPOCH \ + --comment "$REVOCATION_COMMENT" +``` + +The command verifies the signature of the current registry, turns the `allowed` entry of the key +into a `revoked` one recording the revocation epoch and the comment, increments the `version`, +signs the registry and writes it in place. The certificates of a revoked key are rejected for every +epoch. + +> [!WARNING] +> The revocation also rejects the current certificate chain of the Mithril network, which stops +> certifying from the publication of the revocation until the re-genesis with the fixed circuit +> keys. Before publishing, whitelist the digests of the fixed circuit keys (see above) in the same +> published registry and prepare the distribution embedding them, so the re-genesis follows the +> publication immediately. + +After the publication of the revocation (see below), run a re-genesis with the fixed circuit keys, +following the [update-circuit-keys](../update-circuit-keys/README.md) and +[genesis-manually](../genesis-manually/README.md) runbooks. + +## Publish the registry + +Create a pull request with the signed registry at `$REGISTRY_PATH`, reviewed by the tech lead and +the cryptographers. + +> [!IMPORTANT] +> The signature covers the exact bytes of the `registry` object, so the signed registry file must +> never be reformatted: it is excluded from `prettier` in `.prettierignore`, and a reformatted +> registry fails the genesis signature verification of every node. + +For the first registry of a Mithril network, also reference it from the Mithril network entry of +[networks.json](../../../networks.json): + +```json +"circuit-verification-key-registry": { + "url": "https://raw.githubusercontent.com/IntersectMBO/mithril/main/mithril-infra/configuration/**YOUR_MITHRIL_NETWORK**/circuit-verification-key-registry.json" +} +``` + +and set the `CIRCUIT_VERIFICATION_KEY_REGISTRY_URL` variable of the GitHub environment of the +Mithril network to the same URL. + +Publish the registry before the first epoch whose certificates need it, with at least one hour of +lead time. Once the pull request is merged on `main`: + +- The clients download the new registry at their next certificate verification, a long-running + client keeping a verified registry for at most an hour. +- The aggregators of the Mithril network download the new registry from the URL of the + `CIRCUIT_VERIFICATION_KEY_REGISTRY_URL` variable, passed to them by their deployment, at their + next certificate verification once their previous download is more than an hour old. + +## Sign a hand-authored registry + +A registry authored by hand (the `registry` object above, without `signature`) can be signed as a +whole. On the air-gapped machine: + +```bash +export REGISTRY_TO_SIGN_PATH=**PATH_TO_YOUR_UNSIGNED_REGISTRY_FILE** +``` + +```bash +$MITHRIL_AGGREGATOR circuit-key-registry sign \ + --to-sign-registry-path $REGISTRY_TO_SIGN_PATH \ + --target-signed-registry-path $REGISTRY_PATH \ + --genesis-secret-key-path $GENESIS_SECRET_KEY_PATH +``` + +## Use a local registry with the client + +For tests and local deployments, the client CLI reads the registry from a local file instead of +resolving it through `networks.json` (the genesis signature verification still applies): + +```bash +mithril-client --unstable --circuit-verification-key-registry-path $REGISTRY_PATH cardano-db snapshot list +``` + +Library users get the same through `with_circuit_verification_key_registry_retriever` on the client +builder. diff --git a/docs/runbook/genesis-manually/README.md b/docs/runbook/genesis-manually/README.md index ad0738880e1..71e20f47316 100644 --- a/docs/runbook/genesis-manually/README.md +++ b/docs/runbook/genesis-manually/README.md @@ -15,6 +15,14 @@ The era controls which key material the subcommand expects: The signing-key file (`genesis.sk`) and the verification-key file (`genesis.vk`) layouts are auto-detected. +## Circuit verification key registry + +For the `Snark` and `IvcSnark` aggregate signature types, the certificates following the genesis +certificate are rejected unless the circuit verification key registry of the Mithril network allows +their circuit verification keys from the genesis epoch: whitelist the digests of the deployed +circuit keys and publish the registry before the genesis, following the +[circuit-key-registry](../circuit-key-registry/README.md) runbook. + ## Configure environment variables Export the environment variables: diff --git a/docs/runbook/protocol-configuration-markers/README.md b/docs/runbook/protocol-configuration-markers/README.md index fa42ed0180d..3aa7da86bf9 100644 --- a/docs/runbook/protocol-configuration-markers/README.md +++ b/docs/runbook/protocol-configuration-markers/README.md @@ -131,6 +131,12 @@ Manually edit previously exported JSON file written at `$ASSETS_PATH/protocol-co > [!IMPORTANT] > :fire: Make sure to keep, if it exists, at least the three last epoch's configuration without any modification. +> [!IMPORTANT] +> For the `Snark` and `IvcSnark` aggregate signature types, changing `k` or `m` changes the +> certificate circuit verification key digest: whitelist the new digest in the circuit verification +> key registry and publish it before the first epoch certified with the new parameters, following +> the [circuit-key-registry](../circuit-key-registry/README.md) runbook. + #### Generate Tx Datum payload file Generate Tx Datum payload file by using previously edited JSON file diff --git a/docs/runbook/update-circuit-keys/README.md b/docs/runbook/update-circuit-keys/README.md index dbb6468b8c5..1327c4757a9 100644 --- a/docs/runbook/update-circuit-keys/README.md +++ b/docs/runbook/update-circuit-keys/README.md @@ -42,6 +42,8 @@ Release manager: - Prepares the release of this update - Schedule the re-genesis of the certificate chain +- Publishes the new version of the circuit verification key registry (see + [circuit-key-registry](../circuit-key-registry/README.md)) ## Download of the production SRS @@ -87,6 +89,16 @@ cargo test -p mithril-stm --features future_snark --release write_recursive_circ that will update the files holding the values of the production keys, `mithril-stm/src/circuits/halo2/non_recursive_circuit_verification_key_for_production.vkey` and `mithril-stm/src/circuits/halo2_ivc/recursive_circuit_verification_key_for_production.vkey`. +## Update of the circuit verification key registry + +Changing a circuit changes its verification key, and thus its digest in the circuit verification key +registry. A new registry version must be signed with the genesis key and published for the Mithril +network, whitelisting the new keys from the epoch of the re-genesis and expiring the outgoing ones +at the epoch preceding it (or revoking them, in case of a vulnerability), following the +[circuit-key-registry](../circuit-key-registry/README.md) runbook. +Clients resolve and download the registry through the published `networks.json`, so without this +publication they reject the certificates produced with the new keys. + ## Scheduling of the re-genesis Once the review is done and all the circuit verification keys are updated, the release manager can schedule the re-genesis. Re-genesis is scheduled with the release of the next distribution where the new circuit is deployed. It goes through the sequence: diff --git a/docs/website/root/manual/develop/nodes/mithril-aggregator.md b/docs/website/root/manual/develop/nodes/mithril-aggregator.md index 8ab2bc178ac..871b5eeff35 100644 --- a/docs/website/root/manual/develop/nodes/mithril-aggregator.md +++ b/docs/website/root/manual/develop/nodes/mithril-aggregator.md @@ -561,40 +561,41 @@ Here is a list of the available parameters for the serve command: `serve` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ---------------------------------------------------------------- | ------------------------------------------------------------------ | :------------------: | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------: | -| `server_ip` | `--server-ip` | - | `SERVER_IP` | Listening server IP | `0.0.0.0` | - | :heavy_check_mark: | -| `server_port` | `--server-port` | - | `SERVER_PORT` | Listening server port | `8080` | - | :heavy_check_mark: | -| `public_server_url` | - | - | `PUBLIC_SERVER_URL` | Public URL of the aggregator | - | `https://aggregator.release-mainnet.api.mithril.network/aggregator` | - | -| `snapshot_directory` | `--snapshot-directory` | - | `SNAPSHOT_DIRECTORY` | Directory to store local snapshots of the **Cardano node** | `.` | - | :heavy_check_mark: | -| `snapshot_uploader_type` | - | - | `SNAPSHOT_UPLOADER_TYPE` | Type of snapshot uploader to use | - | `gcp` or `local` | :heavy_check_mark: | -| `snapshot_bucket_name` | - | - | `SNAPSHOT_BUCKET_NAME` | Name of the bucket where the snapshots are stored | - | `snapshot-bucket` | Required if `snapshot_uploader_type` is `gcp` | -| `snapshot_use_cdn_domain` | - | - | `SNAPSHOT_USE_CDN_DOMAIN` | Use CDN domain for constructing snapshot url | `false` | - | To be used if `snapshot_uploader_type` is `gcp` | -| `run_interval` | - | - | `RUN_INTERVAL` | Interval between two runtime cycles in ms | - | `60000` | :heavy_check_mark: | -| `chain_observer_type` | `--chain-observer-type` | - | `CHAIN_OBSERVER_TYPE` | Chain observer type that can be `cardano-cli`, `pallas` or `fake`. | `pallas` | - | - | -| `era_reader_adapter_type` | `--era-reader-adapter-type` | - | `ERA_READER_ADAPTER_TYPE` | Era reader adapter type that can be `cardano-chain`, `file` or `bootstrap`. | `bootstrap` | - | - | -| `era_reader_adapter_params` | `--era-reader-adapter-params` | - | `ERA_READER_ADAPTER_PARAMS` | Era reader adapter params that is an optional JSON encoded parameters structure that is expected depending on the `era_reader_adapter_type` parameter | - | - | - | -| `protocol_configuration_reader_adapter_config` | `--protocol-configuration-reader-adapter-config` | - | `PROTOCOL_CONFIGURATION_READER_ADAPTER_CONFIG` | Protocol configuration reader adapter configuration that is an JSON encoded parameters structure that is expected depending on the json `type` attribute | - | Cardano chain :
`{"type": "cardano-chain", "address": "**ADDRESS**", "verification_key": "**VERIFICATION_KEY**"}`
Fake (test purpose only) :
`{"type": "fake", "protocol_parameters": {"k": 1944, "m": 16948, "phi_f": 0.2}}` | - | -| `ancillary_files_signer_config` | - | - | `ANCILLARY_FILES_SIGNER_CONFIG` | Configuration of the ancillary files signer

Can either be a secret key or a key stored in a Google Cloud Platform KMS account.

**IMPORTANT**: The cryptographic scheme used is ED25519 | - | - secret-key:
`{ "type": "secret-key", "secret_key": "136372c3138312c3138382c3130352c3233312c3135" }`
- Gcp kms:
`{ "type": "gcp-kms", "resource_name": "projects/project_name/locations/_location_name/keyRings/key_ring_name/cryptoKeys/key_name/cryptoKeyVersions/key_version" }` | - | -| `signed_entity_types` | `--signed-entity-types` | - | `SIGNED_ENTITY_TYPES` | Signed entity types parameters (discriminants names in an ordered comma separated list) | - | `MithrilStakeDistribution,CardanoStakeDistribution,CardanoDatabase,CardanoTransactions` | - | -| `snapshot_compression_algorithm` | `--snapshot-compression-algorithm` | - | `SNAPSHOT_COMPRESSION_ALGORITHM` | Compression algorithm of the snapshot archive | `zstandard` | `zstandard` | - | -| `zstandard_parameters` | - | - | `ZSTANDARD_PARAMETERS__LEVEL` and `ZSTANDARD_PARAMETERS__NUMBER_OF_WORKERS` | Zstandard specific parameters | - | `{ level: 9, number_of_workers: 4 }` | - | -| `blockfrost_parameters` | - | - | `BLOCKFROST_PARAMETERS` | Optional parameters to connect to the Blockfrost API. Used to fetch the ticker and name of
the registered stake pools.

`base_url` (optional) allows you to override the default URL, which is otherwise automatically determined from the project ID. | - | `{ "project_id": "preprodWuV1ICdtOWfZYfdcxpZ0tsS1N9rVZomQ" }`
or `{ "project_id": "preprodWuV1ICdtOWfZYfdcxpZ0tsS1N9rVZomQ", "base_url": "https://your-custom-blockfrost-server.io/api/v0/" }` | - | -| `signer_importer_run_interval` | - | - | `SIGNER_IMPORTER_RUN_INTERVAL` | Time interval at which the pools names and ticker in blockfrost will be imported (in minutes). | `720` | - | :heavy_check_mark: | -| `allow_unparsable_block` | `--allow-unparsable-block` | - | `ALLOW_UNPARSABLE_BLOCK` | If set no error is returned in case of unparsable block and an error log is written instead. Will be ignored on (pre)production networks. | `false` | - | - | -| `cardano_transactions_prover_cache_pool_size` | `--cardano-transactions-prover-cache-pool-size` | - | `CARDANO_TRANSACTIONS_PROVER_CACHE_POOL_SIZE` | Cardano transactions prover cache pool size | `10` | `10` | - | -| `cardano_transactions_database_connection_pool_size` | `--cardano-transactions-database-connection-pool-size` | - | `CARDANO_TRANSACTIONS_DATABASE_CONNECTION_POOL_SIZE` | Cardano transactions database connection pool size | `10` | `10` | - | -| `cardano_prover_max_hashes_allowed_by_request` | `--cardano-prover-max-hashes-allowed-by-request` | - | `CARDANO_PROVER_MAX_HASHES_ALLOWED_BY_REQUEST` | Maximum number of hashes allowed by request to the Cardano prover (applies to both transaction hashes and block hashes) | `100` | `100` | - | -| `cardano_transactions_block_streamer_max_roll_forwards_per_poll` | `--cardano-transactions-block-streamer-max-roll-forwards-per-poll` | - | `CARDANO_TRANSACTIONS_BLOCK_STREAMER_MAX_ROLL_FORWARDS_PER_POLL` | Maximum number of roll forwards during a poll of the block streamer when importing transactions | `1000` | `1000` | - | -| `preload_security_parameter` | - | - | `PRELOAD_SECURITY_PARAMETER` | Blocks offset, from the tip of the chain, to exclude during the cardano transactions preload
`[default: 2160]`. | `2160` | - | :heavy_check_mark: | -| `enable_metrics_server` | `--enable-metrics-server` | - | `ENABLE_METRICS_SERVER` | Enable metrics HTTP server (Prometheus endpoint on /metrics) | `false` | - | - | -| `metrics_server_ip` | `--metrics-server-ip` | - | `METRICS_SERVER_IP` | Metrics HTTP server IP | `0.0.0.0` | - | - | -| `metrics_server_port` | `--metrics-server-port` | - | `METRICS_SERVER_PORT` | Metrics HTTP server listening port | `9090` | - | - | -| `persist_usage_report_interval_in_seconds` | | - | `PERSIST_USAGE_REPORT_INTERVAL_IN_SECONDS` | Duration in seconds between two recording of usage metrics | `10` | `5` | - | -| `leader_aggregator_endpoint` | `--leader-aggregator-endpoint` | - | `LEADER_AGGREGATOR_ENDPOINT` | Leader aggregator endpoint | - | `https://aggregator.pre-release-preview.api.mithril.network/aggregator` | - | -| `certificate_chain_aggregator_endpoint` | `--certificate-chain-aggregator-endpoint` | - | `CERTIFICATE_CHAIN_AGGREGATOR_ENDPOINT` | Certificate chain aggregator endpoint | - | `https://aggregator.pre-release-preview.api.mithril.network/aggregator` | - | -| `aggregate_signature_type` | - | - | `AGGREGATE_SIGNATURE_TYPE` | Aggregate signature type used to create certificates | `Concatenation` | - | :heavy_check_mark: | -| `signature_processor_wait_delay_on_error_ms` | - | - | `SIGNATURE_PROCESSOR_WAIT_DELAY_ON_ERROR_MS` | Delay to wait between two signature processing attempts after an error | `1000` | - | :heavy_check_mark: | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------------------------------- | ------------------------------------------------------------------ | :------------------: | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------: | +| `server_ip` | `--server-ip` | - | `SERVER_IP` | Listening server IP | `0.0.0.0` | - | :heavy_check_mark: | +| `server_port` | `--server-port` | - | `SERVER_PORT` | Listening server port | `8080` | - | :heavy_check_mark: | +| `public_server_url` | - | - | `PUBLIC_SERVER_URL` | Public URL of the aggregator | - | `https://aggregator.release-mainnet.api.mithril.network/aggregator` | - | +| `snapshot_directory` | `--snapshot-directory` | - | `SNAPSHOT_DIRECTORY` | Directory to store local snapshots of the **Cardano node** | `.` | - | :heavy_check_mark: | +| `snapshot_uploader_type` | - | - | `SNAPSHOT_UPLOADER_TYPE` | Type of snapshot uploader to use | - | `gcp` or `local` | :heavy_check_mark: | +| `snapshot_bucket_name` | - | - | `SNAPSHOT_BUCKET_NAME` | Name of the bucket where the snapshots are stored | - | `snapshot-bucket` | Required if `snapshot_uploader_type` is `gcp` | +| `snapshot_use_cdn_domain` | - | - | `SNAPSHOT_USE_CDN_DOMAIN` | Use CDN domain for constructing snapshot url | `false` | - | To be used if `snapshot_uploader_type` is `gcp` | +| `run_interval` | - | - | `RUN_INTERVAL` | Interval between two runtime cycles in ms | - | `60000` | :heavy_check_mark: | +| `chain_observer_type` | `--chain-observer-type` | - | `CHAIN_OBSERVER_TYPE` | Chain observer type that can be `cardano-cli`, `pallas` or `fake`. | `pallas` | - | - | +| `era_reader_adapter_type` | `--era-reader-adapter-type` | - | `ERA_READER_ADAPTER_TYPE` | Era reader adapter type that can be `cardano-chain`, `file` or `bootstrap`. | `bootstrap` | - | - | +| `era_reader_adapter_params` | `--era-reader-adapter-params` | - | `ERA_READER_ADAPTER_PARAMS` | Era reader adapter params that is an optional JSON encoded parameters structure that is expected depending on the `era_reader_adapter_type` parameter | - | - | - | +| `protocol_configuration_reader_adapter_config` | `--protocol-configuration-reader-adapter-config` | - | `PROTOCOL_CONFIGURATION_READER_ADAPTER_CONFIG` | Protocol configuration reader adapter configuration that is an JSON encoded parameters structure that is expected depending on the json `type` attribute | - | Cardano chain :
`{"type": "cardano-chain", "address": "**ADDRESS**", "verification_key": "**VERIFICATION_KEY**"}`
Fake (test purpose only) :
`{"type": "fake", "protocol_parameters": {"k": 1944, "m": 16948, "phi_f": 0.2}}` | - | +| `ancillary_files_signer_config` | - | - | `ANCILLARY_FILES_SIGNER_CONFIG` | Configuration of the ancillary files signer

Can either be a secret key or a key stored in a Google Cloud Platform KMS account.

**IMPORTANT**: The cryptographic scheme used is ED25519 | - | - secret-key:
`{ "type": "secret-key", "secret_key": "136372c3138312c3138382c3130352c3233312c3135" }`
- Gcp kms:
`{ "type": "gcp-kms", "resource_name": "projects/project_name/locations/_location_name/keyRings/key_ring_name/cryptoKeys/key_name/cryptoKeyVersions/key_version" }` | - | +| `signed_entity_types` | `--signed-entity-types` | - | `SIGNED_ENTITY_TYPES` | Signed entity types parameters (discriminants names in an ordered comma separated list) | - | `MithrilStakeDistribution,CardanoStakeDistribution,CardanoDatabase,CardanoTransactions` | - | +| `snapshot_compression_algorithm` | `--snapshot-compression-algorithm` | - | `SNAPSHOT_COMPRESSION_ALGORITHM` | Compression algorithm of the snapshot archive | `zstandard` | `zstandard` | - | +| `zstandard_parameters` | - | - | `ZSTANDARD_PARAMETERS__LEVEL` and `ZSTANDARD_PARAMETERS__NUMBER_OF_WORKERS` | Zstandard specific parameters | - | `{ level: 9, number_of_workers: 4 }` | - | +| `blockfrost_parameters` | - | - | `BLOCKFROST_PARAMETERS` | Optional parameters to connect to the Blockfrost API. Used to fetch the ticker and name of
the registered stake pools.

`base_url` (optional) allows you to override the default URL, which is otherwise automatically determined from the project ID. | - | `{ "project_id": "preprodWuV1ICdtOWfZYfdcxpZ0tsS1N9rVZomQ" }`
or `{ "project_id": "preprodWuV1ICdtOWfZYfdcxpZ0tsS1N9rVZomQ", "base_url": "https://your-custom-blockfrost-server.io/api/v0/" }` | - | +| `signer_importer_run_interval` | - | - | `SIGNER_IMPORTER_RUN_INTERVAL` | Time interval at which the pools names and ticker in blockfrost will be imported (in minutes). | `720` | - | :heavy_check_mark: | +| `allow_unparsable_block` | `--allow-unparsable-block` | - | `ALLOW_UNPARSABLE_BLOCK` | If set no error is returned in case of unparsable block and an error log is written instead. Will be ignored on (pre)production networks. | `false` | - | - | +| `cardano_transactions_prover_cache_pool_size` | `--cardano-transactions-prover-cache-pool-size` | - | `CARDANO_TRANSACTIONS_PROVER_CACHE_POOL_SIZE` | Cardano transactions prover cache pool size | `10` | `10` | - | +| `cardano_transactions_database_connection_pool_size` | `--cardano-transactions-database-connection-pool-size` | - | `CARDANO_TRANSACTIONS_DATABASE_CONNECTION_POOL_SIZE` | Cardano transactions database connection pool size | `10` | `10` | - | +| `cardano_prover_max_hashes_allowed_by_request` | `--cardano-prover-max-hashes-allowed-by-request` | - | `CARDANO_PROVER_MAX_HASHES_ALLOWED_BY_REQUEST` | Maximum number of hashes allowed by request to the Cardano prover (applies to both transaction hashes and block hashes) | `100` | `100` | - | +| `cardano_transactions_block_streamer_max_roll_forwards_per_poll` | `--cardano-transactions-block-streamer-max-roll-forwards-per-poll` | - | `CARDANO_TRANSACTIONS_BLOCK_STREAMER_MAX_ROLL_FORWARDS_PER_POLL` | Maximum number of roll forwards during a poll of the block streamer when importing transactions | `1000` | `1000` | - | +| `preload_security_parameter` | - | - | `PRELOAD_SECURITY_PARAMETER` | Blocks offset, from the tip of the chain, to exclude during the cardano transactions preload
`[default: 2160]`. | `2160` | - | :heavy_check_mark: | +| `enable_metrics_server` | `--enable-metrics-server` | - | `ENABLE_METRICS_SERVER` | Enable metrics HTTP server (Prometheus endpoint on /metrics) | `false` | - | - | +| `metrics_server_ip` | `--metrics-server-ip` | - | `METRICS_SERVER_IP` | Metrics HTTP server IP | `0.0.0.0` | - | - | +| `metrics_server_port` | `--metrics-server-port` | - | `METRICS_SERVER_PORT` | Metrics HTTP server listening port | `9090` | - | - | +| `persist_usage_report_interval_in_seconds` | | - | `PERSIST_USAGE_REPORT_INTERVAL_IN_SECONDS` | Duration in seconds between two recording of usage metrics | `10` | `5` | - | +| `leader_aggregator_endpoint` | `--leader-aggregator-endpoint` | - | `LEADER_AGGREGATOR_ENDPOINT` | Leader aggregator endpoint | - | `https://aggregator.pre-release-preview.api.mithril.network/aggregator` | - | +| `certificate_chain_aggregator_endpoint` | `--certificate-chain-aggregator-endpoint` | - | `CERTIFICATE_CHAIN_AGGREGATOR_ENDPOINT` | Certificate chain aggregator endpoint | - | `https://aggregator.pre-release-preview.api.mithril.network/aggregator` | - | +| `aggregate_signature_type` | - | - | `AGGREGATE_SIGNATURE_TYPE` | Aggregate signature type used to create certificates | `Concatenation` | - | :heavy_check_mark: | +| `signature_processor_wait_delay_on_error_ms` | - | - | `SIGNATURE_PROCESSOR_WAIT_DELAY_ON_ERROR_MS` | Delay to wait between two signature processing attempts after an error | `1000` | - | :heavy_check_mark: | +| `circuit_verification_key_registry_url` | - | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_URL` | URL of the signed circuit verification key registry enforced on the certificates whose
aggregate signature type requires it, refreshed at most once per hour when a certificate is
verified so a published revocation reaches the running aggregator without a redeployment.

A `file://` URL reads the registry from a local file (tests and local deployments). An
empty URL, as set by a deployment without registry, means no registry source. | - | `https://raw.githubusercontent.com/IntersectMBO/mithril/main/mithril-infra/configuration/release-mainnet/circuit-verification-key-registry.json` | - | `genesis bootstrap` command: diff --git a/docs/website/root/manual/develop/nodes/mithril-client.md b/docs/website/root/manual/develop/nodes/mithril-client.md index e164c406c15..908f5870794 100644 --- a/docs/website/root/manual/develop/nodes/mithril-client.md +++ b/docs/website/root/manual/develop/nodes/mithril-client.md @@ -544,221 +544,231 @@ The configuration parameters can be set in either of the following ways: Here is a list of the available parameters: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | :----------------: | -| `verbose` | `--verbose` | `-v` | - | Verbosity level | - | Parsed from the number of occurrences: `-v` for `Warning`, `-vv` for `Info`, `-vvv` for `Debug` and `-vvvv` for `Trace` | :heavy_check_mark: | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | :heavy_check_mark: | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | `https://aggregator.pre-release-preview.api.mithril.network/aggregator` | :heavy_check_mark: | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `version` | `--version` | `-V` | - | Print version | - | `./mithril-client.log` | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | :----------------: | +| `verbose` | `--verbose` | `-v` | - | Verbosity level | - | Parsed from the number of occurrences: `-v` for `Warning`, `-vv` for `Info`, `-vvv` for `Debug` and `-vvvv` for `Trace` | :heavy_check_mark: | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | :heavy_check_mark: | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | `https://aggregator.pre-release-preview.api.mithril.network/aggregator` | :heavy_check_mark: | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `version` | `--version` | `-V` | - | Print version | - | `./mithril-client.log` | - | `cardano-db snapshot show` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (deprecated, full database restoration only) or `v2` (default, full or partial database restoration) | `v2` | - | - | -| `digest` | - | - | - | Digest of the Cardano db snapshot to show or `latest` for the latest artifact | - | - | :heavy_check_mark: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (deprecated, full database restoration only) or `v2` (default, full or partial database restoration) | `v2` | - | - | +| `digest` | - | - | - | Digest of the Cardano db snapshot to show or `latest` for the latest artifact | - | - | :heavy_check_mark: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `cardano-db snapshot list` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | -| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (deprecated, full database restoration only) or `v2` (default, full or partial database restoration) | `v2` | - | - | -| `epoch` | `--epoch` | - | - | [backend `v2` only] Epoch of the Cardano db snapshots to list, or `latest` for the latest artifact, or `latest-X` for the artifact of the latest epoch minus X | - | - | - | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | +| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (deprecated, full database restoration only) or `v2` (default, full or partial database restoration) | `v2` | - | - | +| `epoch` | `--epoch` | - | - | [backend `v2` only] Epoch of the Cardano db snapshots to list, or `latest` for the latest artifact, or `latest-X` for the artifact of the latest epoch minus X | - | - | - | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `cardano-db download` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (deprecated, full database restoration only) or `v2` (default, full or partial database restoration) | `v2` | - | - | -| `digest` | - | - | - | Digest of the Cardano db snapshot to download or `latest` for the latest artifact | - | - | :heavy_check_mark: | -| `download_dir` | `--download-dir` | - | - | Directory where the immutable and ancillary files will be downloaded | - | - | - | -| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | -| `include_ancillary` | `--include-ancillary` | - | - | Include ancillary files in the download, if set the `ancillary_verification_key` is required in order to verify the ancillary files | `false` | - | - | -| `ancillary_verification_key` | `--ancillary-verification-key` | - | `ANCILLARY_VERIFICATION_KEY` | Ancillary verification key to verify the ancillary files | - | - | - | -| `start` | `--start` | - | - | [backend `v2` only] The first immutable file number to download | - | - | - | -| `end` | `--end` | - | - | [backend `v2` only] The last immutable file number to download | - | - | - | -| `allow_override` | `--allow-override` | - | - | [backend `v2` only] Allow existing files in the download directory to be overridden | `false` | - | - | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (deprecated, full database restoration only) or `v2` (default, full or partial database restoration) | `v2` | - | - | +| `digest` | - | - | - | Digest of the Cardano db snapshot to download or `latest` for the latest artifact | - | - | :heavy_check_mark: | +| `download_dir` | `--download-dir` | - | - | Directory where the immutable and ancillary files will be downloaded | - | - | - | +| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | +| `include_ancillary` | `--include-ancillary` | - | - | Include ancillary files in the download, if set the `ancillary_verification_key` is required in order to verify the ancillary files | `false` | - | - | +| `ancillary_verification_key` | `--ancillary-verification-key` | - | `ANCILLARY_VERIFICATION_KEY` | Ancillary verification key to verify the ancillary files | - | - | - | +| `start` | `--start` | - | - | [backend `v2` only] The first immutable file number to download | - | - | - | +| `end` | `--end` | - | - | [backend `v2` only] The last immutable file number to download | - | - | - | +| `allow_override` | `--allow-override` | - | - | [backend `v2` only] Allow existing files in the download directory to be overridden | `false` | - | - | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `cardano-db verify` command (`v2` backend only): -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | -------------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (not supported for verify command) or `v2` (default, full or partial database restoration) | `v2` | - | - | -| `digest` | - | - | - | Digest of the Cardano db snapshot to verify or `latest` for the latest artifact | - | - | :heavy_check_mark: | -| `db_dir` | `--db-dir` | - | - | Directory from where the immutable will be verified | - | - | - | -| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | - | -| `start` | `--start` | - | - | The first immutable file number to verify | - | - | - | -| `end` | `--end` | - | - | The last immutable file number to verify | - | - | - | -| `allow_missing` | `--allow-missing` | - | - | If set, the verification will not fail if some immutable files are missing | `false` | - | - | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (not supported for verify command) or `v2` (default, full or partial database restoration) | `v2` | - | - | +| `digest` | - | - | - | Digest of the Cardano db snapshot to verify or `latest` for the latest artifact | - | - | :heavy_check_mark: | +| `db_dir` | `--db-dir` | - | - | Directory from where the immutable will be verified | - | - | - | +| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | - | +| `start` | `--start` | - | - | The first immutable file number to verify | - | - | - | +| `end` | `--end` | - | - | The last immutable file number to verify | - | - | - | +| `allow_missing` | `--allow-missing` | - | - | If set, the verification will not fail if some immutable files are missing | `false` | - | - | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `mithril-stake-distribution list` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `mithril-stake-distribution download` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | -------------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `artifact_hash` | - | - | - | Hash of the Mithril stake distribution artifact, or `latest` for the latest artifact | - | - | :heavy_check_mark: | -| `download_dir` | `--download-dir` | - | - | Directory where the Mithril stake distribution will be downloaded | - | - | - | -| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `artifact_hash` | - | - | - | Hash of the Mithril stake distribution artifact, or `latest` for the latest artifact | - | - | :heavy_check_mark: | +| `download_dir` | `--download-dir` | - | - | Directory where the Mithril stake distribution will be downloaded | - | - | - | +| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `cardano-transaction snapshot show` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------------ | --------------------------- | ------- | :----------------: | -| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (default) or `v2` (unstable, with additional information in output) | `v1` | - | - | -| `hash` | - | - | - | Hash of the Cardano transaction snapshot to show or `latest` for the latest artifact | - | - | :heavy_check_mark: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (default) or `v2` (unstable, with additional information in output) | `v1` | - | - | +| `hash` | - | - | - | Hash of the Cardano transaction snapshot to show or `latest` for the latest artifact | - | - | :heavy_check_mark: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `cardano-transaction snapshot list` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------------ | --------------------------- | ------- | :-------: | -| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (default) or `v2` (unstable, with additional information in output) | `v1` | - | - | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | +| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (default) or `v2` (unstable, with additional information in output) | `v1` | - | - | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `cardano-transaction certify` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | -------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------- | ------- | :----------------: | -| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (default) or `v2` (unstable, with additional information in output) | `v1` | - | - | -| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | -| `transactions_hashes` | - | - | - | Hashes of the transactions to certify | - | - | :heavy_check_mark: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `backend` | `--backend` | `-b` | - | Backend to use, either: `v1` (default) or `v2` (unstable, with additional information in output) | `v1` | - | - | +| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | +| `transactions_hashes` | - | - | - | Hashes of the transactions to certify | - | - | :heavy_check_mark: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `cardano-block snapshot show` command: @@ -768,23 +778,24 @@ This command is unstable. ::: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | -------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `hash` | - | - | - | Hash of the Cardano blocks transactions snapshot to show or `latest` for the latest artifact | - | - | :heavy_check_mark: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `hash` | - | - | - | Hash of the Cardano blocks transactions snapshot to show or `latest` for the latest artifact | - | - | :heavy_check_mark: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `cardano-block snapshot list` command: @@ -794,22 +805,23 @@ This command is unstable. ::: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `cardano-block certify` command: @@ -819,65 +831,68 @@ This command is unstable. ::: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | -------------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | -| `blocks_hashes` | - | - | - | Hashes of the blocks to certify | - | - | :heavy_check_mark: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | +| `blocks_hashes` | - | - | - | Hashes of the blocks to certify | - | - | :heavy_check_mark: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `cardano-stake-distribution list` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | `cardano-stake-distribution download` command: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | -------------------------- | --------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `unique_identifier` | - | - | - | Hash or Epoch of the Cardano stake distribution artifact, or `latest` for the latest artifact | - | - | :heavy_check_mark: | -| `download_dir` | `--download-dir` | - | - | Directory where the Cardano stake distribution will be downloaded | - | - | - | -| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `unique_identifier` | - | - | - | Hash or Epoch of the Cardano stake distribution artifact, or `latest` for the latest artifact | - | - | :heavy_check_mark: | +| `download_dir` | `--download-dir` | - | - | Directory where the Cardano stake distribution will be downloaded | - | - | - | +| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | :heavy_check_mark: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `tools utxo-hd snapshot-converter` command: @@ -887,30 +902,31 @@ This command is not compatible with **Linux ARM environments**. ::: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `db_directory` | `--db-directory` | - | - | Path to the Cardano node database directory | - | - | :heavy_check_mark: | -| `cardano_node_version` | `--cardano-node-version` | - | - | Cardano node version of the Mithril signed snapshot (`latest` and `pre-release` are also supported to download the latest or pre-release distribution). | - | - | :heavy_check_mark: | -| `cardano_network` | `--cardano-network` | - | - | Cardano network | - | - | - | -| `binary-path` | `--binary-path` | - | - | Path to the Cardano snapshot converter binary | - | - | - | -| `config-path` | `--config-path` | - | - | Path to JSON configuration file for the Cardano snapshot converter | - | - | - | -| `utxo_hd_flavor` | `--utxo-hd-flavor` | - | - | UTxO-HD flavor to convert the ledger snapshot to (`Legacy`, `LMDB` or `LSM`) | - | - | :heavy_check_mark: | -| `commit` | `--commit` | - | - | Replaces the current ledger state in the `db_directory`. | `false` | - | - | -| `github_token` | `--github-token` | - | `GITHUB_TOKEN` | GitHub token for authenticated API calls | - | - | - | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `db_directory` | `--db-directory` | - | - | Path to the Cardano node database directory | - | - | :heavy_check_mark: | +| `cardano_node_version` | `--cardano-node-version` | - | - | Cardano node version of the Mithril signed snapshot (`latest` and `pre-release` are also supported to download the latest or pre-release distribution). | - | - | :heavy_check_mark: | +| `cardano_network` | `--cardano-network` | - | - | Cardano network | - | - | - | +| `binary-path` | `--binary-path` | - | - | Path to the Cardano snapshot converter binary | - | - | - | +| `config-path` | `--config-path` | - | - | Path to JSON configuration file for the Cardano snapshot converter | - | - | - | +| `utxo_hd_flavor` | `--utxo-hd-flavor` | - | - | UTxO-HD flavor to convert the ledger snapshot to (`Legacy`, `LMDB` or `LSM`) | - | - | :heavy_check_mark: | +| `commit` | `--commit` | - | - | Replaces the current ledger state in the `db_directory`. | `false` | - | - | +| `github_token` | `--github-token` | - | `GITHUB_TOKEN` | GitHub token for authenticated API calls | - | - | - | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `mithril-client tools discover-aggregator` command: @@ -920,26 +936,27 @@ This command is unstable. ::: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | -| `network` | - | - | - | Mithril network name | - | - | :heavy_check_mark: | -| `max_entries` | `--max-entries` | - | - | Maximum number of entries to retrieve | `1` | - | - | -| `signed_entity_types` | `--signed-entity-types` | - | - | Signed entity types to consider for the discovery | - | - | - | -| `aggregate_signature_types` | `--aggregate-signature-types` | - | - | Aggregate signature types to consider for the discovery | - | - | - | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :----------------: | +| `network` | - | - | - | Mithril network name | - | - | :heavy_check_mark: | +| `max_entries` | `--max-entries` | - | - | Maximum number of entries to retrieve | `1` | - | - | +| `signed_entity_types` | `--signed-entity-types` | - | - | Signed entity types to consider for the discovery | - | - | - | +| `aggregate_signature_types` | `--aggregate-signature-types` | - | - | Aggregate signature types to consider for the discovery | - | - | - | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help (see more with '--help') | - | - | - | `mithril-client tools cache reset` command: @@ -949,19 +966,20 @@ This command is unstable. ::: -| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | -| ------------------------------ | -------------------------------- | :------------------: | --------------------- | ------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | -| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | -| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | -| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | -| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | -| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | -| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | -| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | -| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | -| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | -| `era` | `--era` | - | - | Override the Mithril era | - | - | - | -| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | -| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | -| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | -| `help` | `--help` | `-h` | - | Print help | - | - | - | +| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory | +| ---------------------------------------- | ------------------------------------------ | :------------------: | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------- | :-------: | +| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - | +| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - | +| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - | +| `aggregator_endpoint` | `--aggregator-endpoint` | - | `AGGREGATOR_ENDPOINT` | Override configuration Aggregator endpoint URL | - | - | - | +| `json` | `--json` | - | - | Enable JSON output for command results | `false` | - | - | +| `log_format_json` | `--log-format-json` | - | - | Enable JSON output for logs displayed according to verbosity level | `false` | - | - | +| `log_output` | `--log-output` | - | - | Redirect the logs to a file | - | - | - | +| `unstable` | `--unstable` | - | - | Enable unstable commands | `false` | - | - | +| `origin_tag` | `--origin-tag` | - | - | Request origin tag | - | - | - | +| `circuit_verification_key_registry_path` | `--circuit-verification-key-registry-path` | - | `CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH` | Read the circuit verification key registry from a local signed registry file instead of resolving it through the published networks configuration (unstable, for local deployments) | - | - | - | +| `era` | `--era` | - | - | Override the Mithril era | - | - | - | +| `use_certificate_chain_cache` | `--use-certificate-chain-cache` | - | - | Use the certificate chain cache to verify the certificate chain (unstable) | `false` | - | - | +| `certificate_chain_cache_mode` | `--certificate-chain-cache-mode` | - | - | Verification mode of the certificate chain when the cache is used (unstable) | `FullVerification` | - | - | +| `certificate_chain_cache_path` | `--certificate-chain-cache-path` | - | - | Directory of the certificate chain cache, requires --use-certificate-chain-cache (unstable) | `./certificate-chain-cache` | - | - | +| `help` | `--help` | `-h` | - | Print help | - | - | - | diff --git a/internal/cardano-node/mithril-cardano-node-internal-database/Cargo.toml b/internal/cardano-node/mithril-cardano-node-internal-database/Cargo.toml index b1608e3c4db..730af80f867 100644 --- a/internal/cardano-node/mithril-cardano-node-internal-database/Cargo.toml +++ b/internal/cardano-node/mithril-cardano-node-internal-database/Cargo.toml @@ -15,7 +15,7 @@ anyhow = { workspace = true } async-trait = { workspace = true } digest = { workspace = true } hex = { workspace = true } -mithril-common = { path = "../../../mithril-common", version = "0.7.26" } +mithril-common = { path = "../../../mithril-common", version = "0.7.27" } serde = { workspace = true } serde_json = { workspace = true } sha2 = "0.10.9" diff --git a/internal/mithril-aggregator-client/Cargo.toml b/internal/mithril-aggregator-client/Cargo.toml index 05623ce7b6c..e9c1bb27215 100644 --- a/internal/mithril-aggregator-client/Cargo.toml +++ b/internal/mithril-aggregator-client/Cargo.toml @@ -13,7 +13,7 @@ include = ["**/*.rs", "Cargo.toml", "README.md"] [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } -mithril-common = { path = "../../mithril-common", version = "0.7.26" } +mithril-common = { path = "../../mithril-common", version = "0.7.27" } reqwest = { workspace = true } semver = { workspace = true } serde = { workspace = true } diff --git a/internal/mithril-aggregator-discovery/Cargo.toml b/internal/mithril-aggregator-discovery/Cargo.toml index c72b0fb32f6..a0998bc06a2 100644 --- a/internal/mithril-aggregator-discovery/Cargo.toml +++ b/internal/mithril-aggregator-discovery/Cargo.toml @@ -14,7 +14,7 @@ include = ["**/*.rs", "Cargo.toml", "README.md", ".gitignore"] anyhow = { workspace = true } async-trait = { workspace = true } mithril-aggregator-client = { path = "../mithril-aggregator-client", version = "0.2.4" } -mithril-common = { path = "../../mithril-common", version = "0.7.26" } +mithril-common = { path = "../../mithril-common", version = "0.7.27" } rand = { version = "0.10.2" } reqwest = { workspace = true } serde = { workspace = true } diff --git a/internal/mithril-circuit-key-registry/Cargo.toml b/internal/mithril-circuit-key-registry/Cargo.toml index 42d8dcdbb47..f021b7553f7 100644 --- a/internal/mithril-circuit-key-registry/Cargo.toml +++ b/internal/mithril-circuit-key-registry/Cargo.toml @@ -27,7 +27,7 @@ anyhow = { workspace = true } async-trait = { workspace = true } chrono = { workspace = true } futures = "0.3.32" -mithril-common = { path = "../../mithril-common", version = "0.7.26" } +mithril-common = { path = "../../mithril-common", version = "0.7.27" } reqwest = { workspace = true, features = ["stream"] } serde = { workspace = true } serde_json = { workspace = true } diff --git a/internal/mithril-circuit-key-registry/README.md b/internal/mithril-circuit-key-registry/README.md index f9bca82569f..b544aa70d62 100644 --- a/internal/mithril-circuit-key-registry/README.md +++ b/internal/mithril-circuit-key-registry/README.md @@ -14,4 +14,5 @@ It holds: The nodes enforce the registry through the `CircuitVerificationKeyCertifier` trait of `mithril-common`. The operations on the registry are provided by the -`circuit-key-registry` command of the Mithril aggregator. +`circuit-key-registry` command of the Mithril aggregator, documented in the +[runbook](../../docs/runbook/circuit-key-registry/README.md). diff --git a/mithril-aggregator/Cargo.toml b/mithril-aggregator/Cargo.toml index b23bea71f46..bc16d1637ce 100644 --- a/mithril-aggregator/Cargo.toml +++ b/mithril-aggregator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-aggregator" -version = "0.10.12" +version = "0.10.13" description = "A Mithril Aggregator server" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-aggregator/src/configuration.rs b/mithril-aggregator/src/configuration.rs index 00143c00b8e..09fd56d5814 100644 --- a/mithril-aggregator/src/configuration.rs +++ b/mithril-aggregator/src/configuration.rs @@ -331,6 +331,13 @@ pub trait ConfigurationSource { panic!("custom_origin_tag_white_list is not implemented."); } + /// URL of the signed circuit verification key registry enforced on the certificates whose + /// aggregate signature type requires it, none when no registry source is configured, an + /// empty URL meaning none as well. + fn circuit_verification_key_registry_url(&self) -> Option { + None + } + /// Get the server URL. fn get_server_url(&self) -> StdResult { panic!("get_server_url is not implemented."); @@ -674,6 +681,15 @@ pub struct ServeCommandConfiguration { /// Delay to wait between two signature processing attempts after an error pub signature_processor_wait_delay_on_error_ms: u64, + + /// URL of the signed circuit verification key registry enforced on the certificates whose + /// aggregate signature type requires it, refreshed at most once per hour when a certificate is + /// verified so a published revocation reaches the running aggregator without a redeployment. + /// + /// A `file://` URL reads the registry from a local file (tests and local deployments). An + /// empty URL, as set by a deployment without registry, means no registry source. + #[example = "`https://raw.githubusercontent.com/IntersectMBO/mithril/main/mithril-infra/configuration/release-mainnet/circuit-verification-key-registry.json`"] + pub circuit_verification_key_registry_url: Option, } /// Uploader needed to copy the snapshot once computed. @@ -853,6 +869,7 @@ impl ServeCommandConfiguration { custom_origin_tag_white_list: None, aggregate_signature_type: AggregateSignatureType::Concatenation, signature_processor_wait_delay_on_error_ms: 5000, + circuit_verification_key_registry_url: None, } } @@ -1064,6 +1081,12 @@ impl ConfigurationSource for ServeCommandConfiguration { self.custom_origin_tag_white_list.clone() } + fn circuit_verification_key_registry_url(&self) -> Option { + self.circuit_verification_key_registry_url + .clone() + .filter(|url| !url.is_empty()) + } + fn get_server_url(&self) -> StdResult { match &self.public_server_url { Some(url) => SanitizedUrlWithTrailingSlash::parse(url), @@ -1337,6 +1360,27 @@ mod test { } } + #[test] + fn circuit_verification_key_registry_url_treats_an_empty_url_as_no_source() { + for (url, expected) in [ + (None, None), + (Some("".to_string()), None), + ( + Some("https://registry.example/registry.json".to_string()), + Some("https://registry.example/registry.json".to_string()), + ), + ] { + let configuration = ServeCommandConfiguration { + circuit_verification_key_registry_url: url, + ..ServeCommandConfiguration::new_sample(temp_dir!()) + }; + assert_eq!( + configuration.circuit_verification_key_registry_url(), + expected + ); + } + } + #[test] fn compute_allowed_signed_entity_types_discriminants_append_default_discriminants() { let config = ServeCommandConfiguration { diff --git a/mithril-aggregator/src/dependency_injection/builder/mod.rs b/mithril-aggregator/src/dependency_injection/builder/mod.rs index fcca73fb302..939ba4cfe62 100644 --- a/mithril-aggregator/src/dependency_injection/builder/mod.rs +++ b/mithril-aggregator/src/dependency_injection/builder/mod.rs @@ -25,6 +25,10 @@ use mithril_cardano_node_internal_database::{ ImmutableFileObserver, digesters::{ImmutableDigester, cache::ImmutableFileDigestCacheProvider}, }; +#[cfg(feature = "future_snark")] +use mithril_circuit_key_registry::CircuitVerificationKeyRegistryRetriever; +#[cfg(feature = "future_snark")] +use mithril_common::certificate_chain::CircuitVerificationKeyCertifier; use mithril_common::{ api_version::APIVersionProvider, certificate_chain::CertificateVerifier, @@ -191,6 +195,15 @@ pub struct DependenciesBuilder { /// Certificate verifier service. pub certificate_verifier: Option>, + /// Circuit verification key registry retriever service. + #[cfg(feature = "future_snark")] + pub circuit_verification_key_registry_retriever: + Option>, + + /// Circuit verification key certifier service. + #[cfg(feature = "future_snark")] + pub circuit_verification_key_certifier: Option>, + /// Genesis signature verifier service. pub genesis_verifier: Option>, @@ -335,6 +348,10 @@ impl DependenciesBuilder { file_archiver: None, snapshotter: None, certificate_verifier: None, + #[cfg(feature = "future_snark")] + circuit_verification_key_registry_retriever: None, + #[cfg(feature = "future_snark")] + circuit_verification_key_certifier: None, genesis_verifier: None, certificate_chain_synchronizer: None, mithril_signer_registration_leader: None, diff --git a/mithril-aggregator/src/dependency_injection/builder/protocol/certificates.rs b/mithril-aggregator/src/dependency_injection/builder/protocol/certificates.rs index aec60ed3839..19699947fb2 100644 --- a/mithril-aggregator/src/dependency_injection/builder/protocol/certificates.rs +++ b/mithril-aggregator/src/dependency_injection/builder/protocol/certificates.rs @@ -3,6 +3,17 @@ use std::sync::Arc; #[cfg(feature = "future_snark")] use tokio::runtime::Handle; +#[cfg(feature = "future_snark")] +use std::path::PathBuf; + +#[cfg(feature = "future_snark")] +use mithril_circuit_key_registry::{ + CachedCircuitVerificationKeyCertifier, CircuitVerificationKeyRegistryRetriever, + FileCircuitVerificationKeyRegistryRetriever, HttpCircuitVerificationKeyRegistryRetriever, + MithrilCircuitVerificationKeyCertifier, UnconfiguredCircuitVerificationKeyRegistryRetriever, +}; +#[cfg(feature = "future_snark")] +use mithril_common::certificate_chain::CircuitVerificationKeyCertifier; use mithril_common::certificate_chain::{CertificateVerifier, MithrilCertificateVerifier}; use mithril_common::crypto_helper::GenesisVerifier; #[cfg(feature = "future_snark")] @@ -139,6 +150,8 @@ impl DependenciesBuilder { self.root_logger(), certificate_chain_aggregator_client.clone(), self.get_genesis_verifier().await?, + #[cfg(feature = "future_snark")] + self.get_circuit_verification_key_certifier().await?, )); Arc::new(MithrilCertificateChainSynchronizer::new( @@ -168,11 +181,76 @@ impl DependenciesBuilder { self.root_logger(), self.get_certificate_repository().await?, self.get_genesis_verifier().await?, + #[cfg(feature = "future_snark")] + self.get_circuit_verification_key_certifier().await?, )); Ok(verifier) } + /// Build the certifier enforcing the signed circuit verification key registry read from the + /// configured registry path, with a caching decorator refreshing it periodically. + #[cfg(feature = "future_snark")] + async fn build_circuit_verification_key_certifier( + &mut self, + ) -> Result> { + Ok(Arc::new(CachedCircuitVerificationKeyCertifier::new( + Arc::new(MithrilCircuitVerificationKeyCertifier::new( + self.get_circuit_verification_key_registry_retriever().await?, + self.get_genesis_verifier().await?, + )), + self.root_logger(), + ))) + } + + /// Build the retriever of the signed circuit verification key registry from the configured + /// registry URL: downloaded over HTTP, or read from a local file for a `file://` URL. Without + /// a URL, every retrieval fails so the certificates requiring the registry are rejected. + #[cfg(feature = "future_snark")] + async fn build_circuit_verification_key_registry_retriever( + &mut self, + ) -> Result> { + let retriever: Arc = match self + .configuration + .circuit_verification_key_registry_url() + .as_deref() + { + Some(registry_url) => match registry_url.strip_prefix("file://") { + Some(registry_path) => Arc::new(FileCircuitVerificationKeyRegistryRetriever::new( + PathBuf::from(registry_path), + )), + None => Arc::new( + HttpCircuitVerificationKeyRegistryRetriever::new(registry_url.to_string()) + .map_err(|e| DependenciesBuilderError::Initialization { + message: + "Could not build the circuit verification key registry retriever" + .to_string(), + error: Some(e), + })?, + ), + }, + None => Arc::new(UnconfiguredCircuitVerificationKeyRegistryRetriever), + }; + + Ok(retriever) + } + + /// [CircuitVerificationKeyRegistryRetriever] service. + #[cfg(feature = "future_snark")] + pub async fn get_circuit_verification_key_registry_retriever( + &mut self, + ) -> Result> { + get_dependency!(self.circuit_verification_key_registry_retriever) + } + + /// [CircuitVerificationKeyCertifier] service. + #[cfg(feature = "future_snark")] + pub async fn get_circuit_verification_key_certifier( + &mut self, + ) -> Result> { + get_dependency!(self.circuit_verification_key_certifier) + } + /// [CertificateVerifier] service. pub async fn get_certificate_verifier(&mut self) -> Result> { get_dependency!(self.certificate_verifier) diff --git a/mithril-aggregator/src/services/certificate_chain_synchronizer/synchronizer_service.rs b/mithril-aggregator/src/services/certificate_chain_synchronizer/synchronizer_service.rs index e44f46dcb77..5409b086ea6 100644 --- a/mithril-aggregator/src/services/certificate_chain_synchronizer/synchronizer_service.rs +++ b/mithril-aggregator/src/services/certificate_chain_synchronizer/synchronizer_service.rs @@ -307,6 +307,8 @@ mod tests { use mithril_common::certificate_chain::MithrilCertificateVerifier; use mithril_common::crypto_helper::GenesisVerifier; use mithril_common::entities::Epoch; + #[cfg(feature = "future_snark")] + use mithril_common::test::double::FakeCircuitVerificationKeyCertifier; use mithril_common::test::{ builder::{CertificateChainBuilder, CertificateChainFixture}, double::{Dummy, FakeCertificaterRetriever, fake_data}, @@ -408,6 +410,8 @@ mod tests { remote_certificate_chain, )), genesis_verifier, + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyCertifier::that_fails()), ); Arc::new(verifier) } diff --git a/mithril-aggregator/src/tools/genesis/operations.rs b/mithril-aggregator/src/tools/genesis/operations.rs index e39f24eac8d..ec5506d5bf4 100644 --- a/mithril-aggregator/src/tools/genesis/operations.rs +++ b/mithril-aggregator/src/tools/genesis/operations.rs @@ -28,6 +28,10 @@ use crate::{ dependency_injection::GenesisCommandDependenciesContainer, }; #[cfg(feature = "future_snark")] +use mithril_circuit_key_registry::{ + MithrilCircuitVerificationKeyCertifier, UnconfiguredCircuitVerificationKeyRegistryRetriever, +}; +#[cfg(feature = "future_snark")] use mithril_common::crypto_helper::{ GenesisBundleError, GenesisEd25519SecretKey, GenesisSchnorrSigner, GenesisSigningKeyBundle, GenesisVerificationKeyBundle, ProtocolKey, sha256_digest, signed_message_from_digest, @@ -73,7 +77,8 @@ impl GenesisTools { } /// Build a certificate verifier that checks genesis certificates against the supplied genesis - /// verifier. + /// verifier. Genesis certificates carry no aggregate signature, so the circuit verification + /// key registry is never checked and no registry source is configured. fn build_certificate_verifier( &self, genesis_verifier: &GenesisVerifier, @@ -82,6 +87,11 @@ impl GenesisTools { self.logger.clone(), self.certificate_repository.clone(), Arc::new(genesis_verifier.clone()), + #[cfg(feature = "future_snark")] + Arc::new(MithrilCircuitVerificationKeyCertifier::new( + Arc::new(UnconfiguredCircuitVerificationKeyRegistryRetriever), + Arc::new(genesis_verifier.clone()), + )), ) } @@ -466,6 +476,9 @@ mod tests { test::{TempDir, builder::MithrilFixtureBuilder, double::fake_data}, }; + #[cfg(feature = "future_snark")] + use mithril_common::test::double::FakeCircuitVerificationKeyCertifier; + use crate::database::test_helper::main_db_connection; use crate::test::TestLogger; @@ -512,6 +525,8 @@ mod tests { TestLogger::stdout(), certificate_store.clone(), genesis_verifier.clone(), + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyCertifier::that_fails()), )); let configuration = GenesisToolsConfiguration { network: fake_data::network(), diff --git a/mithril-client-cli/Cargo.toml b/mithril-client-cli/Cargo.toml index a3dd5024953..43a41503217 100644 --- a/mithril-client-cli/Cargo.toml +++ b/mithril-client-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-client-cli" -version = "0.13.25" +version = "0.13.26" description = "A Mithril Client" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-client-cli/src/command_context.rs b/mithril-client-cli/src/command_context.rs index 7f8b13628d8..b35814de771 100644 --- a/mithril-client-cli/src/command_context.rs +++ b/mithril-client-cli/src/command_context.rs @@ -1,8 +1,12 @@ use anyhow::anyhow; use slog::Logger; +#[cfg(feature = "future_snark")] +use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; +#[cfg(feature = "future_snark")] +use mithril_client::circuit_key_registry::FileCircuitVerificationKeyRegistryRetriever; use mithril_client::{ AggregatorDiscoveryType, ClientBuilder, GenesisVerificationKey, MithrilResult, }; @@ -164,6 +168,17 @@ impl CommandContext { builder = builder.with_era_fetcher(Arc::new(ForcedEraFetcher::new(era.to_string()))); } + #[cfg(feature = "future_snark")] + if let Some(registry_path) = params.get("circuit_verification_key_registry_path") { + self.require_unstable( + "--circuit-verification-key-registry-path ", + Some("cardano-db download latest"), + )?; + builder = builder.with_circuit_verification_key_registry_retriever(Arc::new( + FileCircuitVerificationKeyRegistryRetriever::new(PathBuf::from(registry_path)), + )); + } + Ok(builder) } } @@ -208,6 +223,46 @@ mod tests { assert!(result.is_err(), "Expected Err, got {result:?}"); } + #[cfg(feature = "future_snark")] + mod circuit_verification_key_registry_path { + use super::*; + + fn context_with_registry_path(unstable_enabled: bool) -> CommandContext { + CommandContext::new( + ConfigParameters::build(&[ + ( + "aggregator_endpoint", + "https://aggregator.example/aggregator", + ), + ("genesis_verification_key", "whatever"), + ( + "circuit_verification_key_registry_path", + "./circuit-verification-key-registry.json", + ), + ]), + unstable_enabled, + true, + Logger::root(slog::Discard, o!()), + ) + } + + #[test] + fn is_refused_without_the_unstable_flag() { + context_with_registry_path(false) + .setup_mithril_client_builder() + .map(|_| ()) + .expect_err("the registry path must require the unstable flag"); + } + + #[test] + fn is_accepted_with_the_unstable_flag() { + context_with_registry_path(true) + .setup_mithril_client_builder() + .map(|_| ()) + .expect("the registry path must be accepted with the unstable flag"); + } + } + #[test] fn can_edit_config_parameters() { struct ParamSource { diff --git a/mithril-client-cli/src/main.rs b/mithril-client-cli/src/main.rs index bd43b9e91f9..9cfbdf3bcd7 100644 --- a/mithril-client-cli/src/main.rs +++ b/mithril-client-cli/src/main.rs @@ -98,6 +98,13 @@ pub struct Args { #[clap(long, global = true)] origin_tag: Option, + /// Read the circuit verification key registry from a local signed registry file instead of + /// resolving it through the published networks configuration (unstable, for local deployments) + #[cfg(feature = "future_snark")] + #[clap(long, env = "CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH", global = true)] + #[example = "`./circuit-verification-key-registry.json`"] + circuit_verification_key_registry_path: Option, + /// Override the Mithril era #[clap(long, global = true)] #[example = "`pythagoras`"] @@ -260,6 +267,12 @@ impl Source for Args { register_config_value_option!(map, &namespace, myself.aggregator_endpoint); register_config_value_option!(map, &namespace, myself.origin_tag); register_config_value_option!(map, &namespace, myself.era); + #[cfg(feature = "future_snark")] + register_config_value_option!( + map, + &namespace, + myself.circuit_verification_key_registry_path + ); Ok(map) } diff --git a/mithril-client/Cargo.toml b/mithril-client/Cargo.toml index 615d9eb763e..7aece240a33 100644 --- a/mithril-client/Cargo.toml +++ b/mithril-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-client" -version = "0.14.27" +version = "0.14.28" description = "Mithril client library" authors = { workspace = true } edition = { workspace = true } @@ -30,18 +30,25 @@ unstable = [] # These features are for support of dependent crates only. # They do not change the operation of the main crate. -native-tls = ["reqwest/native-tls"] -native-tls-no-alpn = ["reqwest/native-tls-no-alpn"] -native-tls-vendored = ["reqwest/native-tls-vendored"] -native-tls-vendored-no-alpn = ["reqwest/native-tls-vendored-no-alpn"] +native-tls = ["reqwest/native-tls", "mithril-circuit-key-registry?/native-tls"] +native-tls-no-alpn = ["reqwest/native-tls-no-alpn", "mithril-circuit-key-registry?/native-tls"] +native-tls-vendored = ["reqwest/native-tls-vendored", "mithril-circuit-key-registry?/native-tls"] +native-tls-vendored-no-alpn = [ + "reqwest/native-tls-vendored-no-alpn", + "mithril-circuit-key-registry?/native-tls", +] -rustls = ["reqwest/rustls"] -rustls-no-provider = ["reqwest/rustls-no-provider"] +rustls = ["reqwest/rustls", "mithril-circuit-key-registry?/rustls"] +rustls-no-provider = ["reqwest/rustls-no-provider", "mithril-circuit-key-registry?/rustls"] # Support compressed traffic with `reqwest` enable-http-compression = ["reqwest/gzip", "reqwest/zstd", "reqwest/deflate", "reqwest/brotli"] -future_snark = ["mithril-common/future_snark"] +future_snark = [ + "mithril-common/future_snark", + "dep:mithril-circuit-key-registry", + "mithril-circuit-key-registry/future_snark", +] # Enables usage of `rug` numerical backend in `mithril-stm` (dependency of `mithril-common`). rug-backend = ["mithril-common/rug-backend"] @@ -63,7 +70,8 @@ chrono = { workspace = true } flume = { version = "0.12.0", optional = true } futures = "0.3.32" mithril-aggregator-client = { path = "../internal/mithril-aggregator-client", version = "0.2.4" } -mithril-common = { path = "../mithril-common", version = "0.7.26", default-features = false } +mithril-circuit-key-registry = { path = "../internal/mithril-circuit-key-registry", version = "0.1.1", optional = true } +mithril-common = { path = "../mithril-common", version = "0.7.27", default-features = false } reqwest = { workspace = true, default-features = false, features = ["charset", "http2", "query", "stream", "system-proxy"] } serde = { workspace = true } serde_json = { workspace = true } diff --git a/mithril-client/src/certificate_client/mod.rs b/mithril-client/src/certificate_client/mod.rs index a4a4ad90d79..fb104f4d614 100644 --- a/mithril-client/src/certificate_client/mod.rs +++ b/mithril-client/src/certificate_client/mod.rs @@ -70,6 +70,8 @@ pub use verify_cache::MemoryCertificateVerifierCache; #[cfg(test)] pub(crate) mod tests_utils { + #[cfg(feature = "future_snark")] + use mithril_circuit_key_registry::test::double::FakeCircuitVerificationKeyRegistryRetriever; use mithril_common::entities::Certificate; use mithril_common::messages::CertificateMessage; use mockall::predicate::eq; @@ -151,6 +153,8 @@ pub(crate) mod tests_utils { self.verifier_cache, #[cfg(feature = "unstable")] self.verifier_cache_mode, + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyRegistryRetriever::that_fails()), logger.clone(), ) .unwrap(), diff --git a/mithril-client/src/certificate_client/verify.rs b/mithril-client/src/certificate_client/verify.rs index ae226e1dcdc..a10fc42196e 100644 --- a/mithril-client/src/certificate_client/verify.rs +++ b/mithril-client/src/certificate_client/verify.rs @@ -19,6 +19,12 @@ use mithril_common::{ logging::LoggerExtensions, }; +#[cfg(feature = "future_snark")] +use mithril_circuit_key_registry::{ + CachedCircuitVerificationKeyCertifier, CircuitVerificationKeyRegistryRetriever, + MithrilCircuitVerificationKeyCertifier, +}; + use crate::certificate_client::fetch::InternalCertificateRetriever; use crate::certificate_client::{ CertificateAggregatorRequest, CertificateClient, CertificateVerifier, @@ -91,6 +97,9 @@ impl MithrilCertificateVerifier { feedback_sender: FeedbackSender, #[cfg(feature = "unstable")] verifier_cache: Option>, #[cfg(feature = "unstable")] cache_mode: CertificateVerifierCacheMode, + #[cfg(feature = "future_snark")] circuit_key_registry_retriever: Arc< + dyn CircuitVerificationKeyRegistryRetriever, + >, logger: Logger, ) -> MithrilResult { let logger = logger.new_with_component_name::(); @@ -116,7 +125,15 @@ impl MithrilCertificateVerifier { let internal_verifier = Arc::new(CommonMithrilCertificateVerifier::new( logger.clone(), certificate_retriever, - genesis_verifier, + genesis_verifier.clone(), + #[cfg(feature = "future_snark")] + Arc::new(CachedCircuitVerificationKeyCertifier::new( + Arc::new(MithrilCircuitVerificationKeyCertifier::new( + circuit_key_registry_retriever, + genesis_verifier, + )), + logger.clone(), + )), )); Ok(Self { @@ -318,6 +335,8 @@ impl CertificateVerifier for MithrilCertificateVerifier { #[cfg(test)] mod tests { + #[cfg(feature = "future_snark")] + use mithril_circuit_key_registry::test::double::FakeCircuitVerificationKeyRegistryRetriever; #[cfg(feature = "future_snark")] use mithril_common::crypto_helper::{ GenesisSchnorrSigner, GenesisVerificationKeyBundle, ProtocolKey, @@ -427,6 +446,8 @@ mod tests { None, #[cfg(feature = "unstable")] CertificateVerifierCacheMode::default(), + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyRegistryRetriever::that_fails()), TestLogger::stdout(), ) .map(|_| ()) @@ -563,6 +584,8 @@ mod tests { FeedbackSender::new(&[]), Some(cache), cache_mode, + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyRegistryRetriever::that_fails()), TestLogger::stdout(), ) .unwrap() diff --git a/mithril-client/src/circuit_key_registry.rs b/mithril-client/src/circuit_key_registry.rs new file mode 100644 index 00000000000..b1b11492608 --- /dev/null +++ b/mithril-client/src/circuit_key_registry.rs @@ -0,0 +1,400 @@ +//! Retrieval of the signed circuit verification key registry of the client's network, resolved +//! from the networks configuration file published in the Mithril repository. +//! +//! The registry retriever trait and the registry types are re-exported here, so a custom +//! retriever can be given to the client builder without depending on the registry crate. + +use std::collections::HashMap; + +use anyhow::{Context, anyhow}; +use async_trait::async_trait; +use serde::Deserialize; + +use mithril_circuit_key_registry::BoundedHttpDownloader; +#[cfg(not(target_family = "wasm"))] +pub use mithril_circuit_key_registry::FileCircuitVerificationKeyRegistryRetriever; +pub use mithril_circuit_key_registry::{ + CircuitVerificationKeyRegistry, CircuitVerificationKeyRegistryRetriever, + CircuitVerificationKeyRegistryRetrieverError, SignedCircuitVerificationKeyRegistry, +}; +use mithril_common::StdResult; + +/// URL of the networks configuration file published in the Mithril repository. +pub const DEFAULT_NETWORKS_CONFIGURATION_URL: &str = + "https://raw.githubusercontent.com/IntersectMBO/mithril/main/networks.json"; + +/// Representation of a Cardano network environment in the networks configuration file. +#[derive(Debug, Clone, Deserialize)] +struct CardanoNetworkConfiguration { + /// Mithril networks of the environment, keyed by their name. + #[serde(rename = "mithril-networks", default)] + mithril_networks: Vec>, +} + +/// Representation of a Mithril network in the networks configuration file. +#[derive(Debug, Clone, Deserialize)] +struct MithrilNetworkConfiguration { + /// Aggregators serving the network. + #[serde(default)] + aggregators: Vec, + + /// Reference to the signed circuit verification key registry of the network. + #[serde(rename = "circuit-verification-key-registry")] + circuit_verification_key_registry: Option, +} + +impl MithrilNetworkConfiguration { + /// Whether one of the network's aggregators serves the given endpoint. + fn is_served_by(&self, aggregator_endpoint: &str) -> bool { + self.aggregators.iter().any(|aggregator| { + Self::normalize_endpoint(&aggregator.url) + == Self::normalize_endpoint(aggregator_endpoint) + }) + } + + /// Return the registry URL referenced by the network. + fn registry_url(&self) -> Option { + self.circuit_verification_key_registry + .as_ref() + .map(|registry| registry.url.clone()) + } + + /// Normalize an aggregator endpoint for comparison, ignoring surrounding whitespace and + /// trailing slashes. + fn normalize_endpoint(endpoint: &str) -> &str { + endpoint.trim().trim_end_matches('/') + } +} + +/// Representation of an aggregator in the networks configuration file. +#[derive(Debug, Clone, Deserialize)] +struct AggregatorConfiguration { + /// Endpoint of the aggregator. + url: String, +} + +/// Reference to a remote resource by URL in the networks configuration file. +#[derive(Debug, Clone, Deserialize)] +struct UrlReference { + /// URL of the resource. + url: String, +} + +/// The Mithril networks listed in the networks configuration file. +struct MithrilNetworksConfiguration { + networks: Vec, +} + +impl MithrilNetworksConfiguration { + /// Parse the networks configuration file, tolerating top-level entries that do not follow the + /// Cardano network environment shape, so a future metadata field cannot fail the whole + /// resolution. + fn parse(networks_configuration_json: &str) -> StdResult { + let root: HashMap = + serde_json::from_str(networks_configuration_json)?; + let networks = root + .into_values() + .filter_map(|cardano_network| { + serde_json::from_value::(cardano_network).ok() + }) + .flat_map(|cardano_network| cardano_network.mithril_networks) + .flat_map(|mithril_networks| mithril_networks.into_values()) + .collect(); + + Ok(Self { networks }) + } + + /// Return the registry URL of the network served by the given aggregator endpoint. + fn registry_url_of_aggregator(&self, aggregator_endpoint: &str) -> Option { + self.networks + .iter() + .find(|network| network.is_served_by(aggregator_endpoint)) + .and_then(MithrilNetworkConfiguration::registry_url) + } +} + +/// A [CircuitVerificationKeyRegistryRetriever] resolving the signed registry of the client's +/// network from the networks configuration file, then downloading it over HTTP. +/// +/// The network entry is selected by matching the aggregator endpoint. The networks +/// configuration is routing, never trust: the certifier verifies the genesis signature of the +/// registry it points to, so a wrong route can only yield a registry that fails that +/// verification or an older registry of the same network. +pub struct RemoteCircuitVerificationKeyRegistryRetriever { + networks_configuration_url: String, + aggregator_endpoint: String, + downloader: BoundedHttpDownloader, +} + +impl RemoteCircuitVerificationKeyRegistryRetriever { + /// Build a retriever for the network served by the given aggregator endpoint. + pub fn new(aggregator_endpoint: String) -> StdResult { + Self::new_with_networks_configuration_url( + DEFAULT_NETWORKS_CONFIGURATION_URL.to_string(), + aggregator_endpoint, + ) + } + + /// Build a retriever resolving from the given networks configuration file URL. + pub fn new_with_networks_configuration_url( + networks_configuration_url: String, + aggregator_endpoint: String, + ) -> StdResult { + Ok(Self { + networks_configuration_url, + aggregator_endpoint, + downloader: BoundedHttpDownloader::new()?, + }) + } + + /// Build a retriever also accepting plain HTTP URLs, for the tests served by a local server. + #[cfg(all(test, not(target_family = "wasm")))] + fn new_allowing_plain_http( + networks_configuration_url: String, + aggregator_endpoint: String, + ) -> StdResult { + Ok(Self { + networks_configuration_url, + aggregator_endpoint, + downloader: BoundedHttpDownloader::new_allowing_plain_http()?, + }) + } + + /// Resolve the registry URL of the client's network from the networks configuration file, + /// then download and parse the signed registry. + async fn resolve_and_download_registry( + &self, + ) -> StdResult { + let networks_configuration_json = self + .downloader + .download_with_retry(&self.networks_configuration_url) + .await?; + let networks_configuration = MithrilNetworksConfiguration::parse( + &networks_configuration_json, + ) + .with_context(|| { + format!( + "Failed to parse networks configuration downloaded from '{}'", + self.networks_configuration_url + ) + })?; + let registry_url = networks_configuration + .registry_url_of_aggregator(&self.aggregator_endpoint) + .ok_or_else(|| { + anyhow!( + "No circuit verification key registry is referenced in '{}' for the network of aggregator '{}'", + self.networks_configuration_url, + self.aggregator_endpoint + ) + })?; + let registry_json = self.downloader.download_with_retry(®istry_url).await?; + + serde_json::from_str(®istry_json).with_context(|| { + format!("Failed to parse signed registry downloaded from '{registry_url}'") + }) + } +} + +#[cfg_attr(target_family = "wasm", async_trait(?Send))] +#[cfg_attr(not(target_family = "wasm"), async_trait)] +impl CircuitVerificationKeyRegistryRetriever for RemoteCircuitVerificationKeyRegistryRetriever { + async fn retrieve_signed_registry( + &self, + ) -> Result + { + self.resolve_and_download_registry() + .await + .map_err(CircuitVerificationKeyRegistryRetrieverError) + } +} + +#[cfg(all(test, not(target_family = "wasm")))] +mod tests { + use httpmock::MockServer; + + use mithril_circuit_key_registry::{DOWNLOAD_MAX_ATTEMPTS, DOWNLOAD_MAX_BODY_SIZE_IN_BYTES}; + use mithril_common::crypto_helper::{GenesisEd25519Signer, GenesisSigner}; + + use super::*; + + const AGGREGATOR_ENDPOINT: &str = "https://aggregator.devnet.example/aggregator"; + + fn genesis_signer() -> GenesisSigner { + GenesisSigner::from_ed25519(GenesisEd25519Signer::create_deterministic_signer()) + } + + fn signed_registry(genesis_signer: &GenesisSigner) -> SignedCircuitVerificationKeyRegistry { + SignedCircuitVerificationKeyRegistry::try_new( + CircuitVerificationKeyRegistry { + version: 1, + entries: vec![], + }, + genesis_signer, + ) + .unwrap() + } + + fn networks_configuration_json(server: &MockServer, aggregator_endpoint: &str) -> String { + format!( + r#"{{ + "devnet": {{ + "mithril-networks": [ + {{ + "release-devnet": {{ + "aggregators": [{{ "url": "{aggregator_endpoint}" }}], + "circuit-verification-key-registry": {{ "url": "{registry_url}" }} + }} + }} + ] + }} + }}"#, + registry_url = server.url("/registry.json"), + ) + } + + fn retriever_over( + server: &MockServer, + aggregator_endpoint: &str, + ) -> RemoteCircuitVerificationKeyRegistryRetriever { + RemoteCircuitVerificationKeyRegistryRetriever::new_allowing_plain_http( + server.url("/networks.json"), + aggregator_endpoint.to_string(), + ) + .unwrap() + } + + #[test] + fn parses_a_network_without_registry_reference() { + let configuration = MithrilNetworksConfiguration::parse(&format!( + r#"{{ "devnet": {{ "mithril-networks": [ {{ "release-devnet": {{ "aggregators": [ {{ "url": "{AGGREGATOR_ENDPOINT}" }} ] }} }} ] }} }}"# + )) + .unwrap(); + + assert_eq!(1, configuration.networks.len()); + assert_eq!( + None, + configuration.registry_url_of_aggregator(AGGREGATOR_ENDPOINT) + ); + } + + #[tokio::test] + async fn resolves_the_registry_of_the_network_matching_the_aggregator_endpoint() { + let server = MockServer::start(); + let genesis_signer = genesis_signer(); + let signed_registry = signed_registry(&genesis_signer); + server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/networks.json"); + then.status(200) + .body(networks_configuration_json(&server, AGGREGATOR_ENDPOINT)); + }); + server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/registry.json"); + then.status(200) + .body(serde_json::to_string(&signed_registry).unwrap()); + }); + + let retrieved = retriever_over(&server, AGGREGATOR_ENDPOINT) + .retrieve_signed_registry() + .await + .unwrap(); + + assert_eq!(signed_registry, retrieved); + } + + #[tokio::test] + async fn tolerates_top_level_metadata_entries_in_the_networks_configuration() { + let server = MockServer::start(); + let genesis_signer = genesis_signer(); + let signed_registry = signed_registry(&genesis_signer); + let networks_configuration_with_metadata = format!( + r#"{{ "version": 2, {} }}"#, + networks_configuration_json(&server, AGGREGATOR_ENDPOINT) + .trim() + .trim_start_matches('{') + .trim_end_matches('}') + ); + server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/networks.json"); + then.status(200).body(networks_configuration_with_metadata); + }); + server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/registry.json"); + then.status(200) + .body(serde_json::to_string(&signed_registry).unwrap()); + }); + + let retrieved = retriever_over(&server, AGGREGATOR_ENDPOINT) + .retrieve_signed_registry() + .await + .unwrap(); + + assert_eq!(signed_registry, retrieved); + } + + #[tokio::test] + async fn fails_on_a_response_exceeding_the_body_size_limit_before_using_it() { + let server = MockServer::start(); + let oversized_networks_configuration = format!( + "{}{}", + networks_configuration_json(&server, AGGREGATOR_ENDPOINT), + " ".repeat(DOWNLOAD_MAX_BODY_SIZE_IN_BYTES as usize) + ); + server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/networks.json"); + then.status(200).body(oversized_networks_configuration); + }); + let registry = server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/registry.json"); + then.status(200); + }); + + retriever_over(&server, AGGREGATOR_ENDPOINT) + .retrieve_signed_registry() + .await + .expect_err("an oversized response must fail retrieval"); + + assert_eq!(0, registry.hits()); + } + + #[tokio::test] + async fn fails_when_no_network_is_served_by_the_aggregator_endpoint() { + let server = MockServer::start(); + let registry = server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/registry.json"); + then.status(200); + }); + server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/networks.json"); + then.status(200) + .body(networks_configuration_json(&server, AGGREGATOR_ENDPOINT)); + }); + + retriever_over(&server, "https://another-network.example/aggregator") + .retrieve_signed_registry() + .await + .expect_err("an unmatched aggregator endpoint must fail retrieval"); + + assert_eq!(0, registry.hits()); + } + + #[tokio::test] + async fn retries_a_failed_download() { + let server = MockServer::start(); + server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/networks.json"); + then.status(200) + .body(networks_configuration_json(&server, AGGREGATOR_ENDPOINT)); + }); + let failing_registry = server.mock(|when, then| { + when.method(httpmock::Method::GET).path("/registry.json"); + then.status(500); + }); + + retriever_over(&server, AGGREGATOR_ENDPOINT) + .retrieve_signed_registry() + .await + .expect_err("a persistently failing download must fail retrieval"); + + assert_eq!(DOWNLOAD_MAX_ATTEMPTS, failing_registry.hits()); + } +} diff --git a/mithril-client/src/client.rs b/mithril-client/src/client.rs index dceaa4832b9..8b3fdbc5a63 100644 --- a/mithril-client/src/client.rs +++ b/mithril-client/src/client.rs @@ -20,6 +20,8 @@ use mithril_aggregator_discovery::{ CapableAggregatorDiscoverer, HttpConfigAggregatorDiscoverer, RequiredAggregatorCapabilities, ShuffleAggregatorDiscoverer, }; +#[cfg(feature = "future_snark")] +use mithril_circuit_key_registry::CircuitVerificationKeyRegistryRetriever; use mithril_common::{MITHRIL_CLIENT_TYPE_HEADER, MITHRIL_ORIGIN_TAG_HEADER}; use crate::MithrilResult; @@ -35,6 +37,8 @@ use crate::certificate_client::{ }; #[cfg(feature = "unstable")] use crate::certificate_client::{CertificateVerifierCache, CertificateVerifierCacheMode}; +#[cfg(feature = "future_snark")] +use crate::circuit_key_registry::RemoteCircuitVerificationKeyRegistryRetriever; #[cfg(not(target_family = "wasm"))] use crate::common::MithrilNetwork; use crate::era::{EraFetcher, MithrilEraClient}; @@ -230,6 +234,8 @@ pub struct ClientBuilder { certificate_verifier_cache: Option>, #[cfg(feature = "unstable")] certificate_verifier_cache_mode: Option, + #[cfg(feature = "future_snark")] + circuit_key_registry_retriever: Option>, era_fetcher: Option>, logger: Option, feedback_receivers: Vec>, @@ -285,6 +291,8 @@ impl ClientBuilder { certificate_verifier_cache: None, #[cfg(feature = "unstable")] certificate_verifier_cache_mode: None, + #[cfg(feature = "future_snark")] + circuit_key_registry_retriever: None, era_fetcher: None, logger: None, feedback_receivers: vec![], @@ -345,13 +353,22 @@ impl ClientBuilder { let feedback_sender = FeedbackSender::new(&self.feedback_receivers); - let aggregator_client = Arc::new(self.build_aggregator_client(logger.clone())?); + let aggregator_endpoint = self.resolve_aggregator_endpoint()?; + let aggregator_client = + Arc::new(self.build_aggregator_client(aggregator_endpoint.clone(), logger.clone())?); let mithril_era_client = match self.era_fetcher { None => Arc::new(MithrilEraClient::new(aggregator_client.clone())), Some(era_fetcher) => Arc::new(MithrilEraClient::new(era_fetcher)), }; + #[cfg(feature = "future_snark")] + let circuit_key_registry_retriever = match self.circuit_key_registry_retriever { + Some(circuit_key_registry_retriever) => circuit_key_registry_retriever, + None => Arc::new(RemoteCircuitVerificationKeyRegistryRetriever::new( + aggregator_endpoint.clone(), + )?), + }; let certificate_verifier = match self.certificate_verifier { None => Arc::new( MithrilCertificateVerifier::new( @@ -362,6 +379,8 @@ impl ClientBuilder { self.certificate_verifier_cache, #[cfg(feature = "unstable")] self.certificate_verifier_cache_mode.unwrap_or_default(), + #[cfg(feature = "future_snark")] + circuit_key_registry_retriever, logger.clone(), ) .with_context(|| "Building certificate verifier failed")?, @@ -513,16 +532,24 @@ impl ClientBuilder { )) } - fn build_aggregator_client(&self, logger: Logger) -> MithrilResult { - let aggregator_endpoint = match self.aggregator_discovery { - AggregatorDiscoveryType::Url(ref url) => url.clone(), + /// Resolve the aggregator endpoint from the configured URL or through discovery. + fn resolve_aggregator_endpoint(&self) -> MithrilResult { + match self.aggregator_discovery { + AggregatorDiscoveryType::Url(ref url) => Ok(url.clone()), #[cfg(not(target_family = "wasm"))] - AggregatorDiscoveryType::Automatic(ref network) => self + AggregatorDiscoveryType::Automatic(ref network) => Ok(self .discover_aggregator(network)? .next() .with_context(|| "No aggregator was available through discovery")? - .into(), - }; + .into()), + } + } + + fn build_aggregator_client( + &self, + aggregator_endpoint: String, + logger: Logger, + ) -> MithrilResult { let headers = self.compute_http_headers(); AggregatorHttpClient::builder(aggregator_endpoint) @@ -578,6 +605,18 @@ impl ClientBuilder { } } + /// Set a custom registry retriever for the circuit verification key registry check on + /// certificate verification, replacing the default one resolving the registry of the + /// client's network from the published networks configuration. + #[cfg(feature = "future_snark")] + pub fn with_circuit_verification_key_registry_retriever( + mut self, + circuit_key_registry_retriever: Arc, + ) -> ClientBuilder { + self.circuit_key_registry_retriever = Some(circuit_key_registry_retriever); + self + } + cfg_fs! { /// Set the [FileDownloader] that will be used to download artifacts with HTTP. pub fn with_http_file_downloader( diff --git a/mithril-client/src/lib.rs b/mithril-client/src/lib.rs index 0de029a6c4c..8da6e9f1f4e 100644 --- a/mithril-client/src/lib.rs +++ b/mithril-client/src/lib.rs @@ -185,6 +185,8 @@ cfg_unstable! { pub mod cardano_transaction_v2_client; } pub mod certificate_client; +#[cfg(feature = "future_snark")] +pub mod circuit_key_registry; mod client; pub mod era; pub mod feedback; diff --git a/mithril-common/Cargo.toml b/mithril-common/Cargo.toml index d4e9db30a59..d4b0cbf3d23 100644 --- a/mithril-common/Cargo.toml +++ b/mithril-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-common" -version = "0.7.26" +version = "0.7.27" description = "Common types, interfaces, and utilities for Mithril nodes." authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-common/src/certificate_chain/certificate_verifier.rs b/mithril-common/src/certificate_chain/certificate_verifier.rs index 563485a7ece..4fc6b6304fa 100644 --- a/mithril-common/src/certificate_chain/certificate_verifier.rs +++ b/mithril-common/src/certificate_chain/certificate_verifier.rs @@ -11,6 +11,8 @@ use mithril_stm::{AggregateSignatureType, AncillaryVerifierData}; use crate::StdResult; #[cfg(feature = "future_snark")] +use crate::certificate_chain::CircuitVerificationKeyCertifier; +#[cfg(feature = "future_snark")] use crate::crypto_helper::ProtocolAggregateVerificationKeyForSnark; use crate::crypto_helper::{ GenesisEd25519Error, GenesisVerifier, ProtocolAggregateVerificationKey, @@ -90,6 +92,14 @@ pub enum CertificateVerifierError { /// certificate that's not a standard certificate. #[error("can't validate standard certificate: given certificate isn't a standard certificate")] InvalidStandardCertificateProvided, + + /// Error raised when a certificate whose aggregate signature type requires certified circuit + /// verification keys carries no ancillary verifier data. + #[cfg(feature = "future_snark")] + #[error( + "certificate is missing the ancillary verifier data carrying its circuit verification keys" + )] + MissingAncillaryVerifierData, } /// CertificateVerifier is the cryptographic engine in charge of verifying multi signatures and @@ -128,20 +138,30 @@ pub struct MithrilCertificateVerifier { logger: Logger, certificate_retriever: Arc, genesis_verifier: Arc, + #[cfg(feature = "future_snark")] + circuit_verification_key_certifier: Arc, } impl MithrilCertificateVerifier { /// MithrilCertificateVerifier factory + /// + /// The circuit verification key certifier enforces the circuit verification key registry on + /// the certificates whose aggregate signature type requires it. pub fn new( logger: Logger, certificate_retriever: Arc, genesis_verifier: Arc, + #[cfg(feature = "future_snark")] circuit_verification_key_certifier: Arc< + dyn CircuitVerificationKeyCertifier, + >, ) -> Self { debug!(logger, "New MithrilCertificateVerifier created"); Self { logger: logger.new_with_component_name::(), certificate_retriever, genesis_verifier, + #[cfg(feature = "future_snark")] + circuit_verification_key_certifier, } } @@ -188,6 +208,44 @@ impl MithrilCertificateVerifier { .map_err(|e| CertificateVerifierError::VerifyMultiSignature(e.to_string())) } + /// Verify that the circuit verification keys carried by the certificate are certified by the + /// genesis-signed registry, for the aggregate signature types that require it. + /// + /// The digests are taken from the ancillary verifier data the aggregate signature is verified + /// against, so certifying them certifies the circuits used to produce the signature. + #[cfg(feature = "future_snark")] + async fn verify_certified_circuit_verification_keys( + &self, + certificate: &Certificate, + ) -> StdResult<()> { + let requires_certification = certificate.signature.aggregate_signature_type().is_some_and( + |aggregate_signature_type| { + aggregate_signature_type.requires_certified_circuit_verification_keys() + }, + ); + if !requires_certification { + return Ok(()); + } + + let ancillary_verifier_data = certificate + .ancillary_verifier_data + .as_ref() + .ok_or(CertificateVerifierError::MissingAncillaryVerifierData)?; + + self.circuit_verification_key_certifier + .check( + &ancillary_verifier_data.circuit_verification_key_digests(), + certificate.epoch, + ) + .await + .with_context(|| { + format!( + "Certificate verifier failed certifying the circuit verification keys of certificate '{}'", + certificate.hash + ) + }) + } + /// Verify the parts of a standard certificate that do not depend on its predecessor: its hash, /// signed message, multi-signature and epoch. fn verify_standard_certificate_integrity(&self, certificate: &Certificate) -> StdResult<()> { @@ -462,6 +520,8 @@ impl CertificateVerifier for MithrilCertificateVerifier { certificate: &Certificate, previous_certificate: &Certificate, ) -> StdResult<()> { + #[cfg(feature = "future_snark")] + self.verify_certified_circuit_verification_keys(certificate).await?; self.verify_standard_certificate_integrity(certificate)?; self.verify_epoch_chaining(certificate, previous_certificate)?; self.verify_previous_hash_matches_previous_certificate_hash( @@ -498,6 +558,8 @@ impl CertificateVerifier for MithrilCertificateVerifier { if certificate.signature.aggregate_signature_type().is_some_and( |aggregate_signature_type| aggregate_signature_type.certifies_full_certificate_chain(), ) { + #[cfg(feature = "future_snark")] + self.verify_certified_circuit_verification_keys(certificate).await?; self.verify_standard_certificate_integrity(certificate)?; return Ok(None); @@ -520,6 +582,8 @@ mod tests { use mithril_stm::{AggregateSignatureType, AncillaryProofInput}; + #[cfg(feature = "future_snark")] + use crate::test::double::FakeCircuitVerificationKeyCertifier; use crate::test::{ TestLogger, builder::{CertificateChainBuilder, CertificateChainBuilderContext, MithrilFixtureBuilder}, @@ -573,6 +637,8 @@ mod tests { TestLogger::stdout(), Arc::new(self.mock_certificate_retriever), genesis_verifier, + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyCertifier::that_fails()), ) } } @@ -616,6 +682,8 @@ mod tests { TestLogger::stdout(), Arc::new(MockCertificateRetriever::new()), Arc::new(genesis_verifier), + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyCertifier::that_fails()), ); let message_tampered = message_hash[1..].to_vec(); assert!( @@ -1198,6 +1266,8 @@ mod tests { TestLogger::stdout(), Arc::new(certificate_retriever), Arc::new(fake_certificates.genesis_verifier.clone()), + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyCertifier::that_fails()), ); let certificate_to_verify = fake_certificates[0].clone(); @@ -1218,6 +1288,8 @@ mod tests { TestLogger::stdout(), Arc::new(certificate_retriever), Arc::new(fake_certificates.genesis_verifier.clone()), + #[cfg(feature = "future_snark")] + Arc::new(FakeCircuitVerificationKeyCertifier::that_fails()), ); let certificate_to_verify = fake_certificates[0].clone(); @@ -1835,4 +1907,93 @@ mod tests { } } } + + #[cfg(feature = "future_snark")] + mod certified_circuit_verification_keys { + use crate::test::double::fake_data::snark_aggregate_signature; + + use super::*; + + fn promote_to_snark_aggregate_signature_without_ancillary_data( + mut certificate: Certificate, + ) -> Certificate { + let CertificateSignature::MultiSignature(entity_type, _) = + certificate.signature.clone() + else { + panic!("certificate signature must be a multi signature"); + }; + certificate.signature = + CertificateSignature::MultiSignature(entity_type, snark_aggregate_signature()); + certificate.ancillary_verifier_data = None; + certificate + } + + fn failing_certifier() -> Arc { + Arc::new(FakeCircuitVerificationKeyCertifier::that_fails()) + } + + #[tokio::test] + async fn skips_the_check_for_a_concatenation_certificate() { + let fake_certificates = setup_certificate_chain(2, 1); + let verifier = MithrilCertificateVerifier::new( + TestLogger::stdout(), + Arc::new(MockCertificateRetriever::new()), + Arc::new(fake_certificates.genesis_verifier.clone()), + failing_certifier(), + ); + + verifier + .verify_certified_circuit_verification_keys(&fake_certificates[0]) + .await + .expect("a concatenation certificate must not be checked against the registry"); + } + + #[tokio::test] + async fn rejects_a_snark_certificate_without_ancillary_verifier_data() { + let fake_certificates = setup_certificate_chain(2, 1); + let certificate = promote_to_snark_aggregate_signature_without_ancillary_data( + fake_certificates[0].clone(), + ); + let verifier = MithrilCertificateVerifier::new( + TestLogger::stdout(), + Arc::new(MockCertificateRetriever::new()), + Arc::new(fake_certificates.genesis_verifier.clone()), + failing_certifier(), + ); + + let error = verifier + .verify_certified_circuit_verification_keys(&certificate) + .await + .expect_err("a SNARK certificate without ancillary verifier data must be rejected"); + + assert_error_matches!( + CertificateVerifierError::MissingAncillaryVerifierData, + error + ); + } + + #[tokio::test] + async fn verify_standard_certificate_enforces_the_check_before_any_other_verification() { + let fake_certificates = setup_certificate_chain(2, 1); + let certificate = promote_to_snark_aggregate_signature_without_ancillary_data( + fake_certificates[0].clone(), + ); + let verifier = MithrilCertificateVerifier::new( + TestLogger::stdout(), + Arc::new(MockCertificateRetriever::new()), + Arc::new(fake_certificates.genesis_verifier.clone()), + failing_certifier(), + ); + + let error = verifier + .verify_standard_certificate(&certificate, &fake_certificates[1]) + .await + .expect_err("standard certificate verification must enforce the check"); + + assert_error_matches!( + CertificateVerifierError::MissingAncillaryVerifierData, + error + ); + } + } } diff --git a/mithril-common/src/test/double/circuit_key_registry_certifier.rs b/mithril-common/src/test/double/circuit_key_registry_certifier.rs new file mode 100644 index 00000000000..ad3373ccfd8 --- /dev/null +++ b/mithril-common/src/test/double/circuit_key_registry_certifier.rs @@ -0,0 +1,34 @@ +//! A module used for a fake implementation of a circuit verification key certifier +//! + +use anyhow::anyhow; +use async_trait::async_trait; + +use mithril_stm::CircuitVerificationKeyDigest; + +use crate::StdResult; +use crate::certificate_chain::CircuitVerificationKeyCertifier; +use crate::entities::Epoch; + +/// A fake [CircuitVerificationKeyCertifier] failing every check, as when no registry can be +/// retrieved. +pub struct FakeCircuitVerificationKeyCertifier; + +impl FakeCircuitVerificationKeyCertifier { + /// Create a fake certifier failing every check. + pub fn that_fails() -> Self { + Self + } +} + +#[cfg_attr(target_family = "wasm", async_trait(?Send))] +#[cfg_attr(not(target_family = "wasm"), async_trait)] +impl CircuitVerificationKeyCertifier for FakeCircuitVerificationKeyCertifier { + async fn check( + &self, + _digests: &[CircuitVerificationKeyDigest], + _epoch: Epoch, + ) -> StdResult<()> { + Err(anyhow!("Verified registry not available")) + } +} diff --git a/mithril-common/src/test/double/mod.rs b/mithril-common/src/test/double/mod.rs index 31fe8acc671..c65346b1e30 100644 --- a/mithril-common/src/test/double/mod.rs +++ b/mithril-common/src/test/double/mod.rs @@ -4,6 +4,8 @@ mod api_version; mod certificate_retriever; +#[cfg(feature = "future_snark")] +mod circuit_key_registry_certifier; mod dummies; pub mod fake_data; pub mod fake_keys; @@ -11,6 +13,8 @@ pub(super) mod precomputed_kes_key; pub use api_version::DummyApiVersionDiscriminantSource; pub use certificate_retriever::FakeCertificaterRetriever; +#[cfg(feature = "future_snark")] +pub use circuit_key_registry_certifier::FakeCircuitVerificationKeyCertifier; /// A trait for giving a type a dummy value. /// diff --git a/mithril-infra/assets/docker/docker-compose-aggregator-base.yaml b/mithril-infra/assets/docker/docker-compose-aggregator-base.yaml index 72af86db731..6af44ac6b98 100644 --- a/mithril-infra/assets/docker/docker-compose-aggregator-base.yaml +++ b/mithril-infra/assets/docker/docker-compose-aggregator-base.yaml @@ -62,6 +62,7 @@ services: - ZSTANDARD_PARAMETERS__LEVEL=${ZSTANDARD_PARAMETERS__LEVEL} - ZSTANDARD_PARAMETERS__NUMBER_OF_WORKERS=${ZSTANDARD_PARAMETERS__NUMBER_OF_WORKERS} - DATA_STORES_DIRECTORY=/mithril-aggregator/mithril/stores + - CIRCUIT_VERIFICATION_KEY_REGISTRY_URL=${CIRCUIT_VERIFICATION_KEY_REGISTRY_URL} - STORE_RETENTION_LIMIT=5 - CARDANO_NODE_SOCKET_PATH=/ipc/node.socket - CARDANO_NODE_VERSION=${CARDANO_IMAGE_ID} diff --git a/mithril-infra/assets/infra.version b/mithril-infra/assets/infra.version index d28594c41e1..c903512483d 100644 --- a/mithril-infra/assets/infra.version +++ b/mithril-infra/assets/infra.version @@ -1,2 +1,2 @@ -0.5.26 +0.5.27 diff --git a/mithril-infra/configuration/dev-preview/circuit-verification-key-registry.json b/mithril-infra/configuration/dev-preview/circuit-verification-key-registry.json new file mode 100644 index 00000000000..200b1feaae4 --- /dev/null +++ b/mithril-infra/configuration/dev-preview/circuit-verification-key-registry.json @@ -0,0 +1,24 @@ +{ + "registry": { + "entries": [ + { + "comment": "initial publication", + "digest": "21bd5482d438aec353d1349f5933db8b7f3b8a9894f4739eeec1d71dd7113b1f", + "end_epoch": null, + "name": "certificate-circuit v1 (k=1054, m=8400)", + "start_epoch": 0, + "status": "allowed" + }, + { + "comment": "initial publication", + "digest": "8a6b414e9b007a6c4ff68a349ea2a7447cb1c94cb7d3de59307197284a8db252", + "end_epoch": null, + "name": "ivc-circuit v1", + "start_epoch": 0, + "status": "allowed" + } + ], + "version": 2 +}, + "signature": "15c26ff2221a4ec2b58bbec56267c6de23466cc8b994863b5de578ed083adfddc2324373aa689fc9d148b15fdb5ae97b04ce15b289bbd4451c0cc134551df307" +} \ No newline at end of file diff --git a/mithril-infra/configuration/testing-preview/circuit-verification-key-registry.json b/mithril-infra/configuration/testing-preview/circuit-verification-key-registry.json new file mode 100644 index 00000000000..05aa0f14edf --- /dev/null +++ b/mithril-infra/configuration/testing-preview/circuit-verification-key-registry.json @@ -0,0 +1,24 @@ +{ + "registry": { + "entries": [ + { + "comment": "initial publication", + "digest": "b4f2e431d9b6f016d6c551a3b6ae9f2b6b494941181eabdafd1313fc7c240f25", + "end_epoch": null, + "name": "certificate-circuit v1 (k=1944, m=16948)", + "start_epoch": 0, + "status": "allowed" + }, + { + "comment": "initial publication", + "digest": "8a6b414e9b007a6c4ff68a349ea2a7447cb1c94cb7d3de59307197284a8db252", + "end_epoch": null, + "name": "ivc-circuit v1", + "start_epoch": 0, + "status": "allowed" + } + ], + "version": 2 +}, + "signature": "ec9b9fde6ef6810240c8249e4a7f14017cb61c296a83285c174e4ce3296067df0b6cbdc0c1d309ad8c3ed3df92746b0c06f30c0826abc8388d3b9cbcccafc70e" +} \ No newline at end of file diff --git a/mithril-infra/mithril.aggregator.tf b/mithril-infra/mithril.aggregator.tf index 3db5f0f4a5e..f0439626e6a 100644 --- a/mithril-infra/mithril.aggregator.tf +++ b/mithril-infra/mithril.aggregator.tf @@ -21,6 +21,7 @@ resource "null_resource" "mithril_aggregator" { mithril_aggregator_auth_username = var.mithril_aggregator_auth_username, mithril_aggregator_auth_password = var.mithril_aggregator_auth_password, mithril_aggregator_aggregate_signature_type = var.mithril_aggregator_aggregate_signature_type, + mithril_circuit_verification_key_registry_url = var.mithril_circuit_verification_key_registry_url, mithril_aggregator_signed_entity_types = var.mithril_aggregator_signed_entity_types, mithril_aggregator_snapshot_compression_algorithm = var.mithril_aggregator_snapshot_compression_algorithm, mithril_aggregator_zstandard_parameters_level = var.mithril_aggregator_zstandard_parameters_level, @@ -155,6 +156,7 @@ EOT "export GOOGLE_APPLICATION_CREDENTIALS_JSON='${local.google_cloud_storage_credentials_json}'", "export SIGNED_ENTITY_TYPES='${var.mithril_aggregator_signed_entity_types}'", "export AGGREGATE_SIGNATURE_TYPE='${var.mithril_aggregator_aggregate_signature_type}'", + "export CIRCUIT_VERIFICATION_KEY_REGISTRY_URL='${var.mithril_circuit_verification_key_registry_url}'", "export SNAPSHOT_BUCKET_NAME='${google_storage_bucket.cloud_storage.name}'", "export SNAPSHOT_USE_CDN_DOMAIN='${var.mithril_aggregator_snapshot_use_cdn_domain}'", "export SNAPSHOT_COMPRESSION_ALGORITHM=${var.mithril_aggregator_snapshot_compression_algorithm}", diff --git a/mithril-infra/variables.tf b/mithril-infra/variables.tf index 99986cdcdaf..c024e9f7982 100644 --- a/mithril-infra/variables.tf +++ b/mithril-infra/variables.tf @@ -522,6 +522,12 @@ variable "mithril_genesis_verification_key_url" { type = string description = "The url of the Mithril genesis verification key used by to verify a genesis certificate" } + +variable "mithril_circuit_verification_key_registry_url" { + type = string + description = "The url of the signed circuit verification key registry downloaded by the aggregator and enforced on the SNARK certificates (empty when the aggregate signature type does not require it)" + default = "" +} variable "mithril_genesis_secret_key" { type = string description = "The Mithril genesis secret key used by the aggregator to bootstrap a genesis certificate (test only)" diff --git a/mithril-test-lab/mithril-end-to-end/Cargo.toml b/mithril-test-lab/mithril-end-to-end/Cargo.toml index f9d55c42765..d149fa794f7 100644 --- a/mithril-test-lab/mithril-end-to-end/Cargo.toml +++ b/mithril-test-lab/mithril-end-to-end/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-end-to-end" -version = "0.5.20" +version = "0.5.21" authors = { workspace = true } edition = { workspace = true } documentation = { workspace = true } diff --git a/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs b/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs index 8044eb37a8c..b7aa7857fbf 100644 --- a/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs +++ b/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs @@ -65,6 +65,7 @@ pub struct Aggregator { chain_observer: Arc, full_node: FullNode, aggregate_signature_type: AggregateSignatureType, + startup_protocol_parameters: ProtocolParameters, } impl Aggregator { @@ -109,6 +110,10 @@ impl Aggregator { let public_server_url = format!("http://localhost:{server_port_parameter}/aggregator"); let cardano_node_version = aggregator_config.cardano_node_version.to_string(); let aggregate_signature_type = aggregator_config.aggregate_signature_type.to_string(); + let circuit_verification_key_registry_url = format!( + "file://{}", + Self::circuit_verification_key_registry_path().display() + ); let mut env = EnvVars::from([ ("NETWORK", "devnet"), ("NETWORK_MAGIC", &magic_id), @@ -144,6 +149,10 @@ impl Aggregator { "GENESIS_SECRET_KEY", aggregator_config.genesis_keys.secret_key, ), + ( + "CIRCUIT_VERIFICATION_KEY_REGISTRY_URL", + &circuit_verification_key_registry_url, + ), ( "ERA_READER_ADAPTER_TYPE", aggregator_config.mithril_era_reader_adapter, @@ -250,6 +259,7 @@ impl Aggregator { chain_observer, full_node: aggregator_config.full_node.clone(), aggregate_signature_type: aggregator_config.aggregate_signature_type, + startup_protocol_parameters: aggregator_config.startup_protocol_parameters.clone(), }) } @@ -257,6 +267,35 @@ impl Aggregator { format!("{}", index + 1) } + pub fn circuit_verification_key_registry_path() -> PathBuf { + std::env::temp_dir().join("circuit-verification-key-registry.json") + } + + /// Protocol parameters the scenarios switch to after the startup ones, per aggregate signature + /// type. + pub fn updated_protocol_parameters( + aggregate_signature_type: AggregateSignatureType, + ) -> ProtocolParameters { + match aggregate_signature_type { + AggregateSignatureType::Concatenation => ProtocolParameters { + k: 283, + m: 433, + phi_f: 0.77, + }, + AggregateSignatureType::Snark => ProtocolParameters { + k: 7, + m: 10, + phi_f: 0.95, + }, + // The IVC parameters must not change as this means a new genesis certificate must be created. + AggregateSignatureType::IvcSnark => ProtocolParameters { + k: 5, + m: 9, + phi_f: 0.95, + }, + } + } + pub fn copy_configuration(other: &Aggregator) -> Self { Self { index: other.index, @@ -270,6 +309,7 @@ impl Aggregator { chain_observer: other.chain_observer.clone(), full_node: other.full_node.clone(), aggregate_signature_type: other.aggregate_signature_type, + startup_protocol_parameters: other.startup_protocol_parameters.clone(), } } @@ -345,6 +385,13 @@ impl Aggregator { .with_context(|| "`mithril-aggregator genesis bootstrap` crashed")?; if exit_status.success() { + drop(command); + if matches!( + self.aggregate_signature_type, + AggregateSignatureType::Snark | AggregateSignatureType::IvcSnark + ) { + self.bootstrap_circuit_key_registry().await?; + } Ok(()) } else { command.tail_logs(Some(command_name), 40).await?; @@ -361,6 +408,48 @@ impl Aggregator { } } + async fn bootstrap_circuit_key_registry(&self) -> StdResult<()> { + let mut command = self.command.write().await; + let command_name = &format!( + "mithril-aggregator-circuit-key-registry-bootstrap-{}", + self.name_suffix, + ); + command.set_log_name(command_name); + + let mut args = vec!["circuit-key-registry".to_string(), "bootstrap".to_string()]; + for protocol_parameters in [ + self.startup_protocol_parameters.clone(), + Self::updated_protocol_parameters(self.aggregate_signature_type), + ] { + args.push("--protocol-parameters".to_string()); + args.push(serde_json::to_string(&protocol_parameters)?); + } + args.push("--target-registry-path".to_string()); + args.push(Self::circuit_verification_key_registry_path().display().to_string()); + + let exit_status = command + .start(&args)? + .wait() + .await + .with_context(|| "`mithril-aggregator circuit-key-registry bootstrap` crashed")?; + + if exit_status.success() { + Ok(()) + } else { + command.tail_logs(Some(command_name), 40).await?; + + Err(match exit_status.code() { + Some(c) => anyhow!( + "`mithril-aggregator circuit-key-registry bootstrap` exited with code: {c}" + ), + None => anyhow!( + "`mithril-aggregator circuit-key-registry bootstrap` was terminated with a signal" + ), + }) + .map_err(|e| anyhow!(RetryableDevnetError(e.to_string()))) + } + } + pub async fn stop(&self) -> StdResult<()> { let mut process = self.process.write().await; if let Some(mut process_running) = process.take() { diff --git a/mithril-test-lab/mithril-end-to-end/src/mithril/client.rs b/mithril-test-lab/mithril-end-to-end/src/mithril/client.rs index 659d55dcd48..4d00d61b22c 100644 --- a/mithril-test-lab/mithril-end-to-end/src/mithril/client.rs +++ b/mithril-test-lab/mithril-end-to-end/src/mithril/client.rs @@ -8,7 +8,7 @@ use mithril_common::StdResult; use mithril_common::entities::{BlockHash, EpochSpecifier, TransactionHash}; use crate::utils::{MithrilCommand, NodeVersion}; -use crate::{ANCILLARY_MANIFEST_VERIFICATION_KEY, GenesisKeys}; +use crate::{ANCILLARY_MANIFEST_VERIFICATION_KEY, Aggregator, GenesisKeys}; #[derive(Debug)] pub struct Client { @@ -435,6 +435,9 @@ impl Client { bin_dir: &Path, genesis_keys: GenesisKeys, ) -> StdResult { + let registry_file_path = Aggregator::circuit_verification_key_registry_path() + .display() + .to_string(); let env = HashMap::from([ ("GENESIS_VERIFICATION_KEY", genesis_keys.verification_key), ("AGGREGATOR_ENDPOINT", &aggregator_endpoint), @@ -442,6 +445,10 @@ impl Client { "ANCILLARY_VERIFICATION_KEY", ANCILLARY_MANIFEST_VERIFICATION_KEY, ), + ( + "CIRCUIT_VERIFICATION_KEY_REGISTRY_PATH", + registry_file_path.as_str(), + ), ]); let version = NodeVersion::fetch(Self::BIN_NAME, bin_dir)?; diff --git a/mithril-test-lab/mithril-end-to-end/src/toolkit/exec.rs b/mithril-test-lab/mithril-end-to-end/src/toolkit/exec.rs index 42397972104..da518c5c127 100644 --- a/mithril-test-lab/mithril-end-to-end/src/toolkit/exec.rs +++ b/mithril-test-lab/mithril-end-to-end/src/toolkit/exec.rs @@ -6,13 +6,11 @@ use anyhow::Context; use slog_scope::info; use mithril_common::StdResult; -use mithril_common::entities::{Epoch, ProtocolParameters}; +use mithril_common::entities::Epoch; use mithril_common::messages::AggregatorStatusMessage; use crate::toolkit::ScenarioToolkitContext; -use crate::{ - AggregateSignatureType, Aggregator, Devnet, MithrilInfrastructure, ProtocolConfiguration, -}; +use crate::{Aggregator, Devnet, MithrilInfrastructure, ProtocolConfiguration}; #[derive(Debug, Clone)] pub struct ExecToolkit { @@ -137,25 +135,9 @@ impl ExecToolkit { infrastructure: &MithrilInfrastructure, epoch: Epoch, ) -> StdResult<()> { - let protocol_parameters_new = - match infrastructure.most_constraining_aggregate_signature_type() { - AggregateSignatureType::Concatenation => ProtocolParameters { - k: 283, - m: 433, - phi_f: 0.77, - }, - AggregateSignatureType::Snark => ProtocolParameters { - k: 7, - m: 10, - phi_f: 0.95, - }, - // The IVC parameters must not change as this means a new genesis certificate must be created. - AggregateSignatureType::IvcSnark => ProtocolParameters { - k: 5, - m: 9, - phi_f: 0.95, - }, - }; + let protocol_parameters_new = Aggregator::updated_protocol_parameters( + infrastructure.most_constraining_aggregate_signature_type(), + ); if aggregator.is_reading_protocol_configurations_on_chain() { info!("> updating on-chain protocol parameters to {protocol_parameters_new:?}...");