# Canton Console¶

Canton offers a console (REPL) where entities can be dynamically started and stopped, and a variety of administrative or debugging commands can be run.

All console commands must be valid Scala (the console is built on Ammonite - a Scala based scripting and REPL framework). Note that we also define a set of implicit type conversions to improve the console usability: notably, whenever a console command requires a DomainAlias, Fingerprint or Identifier, you can instead also call it with a String which will be automatically converted to the correct type (i.e., you can, e.g., write participant1.domains.get_agreement("domain1") instead of participant1.domains.get_agreement(DomainAlias.tryCreate("domain1"))).

The examples/ sub-directories contain some sample scripts, with the extension .canton.

Commands are organised by thematic groups. Some commands also need to be explicitly turned on via configuration directives to be accessible.

Some operations are available on both types of nodes, whereas some operations are specific to either participant or domain nodes. For consistency, we organise the manual by node type, which means that some commands will appear twice. However, the detailed explanations are only given within the participant documentation.

## Node References¶

To issue the command on a particular node, you must refer to it via its reference, which is a Scala variable. Named variables are created for all domain entities and participants using their configured identifiers. For example the sample examples/01-simple-topology/simple-topology.conf configuration file references the domain mydomain, and participants participant1 and participant2. These are available in the console as mydomain, participant1 and participant2. Additionally, the console provides the following generic references.

mydomain

Manage local domain 'mydomain'; type 'mydomain help' or 'mydomain help("<methodName>")' for more help

participant1

Manage participant 'participant1'; type 'participant1 help' or 'participant1 help("<methodName>")' for more help

participant2

Manage participant 'participant2'; type 'participant2 help' or 'participant2 help("<methodName>")' for more help

domains

All domain nodes

mediators

All mediator nodes

nodes

All nodes

participants

All participant nodes

sequencers

All sequencer nodes

## Help¶

Canton can be very helpful if you ask for help. Try to type

help


or

participant1.help()


to get an overview of the commands and command groups that exist. help() works on every level (e.g. participant1.domains.help()) or can be used to search for particular functions (help(“list”)) or to get detailed help explanation for each command (participant1.parties.help(“list”)).

## Lifecycle Operations¶

These are supported by individual and sequences of domains and participants. If called on a sequence, operations will be called sequentially in the order of the sequence. For example:

nodes.local start


can be used to start all configured local domains and participants.

If the node is running with database persistence, it will support the database migration command (db.migrate). The migrations are performed automatically when the node is started for the first time. However, new migrations added as part of new versions of the software must be run manually using the command. While we technically support upgradability of the database, we are currently not testing it and are performing breaking changes on every minor release until we hit the beta stage.

Notice that the domain, sequencer and mediator nodes might need extra setup to be fully functional. Check domain bootstrapping for more details.

## Other Top-level Commands¶

The following commands are available for convenience:

exit

Leave the console

help

Help with console commands; type help("<command>") for detailed help for <command>

health.dump

Generate and write a dump of Canton's state for a bug report

Return type

String
health.help

Arguments:

• methodName: String
health.status

Aggregate status info of all participants and domains

Return type

com.digitalasset.canton.admin.api.client.data.CantonStatus
console.command_timeout

Yields the timeout for running console commands

Return type

scala.concurrent.duration.Duration

Yields the timeout for running console commands. When the timeout has elapsed, the console stops waiting for the command result. The command will continue running in the background.

console.help

Arguments:

• methodName: String
console.set_command_timeout

Sets the timeout for running console commands.

Arguments:

• newTimeout: scala.concurrent.duration.Duration

Sets the timeout for running console commands. When the timeout has elapsed, the console stops waiting for the command result. The command will continue running in the background. The new timeout must be positive.

logging.help

Arguments:

• methodName: String
logging.set_level

Dynamically change log level (TRACE, DEBUG, INFO, WARN, ERROR, OFF)

Arguments:

• loggerName: String
• level: String
utils.auto_close

(Testing) Register AutoCloseable object to be shutdown if Canton is shut down

Arguments:

• closeable: AutoCloseable
utils.contract_data_to_instance

Convert contract data to a contract instance.

Arguments:

Return type

com.digitalasset.canton.protocol.SerializableContract

The utils.contract_data_to_instance bridges the gap between participant.ledger_api.acs commands that return various pieces of "contract data" and the participant.repair.add command used to add "contract instances" as part of repair workflows. Such workflows (for example migrating contracts from other Daml ledgers to Canton participants) typically consist of extracting contract data using participant.ledger_api.acs commands, modifying the contract data, and then converting the contractData using this function before finally adding the resulting contract instances to Canton participants via participant.repair.add. Obtain the contractData by invoking .toContractData on the WrappedCreatedEvent returned by the corresponding participant.ledger_api.acs.of_party or of_all call. The ledgerTime parameter should be chosen to be a time meaningful to the domain on which you plan to subsequently invoke participant.repair.add on and will be retained alongside the contract instance by the participant.repair.add invocation.

