light_client/rpc/
merkle_tree.rs

1use std::mem;
2
3use async_trait::async_trait;
4use light_concurrent_merkle_tree::{
5    copy::ConcurrentMerkleTreeCopy, errors::ConcurrentMerkleTreeError, light_hasher::Poseidon,
6};
7use light_indexed_merkle_tree::{copy::IndexedMerkleTreeCopy, errors::IndexedMerkleTreeError};
8use light_sdk::state::MerkleTreeMetadata;
9use solana_sdk::pubkey::Pubkey;
10use thiserror::Error;
11
12use super::{RpcConnection, RpcError};
13
14#[derive(Error, Debug)]
15pub enum MerkleTreeExtError {
16    #[error(transparent)]
17    Rpc(#[from] RpcError),
18
19    #[error(transparent)]
20    ConcurrentMerkleTree(#[from] ConcurrentMerkleTreeError),
21
22    #[error(transparent)]
23    IndexedMerkleTree(#[from] IndexedMerkleTreeError),
24}
25
26/// Extension to the RPC connection which provides convenience utilities for
27/// fetching Merkle trees.
28#[async_trait]
29pub trait MerkleTreeExt: RpcConnection {
30    async fn get_state_merkle_tree(
31        &mut self,
32        pubkey: Pubkey,
33    ) -> Result<ConcurrentMerkleTreeCopy<Poseidon, 26>, MerkleTreeExtError> {
34        let account = self.get_account(pubkey).await?.unwrap();
35        let tree = ConcurrentMerkleTreeCopy::from_bytes_copy(
36            &account.data[8 + mem::size_of::<MerkleTreeMetadata>()..],
37        )?;
38
39        Ok(tree)
40    }
41
42    async fn get_address_merkle_tree(
43        &mut self,
44        pubkey: Pubkey,
45    ) -> Result<IndexedMerkleTreeCopy<Poseidon, usize, 26, 16>, MerkleTreeExtError> {
46        let account = self.get_account(pubkey).await?.unwrap();
47        let tree = IndexedMerkleTreeCopy::from_bytes_copy(
48            &account.data[8 + mem::size_of::<MerkleTreeMetadata>()..],
49        )?;
50
51        Ok(tree)
52    }
53}