From 754e978db4b1fc0c4a68476de23d913efbf49090 Mon Sep 17 00:00:00 2001 From: PabloMansanet Date: Mon, 30 Mar 2026 12:57:25 +0200 Subject: [PATCH 1/5] Update solana readmes --- chains/solana/README.md | 91 ++++++++++++++++++++++----- chains/solana/contracts/README.md | 100 ++++++++++++------------------ 2 files changed, 115 insertions(+), 76 deletions(-) diff --git a/chains/solana/README.md b/chains/solana/README.md index 289fdec8e4..ecedb37e8e 100644 --- a/chains/solana/README.md +++ b/chains/solana/README.md @@ -1,28 +1,89 @@ # CCIP Solana Onchain -- `contracts`: solana programs (rust) + tests (go) built on the anchor framework -- `gobindings`: auto-generated go bindings for contracts using `anchor-go` -- `scripts`: various scripts for generating artifacts +## Project Structure + +- `contracts/` — Solana programs (Rust/Anchor) + integration tests (Go) + - `programs/` — Anchor program source code (ccip-router, fee-quoter, token pools, mcm, timelock, etc.) + - `tests/` — Go integration tests organized by area (`ccip/`, `mcms/`, `examples/`) + - `target/deploy/` — compiled `.so` program binaries and IDL JSON files + - `target/vendor/` — pre-built third-party program binaries (CCTP), committed to git +- `gobindings/` — auto-generated Go bindings for contracts using `anchor-go` +- `scripts/` — build and generation scripts (e.g. `anchor-go-gen.sh`) +- `utils/` — shared Go utility libraries ## Dependencies -- rust: https://www.rust-lang.org/tools/install -- go: https://go.dev/doc/install -- solana: https://docs.anza.xyz/cli/install -- anchor: https://www.anchor-lang.com/docs/installation +- [Rust](https://www.rust-lang.org/tools/install) +- [Go](https://go.dev/doc/install) (see `go.mod` for required version) +- [Solana CLI](https://docs.anza.xyz/cli/install) (provides `solana-test-validator`) +- [Anchor CLI](https://www.anchor-lang.com/docs/installation) +- [anchor-go](https://github.com/gagliardetto/anchor-go) v1.0.0 — `go install github.com/gagliardetto/anchor-go@v1.0.0` +- [golangci-lint](https://golangci-lint.run/welcome/install/) — for `make lint-go` +- [gotestloghelper](https://github.com/smartcontractkit/chainlink-testing-framework) — for `make go-tests` output formatting + +### macOS (Apple Silicon) Note + +The `solana-test-validator` requires GNU tar. Without it, you'll see errors like +`Archive error: extra entry found: "._genesis.bin"`. Install it and put it on your PATH: + +```bash +brew install gnu-tar +export PATH="/opt/homebrew/opt/gnu-tar/libexec/gnubin:$PATH" +``` + +See [solana-labs/solana#35629](https://github.com/solana-labs/solana/issues/35629) for details. ## Development +### Build contracts + +```bash +# Build on the host (requires Anchor CLI + Solana CLI + Rust toolchain) +make build-contracts + +# Or build inside Docker for reproducibility +make docker-build-contracts +``` + +### Generate Go bindings + +After any contract changes, regenerate the Go bindings: + ```bash -# install anchor-go if needed -go install github.com/gagliardetto/anchor-go@v0.2.3 +make anchor-go-gen +``` + +This builds the contracts, then runs `anchor-go` against the IDL files to produce bindings in `gobindings/`. + +### Run tests + +```bash +# Go integration tests (spins up local solana-test-validator per test) +make go-tests + +# Rust unit tests +make rust-tests + +# Run a specific test suite +go test ./contracts/tests/ccip/ -run TestCCIPRouter -v -count=1 +go test ./contracts/tests/mcms/ -run TestMcmSetConfig -v -count=1 +go test ./contracts/tests/examples/ -run TestBaseTokenPoolHappyPath -v -count=1 +``` -# build contracts + IDL -anchor build +Note: Go integration tests require that contracts have been built (`make build-contracts`) +and that the vendor `.so` files exist in `contracts/target/vendor/`. -# go bindings need to be regenerated if contract changes were made -./scripts/anchor-go-gen.sh +### Format and lint -# test contracts -go test ./... -v -count=1 -failfast +```bash +make format # format Go + Rust +make lint-go # run golangci-lint ``` + +### Full CI check + +```bash +make solana-checks +``` + +This runs, in order: `clippy`, `anchor-go-gen`, `format`, `gomodtidy`, `lint-go`, `rust-tests`, `go-tests`, `build-contracts`. diff --git a/chains/solana/contracts/README.md b/chains/solana/contracts/README.md index 09242816ee..8774296f9f 100644 --- a/chains/solana/contracts/README.md +++ b/chains/solana/contracts/README.md @@ -1,97 +1,75 @@ -# Chainlink Solana contracts (programs) +# Chainlink Solana Contracts (Programs) ## Prerequisites -Install Rust, Solana & Anchor. See https://solana.com/docs/intro/installation +- [Rust](https://www.rust-lang.org/tools/install) +- [Solana CLI](https://docs.anza.xyz/cli/install) (provides `solana-test-validator`) +- [Anchor CLI](https://www.anchor-lang.com/docs/installation) +- [Go](https://go.dev/doc/install) (see `go.mod` for required version) +- [anchor-go](https://github.com/gagliardetto/anchor-go) v1.0.0 — `go install github.com/gagliardetto/anchor-go@v1.0.0` ## Build To build on the host: -``` +```bash anchor build +# or from the repo root: +make build-contracts ``` -To build inside a docker environment: +To build inside a Docker environment (reproducible builds): ```bash -anchor build --verifiable +make docker-build-contracts ``` -To build for a specific network, specify via a cargo feature: +## Test + +### Rust unit tests ```bash -anchor build -- --features mainnet +cargo test +# or from the repo root: +make rust-tests ``` -Available networks with declared IDs: - -- mainnet -- testnet -- devnet -- localnet (default) +### Go integration tests -## Test +The Go tests spin up a local `solana-test-validator`, deploy the compiled programs, and run +integration tests against them. -Make sure to run `pnpm i` to fetch mocha and other test dependencies. +Prerequisites: -Start a dockerized shell that contains Solana and Anchor: +- `solana-test-validator` installed and on your PATH +- Contracts built (`anchor build` or `make build-contracts`) +- Vendor programs present in `target/vendor/` (pre-built CCTP `.so` files, committed to git) ```bash -./scripts/anchor-shell.sh +# from the repo root: +make go-tests ``` -Next, generate a keypair for anchor: +To run specific test suites: ```bash -solana-keygen new -o id.json +go test ./tests/ccip/ -run TestCCIPRouter -v -count=1 +go test ./tests/mcms/ -run TestMcmSetConfig -v -count=1 +go test ./tests/examples/ -run TestBaseTokenPoolHappyPath -v -count=1 ``` -### Run anchor TypeScript tests (automatically tests against a local node) +Note: subtests within a single top-level `Test*` function share sequential state, so running +an individual subtest in isolation (e.g. `-run TestCCIPRouter/Config`) will likely fail because +earlier setup subtests won't have executed. -```bash -anchor test -``` - -### Run GoLang tests (automatically tests against a local node) +## Go bindings generation -Pre-requisites: - -- Have the `solana-test-validator` command installed -- Run `anchor build` if there have been any changes to the program under test. +Install `anchor-go` and regenerate bindings after contract changes: ```bash -make contracts-go-tests +go install github.com/gagliardetto/anchor-go@v1.0.0 +make anchor-go-gen ``` -#### `anchor-go` bindings generation - -Install `https://github.com/gagliardetto/anchor-go` - -Current version: [v0.2.3](https://github.com/gagliardetto/anchor-go/tree/v0.2.3) - -To install `anchor-go` locally so that you can use the `anchor-go` command globally, follow these steps: - -1. **Clone the repository:** - - ```bash - git clone https://github.com/gagliardetto/anchor-go.git - cd anchor-go - git checkout v0.2.3 - ``` - -2. **Install the command globally:** - - Run the following command to install the `anchor-go` command globally: - - ```bash - go install - ``` - - This will install the `anchor-go` binary to your `$GOPATH/bin` directory. Make sure that this directory is included in your system's `PATH` environment variable. - -3. **Then run the following command to generate the Go bindings:** - - ```bash - make anchor-go-gen - ``` +This builds the contracts, generates Go bindings from the IDL files in `target/idl/` and +`target/vendor/`, and outputs them to `gobindings/`. From 8816c92731496d3aae75d8951a26743f8ba0733a Mon Sep 17 00:00:00 2001 From: PabloMansanet Date: Mon, 30 Mar 2026 13:59:29 +0200 Subject: [PATCH 2/5] Pin rust version, document anchor-go build limitation --- chains/solana/README.md | 4 ++-- chains/solana/contracts/README.md | 6 +++--- chains/solana/contracts/rust-toolchain.toml | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 chains/solana/contracts/rust-toolchain.toml diff --git a/chains/solana/README.md b/chains/solana/README.md index ecedb37e8e..8a2d7fd29b 100644 --- a/chains/solana/README.md +++ b/chains/solana/README.md @@ -13,11 +13,11 @@ ## Dependencies -- [Rust](https://www.rust-lang.org/tools/install) +- [Rust](https://www.rust-lang.org/tools/install) (version pinned via `contracts/rust-toolchain.toml`) - [Go](https://go.dev/doc/install) (see `go.mod` for required version) - [Solana CLI](https://docs.anza.xyz/cli/install) (provides `solana-test-validator`) - [Anchor CLI](https://www.anchor-lang.com/docs/installation) -- [anchor-go](https://github.com/gagliardetto/anchor-go) v1.0.0 — `go install github.com/gagliardetto/anchor-go@v1.0.0` +- [anchor-go](https://github.com/gagliardetto/anchor-go) v0.2.3 — `GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3` - [golangci-lint](https://golangci-lint.run/welcome/install/) — for `make lint-go` - [gotestloghelper](https://github.com/smartcontractkit/chainlink-testing-framework) — for `make go-tests` output formatting diff --git a/chains/solana/contracts/README.md b/chains/solana/contracts/README.md index 8774296f9f..76d5af9c4f 100644 --- a/chains/solana/contracts/README.md +++ b/chains/solana/contracts/README.md @@ -2,11 +2,11 @@ ## Prerequisites -- [Rust](https://www.rust-lang.org/tools/install) +- [Rust](https://www.rust-lang.org/tools/install) (version pinned via `rust-toolchain.toml`) - [Solana CLI](https://docs.anza.xyz/cli/install) (provides `solana-test-validator`) - [Anchor CLI](https://www.anchor-lang.com/docs/installation) - [Go](https://go.dev/doc/install) (see `go.mod` for required version) -- [anchor-go](https://github.com/gagliardetto/anchor-go) v1.0.0 — `go install github.com/gagliardetto/anchor-go@v1.0.0` +- [anchor-go](https://github.com/gagliardetto/anchor-go) v0.2.3 — `GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3` ## Build @@ -67,7 +67,7 @@ earlier setup subtests won't have executed. Install `anchor-go` and regenerate bindings after contract changes: ```bash -go install github.com/gagliardetto/anchor-go@v1.0.0 +GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3 make anchor-go-gen ``` diff --git a/chains/solana/contracts/rust-toolchain.toml b/chains/solana/contracts/rust-toolchain.toml new file mode 100644 index 0000000000..8142c30126 --- /dev/null +++ b/chains/solana/contracts/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.73.0" From 0e38ef15063343fa48791ba1ced5f0520321c00f Mon Sep 17 00:00:00 2001 From: PabloMansanet Date: Mon, 30 Mar 2026 13:59:56 +0200 Subject: [PATCH 3/5] Install anchor-go from script --- chains/solana/scripts/anchor-go-gen.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/chains/solana/scripts/anchor-go-gen.sh b/chains/solana/scripts/anchor-go-gen.sh index adc02e2aa2..4efb79fec6 100755 --- a/chains/solana/scripts/anchor-go-gen.sh +++ b/chains/solana/scripts/anchor-go-gen.sh @@ -2,6 +2,13 @@ set -e +# Ensure anchor-go v0.2.3 is installed. It requires Go <= 1.22 to compile, +# so we pin GOTOOLCHAIN=go1.20 for the install step. +if ! command -v anchor-go &>/dev/null; then + echo "anchor-go not found, installing v0.2.3..." + GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3 +fi + function generate_bindings() { local idl_path_str="$1" IFS='/' read -r -a idl_path <<< "${idl_path_str}" From 21825220b88f32f5922b142b7532c15f61694b37 Mon Sep 17 00:00:00 2001 From: PabloMansanet Date: Mon, 30 Mar 2026 14:34:08 +0200 Subject: [PATCH 4/5] Pin golangci to a version that both compiles and passes --- chains/solana/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains/solana/README.md b/chains/solana/README.md index 8a2d7fd29b..195a136d70 100644 --- a/chains/solana/README.md +++ b/chains/solana/README.md @@ -18,7 +18,7 @@ - [Solana CLI](https://docs.anza.xyz/cli/install) (provides `solana-test-validator`) - [Anchor CLI](https://www.anchor-lang.com/docs/installation) - [anchor-go](https://github.com/gagliardetto/anchor-go) v0.2.3 — `GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3` -- [golangci-lint](https://golangci-lint.run/welcome/install/) — for `make lint-go` +- [golangci-lint](https://golangci-lint.run/welcome/install/) v2.7.0 — `go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7.0` - [gotestloghelper](https://github.com/smartcontractkit/chainlink-testing-framework) — for `make go-tests` output formatting ### macOS (Apple Silicon) Note From 41b5cafe445cfa2a1276bbe2a2d3ce1e0779fb4a Mon Sep 17 00:00:00 2001 From: PabloMansanet Date: Mon, 30 Mar 2026 15:25:28 +0200 Subject: [PATCH 5/5] Add clippy/rustfmt to pinned toolchain version --- chains/solana/contracts/rust-toolchain.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/chains/solana/contracts/rust-toolchain.toml b/chains/solana/contracts/rust-toolchain.toml index 8142c30126..3c4b81ebf6 100644 --- a/chains/solana/contracts/rust-toolchain.toml +++ b/chains/solana/contracts/rust-toolchain.toml @@ -1,2 +1,3 @@ [toolchain] channel = "1.73.0" +components = ["clippy", "rustfmt"]