# Configure

{% hint style="danger" %}
**Disclaimer**: Canopy is alpha-stage software. While documentation and guides are provided to assist users, they are offered without warranties, guarantees, or assurances of reliability. Users are solely responsible for any issues that may arise, including but not limited to the loss of funds. Please proceed with caution.
{% endhint %}

### Configure

The Canopy software is designed with simplicity in mind, and configuration is meant to be minimal while giving node runners the power to adapt the software to the needs of the deployers or Nested Chains.

#### Data Directory

The data directory of a Canopy node contains the application-level files that Canopy requires to function.

💡 The default location of a Canopy data directory is `$USERHOME/.canopy` or simply `~/.canopy`.

```bash
$ ls ~/.canopy

> book.json config.json keystore.json polls.json validator_key.json
  canopy/ genesis.json heap1.out heap2.out logs proposals.json

```

**Contents**

* **book.json**: The 'peer address book' of the Canopy node. This file contains addresses of 'potential peers' a node may connect to. This file is auto-populated by the P2P module of Canopy and is not meant to be manually edited, *especially while the software is running*.
* **config.json**: The configuration file of the Canopy node. All configuration is handled in this single file. This file is loaded once upon startup, modifying this file during active operation is currently safe, but changes are not reflected until the node is restarted.
* **keystore.json**: The local store of encrypted private keys that may be utilized by the pre-packaged 1) web wallet, 2) command line interface, or 3) admin RPC. Importantly, this file is not critical for Validator operation; storing the validator key in this file does not change node behavior.
* **polls.json**: This file is used to store non-critical 'on-chain' governance polling information parsed from blocks. If this file is modified or corrupted, it may lead to incorrect displays in the prepackaged web-wallet, but otherwise does not affect consensus or any other critical component of node operation.
* **validator\_key.json**: The ⚠️ plain-text **BDN** (BLS) private key of the `operator` of the node. The security model of Canopy presumes there is no unauthorized access to the server. However, due to the non-custodial design of Canopy, the `output` private key (cold / off server) is what holds custody over staked tokens and rewards. Meaning, unauthorized access to the operator key allows `unauthorized pausing`, `unauthorized unstaking`, or P2P spoofing as a Validator, but does not copromise staked funds or rewards. As a result, little to no funds should be kept in the operator address.
* **canopy/**: The nested directory where the [badgerDB](https://github.com/hypermodeinc/badger) blockchain data is stored. Conveniently, Canopy includes data of transactions, blocks, state, and sparse merkle tree in a single database. Writes to the database are guarenteed to be atomic by badger so corruption events should be minimal, if any. Live snapshotting this data while the software is running is not officially supported, but `rsync` (or similar) may be used to quickly copy data across servers, if needed, when the software is stopped. If provided a snapshot **from a trusted party**, this is likely the directory that should be replaced.
* **genesis.json**: The JSON-encoded version of the starting state of the blockchain. This file is interpreted and injected into the database by the software - allowing an 'agreed upon' starting point of the blockchain. Testnet, Mainnet, Canarynet and other Nested Chains will all have unique genesis files. If `invalid block hash` or similar error logs are seen when syncing `height 1` - it's often due to an incorrect genesis.json file or incorrect `chain_id` configuration.
* **heap1.out / heap2.out**: Debug memory profiling files are generated automatically. Heap1 is created at startup, and Heap2 is replaced every 10 seconds. These files will likely be removed in the future, but allow the development team to easily debug OOM situations. These files are overwritten at restart, so save them accordingly.
* **logs/**: the sub-directory of gzipped logs. Logs are automatically directed to stdout, the web wallet, and the admin RPC, and are saved in this directory. While the Canopy software auto-rotates and compresses logs, this directory should be periodically monitored for uncontrolled growth (especially during alpha and beta phases). Inclusion of the appropriate gzipped log file or log output is often a minimum requirement for debugging requests.
* **proposals.json**: the local voting configuration of the Canopy node for governance proposals. This file is only applicable to active Validators, as it configures a Validator to allow a proposal transaction to be included in a block (or not). This file is not meant to be manually edited, especially while the software is running. This file may be safely edited using the prepackaged web wallet under the *governance* section.

#### Config.json

Configuration of a **Canopy Validator** is handled using a single **config.json** file.

➩ The `config.json` file is located in the `data directory` (default \~/.canopy) of the Canopy node and is loaded once upon startup.

This file is able to be edited during software operation, but requires a restart to apply any changes.

```json
{
  "logLevel": "debug",
  "chainId": 1,
  "sleepUntil": 0,
  "rootChain": [
    {
      "chainId": 1,
      "url": "http://localhost:50002"
    },
    {
      "chainId": 2,
      "url": "http://localhost:40002"
    }
  ],
  "runVDF": true,
  "headless": false,
  "walletPort": "50000",
  "explorerPort": "50001",
  "rpcPort": "50002",
  "adminPort": "50003",
  "rpcURL": "http://localhost:50002",
  "adminRPCUrl": "http://localhost:50003",
  "rootChainPollMS": 333,
  "timeoutS": 3,
  "dataDirPath": "/root/.canopy",
  "dbName": "canopy",
  "inMemory": false,
  "networkID": 1,
  "listenAddress": "0.0.0.0:9001",
  "externalAddress": "tcp://canopy-rocks.io",
  "maxInbound": 21,
  "maxOutbound": 7,
  "trutedPeersIDs": null,
  "dialPeers": ["def02e9b054428f198e89179685a48b227f1c189966d4db002f24f8155c5119c
  bb9387146889b5dc4a260184f20d5ecd@tcp://canopy-does-rock.io:9001"],
  "bannedPeersIDs": null,
  "bannedIPs": null,
  "electionTimeoutMS": 200,
  "electionVoteTimeoutMS": 200,
  "proposeTimeoutMS": 1000,
  "proposeVoteTimeoutMS": 1000,
  "precommitTimeoutMS": 200,
  "precommitVoteTimeoutMS": 200,
  "commitTimeoutMS": 200,
  "roundInterruptTimeoutMS": 0,
  "maxTotalBytes": 10000000,
  "maxTransactionCount": 5000,
  "individualMaxTxSize": 4000,
  "dropPercentage": 35
}

```

**logLevel:**

Configures the level of specificity in logs

* DEBUG: (color: BLUE | highest specificity), good for checkout out issues
* INFO: (color: GREEN | medium specificity), good for most use-cases
* WARN: (color: YELLOW | low specificity), only outputs potential problems
* ERROR: (color: RED | minimum specificity), only outputs software issues

**chainId:**

The unique identifier of the chain (1=CNPY, 2=CNRY, etc) within a network

* 1: CNPY
* 2: CNRY

{% hint style="info" %}
**Chain ID** is 1 tier below the **Network ID**. Network ID is `mainnet` or `testnet` whereas `chainId` is the sovereign chain within the network (like CNPY or CNRY). This allows for future-proof partitions of chain IDs.
{% endhint %}

{% hint style="warning" %}
An incorrect `chainId` may result in the inability to connect to peers, sync, or error output like `unequal block-hash`.
{% endhint %}

**sleepUntil:**

A Unix timestamp (in microseconds) that instructs the software to pause execution until the specified time. This allows validators to coordinate and begin operation simultaneously, useful for restarting networks or synchronizing genesis events.

**rootChain**

An array of `chainId | url` objects that specify the RPC endpoint of the root chain.

The **root chain** is a fundamental part of the Canopy architecture. It defines the validator set and provides critical information needed for a chain to operate as a validator.

{% hint style="success" %}
The root chain plays a central role in Canopy’s recursive architecture, essential to understanding how Canopy enables scalable and modular Web3 infrastructure. Refer to the documentation (start with [Core Features](/docs/canopy-network/core-features.md)) for deeper context.
{% endhint %}

For simplicity, you can think of the root chain as the "parent" chain responsible for:

* Determining the active validator set
* Providing configuration and coordination data
* Serving as the chain where validators stake to participate in consensus for nested chains

{% hint style="info" %}
A chain may designate **itself** as its root chain. This is known as **chain independence**.
{% endhint %}

**Validators stake on the root chain** to perform consensus operations for nested chains. They may also stake on nested chains to be "on-deck" for future independence, though this currently plays a more economic/preparatory role.

The Canopy software connects to the root chain over **WebSockets** using an upgraded **JSON-RPC** protocol, enabling fast and reliable access to validator-critical information.

**Best Practices for a root chain RPC node:**

* Must be **trusted**
* Should have **low latency**

Although the field accepts an array, **only one root chain is active at a time**. The array allows for:

* Seamless **root switching**
* Future **graduation to independence**

**runVDF:**

Boolean to enable or disable the **proof-of-age** verifiable delay function. As a Validator of a root chain, this should be `true`.

If the `Nested Chain` relies on some other fork-choice mechanism (like Checkpointing) then this may be disabled.

**headless:**

Disable the pre-packaged web wallet and block explorer of the Canopy software. This is useful for those who utilize the CLI only for operation - though it is encouraged for production deployments to use the front ends provided.

**walletPort:**

The rpcURL:**port** where the pre-packaged web wallet is hosted by the sofware.

View it in browser, behind a reverse proxy is recommended

Default: `50000`

**explorerPort:**

The rpcURL:**port** where the pre-packaged block explorer is hosted by the sofware.

View it in browser, behind a reverse proxy is recommended

Default: `50001`

**rpcPort:**

The rpcURL:**port** where the JSON RPC API is hosted by the software.

See the *JSON RPC Specification* for more details.

Default: `50002`

**adminPort**

The rpcURL:**port** where the administrator JSON RPC API is hosted by the software

See the *JSON RPC Specification* for more details.

Default: `50003`

**rpcURL**

The url where the RPC is hosted by the software. This URL is utilized by the prepackaged web wallet and block explorer to connect to the local node.

Default: <http://localhost>

**adminRPCURL**

The url where the admin RPC is hosted by the software. This URL is utilized by the prepackaged web wallet to connect to the local node.

Default: <http://localhost>

⚠️ **HTTPS is required for production as passwords are sent plain-text**

**timeoutS**

The RPC request timeout duration in seconds.

Default: `3`

**dataDirPath**

The path of the data directory - default is `$USERHOME/.canopy`

> NOTE: Datadirectory path is expiremental and requires the `--data-dir=<PATH>` flag as the software doesn't know where to look for the config.json file.

**dbName**

Modify the name of the database folder inside the data directory.

Changing between software runs will create a brand new database from scratch, resulting in a resync.

Default: `canopy`

**inMemory**

Debug only: run the blockchain database completely in memory and don't persist anything to disk

**networkID**

The unique identifier of the network (1=MAINNET, 2=TESTNET, etc). Each network has many chainIds within it.

* 1: mainnet
* 2:testnet

> NOTE: **chain id** is 1 tier below **network id**. Network ID is `mainnet` or `testnet` whereas `chainId` is the sovereign chains within the network (like CNPY or CNRY). This allows for future proof partitions of chain ids.

💡 An incorrect `networkId` may result in the inability to connect to peers, sync, or error output like `unequal block-hash`.

**listenAddress**

The TCP listening address for the peer-to-peer module.

**Importantly, the port must correspond with the `chainId` with the following formula:**

`:9000 + chainId`

This enables multi-committee setups under a single `netURL`

Default for CNPY: `0.0.0.0:9001`

**externalAddress**

The TCP URL where peers may discover this node. This URL is displayed within peer's address book and is exchanged with PEX events.

➪ This must be configured or no inbound peers will ever be able to be established.

Example: tcp\://canopy-rocks.io (which firewall maps to the listenAddress)

**maxInbound**

The upper bound of inbound peers (peers that dialed this node)

* The **minimum** appropriate ratio of inbound:outbound is 3:1. 4:1 or 5:1 is even healthier for the network.

Default: `21`

**maxOutbound**

The upper bound of outbound peers (peers that this node dials)

* The **minimum** appropriate ratio of inbound:outbound is 3:1. 4:1 or 5:1 is even healthier for the network.

Default: `7`

**trutedPeersIDs**

A string array of `hex-encoded` public keys that will be allowed to surpass limits and will never be dropped due to a bad peer reputation.

Example: `["def02e9b054428f198e89179685a48b227f1c189966d4db002f24f8155c5119c bb9387146889b5dc4a260184f20d5ecd"]`

**dialPeers**

A string array of peers to dial with exponential backoff upon startup.

Format is `publicKey@externalAddress`

Example: `["def02e9b054428f198e89179685a48b227f1c189966d4db002f24f8155c5119c bb9387146889b5dc4a260184f20d5ecd@tcp://canopy-rocks.io"]`

**bannedPeersIDs**

A string array of `hex-encoded` public keys that will not be allowed to connect to this node.

Example: `["def02e9b054428f198e89179685a48b227f1c189966d4db002f24f8155c5119c bb9387146889b5dc4a260184f20d5ecd"]`

**bannedIPs**

A string array of `IPV4 addresses` that will not be allowed to connect to this node.

Example: `["8.8.8.8"]`

**newHeightTimeoutMS**

The amount of time in milliseconds wait taken after starting a new height. This allows processing like `Committing` the previous quorum certificate to storage.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**electionTimeoutMS**

The amount of time in milliseconds wait taken after starting the election phase. This allows time for Validators to annouce themselves as leader candidates.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**electionVoteTimeoutMS**

The amount of time in milliseconds wait taken after starting the election vote phase. This allows time for replicas to vote for who they believe is the leader.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**proposeTimeoutMS**

The amount of time in milliseconds wait taken after starting the propose phase. This allows time for the leader to create and send a block proposal.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**proposeVoteTimeoutMS**

The amount of time in milliseconds wait taken after starting the propose vote phase. This allows time for replicas to vote on the leaders' proposal.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**precommitTimeoutMS**

The amount of time in milliseconds wait taken after starting the precommit phase. This allows time for the leader to send a proof of proposal approval to the replicas.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**precommitVoteTimeoutMS**

The amount of time in milliseconds wait taken after starting the precommit vote phase. This allows time for the replicas time to vote on the proof of proposal approval.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**commitTimeoutMS**

The amount of time in milliseconds wait taken after starting the commit phase. This allows time for the leader to communicate the 'commit' command to replicas.

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**roundInterruptTimeoutMS (deprecated)**

Round interrupt now relies on`msLeftInRound`

{% hint style="warning" %}
This value should not be modified once a genesis event takes place. It determines block timing
{% endhint %}

**maxTotalBytes**

The total amount of bytes allowed in the unconfirmed transaction memory pool (mempool)

{% hint style="info" %}
5-10x block size recommended as a minimum
{% endhint %}

**maxTransactionCount**

The maximum count of individual transactions allowed in the unconfirmed transaction memory pool (mempool)

**individualMaxTxSize**

The maximum number of bytes allowed in an individual transaction in the unconfirmed transaction memory pool (mempool)

**dropPercentage**

The percentage of unconfirmed transaction memory pool (mempool) that is dropped when the mempool overflows. Lowest fee transactions dropped first

**prometheusAddress**

The address of prometheus metric collection

Default: `0.0.0.0:9090`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://canopy-network.gitbook.io/docs/secure-canopy/node-runner/configure.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
