From 1e48b5d5ddd0586ac978633053baef6f0a4f1d0d Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Thu, 19 Dec 2024 19:35:08 +0100 Subject: [PATCH] feat(solana): puts BashMerkleTree within shared --- packages/solana/Cargo.lock | 10 ++++ .../solana/programs/snapshotter/Cargo.toml | 3 +- .../solana/programs/snapshotter/src/lib.rs | 49 +----------------- .../shared/batch-merkle-tree/Cargo.toml | 18 +++++++ .../shared/batch-merkle-tree/src/lib.rs | 50 +++++++++++++++++++ 5 files changed, 81 insertions(+), 49 deletions(-) create mode 100644 packages/solana/shared/batch-merkle-tree/Cargo.toml create mode 100644 packages/solana/shared/batch-merkle-tree/src/lib.rs diff --git a/packages/solana/Cargo.lock b/packages/solana/Cargo.lock index dba4c42d..2446ae61 100644 --- a/packages/solana/Cargo.lock +++ b/packages/solana/Cargo.lock @@ -623,6 +623,15 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "batch-merkle-tree" +version = "0.1.0" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "anchor-lang", +] + [[package]] name = "bincode" version = "1.3.3" @@ -2711,6 +2720,7 @@ name = "snapshotter" version = "0.1.0" dependencies = [ "anchor-lang", + "batch-merkle-tree", ] [[package]] diff --git a/packages/solana/programs/snapshotter/Cargo.toml b/packages/solana/programs/snapshotter/Cargo.toml index 0063eadb..d9907549 100644 --- a/packages/solana/programs/snapshotter/Cargo.toml +++ b/packages/solana/programs/snapshotter/Cargo.toml @@ -17,4 +17,5 @@ no-log-ix-name = [] idl-build = ["anchor-lang/idl-build"] [dependencies] -anchor-lang = "0.30.1" \ No newline at end of file +anchor-lang = "0.30.1" +batch-merkle-tree = { path = "../../shared/batch-merkle-tree" } \ No newline at end of file diff --git a/packages/solana/programs/snapshotter/src/lib.rs b/packages/solana/programs/snapshotter/src/lib.rs index 982aea3c..907630f5 100644 --- a/packages/solana/programs/snapshotter/src/lib.rs +++ b/packages/solana/programs/snapshotter/src/lib.rs @@ -30,6 +30,7 @@ pub fn account_hasher( #[program] pub mod snapshotter { use super::*; + use batch_merkle_tree::BatchMerkleTree; // Determines how many accounts are processed per batch during root calculation. pub const BATCH_SIZE: usize = 10; @@ -169,51 +170,3 @@ pub mod snapshotter { Ok(()) } } - -pub struct BatchMerkleTree { - pub root: Hash, -} - -impl From for BatchMerkleTree { - fn from(root: Hash) -> Self { - BatchMerkleTree { root: root } - } -} - -impl BatchMerkleTree { - pub fn new() -> Self { - BatchMerkleTree { - root: Hash::default(), - } - } - - pub fn push_batch(&mut self, leaves: Vec) -> Result<()> { - let mut current_layer = leaves; - - while current_layer.len() > 1 { - let mut next_layer = Vec::new(); - let mut i = 0; - while i < current_layer.len() { - if i + 1 < current_layer.len() { - next_layer.push(hashv(&[ - ¤t_layer[i].to_bytes(), - ¤t_layer[i + 1].to_bytes(), - ])); - i += 2; - } else { - next_layer.push(current_layer[i]); - i += 1; - } - } - current_layer = next_layer; - } - - self.root = if self.root == Hash::default() { - current_layer[0] - } else { - hashv(&[&self.root.to_bytes(), ¤t_layer[0].to_bytes()]) - }; - - Ok(()) - } -} diff --git a/packages/solana/shared/batch-merkle-tree/Cargo.toml b/packages/solana/shared/batch-merkle-tree/Cargo.toml new file mode 100644 index 00000000..8a929223 --- /dev/null +++ b/packages/solana/shared/batch-merkle-tree/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "batch-merkle-tree" +version = "0.1.0" +description = "A merkle tree that allows to calculate a root over a batch of leaves" +edition = "2021" + +[features] +default = [] +cpi = ["no-entrypoint"] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +idl-build = ["anchor-lang/idl-build"] + +[dependencies] +alloy-sol-types = "0.7.0" +alloy-primitives = "0.7.0" +anchor-lang = "0.30.1" diff --git a/packages/solana/shared/batch-merkle-tree/src/lib.rs b/packages/solana/shared/batch-merkle-tree/src/lib.rs new file mode 100644 index 00000000..65704f9b --- /dev/null +++ b/packages/solana/shared/batch-merkle-tree/src/lib.rs @@ -0,0 +1,50 @@ +use anchor_lang::prelude::*; +use anchor_lang::solana_program::hash::{hashv, Hash}; + +pub struct BatchMerkleTree { + pub root: Hash, +} + +impl From for BatchMerkleTree { + fn from(root: Hash) -> Self { + BatchMerkleTree { root: root } + } +} + +impl BatchMerkleTree { + pub fn new() -> Self { + BatchMerkleTree { + root: Hash::default(), + } + } + + pub fn push_batch(&mut self, leaves: Vec) -> Result<()> { + let mut current_layer = leaves; + + while current_layer.len() > 1 { + let mut next_layer = Vec::new(); + let mut i = 0; + while i < current_layer.len() { + if i + 1 < current_layer.len() { + next_layer.push(hashv(&[ + ¤t_layer[i].to_bytes(), + ¤t_layer[i + 1].to_bytes(), + ])); + i += 2; + } else { + next_layer.push(current_layer[i]); + i += 1; + } + } + current_layer = next_layer; + } + + self.root = if self.root == Hash::default() { + current_layer[0] + } else { + hashv(&[&self.root.to_bytes(), ¤t_layer[0].to_bytes()]) + }; + + Ok(()) + } +}