feat: merkle tree genralization and utxo commitment storage

This commit is contained in:
Oleksandr Pravdyvyi 2024-10-14 13:12:59 +03:00
parent 168c06914c
commit bfab324fb2
8 changed files with 64 additions and 29 deletions

View File

@ -1,6 +1,6 @@
use mempool::mempoolitem::MemPoolItem; use mempool::mempoolitem::MemPoolItem;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use storage::transaction::{Transaction, TxHash}; use storage::{merkle_tree_public::TreeHashType, transaction::Transaction};
#[derive(Debug)] #[derive(Debug)]
pub struct TransactionMempool { pub struct TransactionMempool {
@ -29,7 +29,7 @@ impl<'de> Deserialize<'de> for TransactionMempool {
} }
impl MemPoolItem for TransactionMempool { impl MemPoolItem for TransactionMempool {
type Identifier = TxHash; type Identifier = TreeHashType;
fn identifier(&self) -> Self::Identifier { fn identifier(&self) -> Self::Identifier {
self.tx.hash self.tx.hash

View File

@ -11,6 +11,7 @@ pub mod block;
pub mod error; pub mod error;
pub mod merkle_tree_public; pub mod merkle_tree_public;
pub mod transaction; pub mod transaction;
pub mod utxo_commitment;
///Maximal size of stored blocks in base ///Maximal size of stored blocks in base
/// ///

View File

@ -1,7 +1,7 @@
use rs_merkle::Hasher; use rs_merkle::Hasher;
use sha2::{digest::FixedOutput, Digest, Sha256}; use sha2::{digest::FixedOutput, Digest, Sha256};
use super::HashType; use super::TreeHashType;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
///Our own hasher. ///Our own hasher.
@ -9,12 +9,12 @@ use super::HashType;
pub struct OwnHasher {} pub struct OwnHasher {}
impl Hasher for OwnHasher { impl Hasher for OwnHasher {
type Hash = HashType; type Hash = TreeHashType;
fn hash(data: &[u8]) -> HashType { fn hash(data: &[u8]) -> TreeHashType {
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
hasher.update(data); hasher.update(data);
<HashType>::from(hasher.finalize_fixed()) <TreeHashType>::from(hasher.finalize_fixed())
} }
} }

View File

@ -2,28 +2,32 @@ use std::collections::HashMap;
use rs_merkle::{MerkleProof, MerkleTree}; use rs_merkle::{MerkleProof, MerkleTree};
use crate::transaction::Transaction; use crate::{transaction::Transaction, utxo_commitment::UTXOCommitment};
use super::{hasher::OwnHasher, HashType}; use super::{hasher::OwnHasher, tree_leav_item::TreeLeavItem, TreeHashType};
pub struct PublicTransactionsMerkleTree { pub struct HashStorageMerkleTree<Leav: TreeLeavItem + Clone> {
leaves: HashMap<usize, Transaction>, leaves: HashMap<usize, Leav>,
hash_to_id_map: HashMap<HashType, usize>, hash_to_id_map: HashMap<TreeHashType, usize>,
tree: MerkleTree<OwnHasher>, tree: MerkleTree<OwnHasher>,
} }
impl PublicTransactionsMerkleTree { pub type PublicTransactionMerkleTree = HashStorageMerkleTree<Transaction>;
pub fn new(leaves_vec: Vec<Transaction>) -> Self {
pub type UTXOCommitmentsMerkleTree = HashStorageMerkleTree<UTXOCommitment>;
impl<Leav: TreeLeavItem + Clone> HashStorageMerkleTree<Leav> {
pub fn new(leaves_vec: Vec<Leav>) -> Self {
let mut leaves_map = HashMap::new(); let mut leaves_map = HashMap::new();
let mut hash_to_id_map = HashMap::new(); let mut hash_to_id_map = HashMap::new();
let leaves_hashed: Vec<HashType> = leaves_vec let leaves_hashed: Vec<TreeHashType> = leaves_vec
.iter() .iter()
.enumerate() .enumerate()
.map(|(id, tx)| { .map(|(id, tx)| {
leaves_map.insert(id, tx.clone()); leaves_map.insert(id, tx.clone());
hash_to_id_map.insert(tx.hash, id); hash_to_id_map.insert(tx.hash(), id);
tx.hash tx.hash()
}) })
.collect(); .collect();
Self { Self {
@ -33,23 +37,23 @@ impl PublicTransactionsMerkleTree {
} }
} }
pub fn get_tx(&self, hash: HashType) -> Option<&Transaction> { pub fn get_tx(&self, hash: TreeHashType) -> Option<&Leav> {
self.hash_to_id_map self.hash_to_id_map
.get(&hash) .get(&hash)
.and_then(|id| self.leaves.get(id)) .and_then(|id| self.leaves.get(id))
} }
pub fn get_root(&self) -> Option<HashType> { pub fn get_root(&self) -> Option<TreeHashType> {
self.tree.root() self.tree.root()
} }
pub fn get_proof(&self, hash: HashType) -> Option<MerkleProof<OwnHasher>> { pub fn get_proof(&self, hash: TreeHashType) -> Option<MerkleProof<OwnHasher>> {
self.hash_to_id_map self.hash_to_id_map
.get(&hash) .get(&hash)
.map(|id| self.tree.proof(&[*id])) .map(|id| self.tree.proof(&[*id]))
} }
pub fn get_proof_multiple(&self, hashes: &[HashType]) -> Option<MerkleProof<OwnHasher>> { pub fn get_proof_multiple(&self, hashes: &[TreeHashType]) -> Option<MerkleProof<OwnHasher>> {
let ids_opt: Vec<Option<&usize>> = hashes let ids_opt: Vec<Option<&usize>> = hashes
.iter() .iter()
.map(|hash| self.hash_to_id_map.get(hash)) .map(|hash| self.hash_to_id_map.get(hash))
@ -66,27 +70,27 @@ impl PublicTransactionsMerkleTree {
} }
} }
pub fn add_tx(&mut self, tx: Transaction) { pub fn add_tx(&mut self, tx: Leav) {
let last = self.leaves.len(); let last = self.leaves.len();
self.leaves.insert(last, tx.clone()); self.leaves.insert(last, tx.clone());
self.hash_to_id_map.insert(tx.hash, last); self.hash_to_id_map.insert(tx.hash(), last);
self.tree.insert(tx.hash); self.tree.insert(tx.hash());
self.tree.commit(); self.tree.commit();
} }
pub fn add_tx_multiple(&mut self, txs: Vec<Transaction>) { pub fn add_tx_multiple(&mut self, txs: Vec<Leav>) {
for tx in txs.iter() { for tx in txs.iter() {
let last = self.leaves.len(); let last = self.leaves.len();
self.leaves.insert(last, tx.clone()); self.leaves.insert(last, tx.clone());
self.hash_to_id_map.insert(tx.hash, last); self.hash_to_id_map.insert(tx.hash(), last);
} }
self.tree self.tree
.append(&mut txs.iter().map(|tx| tx.hash).collect()); .append(&mut txs.iter().map(|tx| tx.hash()).collect());
self.tree.commit(); self.tree.commit();
} }

View File

@ -1,4 +1,5 @@
pub mod hasher; pub mod hasher;
pub mod merkle_tree; pub mod merkle_tree;
pub mod tree_leav_item;
pub type HashType = [u8; 32]; pub type TreeHashType = [u8; 32];

View File

@ -0,0 +1,19 @@
use crate::{transaction::Transaction, utxo_commitment::UTXOCommitment};
use super::TreeHashType;
pub trait TreeLeavItem {
fn hash(&self) -> TreeHashType;
}
impl TreeLeavItem for Transaction {
fn hash(&self) -> TreeHashType {
self.hash
}
}
impl TreeLeavItem for UTXOCommitment {
fn hash(&self) -> TreeHashType {
self.hash
}
}

View File

@ -1,10 +1,10 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub type TxHash = [u8; 32]; use crate::merkle_tree_public::TreeHashType;
//ToDo: Update Tx model, when it is clear //ToDo: Update Tx model, when it is clear
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
///General transaction object ///General transaction object
pub struct Transaction { pub struct Transaction {
pub hash: TxHash, pub hash: TreeHashType,
} }

View File

@ -0,0 +1,10 @@
use serde::{Deserialize, Serialize};
use crate::merkle_tree_public::TreeHashType;
//ToDo: Update UTXO Commitment model, when it is clear
#[derive(Debug, Serialize, Deserialize, Clone)]
///General commitment object
pub struct UTXOCommitment {
pub hash: TreeHashType,
}