test: add proptest-based real-IDL coverage tests#225
Merged
prasanna-anchorage merged 17 commits intoApr 8, 2026
Conversation
Two libFuzzer targets covering the full visualsign-solana stack: - fuzz_transaction_string: arbitrary bytes into transaction_string_to_visual_sign - fuzz_versioned_transaction: arbitrary bytes deserialized as VersionedTransaction then passed to versioned_transaction_to_visual_sign Run with: cargo +nightly fuzz run <target> (from src/chain_parsers/visualsign-solana/fuzz/) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- proptest label: runs cargo test -p visualsign-solana - fuzz label: installs nightly + cargo-fuzz, runs each fuzz target for 30s - ubuntu job: restricted to main push/PR to avoid triggering on label events Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On crash, extracts the libFuzzer summary (everything after the ─── line) and posts it as a PR comment via gh. No artifacts or separate jobs needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move proptest and fuzz jobs out of main.yml into dedicated workflow files (proptest.yml, fuzz.yml) so they appear as distinct named checks. Add pull-requests: write permission to fuzz job to allow posting crash comments via gh pr comment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shared composite action posts crash/failure output as a PR comment and tags @copilot to fix the issue. Fuzz and proptest workflows use it via extract steps that write output to GITHUB_OUTPUT. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move build_transaction, options_with_idl, instruction_fields, find_text and related helpers from pipeline_integration.rs into tests/common/mod.rs so they can be reused by other test files without duplication. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test the full visualization pipeline with realistic Borsh-serialized instruction data for Drift deposit, Lifinity swap, Raydium swapBaseInput, Orca swap (including u128 sqrtPriceLimit), Meteora swap, Kamino deposit, Stabble swap (Option<u64> arg), and OpenBook deposit. Each test uses assert_semantic() to verify decoded instruction name and arg values match what was serialized. Lives in its own file to keep pipeline_integration.rs focused on proptest-based property tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 'labeled' to pull_request trigger types and allow the ubuntu job to run when the 'ci' label is present, not just for PRs targeting main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Pin fuzz Cargo.lock to avoid spl-token-2022 breakage on nightly (spl-token-group-interface 0.7.2 pulled in solana-nullable which is incompatible with spl-token-2022 10.0.0) - Remove stale Cargo.lock gitignore rule from visualsign-solana - Remove post-failure-comment action and simplify fuzz/proptest workflows - Use continue-on-error on fuzz steps so crashes show as warnings (known pre-existing panics in instructions.rs bounds checking) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On crash/failure, add fuzz-failure or proptest-failure label to the PR. On clean run, remove the label. This gives visible signal without blocking the check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add || true to --add-label calls so the step doesn't fail if the label operation itself has issues (e.g. label not yet created in the repo). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend the property-based testing section with cargo fuzz targets, semantic pipeline tests, CI workflow labels (proptest, fuzz, ci), and failure label behavior (fuzz-failure, proptest-failure). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Pin nightly toolchain to 2026-03-13 (known-good) in both rust-toolchain.toml and fuzz.yml - Use --locked for cargo install cargo-fuzz in CI and docs - Cache fuzz/target/ and key off fuzz/Cargo.lock instead of src/Cargo.lock Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use ..VisualSignOptions::default() in test helpers to prevent breakage when new fields are added to the struct - Pass github.event.pull_request.number through env var instead of direct context interpolation in shell blocks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ng (#223) * fix: guard against panics on malformed transaction data Two panic sites in the legacy transaction path: 1. instructions.rs: unchecked indexing into account_keys with program_id_index and account indices from compiled instructions. Malformed transactions with out-of-bounds indices cause index-out-of-bounds panics. 2. accounts/decode.rs: arithmetic underflow when message header values (num_readonly_signed_accounts, num_readonly_unsigned_accounts) exceed the actual account keys array length. Fix: apply the same defensive patterns already used in the v0 transaction path — filter_map with bounds checks for instruction indices, saturating_sub for header arithmetic, and an explicit error for empty account keys. Verified with cargo-fuzz: ~930,000 runs across both fuzz targets (fuzz_transaction_string, fuzz_versioned_transaction) with zero crashes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Address Copilot review: improve comments, error message, add tests - Clarify comment to distinguish skipped instructions (OOB program_id) from omitted accounts (OOB account index) - Use "Legacy transaction" in error message for consistency with v0 path - Add unit tests for decode_accounts and decode_v0_accounts with inconsistent header values to lock in saturating_sub behavior Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract load_idl_from_env into common/mod.rs and add real_idl_validation.rs with deterministic structural invariant tests for production IDLs: discriminator presence/uniqueness, instruction name uniqueness, and IDL hash stability. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 4 new property tests against real production IDLs: - arg name completeness in parsed output - overlong data rejection (trailing byte) - truncated data rejection (missing byte) - discriminator isolation (cross-instruction swap) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f65ebb5 to
cdaf441
Compare
prasanna-anchorage
approved these changes
Apr 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds 4 new property tests that run against real production IDLs (loaded via
IDL_FILEenv var):real_idl_all_arg_names_in_parsed_output— after successful parse, every declared arg name appears inprogram_call_argsreal_idl_overlong_data_is_rejected— valid bytes + 1 trailing byte →Errreal_idl_truncated_data_is_rejected— valid bytes with last byte removed →Errreal_idl_wrong_discriminator_not_dispatched_as_original— swapping discriminators between instructions doesn't cause misdispatchThese complement the existing
real_idl_never_panicsandreal_idl_valid_data_always_parses_okcrash-safety tests with targeted correctness assertions.Stacked on
Test plan
IDL_FILE=<path> cargo test --test fuzz_idl_parsing real_idl— all real-IDL tests passcargo test --test fuzz_idl_parsing— full suite passes (tests skip when IDL_FILE unset)🤖 Generated with Claude Code