Skip to content

Commit

Permalink
feat(solana): puts BashMerkleTree within shared
Browse files Browse the repository at this point in the history
  • Loading branch information
allemanfredi committed Dec 19, 2024
1 parent 79ac5b8 commit 1e48b5d
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 49 deletions.
10 changes: 10 additions & 0 deletions packages/solana/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/solana/programs/snapshotter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ no-log-ix-name = []
idl-build = ["anchor-lang/idl-build"]

[dependencies]
anchor-lang = "0.30.1"
anchor-lang = "0.30.1"
batch-merkle-tree = { path = "../../shared/batch-merkle-tree" }
49 changes: 1 addition & 48 deletions packages/solana/programs/snapshotter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -169,51 +170,3 @@ pub mod snapshotter {
Ok(())
}
}

pub struct BatchMerkleTree {
pub root: Hash,
}

impl From<Hash> 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<Hash>) -> 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(&[
&current_layer[i].to_bytes(),
&current_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(), &current_layer[0].to_bytes()])
};

Ok(())
}
}
18 changes: 18 additions & 0 deletions packages/solana/shared/batch-merkle-tree/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
50 changes: 50 additions & 0 deletions packages/solana/shared/batch-merkle-tree/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use anchor_lang::prelude::*;
use anchor_lang::solana_program::hash::{hashv, Hash};

pub struct BatchMerkleTree {
pub root: Hash,
}

impl From<Hash> 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<Hash>) -> 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(&[
&current_layer[i].to_bytes(),
&current_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(), &current_layer[0].to_bytes()])
};

Ok(())
}
}

0 comments on commit 1e48b5d

Please sign in to comment.