utils.contract_instance_to_data

Convert a contract instance to contract data.

Arguments:

Return type

com.digitalasset.canton.admin.api.client.commands.LedgerApiTypeWrappers.ContractData

The utils.contract_instance_to_data converts a Canton "contract instance" to "contract data", a format more amenable to inspection and modification as part of repair workflows. This function consumes the output of the participant.testing commands and can thus be employed in workflows geared at verifying the contents of contracts for diagnostic purposes and in environments in which the "features.enable-testing-commands" configuration can be (at least temporarily) enabled.

utils.generate_daml_script_participants_conf

Create a participants config for Daml script

Arguments:

Return type

java.io.File

The generated config can be passed to daml script via the participant-config parameter. More information about the file format can be found in the documentation: https://docs.daml.com/daml-script/index.html#using-daml-script-in-distributed-topologies

utils.generate_navigator_conf

Create a navigator ui-backend.conf for a participant

Arguments:

Return type

java.io.File
utils.help

Arguments:

• methodName: String
utils.object_args

Reflective inspection of object arguments, handy to inspect case class objects

Arguments:

• obj: T

Return type

List[String]

Return the list field names of the given object. Helpful function when inspecting the return result.

utils.retry_until_true

Wait for a condition to become true

Arguments:

• timeout: java.time.Duration
• maxWaitPeriod: java.time.Duration
• condition: => Boolean
• failure: => String

Return type

(condition: => Boolean, failure: => String): Unit
utils.type_args

Reflective inspection of type arguments, handy to inspect case class types

Return type

List[String]

Return the list of field names of the given type. Helpful function when creating new objects for requests.

ledger_api_utils.create

Build create command

Arguments:

• packageId: String
• module: String
• template: String
• arguments: Map[String,Any]

Return type

com.daml.ledger.api.v1.commands.Command
ledger_api_utils.exercise

Build exercise command from CreatedEvent

Arguments:

• choice: String
• arguments: Map[String,Any]
• event: com.daml.ledger.api.v1.event.CreatedEvent

Return type

com.daml.ledger.api.v1.commands.Command
ledger_api_utils.exercise

Build exercise command

Arguments:

• packageId: String
• module: String
• template: String
• choice: String
• arguments: Map[String,Any]
• contractId: String

Return type

com.daml.ledger.api.v1.commands.Command
ledger_api_utils.help

Arguments:

• methodName: String

## Participant Commands¶

config

Return participant config

Return type

com.digitalasset.canton.participant.config.LocalParticipantConfig
help

Arguments:

• methodName: String
id

Yields the globally unique id of this participant. Throws an exception, if the id has not yet been allocated (e.g., the participant has not yet been started).

Return type

com.digitalasset.canton.identity.ParticipantId
is_initialized

Check if the local instance is running and is fully initialized

Return type

Boolean
is_running

Check if the local instance is running

Return type

Boolean
start

Start the instance

stop

Stop the instance

testing.acs_search

(Testing) Lookup of active contracts

Arguments:

Return type

List[com.digitalasset.canton.protocol.SerializableContract]
testing.await_heartbeat

(Testing) Wait for a heartbeat on the given domain with a timestamp greater than or equal to the given timestamp

Arguments:

testing.bong

(Testing) Send a bong to a set of target parties over the ledger. Levels > 0 leads to an exploding ping with exponential number of contracts. Throw a RuntimeException in case of failure.

Arguments:

Return type

scala.concurrent.duration.Duration

initiate a racy ping to multiple participants, measuring the roundtrip time of the fasted responder, with an optional timeout. Grace-period is the time the bong will wait for a duplicate spent (which would indicate an error in the system) before exiting. If levels > 0, the ping command will lead to a binary explosion and subsequent dilation of contracts, where level determines the number of levels we will explode. As a result, the system will create (2^(L+2) - 3) contracts (where L stands for level). Normally, only the initiator is a validator. Additional validators can be added using the validators argument. The bong command comes handy to run a burst test against the system, leading quickly to an overloading state.

testing.crypto_api

(Testing) Return the sync crypto api provider, which provides access to all cryptographic methods

Return type

com.digitalasset.canton.crypto.SyncCryptoApiProvider
testing.event_search

(Testing) Lookup of events

Arguments:

Return type

Seq[(String, com.digitalasset.canton.participant.sync.TimestampedEvent)]

