A simple Anchor application for Solana with code coverage support using Surfpool.
- Anchor
- Surfpool with register-tracing feature
- sbpf-coverage
- lcov - for generating HTML coverage reports (
brew install lcovon macOS,apt install lcovon Ubuntu, ordnf install lcovon Fedora)
git clone https://github.com/txtx/surfpool.git
cd surfpool
cargo build --features register-tracing --releaseNote: If PR #496 is not yet merged, you will need to checkout that branch first.
To generate accurate coverage reports, you need to disable optimizations, enable debug symbols, and disable LTO in your workspace Cargo.toml:
[profile.release]
overflow-checks = true
lto = "off"
codegen-units = 1
debug = true
opt-level = 0
[profile.release.build-override]
opt-level = 0
incremental = false
codegen-units = 1
debug = trueanchor build
rm target/deploy/simple_anchor_app.*
cargo build-sbf --tools-version v1.51 --arch v1 --debugWhy this complexity? Anchor is opinionated and always builds with SBPFv0. We run
anchor buildfirst to generate the IDL and other artifacts, then remove the compiled program and rebuild it manually withcargo build-sbfusing SBPFv1 (--arch v1) for better coverage results.
Note: At the time of writing, best coverage results are achieved with SBPFv1 (dynamic stack frames), which is why we use
--arch v1. Only with dynamic stack frames can we safely disable optimizations (opt-level = 0) without hitting stack size limits. The--tools-versioncan be v1.51 or higher, and--debugis required for coverage to work.
Warning: Due to cleaning steps (
anchor cleanorcargo clean), the keypair and program ID may get out of sync. If you encounter issues, it's best to clean everything and start fresh withanchor clean, then runanchor keys syncto resync the keys, followed by the full build process.
Run this in the anchor project directory:
SBF_OUT_DIR=$PWD/target/deploy SBF_TRACE_DIR=$PWD/target/sbf_trace_dir surfpool-tracing startNote: Setting
SBF_TRACE_DIRis what signalsLiteSVMto enable register tracing dumps. TheSBF_OUT_DIR=$PWD/target/deployenvironment variable won't be necessary once Surfpool catches up with LiteSVM's ELF data reading from program accounts.
Use Surfpool instead of solana-test-validator:
anchor test --skip-local-validator --skip-buildInstall sbpf-coverage if not already installed:
cargo install sbpf-coverageGenerate and view coverage report:
sbpf-coverage --src-path=$PWD/programs/simple_anchor_app/src --sbf-path=$PWD/target/deploy --sbf-trace-dir=$PWD/target/sbf_trace_dir
genhtml --output-directory coverage target/sbf_trace_dir/*.lcov --rc branch_coverage=1 && open coverage/index.html