diff --git a/Justfile b/Justfile index 88e7fdc..71a2ea0 100644 --- a/Justfile +++ b/Justfile @@ -1,7 +1,21 @@ +# Directory for locally-installed cargo packages. +cargo_root := justfile_directory() / ".cargo-root" +# The solana-verify binary that `install-solana-verify` produces. +solana_verify := cargo_root / "bin" / "solana-verify" +# The settlement program's cargo library name (the on-chain artifact is `.so`). +settlement_program := "cow_settlement" +# The public repository URL. +repo_url := "https://github.com/cowprotocol/solana-programs" + [private] default: @{{ just_executable() }} --list +# Install the pinned solana-verify on the current machine. +[private] +install-solana-verify: + cargo install solana-verify --version "$(cat .solana-verify-version.txt)" --root {{cargo_root}} + # Build the on-chain settlement program (.so) for Solana. build-program: cargo build-sbf --manifest-path programs/settlement/Cargo.toml @@ -93,16 +107,14 @@ doc-dev *args: cargo doc --workspace --no-deps --all-features --document-private-items --config 'build.rustdocflags=["--deny=warnings"]' {{ args }} # Build the settlement program using solana-verify's reproducible Docker build. -# Installs solana-verify via cargo if not already present (same as CI). -build-verified: - cargo install solana-verify --version $(cat .solana-verify-version.txt) --root .cargo-root/ - ./.cargo-root/bin/solana-verify build --library-name cow_settlement +build-verified: install-solana-verify + {{solana_verify}} build --library-name {{settlement_program}} # Deploy the settlement program, then create its state PDA. deploy programid keypair: build-verified #!/usr/bin/env bash set -euo pipefail - solana program deploy ./target/deploy/cow_settlement.so --program-id {{programid}} --keypair {{keypair}} + solana program deploy ./target/deploy/{{settlement_program}}.so --program-id {{programid}} --keypair {{keypair}} # `programid` is a keypair file on a first deploy and an address on an upgrade, # but the CLI only takes the address. @@ -110,10 +122,29 @@ deploy programid keypair: build-verified # A failure here is expected when upgrading a program whose state PDA already # exists, so don't fail the deploy over it. cargo run -p cow-test-cli -- \ - --rpc-url "$(solana config get json_rpc_url | awk '{print $NF}')" \ --program-id "$program_id" \ --keypair "{{keypair}}" \ initialize \ || echo "warning: \`initialize\` failed, the state PDA may already exist" >&2 +# Register the on-chain verification for an already-deployed program. +verify programid keypair commit_hash="": install-solana-verify + #!/usr/bin/env bash + set -euo pipefail + commit_args=() + if [ -n "{{commit_hash}}" ]; then + commit_args=(--commit-hash "{{commit_hash}}") + fi + # Step 1: write the otter-verify PDA, signed by the upgrade authority. + {{solana_verify}} verify-from-repo \ + --keypair "{{keypair}}" \ + --program-id "{{programid}}" \ + --library-name {{settlement_program}} \ + "${commit_args[@]}" \ + {{repo_url}} + # Step 2: queue remote worker to rebuild from the PDA. + {{solana_verify}} remote submit-job \ + --program-id "{{programid}}" \ + --uploader "$(solana address --keypair "{{keypair}}")" + all: build bench test-js-client lint fmt-check fmt-check-js-client doc-dev diff --git a/README.md b/README.md index e2b29fb..92cdefc 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ The repository is a Cargo workspace following the program / client / interface s ### How to build -Build the on-chain program (produces `target/deploy/settlement.so`): +Build the on-chain program (produces `target/deploy/cow_settlement.so`): ```sh just build-program @@ -96,7 +96,7 @@ There are two distinct flows depending on whether this is a first-time deploy or Pass the **program keypair file** as the first argument. Solana derives the program address from it and registers the deployer as the upgrade authority: ```sh -just deploy ./program-keypair.json ./deployer-keypair.json +just deploy ../program-keypair.json ../deployer-keypair.json ``` ### Upgrading an existing program @@ -107,7 +107,7 @@ just deploy ./program-keypair.json ./deployer-keypair.json Pass the **program's public key (address)** as the first argument. The deployer wallet must already be the upgrade authority: ```sh -just deploy FYp8R5K4B3B1Kfr7QuWzMz4TwoT7wptjYtxgCrY5sRXb ./deployer-keypair.json +just deploy FYp8R5K4B3B1Kfr7QuWzMz4TwoT7wptjYtxgCrY5sRXb ../deployer-keypair.json ``` `just deploy` finishes by running `initialize` to create the program's state PDA. @@ -115,6 +115,18 @@ just deploy FYp8R5K4B3B1Kfr7QuWzMz4TwoT7wptjYtxgCrY5sRXb ./deployer-keypair.json If the deployment upgrades an existing program without bumping the major or minor cargo package version, then this latter step fails and prints a warning that can be safely ignored. +### Verifying the deployment on-chain + +Since we use verified builds, we can have our program marked as verified on various block explorers. This is only possible on mainnet, not on testnets. + +To do so, run this once the program is deployed and the matching source is pushed to the public repository: + +```sh +just verify FYp8R5K4B3B1Kfr7QuWzMz4TwoT7wptjYtxgCrY5sRXb ../deployer-keypair.json +``` + +The first argument is the program address, the second is the upgrade authority keypair (it signs the on-chain verification PDA) and the third is an optional `` for the verification, and it uses the current `HEAD` otherwise. + ### Publishing the cargo packages Authenticate your cargo cli with `cargo login`. Ensure you have permission to publish `cow-settlement-interface`, `cow-settlement-client`, and `cow-test-cli`. @@ -156,6 +168,7 @@ You can use the settle CLI for a smoke test of the programs after a release. See - Authorize all [currently existing solver](https://app.notion.com/p/cownation/Solvers-for-Solana-Dev-Contracts-3ca8da5f04ca80968642e85640178cbd) using the solver CLI (`cow solver add --help`). - Make sure the package installs without errors: run `cargo install --path /mnt/lima-solana/repos/solana-programs/solana-program-workbench/test-cli --locked` (it depends on all other packages). - Create a PR with the changes and wait for approval. +- Once the PR is merged to `main`, check out that commit and [verify the deployment on-chain](#verifying-the-deployment-on-chain). - [Publish the cargo packages](#publishing-the-cargo-packages). - Create a [new GitHub release](https://github.com/cowprotocol/solana-programs/releases/new); in doing so, create a new tag like `v0.42`; title "Alpha release, v0.42". @@ -166,6 +179,7 @@ You can use the settle CLI for a smoke test of the programs after a release. See - Commit the code changes resulting from the changes above. - Create a PR with the changes and wait for approval. - [Update the programs](#how-to-deploy). The deployer keypair and the program keypair are in 1password (stored respectively under "Solana Deployer" and "Settlement account by version"). +- Once the PR is merged to `main`, check out that commit and [verify the deployment on-chain](#verifying-the-deployment-on-chain). - [Publish the cargo packages](#publishing-the-cargo-packages). ### Bumping the crate version