Skip to main content

data_anchor_proofs/
lib.rs

1//! This crate contains proofs related to the Solana blockchain.
2//!
3//! The proofs can prove the state of accounts on the chain and whether or not they were updated,
4//! but it makes no semantic assumptions about the account data, it's just considered raw bytes.
5//! The account data must first be deserialized and verified that it matches the expected state.
6
7pub mod blob;
8pub mod blober_account_state;
9pub mod compound;
10mod debug;
11
12#[doc(hidden)]
13#[cfg(test)]
14pub(crate) mod testing {
15    use std::{cmp::max, hash::Hash, ops::Deref};
16
17    use anchor_lang::solana_program::clock::Epoch;
18    use arbitrary::{Arbitrary, Unstructured};
19    use solana_account::Account;
20    use solana_keypair::Keypair;
21    use solana_seed_derivable::SeedDerivable;
22    use solana_signer::Signer;
23
24    /// An arbitrary keypair, since we can't implement [`arbitrary::Arbitrary`] for
25    /// [`solana_keypair::Keypair`] or [`anchor_lang::Pubkey`].
26    ///
27    /// Mainly used to generate valid pubkeys from arbitrary seeds.
28    #[derive(Debug, PartialEq)]
29    pub struct ArbKeypair(Keypair);
30
31    impl Deref for ArbKeypair {
32        type Target = Keypair;
33
34        fn deref(&self) -> &Self::Target {
35            &self.0
36        }
37    }
38
39    // A bunch of these impls aren't good security-wise, but this is all just for testing.
40
41    impl Clone for ArbKeypair {
42        fn clone(&self) -> Self {
43            ArbKeypair(self.0.insecure_clone())
44        }
45    }
46
47    impl Eq for ArbKeypair {}
48
49    impl Hash for ArbKeypair {
50        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
51            self.0.to_bytes().hash(state);
52        }
53    }
54
55    impl<'a> Arbitrary<'a> for ArbKeypair {
56        fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
57            // The seed needs to be at least 32 bytes long.
58            let len: usize = 32 + u.arbitrary_len::<ArbKeypair>()?;
59            let mut seed = Vec::with_capacity(len);
60            for _ in 0..len {
61                seed.push(u.arbitrary()?);
62            }
63            let keypair = Keypair::from_seed(&seed).map_err(|_| arbitrary::Error::NotEnoughData)?;
64
65            Ok(ArbKeypair(keypair))
66        }
67
68        fn size_hint(_depth: usize) -> (usize, Option<usize>) {
69            (32, None)
70        }
71    }
72
73    /// An arbitrary account, since we can't implement [`arbitrary::Arbitrary`] for [`solana_account::Account`].
74    #[derive(Debug, Arbitrary, Clone, PartialEq, Eq, Hash)]
75    pub struct ArbAccount {
76        pub lamports: u64,
77        pub data: Vec<u8>,
78        pub owner: ArbKeypair,
79        pub executable: bool,
80        pub rent_epoch: Epoch,
81    }
82
83    impl From<ArbAccount> for Account {
84        fn from(val: ArbAccount) -> Self {
85            Account {
86                lamports: max(1, val.lamports),
87                data: val.data,
88                owner: val.owner.pubkey(),
89                executable: val.executable,
90                rent_epoch: val.rent_epoch,
91            }
92        }
93    }
94}