The Solana program is written in Rust using the Solana SDK and the Anchor framework. To install all dependencies simply follow their installation guide. It all boils down to this command:
curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bashNote
Make sure the toolchain is added to your PATH:
export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH"
Validate your setup running the following. You should not see errors or warnings
anchor buildWe have a few rust unit tests inside programs/polymer-prover/src/. These cover only signature verification,
proof validation and event parsing without getting into the "solana program" or "anchor" aspect of the code.
cargo testThe integration tests make use of a local solana test validator node. anchor handles the whole process which is
roughly the following:
- build program
- start the local solana validator node
- create accounts and fund them
- deploy the program to the local node
- run the tests
anchor testYou can also use this validator node for extra testing (ie proof-api) simply by running
solana-test-validator --reset --logThe node will be reachable at http://127.0.0.1:8899. Now you can use that node to deploy your program. To do so,
configure the solana sdk to point to your local env like so
solana config set --url localhostThen just deploy your program
anchor deployNow we can run the same integration tests against the local node
anchor test --skip-local-validator --skip-deployBut more importantly, you can use the local node to validate proofs generated with the proof-api by pointing
the e2e tool to the local solana test validator node: http://127.0.0.1:8899.
Another option is to use anchor --detach to start the local node, deploy the program and initialize it. Try it
with
make localnetYou can also use the same tooling to deploy the program to devnet. First, configure the solana sdk
solana config set --url devnetYou will need a new account and funds, so run this
solana-keygen new
solana airdrop 2Assuming the program is built (anchor build) you can now deploy it to devnet.
solana program deploy ./target/deploy/polymer_prover.soNow, you can run the same tests against devnet
anchor test --skip-deploy --provider.cluster devnetFor verifiable deployments, use Docker builds to ensure deterministic builds:
# Build using Docker for deterministic/verifiable builds
anchor build --verifiable --program-name mars
# Upgrade the program on devnet
anchor upgrade target/verifiable/mars.so \
--program-id 5d9Z6bsfZg8THSus5mtfpr5cF9eNQKqaPZWkUHMjgk6u \
--provider.cluster devnet
# Initialize the IDL (required for verification, only needed once per program)
anchor idl init 5d9Z6bsfZg8THSus5mtfpr5cF9eNQKqaPZWkUHMjgk6u \
--filepath target/idl/mars.json \
--provider.cluster devnet
# Verify the deployed program matches your local code
anchor verify 5d9Z6bsfZg8THSus5mtfpr5cF9eNQKqaPZWkUHMjgk6u \
--provider.cluster devnet \
--program-name marsNote: Verifiable builds use Docker to create deterministic binaries. Regular builds may produce different binaries each time due to timestamps, causing verification to fail.
We can also generate go bindings with
make go-bindingsThis will create go module under the ./go directory. Under the hood, we use a modified version of
solana-anchor-go, which can be found here:
https://github.com/polymerdao/solana-anchor-go
The cache account that holds the proof chunks is currently limited to 3000 bytes. That was not always the case though
so if you have created your account (ie called ValidateEvent()) while an older program was running, chances are
you are going to get this error when try to load a new proof:
"Program 8zQzyWLSgLFpm2Si6HASkYidyL2paQaLZGADAQ5mSyPz invoke [1]",
"Program log: Instruction: LoadProof",
"Program log: AnchorError caused by account: cache_account. Error Code: ConstraintSpace. Error Number: 2019. Error Message: A space constraint was violated.",
"Program log: Left: 3012",
"Program log: Right: 1312",
What's happening there is that your account was created with a different size limit than is currently enforced by
the program. Note the Left: 3012 and Right: 1312 logs. That's the current limit (3000 bytes) vs the old one
(1300 bytes) plus 4 bytes to store the cache vector size and the 8 bytes for the account discriminator.
The way to fix it is to tell the program to resize your account. We do that with a special instruction: resize_cache
We have a convenience tool to call such instruction using your credentials. Try:
./target/release/proverctl --cluster https://api.devnet.solana.com resize-cacheThe program id is the public key of the program keypair. This is generated by the solana sdk or anchor and stored
under target/deploy/your_program.json. Once the program is deployed, only the public key is needed to upgrade it.
This is true as long as the upgrade authority (the original deployer) knows its own key. In other words,
the program keypair is a single use private key that once the program is deployed, it can be discarded.
We are storing it under keypair and might include it in the releases. This will help going through the initial
deployments.
Once the program is deployed, it needs to be initialized. This is done by calling the Initialize instruction.
This instruction will create the internal accounts needed by the program to function - ie validate proofs.
Also, note that we need to sign the instruction with the program keypair to prevent front-running attacks.
You can do that with the proverctl tool:
./target/release/proverctl \
--cluster https://api.devnet.solana.com \
--keypair-path /path/to/your/keypair.json \
--program-keypair /path/to/your/program-keypair.json \
initialize \
--client-type 'client_type' \
--signer-addr '0xYourSignerAddress' \
--peptide-chain-id 'peptide_chain_id' \