mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-02 13:23:10 +00:00
feat: utxo core added
This commit is contained in:
parent
a4904c5b8a
commit
33522b6e4c
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -2030,8 +2030,11 @@ dependencies = [
|
||||
"anyhow",
|
||||
"env_logger",
|
||||
"log",
|
||||
"monotree",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"storage",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@ -3,6 +3,7 @@ use std::{path::Path, sync::Arc};
|
||||
use block::Block;
|
||||
use error::DbError;
|
||||
use log::warn;
|
||||
use merkle_tree_public::TreeHashType;
|
||||
use rocksdb::{
|
||||
BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options,
|
||||
};
|
||||
@ -15,6 +16,9 @@ pub mod nullifier_sparse_merkle_tree;
|
||||
pub mod transaction;
|
||||
pub mod utxo_commitment;
|
||||
|
||||
///Account id on blockchain
|
||||
pub type AccountId = TreeHashType;
|
||||
|
||||
///Maximal size of stored blocks in base
|
||||
///
|
||||
///Used to control db size
|
||||
|
||||
@ -8,4 +8,9 @@ anyhow.workspace = true
|
||||
serde_json.workspace = true
|
||||
env_logger.workspace = true
|
||||
log.workspace = true
|
||||
serde.workspace = true
|
||||
serde.workspace = true
|
||||
monotree.workspace = true
|
||||
sha2.workspace = true
|
||||
|
||||
[dependencies.storage]
|
||||
path = "../storage"
|
||||
@ -1 +1,2 @@
|
||||
//ToDo: Add utxo module
|
||||
pub mod utxo_core;
|
||||
pub mod utxo_tree;
|
||||
|
||||
55
utxo/src/utxo_core.rs
Normal file
55
utxo/src/utxo_core.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{digest::FixedOutput, Digest};
|
||||
use storage::{merkle_tree_public::TreeHashType, nullifier::UTXONullifier, AccountId};
|
||||
|
||||
///Raw asset data
|
||||
pub type Asset = Vec<u8>;
|
||||
|
||||
#[derive(Debug)]
|
||||
///Container for raw utxo payload
|
||||
pub struct UTXO {
|
||||
pub hash: TreeHashType,
|
||||
pub owner: AccountId,
|
||||
pub nullifier: Option<UTXONullifier>,
|
||||
pub asset: Asset,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct UTXOPayload {
|
||||
pub owner: AccountId,
|
||||
pub asset: Asset,
|
||||
}
|
||||
|
||||
impl UTXO {
|
||||
pub fn create_utxo_from_payload(payload_with_asset: UTXOPayload) -> Self {
|
||||
let raw_payload = serde_json::to_vec(&payload_with_asset).unwrap();
|
||||
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
|
||||
hasher.update(&raw_payload);
|
||||
|
||||
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
||||
|
||||
Self {
|
||||
hash,
|
||||
owner: payload_with_asset.owner,
|
||||
nullifier: None,
|
||||
asset: payload_with_asset.asset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn consume_utxo(&mut self, nullifier: UTXONullifier) -> Result<()> {
|
||||
if self.nullifier.is_some() {
|
||||
anyhow::bail!("UTXO already consumed");
|
||||
} else {
|
||||
self.nullifier = Some(nullifier);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn interpret_asset<'de, ToInterpret: Deserialize<'de>>(&'de self) -> Result<ToInterpret> {
|
||||
Ok(serde_json::from_slice(&self.asset)?)
|
||||
}
|
||||
}
|
||||
74
utxo/src/utxo_tree.rs
Normal file
74
utxo/src/utxo_tree.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use monotree::database::MemoryDB;
|
||||
use monotree::hasher::Blake3;
|
||||
use monotree::{Hasher, Monotree, Proof};
|
||||
use storage::merkle_tree_public::TreeHashType;
|
||||
|
||||
use crate::utxo_core::UTXO;
|
||||
|
||||
pub struct UTXOSparseMerkleTree {
|
||||
pub curr_root: Option<TreeHashType>,
|
||||
pub tree: Monotree<MemoryDB, Blake3>,
|
||||
pub hasher: Blake3,
|
||||
pub store: HashMap<TreeHashType, UTXO>,
|
||||
}
|
||||
|
||||
impl UTXOSparseMerkleTree {
|
||||
pub fn new() -> Self {
|
||||
UTXOSparseMerkleTree {
|
||||
curr_root: None,
|
||||
tree: Monotree::default(),
|
||||
hasher: Blake3::new(),
|
||||
store: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_item(&mut self, utxo: UTXO) -> Result<(), monotree::Errors> {
|
||||
let root = self.curr_root.as_ref();
|
||||
|
||||
let new_root = self.tree.insert(root, &utxo.hash, &utxo.hash)?;
|
||||
|
||||
self.store.insert(utxo.hash, utxo);
|
||||
|
||||
self.curr_root = new_root;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn insert_items(&mut self, utxos: Vec<UTXO>) -> Result<(), monotree::Errors> {
|
||||
let root = self.curr_root.as_ref();
|
||||
|
||||
let hashes: Vec<TreeHashType> = utxos.iter().map(|item| item.hash).collect();
|
||||
|
||||
let new_root = self.tree.inserts(root, &hashes, &hashes)?;
|
||||
|
||||
for utxo in utxos {
|
||||
self.store.insert(utxo.hash, utxo);
|
||||
}
|
||||
|
||||
self.curr_root = new_root;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_item(&mut self, hash: TreeHashType) -> Result<Option<&UTXO>, monotree::Errors> {
|
||||
let hash = self.tree.get(self.curr_root.as_ref(), &hash)?;
|
||||
|
||||
Ok(hash.and_then(|hash| self.store.get(&hash)))
|
||||
}
|
||||
|
||||
pub fn get_membership_proof(
|
||||
&mut self,
|
||||
nullifier_hash: TreeHashType,
|
||||
) -> Result<Option<Proof>, monotree::Errors> {
|
||||
self.tree
|
||||
.get_merkle_proof(self.curr_root.as_ref(), &nullifier_hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for UTXOSparseMerkleTree {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user