Show the event logs. To select only events from a particular domain, use the domain alias. Leave the domain blank to search the combined event log containing the events of all domains. Note that if the domain is left blank, the values of from and to cannot be set. This is because the combined event log isn't guaranteed to have increasing timestamps.

testing.find_clean_commitments_timestamp

(Testing) The latest timestamp before or at the given one for which no commitment is outstanding

Arguments:

Return type

Option[com.digitalasset.canton.data.CantonTimestamp]

The latest timestamp before or at the given one for which no commitment is outstanding. Note that this doesn't imply that pruning is possible at this timestamp, as the system might require some additional data for crash recovery. Thus, this is useful for testing commitments; use the commands in the pruning group for pruning. Additionally, the result needn't fall on a "commitment tick" as specified by the reconciliation interval.

testing.help

Arguments:

• methodName: String
testing.maybe_bong

(Testing) Like bong, but returns None in case of failure.

Arguments:

Return type

Option[scala.concurrent.duration.Duration]
testing.pcs_search

(Testing) Lookup contracts in the Private Contract Store

Arguments:

Return type

List[(Boolean, com.digitalasset.canton.protocol.SerializableContract)]

Get raw access to the PCS of the given domain sync controller. The filter commands will check if the target value contains the given string. The arguments can be started with ^ such that startsWith is used for comparison or ! to use equals. The activeSet argument allows to restrict the search to the active contract set.

testing.sequencer_messages

(Testing) Retrieve all sequencer messages

Arguments:

Return type

Option[Iterable[com.digitalasset.canton.sequencing.SignedSequencedEvent[com.digitalasset.canton.protocol.messages.DefaultOpenEnvelope]]]

Optionally allows filtering for sequencer from a certain time span (inclusive on both ends) and limiting the number of displayed messages. The returned messages will be ordered on most domain ledger implementations if a time span is given.

testing.state_inspection

Return type

com.digitalasset.canton.participant.admin.SyncStateInspection

The state inspection methods can fatally and permanently corrupt the state of a participant. The API is subject to change in any way.

testing.transaction_search

(Testing) Lookup of accepted transactions

Arguments:

Return type

Seq[(String, com.digitalasset.canton.protocol.LfCommittedTransaction)]

Show the accepted transactions as they appear in the event logs. To select only transactions from a particular domain, use the domain alias. Leave the domain blank to search the combined event log containing the events of all domains. Note that if the domain is left blank, the values of from and to cannot be set. This is because the combined event log isn't guaranteed to have increasing timestamps.

### Database¶

db.help

Arguments:

• methodName: String
db.migrate

Migrates the instance's database if using a database storage

### Health¶

health.help

Arguments:

• methodName: String
health.initialized

Returns true if node has been initialized.

Return type

Boolean
health.maybe_ping

(Testing) Sends a ping to the target participant over the ledger. Yields Some(duration) in case of success and None in case of failure.

Arguments:

Return type

Option[scala.concurrent.duration.Duration]
health.ping

Sends a ping to the target participant over the ledger. Yields the duration in case of success and throws a RuntimeException in case of failure.

Arguments:

Return type

scala.concurrent.duration.Duration
health.running

Check if the node is running

Return type

Boolean
health.status

Get human (and machine) readable status info

Return type

com.digitalasset.canton.health.admin.data.NodeStatus[S]
health.wait_for_initialized

Wait for the node to be initialized

health.wait_for_running

Wait for the node to be running

### Domain Connectivity¶

domains.accept_agreement

Accept the service agreement of the given domain alias

Arguments:

• domainAlias: String
• agreementId: String
domains.active

(Testing) Test whether a participant is connected to and permissioned on a domain reference

Arguments:

Return type

Boolean
domains.active

Test whether a participant is connected to and permissioned on a domain

Arguments:

Return type

Boolean
domains.config

Returns the current configuration of a given domain

Arguments:

Return type

Option[com.digitalasset.canton.participant.domain.DomainConnectionConfig]
domains.connect

Macro to connect a participant to a domain given by connection

Arguments:

Return type

com.digitalasset.canton.participant.domain.DomainConnectionConfig

