Skip to content

Add initialize to test-cli - #108

Open
kaze-cow wants to merge 7 commits into
mainfrom
kaze/sc-331-add-initialize-to-test_cli
Open

Add initialize to test-cli#108
kaze-cow wants to merge 7 commits into
mainfrom
kaze/sc-331-add-initialize-to-test_cli

Conversation

@kaze-cow

@kaze-cow kaze-cow commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

We don't currently have any neat way to Initialize a newly deployed settlement program.

Thankfully there is a test-cli which is well suited for just that!

This PR adds cow initialize, which sends the Initialize instruction and prints the resulting signature and state PDA.

By default, all accounts/permissions are initialized to the transaction payer (which also is expected to have to be the current program upgrade authority). These can be overridden with flags.

just deploy now runs it right after solana program deploy, so a fresh deployment comes out usable in one step. Two details there: the recipe's programid argument is a keypair file on a first deploy but an address on an upgrade, so it's resolved to an address for the CLI; and the RPC endpoint is read from the Solana config, since that's what solana program deploy uses while the CLI would otherwise default to devnet regardless of where we just deployed.

On a plain upgrade the state PDA already exists, so initialize fails there. That's expected and shouldn't fail an otherwise successful deploy, so it only prints a warning. After a minor or major bump the storage is relocated and it creates the new PDA for real. The README section on upgrading is updated accordingly — it previously described running initialize again as a manual step.

How to test

Against devnet (or a local validator with --rpc-url):

$ cargo run -p cow-test-cli -- initialize
signature: ...
state PDA: ...

Re-running it should fail, since the state PDA already exists. Then confirm the usual sell/buy/settle flow works against that freshly initialized deployment.

The whole deployment process can be tested pretty easily if you only have some testnet funds by cerating a fresh keypair and deploying to it. for example:

solana-keygen new -o /tmp/test-deploy.json
just deploy /tmp/test-deploy.json ~/.config/solana/id.json

Example output:

...
Finished building program
Program Solana version: v4.0.3
Docker image Solana version: v4.0.3
ce1a3b7688bc5867e3669e56997b150bec064f91b96528a36810a80fe4900025
Program Id: 3KcWEL1hhwbWDbX611VhXqG5T54Myi4RE9LqBbRX73jz

Signature: 3ZKhKX72aF5Fg6aifydwYHiNJ6t9BJt4FdKfqfpuVLJ4NQnC6sx4DmWmQeLyKM37C1vxnWihF2sg3tGb6wVY6NHz

   Compiling settlement-interface v0.1.0 (/Users/kaze/code/cowprotocol/solana-programs/interface)
   Compiling settlement-client v0.1.0 (/Users/kaze/code/cowprotocol/solana-programs/client)
   Compiling cow-test-cli v0.1.0 (/Users/kaze/code/cowprotocol/solana-programs/test-cli)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.78s
     Running `target/debug/cow --rpc-url 'https://api.devnet.solana.com' --program-id 3KcWEL1hhwbWDbX611VhXqG5T54Myi4RE9LqBbRX73jz --keypair /Users/kaze/.config/solana/id.json initialize`
signature: 5tjC6LcfxFZa4e3ZmsZsCPNZk5nqmh5trWvEUDnH84eexyV9KnHGVoNY3zAq5r2WuPV5s7VZQf9C7jHbT96Q3i2q
state PDA: ELEzQtvEMFTsoDvdSEnf3jnuLjdPPQ7xwmC5jtrX12k5

Creating the singleton settlement state PDA previously required hand-rolling
the transaction. Expose it as `cow initialize`, with `--reclaim-authority`
defaulting to the payer, and print the resulting state PDA.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 18, 2026

Copy link
Copy Markdown

SC-331

The state PDA has to exist before the program is usable, and it has to be
recreated whenever a minor version bump relocates it. Fold that into the
deploy recipe instead of leaving it as a manual follow-up step.

The recipe's `programid` is a keypair file on a first deploy and an address
on an upgrade, so resolve it to an address for the CLI. The RPC endpoint is
read from the Solana config, which is what `solana program deploy` uses --
the CLI otherwise defaults to devnet regardless of where we just deployed.

On a plain upgrade the state PDA already exists, so `initialize` fails there.
That is expected and shouldn't fail the deploy, so it only warns.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kaze-cow kaze-cow self-assigned this Aug 18, 2026
@kaze-cow
kaze-cow marked this pull request as ready for review August 18, 2026 07:37
@kaze-cow
kaze-cow requested a review from a team as a code owner August 18, 2026 07:37
@kaze-cow

Copy link
Copy Markdown
Contributor Author

for general record, though it wasn't merged, we used this branch of the test-cli today as part of the v0.2 release. It worked pretty well once we merged in the version bump and other necessary changes!

@fedgiac fedgiac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. The only thing blocking merge for me is the RPC handling.

Comment on lines +43 to +44
println!("signature: {sig}");
println!("state PDA: {state_pda}");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I've seen other commands with the same output, we could move this to a "print transaction" function.

Comment thread Justfile
# 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}')" \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely change this, the RPC URL of an initialization can easily be inconsistent with that of the program deployment, we would have totally stumbled upon this when we released 2.0.

Also, nit: we should recover the RPC URL in its own line so that if that fails we don't continue execution with a weird URL.

In general, to me it would be great if the CLI itself were to pick up the default URL instead of passing it in.

Comment thread README.md
```

If the package minor or major has been changed, it is also necessary to run initialize again.
`just deploy` finishes by running `initialize` to create the program's state PDA. On a plain upgrade that PDA already exists, so the step fails and prints a warning that can be ignored. After a minor or major bump the storage is relocated, so `initialize` creates the new PDA and is expected to succeed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like on an upgrade you always reuse the same state PDA but this isn't true.

Suggested change
`just deploy` finishes by running `initialize` to create the program's state PDA. On a plain upgrade that PDA already exists, so the step fails and prints a warning that can be ignored. After a minor or major bump the storage is relocated, so `initialize` creates the new PDA and is expected to succeed.
`just deploy` finishes by running `initialize` to create the program's state PDA.\
If the deployment upgrades an existing program _and_ there's an either minor or major version bump, then this latter step fails and prints a warning that can be safely ignored.

In principle we could check if it's already initialized in the CLI, by the way. But I won't push for that, it's fine like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants