> For the complete documentation index, see [llms.txt](https://canopy-network.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://canopy-network.gitbook.io/docs/build/run-test-and-configure.md).

# Run, Test, and Configure

This section covers the local development loop: running the chain, writing integration tests against it, and tuning configuration values. It also documents the most common mistakes and how to avoid th

This page covers the local development loop for a Canopy application: start a node, run the Go Template, make a change, verify the result, and adjust the local environment when needed.

It uses the Go Template as the concrete example. In repository commands, `PLUGIN=go` is the current Makefile parameter for selecting that implementation. In the documentation, we refer to it as the Go Template.

A useful loop is deliberately small: make one focused change, rebuild the Template, run the relevant test, then confirm the resulting state through the node. Do not wait until an application is large before testing it against a real local chain.

### The local development loop

From the Canopy repository root, build the node and the Go Template:

```
make build/canopy
make build/plugin PLUGIN=go
```

Start the node:

```
canopy start
```

The node starts its configured Template and communicates with it over a local Unix socket. Leave this process running while you develop. Its standard output is the first place to look for startup, consensus, and Template connection errors.

After changing Template code, rebuild it before you test:

```
make build/plugin PLUGIN=go
```

Then restart the local process so the node uses the new binary. During normal development, stop the running `canopy start` process with `Ctrl+C`, then run it again.

```
canopy start
```

This explicit rebuild-and-restart loop is the most reliable default. It makes the version of the running Template unambiguous.

### Restart only the Go Template

The Go Template includes `pluginctl.sh` for cases where you need to restart the Template without restarting the entire node. This is useful when iterating on Template logic and you know the node configuration has not changed.

```
cd plugin/go

./pluginctl.sh stop
make build
./pluginctl.sh start
./pluginctl.sh status
```

The script supports `start`, `stop`, `restart`, and `status`. It writes the Go Template log to:

```
/tmp/plugin/go-plugin.log
```

Follow that log in a second terminal when you are diagnosing a connection failure or an error returned by Template code:

```
tail -f /tmp/plugin/go-plugin.log
```

Use the full node restart when you change node configuration, genesis data, protocol code, or anything that affects startup. Restarting only the Template is an iteration tool, not a substitute for a clean local verification.

### Test at three levels

A reliable application has more than one kind of test. Each level answers a different question.

| **Level**                  | **What it verifies**                                                               | **When to run it**                                             |
| -------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Compile                    | Your changes build successfully.                                                   | After every code change.                                       |
| Template integration test  | A transaction moves through the real local node, Template, RPC, and state machine. | For every new transaction type or state transition.            |
| Full repository test suite | Core protocol code and related packages still pass together.                       | Before sharing a substantial change or opening a pull request. |

The Go Template tutorial includes live integration tests. Start the local node first, then run the tutorial test target from the Go Template directory:

```
cd plugin/go
make test
```

The current target runs the Template transaction and custom RPC endpoint tests against the local chain. It has a long timeout because it waits for real block processing. A timeout is not necessarily a test failure in your logic. First confirm that the node is running, the Template is connected, and blocks are being produced.

To run the full Go repository test suite:

```
go test ./... -p=1
```

This is broader and slower. It is useful before you share changes that touch common protocol code, generated types, or more than one Template surface.

### What a good application test proves

For a custom application transaction, an end-to-end test should prove the behavior a user actually relies on. It should create or load a test account, construct and sign a transaction, submit it to the local RPC, wait for inclusion, query the resulting state, and assert the expected value.

For the guestbook example, a useful test would submit a `post_message` transaction and verify that the stored post has the expected author and content. It should also test at least one invalid case, such as empty content or content that exceeds the application limit.

The maintained [Go Template tutorial](https://github.com/canopy-network/canopy/blob/main/plugin/go/TUTORIAL.md) and its `tutorial` directory are the best starting point for this pattern. Use them as the reference for the current repository structure and helper functions rather than copying a transaction-signing flow from an unrelated project.

Keep tests deterministic. Do not make assertions that depend on wall-clock timing, the order in which unrelated transactions arrive, or state left behind by a previous test run. Give each test the setup it needs and assert only the state transition it owns.

### Read the right logs

When something does not behave as expected, narrow the problem before changing code.

If the node does not start, read the terminal where you ran `canopy start`. If the node starts but the application does not respond, check the Go Template log:

```
tail -f /tmp/plugin/go-plugin.log
```

If a transaction is accepted by the RPC but the expected state does not appear, wait for block inclusion before querying state. Then check whether the transaction was rejected before inclusion, included as failed, or processed successfully with different application logic than expected.

A practical debugging sequence is:

1. Confirm the node is running.
2. Confirm the Go Template is running with `./pluginctl.sh status`.
3. Confirm the binary was rebuilt after your latest source change.
4. Submit one reproducible transaction.
5. Check the node output and Template log.
6. Query the transaction and resulting state through the RPC.

This sequence is usually faster than adding print statements throughout the application.

### Configure your local node

Canopy reads node configuration from `config.json` in its data directory. The default local data directory is `~/.canopy`. If you start the node with `--data-dir`, use that directory instead.

For example:

```
canopy start --data-dir ~/.canopy-myapp
```

A separate data directory gives an application its own configuration, genesis files, keystore, and local state. It is the appropriate way to run more than one local chain on the same machine.

Do not replace the entire configuration file with a small JSON snippet. Edit only the values you intend to change, preserve valid JSON, and restart the node afterwards.

#### Settings most useful during application development

| Setting                    | Purpose                                                  | Development guidance                                                                                    |
| -------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `plugin`                   | Selects the Template implementation the node starts.     | Ensure it matches the implementation you built, such as `go`.                                           |
| `pluginTimeoutMS`          | Limits how long the node waits for a Template response.  | Keep the default for normal work. Raise it temporarily only while investigating a known slow operation. |
| `logLevel`                 | Sets node log verbosity.                                 | Use `debug` while diagnosing a problem, then return to `info` to keep output readable.                  |
| `rpcPort` and `adminPort`  | Set the public and administrative RPC ports.             | Change both when running multiple nodes on one machine, then update the matching RPC URLs.              |
| `rpcURL` and `adminRPCUrl` | Tell local tooling where the RPC services are available. | Keep these aligned with their respective ports.                                                         |
| `headless`                 | Disables the embedded wallet and explorer interfaces.    | Useful for an environment where you only need RPC access.                                               |

Here is a JSON fragment showing the shape of two common local changes. It is not a complete `config.json` file:

```
{
  "logLevel": "debug",
  "pluginTimeoutMS": 5000
}
```

A longer Template timeout can help diagnose a slow operation, but it should not become the default fix for inefficient logic. A Template participates in block processing, so work that is unexpectedly expensive should be measured and redesigned.

Consensus timing values should be changed cautiously. Faster local blocks can make iteration feel better, but extremely short timeouts can create misleading failures. Establish that your application works under the default local configuration before tuning block timing.

### Configuration changes require a restart

Configuration is read during node startup. After editing `config.json`, stop the node and start it again:

```
canopy start
```

If a configuration change appears to have no effect, verify that you edited the data directory used by the running process. This is especially important when you use `--data-dir` or work with more than one local chain.

### Common problems

#### My source change has no effect

The usual cause is a stale Template binary. Rebuild the Go Template, then restart it or restart the node.

```
make build/plugin PLUGIN=go
```

#### The Template is not connected

Check that the node is running, then inspect Template status and logs:

```
cd plugin/go
./pluginctl.sh status
tail -f /tmp/plugin/go-plugin.log
```

A Template connection issue is a local process problem, not an onchain application error. Resolve it before changing transaction logic.

#### A test times out

Confirm the local node and Template are both running. Then check whether blocks are being produced and whether the test is waiting for inclusion of a transaction that was rejected or failed. Run one test at a time while you diagnose the issue.

#### My RPC client cannot connect

Confirm the configured `rpcPort` and `rpcURL` agree. If you run multiple local chains, each needs its own data directory and non-conflicting ports.

#### A transaction is included but application state is unchanged

Inspect the transaction result and the Template log. The transaction may have failed during execution, or your test may be querying the wrong key or state prefix. Test both the successful state transition and the expected failure path for every new transaction type.

### Keep the loop small

The fastest way to build with confidence is to make each change easy to verify. Start with one transaction, one state transition, and one end-to-end test. Once that path is dependable, add the next capability.

Next, learn how to submit transactions and query application state through the [RPC Reference](https://canopy-network.gitbook.io/docs/app-builder/rpc-reference).
