solana-labs / solana-program-library

A collection of Solana programs maintained by Solana Labs
https://solanalabs.com
Apache License 2.0
3.44k stars 2.02k forks source link

[spl-account-compression] V1 Release #5848

Open ngundotra opened 10 months ago

ngundotra commented 10 months ago

Features:

Implementation details:

ngundotra commented 9 months ago

Getting the current root:

fn get_root_at_index(
    tree_bytes: &[u8],
    max_depth: usize,
    max_buffer_size: usize,
    current_index: usize,
) -> Result<[u8; 32], &'static str> { // Assuming the root is 32 bytes
    if current_index >= max_buffer_size {
        return Err("Current index is out of bounds");
    }

    // Size of each field in ChangeLog
    let node_size = 32; // Assuming size of Node is 32 bytes
    let u32_size = 4;   // Size of u32

    // Size of ChangeLog
    let changelog_size = node_size + (node_size * max_depth) + u32_size + u32_size;

    // Calculate the starting position of the ChangeLog at the current index
    let changelog_start = (8 + 8 + 8) + (changelog_size * current_index);
    let root_start = changelog_start; // Root is the first element in ChangeLog

    // Extract the root bytes
    let root_bytes = &tree_bytes[root_start..root_start + node_size];

    // Convert the bytes to a 32-byte array
    root_bytes.try_into().map_err(|_| "Failed to extract root")
}

Getting the current active index:

fn get_rightmost_proof_index(
    tree_bytes: &[u8],
    max_depth: u32,
    max_buffer_size: u32,
) -> Result<u32> {
    let changelog_size = 32 + 32 * max_depth + 4 + 4;
    let path_start = 8 + 8 + 8 + changelog_size * max_buffer_size;

    let index_start = path_start + 32 * max_depth + 32;
    let (_, _index_bytes) = tree_bytes.split_at(index_start as usize);
    let (index_bytes, _) = _index_bytes.split_at(4);

    let index = u32::try_from_slice(index_bytes)?;
    Ok(index)
}