test(compression): fix build + add LiteSVM tests for cutils & cnft-vault; re-enable in CI#58
Merged
Merged
Conversation
…x, fixtures, dev-deps, cargo-test script)
Exercises the cutils program end to end under LiteSVM: - Builds a real Token-Metadata sized-collection NFT (mint + metadata + master edition) so Bubblegum MintToCollectionV1's collection check passes. - Creates a ConcurrentMerkleTree<3,8> via account-compression alloc + Bubblegum create_tree_config. - Calls the cutils `mint` instruction to mint one cNFT into the tree/collection. - Recomputes data_hash/creator_hash exactly as Bubblegum stores the leaf (collection verified=true after MintToCollectionV1), builds the empty-node proof for leaf 0, reads the live root, and calls the cutils `verify` instruction, asserting success and that a tampered data_hash fails. Adds the mpl_token_metadata mainnet fixture (required by MintToCollectionV1) and two clippy allows in the program source (diverging_sub_expression false positive from Anchor's #[program] macro, and vec_init_then_push on the intentional MintToCollectionV1 account-meta builder). https://claude.ai/code/session_013dpnF6uSGWXjkJJZseqzcP
Adds programs/cnft-vault/tests/test_vault.rs, a LiteSVM test that: - loads the built cnft-vault program plus the three mainnet fixtures (mpl-bubblegum, spl-account-compression, spl-noop) - creates a Bubblegum ConcurrentMerkleTree<3,8> and mints a cNFT whose leaf_owner is the vault PDA (seeds [b"cNFT-vault"]) - recomputes data_hash/creator_hash, builds the index-0 empty-node proof, reads the live root - calls withdraw_cnft (CPIs Bubblegum Transfer, vault PDA signs via invoke_signed) to move the cNFT to a recipient, asserting success and that a replay with the now-stale root fails Also: add #![allow(clippy::diverging_sub_expression)] (accepted Anchor #[program] false positive) and #[allow(clippy::too_many_arguments)] on build_transfer_instruction, plus rustfmt cleanup, so fmt/clippy are clean. withdraw_two_cnfts is left untested (would need two trees/leaves/proofs). https://claude.ai/code/session_013dpnF6uSGWXjkJJZseqzcP
…ocal validator (not unfunded devnet)
…or keys sync in CI
d8841ae to
9f9b5e7
Compare
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
Re-enables the other two excluded compression examples, the same way as cnft-burn (#57). Both were already migrated to Anchor 1.0 with manual Bubblegum CPI; both were broken only by a leftover, unused
ahash = "=0.8.7"pin (pullsgetrandom 0.2, whichcompile_error!s on the SBF target), and both had no Rust test.Changes (per example)
ahashpin → builds on the current toolchain.[dev-dependencies](litesvm 0.11 + solana-* 3.x + solana-keccak-hasher) and switch the Anchor test script tocargo test(matching the other re-enabled Anchor examples).tests/fixtures/with a provenance README (program IDs, source cluster, dump date 2026-06-05 + slot, refresh command)..github/.ghaignore.compression/cutilscutilsmints a cNFT via BubblegumMintToCollectionV1and verifies a leaf via account-compressionverify_leaf. The test (test_cutils_mint_and_verify): builds a real Token-Metadata sized collection NFT (so the collection check passes), creates a Bubblegum tree, calls the program'smint, recomputesdata_hash/creator_hash(withcollection.verified = true), checks the rebuilt root equals the on-chain root, then callsverifyand asserts success — plus a tampered-data_hashnegative case. Because it usesMintToCollectionV1, this example also needs thempl_token_metadata.sofixture (in addition to bubblegum/account-compression/noop).compression/cnft-vaultcnft-vaultholds cNFTs in a vault PDA and withdraws them via Bubblegum Transfer signed by the PDA. The test (test_withdraw_cnft): mints a cNFT owned by the vault PDA ([b"cNFT-vault"]), then callswithdraw_cnftto transfer it to a recipient, asserts success, and asserts a stale-root replay fails. (withdraw_two_cnftsleft untested — would need two trees/proofs; noted.)Fixtures / notes
Same mechanism the repo already uses for
mpl_token_metadata.so. Each example carries its own fixture copies (Anchor projects are independent workspaces). A crate-level#[allow(clippy::diverging_sub_expression)]was added to eachlib.rs(the sanctioned Anchor#[program]macro false positive; rootrust.ymlalready passes-A clippy::diverging_sub_expression).Verification (CI toolchain, Solana 3.1.x / platform-tools v1.52)
Both:
cargo build-sbfbuilds,cargo testpasses (cutils 2 tests, cnft-vault 1),cargo fmt --checkclean,cargo clippy --tests -D warningsclean. Only mainnet fixtures (not the built program.so) are committed.https://claude.ai/code/session_013dpnF6uSGWXjkJJZseqzcP
Generated by Claude Code