This is a maintenance release that addresses several issues.
As part of Smart Contract Upgrade feature, when a DAR/package is uploaded to a participant node, Canton checks the upgrade compatibility against the DARs already present in a participant's DAR/package stores. Together with the invariant that all active contracts must have their creation package in the store; this ensures that the stakeholder participants of a contract will only vet packages that are compatible with the creation package of the contract.
However, it was discovered that there was a gap in the upload checks: For an LF 1.17 package with a data dependency on a LF 1.15 package, the compatibility check at upload compares neither the package IDs nor the contents of the referenced LF 1.15 packages, only the package names, the package versions, and the module names and identifiers matter. If this occurred, command submission would fail with INVALID_ARGUMENT or the Daml model execution may behave unexpectedly..
If you have been mixing LF 1.15 and LF 1.17 packages then please perform the following step before upgrading to 2.10.1: verify that the package store of each of your participants does not contain invalid upgrades by running the following script in a Canton console connected to the respective participant. remote_participant.ledger_api.packages.check_upgrade_validity
where remote_participant is a reference to a remote Canton participant on version 2.10.0. If you encounter any errors, contact Digital Asset support. Then upgrade to 2.10.1.
On ledger-API start-up, the Daml package store of the participant node is checked for upgrade compatibility for all persisted packages. On compatibility check failure, the participant is shut down with an error message. To disable the check (not recommended), set canton.participants.participant.parameters.unsafe-disable-upgrade-validation=true.
User authorization is extended to all service types for participant nodes in 2.10 for the Canton Admin API.
The user is able to configure authorization on the Admin API of the participant node in a manner similar to what is currently possible on the Ledger API. However, it is necessary to specify explicitly which users are allowed in and which grpc services are accessible to them. An example configuration for both Ledger and Admin API looks like this:
canton {
participants {
participant {
ledger-api {
port = 5001
auth-services = [{
type = jwt-rs-256-jwks
url = "https://target.audience.url/jwks.json"
target-audience = "https://rewrite.target.audience.url"
}]
}
admin-api {
port = 5002
auth-services = [{
type = jwt-rs-256-jwks
url = "https://target.audience.url/jwks.json"
target-audience = "https://rewrite.target.audience.url"
users = [{
user-id = alice
allowed-services = [{
"admin.v0.ParticipantRepairService",
"connection.v30.ApiInfoService",
"v1alpha.ServerReflection",
}]
}]
}]
}
}
}
}
While the users appearing in the sub claims of the JWT tokens on the Ledger API always have to be present in the participant’s user database, no such requirement exists for the Admin API. The user in the authorization service config can be an arbitrary choice of the participant’s operator. This user also needs to be configured in the associated IDP system issuing the JWT tokens.
The configuration can contain a definition of either the target audience or the target scope depending on the specific preference of the client organization. If none is given, the JWT tokens minted by the IDP must specify daml_ledger_api as their scope claim.
Independent of the specific service that the operator wants to expose, it is a good practice to also give access rights to the ServerReflection service. Some tools such as grpcurl or postman need to hit that service to construct their requests.
The changes are backwards compatible
It is now enforced that the execution of choices from LF 1.15 interfaces within LF 1.17 templates is not allowed. Maintaining two versions of a template within the same model leads to inconsistency: LF 1.17 templates support seamless upgrades, whereas LF 1.15 templates do not, requiring an offline migration to fully upgrade the model. This is now enforced by:
These changes preserve backward compatibility, while preventing the participant from crashing.
Please note that this does require recompiling the LV 1.15 interfaces to LF 1.17.
Confidential configuration fields were logged in plain text when using specific configuration syntax or CLI flags
If the logConfigWithDefaults config parameter is set to false (which is the default), the config rendering logic fails to redact some confidential information (e.g DB credentials) when config substitution is used in combination with a config element override.
Suppose we have the following configuration file:
canton.conf
_storage {
password = confidential
}
canton {
storage = ${_storage}
}
Now the confidential config element is changed via another config file:
override.conf
canton.storage.password = confidential2
and then:
canton -c canton.conf -c override.conf
This exposes the confidential password field in the log file.
Alternatively the config element can be changed as well via the CLI:
canton -c canton.conf -C "canton.storage.password=confidential2"
In both cases the password field was not redacted and it now is.
RepairService contract import discards re-computed contract keys in the repaired contract
The repair service re-computes contract metadata when adding new contracts. However, instead of repairing the contract with the re-computed keys, it re-uses the keys from the input contract. Combined with a gap in the console macros which do not propagate contract keys during ACS export, migrating contracts with keys in that way can result in an inconsistency between the ACS and contract key store, which could cause the participant to halt when attempting to fetch a contract by key. This has been fixed.
Zombie IDE processes
Multiple IDE instances may start processes that create a package database while a multi-build is running. These simultaneous operations can lead to collisions, corrupting the package database. Running a daml build while interacting with a daml studio can sometimes collide when creating/updating the package-database, leading to corruption. The workaround was to close the IDE, kill all damlc processes, and then run daml clean --all followed by daml build --all.
Smart Contract Upgrade runtime error details are hidden by the IDE
The IDE does not show the error details when a runtime error occurs during the upgrade process.
This is because the IDE does not propagate the error details from the Canton server to the client.
Compiler emits a misleading warning about changed precondition
The compiler performs best-effort checks to verify that the expressions defining the ensure clause, signatories, observers, or the key of a template remain unchanged between templates in an upgrade relationship. If a change is detected, a warning is emitted. However, if the precondition expression calls a utility package—such as the standard library—a warning may be erroneously triggered.
IDE does not close daml processes when closed
An incompatibility between the latest version of VS Code and the VS Code client library we are using causes the Daml process to remain open improperly on Windows and Mac, preventing it from closing as expected.
PQS pruning avoids deadlocks
Pruning for the Participant Query Store (PQS) no longer uses any DDL commands, which were causing readers to encounter deadlocks whilst pruning was running.
The Daml 2.10.1 SDK has been released. You can install it using the command: daml install 2.10.1.
The table below lists how you can download Daml Enterprise or individual components.
Daml Enterprise v2.10.1 |
||
Component |
File download |
Container Image |
SDK |
NA |
|
Canton for Daml Enterprise |
digitalasset-docker.jfrog.io/canton-enterprise:2.10.1 |
|
Daml Finance |
GitHub Page |
NA |
HTTP JSON API Service |
digitalasset-docker.jfrog.io/http-json:2.10.1 |
|
Trigger Service |
digitalasset-docker.jfrog.io/trigger-service:2.10.1 |
|
OAuth 2.0 middleware (Open-Source) |
digitalasset-docker.jfrog.io/oauth2-middleware:2.10.1 |
|
Participant Query Store |
digitalasset-docker.jfrog.io/participant-query-store:0.5.5 |
|
Daml Shell |
digitalasset-docker.jfrog.io/daml-shell:0.1.6 |
|
Trigger Runner |
digitalasset-docker.jfrog.io/trigger-runner:2.10.1 |
|
Daml Script |
digitalasset-docker.jfrog.io/daml-script:2.10.1 |
If you are using Oracle JVM and testing security provider signatures, note that the Canton JAR file embeds the Bouncy Castle provider as a dependency. To enable the JVM to verify the signature, put the bcprov JAR on the classpath before the Canton standalone JAR. For example:
java -cp bcprov-jdk15on-1.70.jar:canton-with-drivers-2.10.1-all.jar com.digitalasset.canton.CantonEnterpriseApp
Note: These Docker images are designed to be suitable for production use, with minimal size and attack surface. Minimal images can sometimes make debugging difficult (e.g. no shell in the containers). For convenience, we provide “debug” versions of each of the above images, which you can access by appending “-debug” to the image tag (e.g. digitalasset-docker.jfrog.io/http-json:2.10.1-debug).