The connect macro performs a series of commands in order to connect this participant to a domain. First, register will be invoked with the given arguments, but first registered with manualConnect = true. If you already set manualConnect = true, then nothing else will happen and you will have to do the remaining steps yourselves. Otherwise, if the domain requires an agreement, it is fetched and presented to the user for evaluation. If the user is fine with it, the agreement is confirmed. If you want to auto-confirm, then set the environment variable CANTON_AUTO_APPROVE_AGREEMENTS=yes. Finally, the command will invoke reconnect to startup the connection. If the reconnect succeeded, the registered configuration will be updated with manualStart = true. If anything fails, the domain will remain registered with manualConnect = true and you will have to perform these steps manually. The arguments are: domainAlias - The name you will be using to refer to this domain. Can not be changed anymore. connection - The connection string to connect to this domain. I.e. https://url:port manualConnect - Whether this connection should be handled manually and also excluded from automatic re-connect. domainId - Optionally the domainId you expect to see on this domain. certificatesPath - Path to TLS certificate files to use as a trust anchor. priority - The priority of the domain. The higher the more likely a domain will be used.

domains.connect

Macro to connect a participant to a domain given by connection

Arguments:

This variant of connect expects a domain connection config. Otherwise the behaviour is equivalent to the connect command with explicit arguments.

domains.connect_ha

Macro to connect a participant to a domain that supports connecting via many endpoints

Arguments:

• domainAlias: String
• firstConnection: String
• additionalConnections: String*

Return type

com.digitalasset.canton.participant.domain.DomainConnectionConfig

Domains can provide many endpoints to connect to for availability and performance benefits. This version of connect allows specifying multiple endpoints for a single domain connection: connect_ha("mydomain", "https://host1.mydomain.net", "https://host2.mydomain.net", "https://host3.mydomain.net") To create a more advanced connection config use domains.toConfig with a single host, then use config.addConnection to add additional connections before connecting: config = myparticipaint.domains.toConfig("mydomain", "https://host1.mydomain.net", ...otherArguments) config = config.addConnection("https://host2.mydomain.net", "https://host3.mydomain.net") myparticipant.domains.connect(config)

domains.connect_local

Macro to connect a participant to a locally configured domain given by reference

Arguments:

domains.disconnect

Disconnect this participant from the given domain

Arguments:

domains.get_agreement

Get the service agreement of the given domain alias and if it has been accepted already.

Arguments:

Return type

Option[(com.digitalasset.canton.participant.admin.v0.Agreement, Boolean)]
domains.help

Arguments:

• methodName: String
domains.id_of

Returns the id of the given domain alias

Arguments:

Return type

com.digitalasset.canton.DomainId
domains.is_connected

(Testing) Test whether a participant is connected to a domain reference

Arguments:

Return type

Boolean
domains.list_connected

List the connected domains of this participant

Return type

Seq[(com.digitalasset.canton.DomainAlias, com.digitalasset.canton.DomainId)]
domains.list_registered

List the configured domains of this participant

Return type

Seq[(com.digitalasset.canton.participant.domain.DomainConnectionConfig, Boolean)]
domains.modify

Modify existing domain connection

Arguments:

domains.reconnect

Reconnect this participant to all domains which are not marked as manual start

domains.reconnect

Connect this participant to the given domain

Arguments:

domains.register

Register new domain connection

Arguments:

### Packages¶

packages.find

Find packages that contain a module with the given name

Arguments:

• moduleName: String

Return type

Seq[com.digitalasset.canton.participant.admin.v0.PackageDescription]
packages.help

Arguments:

• methodName: String
packages.list

List packages stored on the participant

Arguments:

• limit: Option[Int]

Return type

Seq[com.digitalasset.canton.participant.admin.v0.PackageDescription]

If a limit is given, only up to limit packages are returned.

packages.list_contents

List package contents

Arguments:

• packageId: String

Return type

Seq[com.digitalasset.canton.participant.admin.v0.ModuleDescription]
packages.synchronize_vetting

Ensure that all vetting transactions issued by this participant have been observed by all configured participants

Arguments:

• timeout: scala.concurrent.duration.FiniteDuration

Sometimes, when scripting tests and demos, a dar or package is uploaded and we need to ensure that commands are only submitted once the package vetting has been observed by some other connected participant known to the console. This command can be used in such cases.

### DAR Management¶

Downloads the DAR file with the given hash to the given directory

Arguments:

• darHash: String
• directory: String
dars.help

Arguments:

• methodName: String
dars.list

List installed DAR files

Arguments:

• limit: Option[Int]

Return type

Seq[com.digitalasset.canton.participant.admin.v0.DarDescription]

Arguments:

• path: String
• vetAllPackages: Boolean
• synchronizeVetting: Boolean

Return type

String

### How do I read or write ByteString’s from or to a file?¶

• Canton uses Protobuf for serialization and de-serialization and we dump serialized binary data into ByteString. In some cases you need to read or write byte strings from or to a file. For convenience, you can use com.digitalasset.canton.util.BinaryFileUtil.writeByteStringToFile(outputFile: String, bytes: ByteString) and the corresponding readByteStringFromFile(inputFile: String) in your console script.