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

View File

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

View File

@ -1,7 +1,7 @@
use rs_merkle::Hasher;
use sha2::{digest::FixedOutput, Digest, Sha256};
use super::HashType;
use super::TreeHashType;
#[derive(Debug, Clone)]
///Our own hasher.
@ -9,12 +9,12 @@ use super::HashType;
pub struct 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();
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 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 {
leaves: HashMap<usize, Transaction>,
hash_to_id_map: HashMap<HashType, usize>,
pub struct HashStorageMerkleTree<Leav: TreeLeavItem + Clone> {
leaves: HashMap<usize, Leav>,
hash_to_id_map: HashMap<TreeHashType, usize>,
tree: MerkleTree<OwnHasher>,
}
impl PublicTransactionsMerkleTree {
pub fn new(leaves_vec: Vec<Transaction>) -> Self {
pub type PublicTransactionMerkleTree = HashStorageMerkleTree<Transaction>;
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 hash_to_id_map = HashMap::new();
let leaves_hashed: Vec<HashType> = leaves_vec
let leaves_hashed: Vec<TreeHashType> = leaves_vec
.iter()
.enumerate()
.map(|(id, tx)| {
leaves_map.insert(id, tx.clone());
hash_to_id_map.insert(tx.hash, id);
tx.hash
hash_to_id_map.insert(tx.hash(), id);
tx.hash()
})
.collect();
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
.get(&hash)
.and_then(|id| self.leaves.get(id))
}
pub fn get_root(&self) -> Option<HashType> {
pub fn get_root(&self) -> Option<TreeHashType> {
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
.get(&hash)
.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
.iter()
.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();
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();
}
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() {
let last = self.leaves.len();
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
.append(&mut txs.iter().map(|tx| tx.hash).collect());
.append(&mut txs.iter().map(|tx| tx.hash()).collect());
self.tree.commit();
}

View File

@ -1,4 +1,5 @@
pub mod hasher;
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};
pub type TxHash = [u8; 32];
use crate::merkle_tree_public::TreeHashType;
//ToDo: Update Tx model, when it is clear
#[derive(Debug, Serialize, Deserialize, Clone)]
///General transaction object
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,
}