Add Borsh serialization and Solana support#207
Open
AHartNtkn wants to merge 13 commits into
Open
Conversation
5 tasks
29609c3 to
dfb0174
Compare
58d299a to
b2861eb
Compare
cee0817 to
f6ffde4
Compare
2967b20 to
36475d3
Compare
This was referenced Feb 12, 2026
ab9690b to
71dbe49
Compare
b4ec6da to
14e21d7
Compare
ece8158 to
90a4fa8
Compare
- Add borsh, sha2, solana-program, solana-secp256k1, dashu as optional deps - Add `borsh` and `solana` feature flags - Add k256 dev-dependency for tests without default features - Digest: add Borsh derive, make field public, add from_bytes/to_bytes methods - Digest: replace bytemuck::from_bytes with from_bytes() in TryFrom/FromHex - Constants: feature-gate VK bytes by solana (Borsh circuit vs risc0 serde circuit) - Constants: extract BATCH_AGGREGATION_VK_BYTES, add EMPTY_HASH_WORDS, bytes_to_words_const - Error: add DeltaPointNotOnCurve and DeltaMismatch variants Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Action, ComplianceInstance, ComplianceInstanceWords, ComplianceUnit - DeltaProof (placeholder), DeltaWitness (placeholder) + len/is_empty/as_slice - DeltaProof (k256), DeltaWitness (k256): manual BorshSerialize/BorshDeserialize - LogicInstance, AppData, ExpirableBlob, LogicVerifierInputs - Transaction, Delta Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- delta_proof: feature-gate hasher (SHA-256 for solana, Keccak-256 for EVM) - LogicInstance: split to_journal() into zkvm (risc0 serde) and borsh variants - LogicVerifierInputs: add instance_journal field for pre-serialized journal bytes - LogicVerifier: use pre-serialized instance_journal instead of recomputing - ComplianceInstance: add Solana borsh to_journal() impl - ComplianceWitness: relax feature gate from zkvm+k256 to just k256 - arm_test_app: add instance_journal to LogicVerifierInputs construction Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses Solana syscalls (hashv, secp256k1_recover) and solana-secp256k1 for EC point arithmetic instead of k256, which exceeds SBF stack frame limits. Module is gated on cfg(all(feature = "solana", not(feature = "zkvm"))). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- arm_circuits/Cargo.toml: add methods crates to workspace members - All methods/Cargo.toml: add borsh and bin features - All methods/build.rs: forward borsh/bin features to guest via GuestOptionsBuilder - All guest/Cargo.toml: add borsh/bincode deps, forward borsh to anoma-rm-risc0/borsh - All guest/src/main.rs: feature-conditional output (borsh/bincode/default risc0 serde) - compliance guest: add k256 and zkvm features to anoma-rm-risc0 dep - trivial_logic guest: add zkvm and k256 features with default-features = false - arm_test_app: add instance_journal to LogicVerifierInputs construction Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DeltaWitness::Serialize uses serialize_bytes (u64 length prefix + bytes) but DeltaWitness::Deserialize reads [u8; 32] (fixed-size, no prefix). These are incompatible in bincode: the deserialized key silently contains the length prefix bytes instead of the actual key, producing a corrupted DeltaWitness without erroring. DeltaProof does not have this issue — its Deserialize correctly uses Vec::deserialize to match serialize_bytes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DeltaWitness::Serialize uses serialize_bytes which writes a u64 length prefix in bincode. DeltaWitness::Deserialize was reading [u8; 32] which expects no prefix, causing silent data corruption on roundtrip. Change Deserialize to use Vec::deserialize (matching what DeltaProof already does), with an explicit length check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix the same serialize_bytes/Deserialize mismatch in the placeholder DeltaWitness (delta_types.rs) that was fixed in the k256 version. Uses Vec::deserialize to match serialize_bytes, same pattern as placeholder DeltaProof. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
`unsigned_is_multiple_of` is unstable until Rust 1.87.0. The nix flake in solana-protocol-adapter pins Rust 1.84.1 (the last version compatible with Anchor 0.31.x), so this breaks downstream compilation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
14e21d7 to
3d87f52
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.
Problem
arm-risc0needed Solana/Borsh support in thearmcrate while preserving existing behavior for non-Solana targets. During this work, logic verification also needed to remain bound to the action-context instance.What This PR Changes
arm.arm/Cargo.toml: adds optional deps (borsh,sha2,solana-program,solana-secp256k1,dashu)borsh = ["dep:borsh"]solana = ["transaction", "borsh", "dep:sha2", "dep:solana-program", "dep:solana-secp256k1", "dep:dashu"]Action,ComplianceUnit,Transaction,Delta,LogicInstance,LogicVerifierInputs,ComplianceInstance,Digest, and related app-data structsDigestnow has explicitfrom_bytes/to_byteshelpers used by Solana pathsarm/src/constants.rsnow gates VK bytes byfeature = "solana"LogicVerifierInputsnow carriesinstance_journalto_logic_verifier(...)decodes provided journal and checks equality againstto_instance(is_consumed, root)ArmError::LogicInstanceMismatchon mismatcharm/src/solana_delta.rs(enabled forsolanawithoutzkvm)hashv,secp256k1_recover) andsolana-secp256k1DeltaPointNotOnCurveandDeltaMismatchDeltaProofand 32-byteDeltaWitnessScope
Only files in this PR diff (
origin/anthony/arm-dep-minimum...origin/anthony/arm-solana-support):arm/Cargo.tomlarm/src/action.rsarm/src/compliance.rsarm/src/compliance_unit.rsarm/src/constants.rsarm/src/delta_proof.rsarm/src/delta_types.rsarm/src/digest.rsarm/src/error.rsarm/src/lib.rsarm/src/logic_instance.rsarm/src/logic_proof.rsarm/src/solana_delta.rsarm/src/transaction.rsarm_tests/arm_test_app/src/lib.rsVerification
Ran on branch
anthony/arm-solana-support.cargo fmt --all -- --check✅cargo check -p anoma-rm-risc0✅cargo check -p anoma-rm-risc0 --no-default-features✅cargo check -p anoma-rm-risc0 --no-default-features --features solana✅cargo clippy --workspace --all-targets -- -D warnings✅cargo test -p anoma-rm-risc0✅ (4 passed)cargo test -p anoma-rm-risc0 --no-default-features✅ (6 passed)cargo test -p anoma-rm-risc0 --no-default-features --features solana✅ (7 passed)./scripts/anchor-test.sh✅ (36 passing)export PATH="$(dirname "$(dirname "$SBF_SDK_PATH")"):$PATH"Tracking
arm_circuits/*guest serialization/feature forwarding)