Merge pull request #16 from vacp2p/utxo_core_testing

UTXO Core testing
This commit is contained in:
tyshko-rostyslav 2024-10-28 15:53:22 -04:00 committed by GitHub
commit 2725e5976a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 207 additions and 2 deletions

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::merkle_tree_public::TreeHashType;
//ToDo: Update Nullifier model, when it is clear
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
///General nullifier object
pub struct UTXONullifier {
pub utxo_hash: TreeHashType,

View File

@ -6,7 +6,7 @@ use storage::{merkle_tree_public::TreeHashType, nullifier::UTXONullifier, Accoun
///Raw asset data
pub type Asset = Vec<u8>;
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq, Clone)]
///Container for raw utxo payload
pub struct UTXO {
pub hash: TreeHashType,
@ -53,3 +53,93 @@ impl UTXO {
Ok(serde_json::from_slice(&self.asset)?)
}
}
#[cfg(test)]
mod tests {
use super::*;
use storage::{merkle_tree_public::TreeHashType, nullifier::UTXONullifier, AccountId};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct TestAsset {
id: u32,
name: String,
}
fn sample_account() -> AccountId {
AccountId::default()
}
fn sample_nullifier() -> UTXONullifier {
UTXONullifier::default()
}
fn sample_tree_hash() -> TreeHashType {
TreeHashType::default()
}
fn sample_payload() -> UTXOPayload {
UTXOPayload {
owner: sample_account(),
asset: serde_json::to_vec(&TestAsset {
id: 1,
name: "Test".to_string(),
})
.unwrap(),
}
}
#[test]
fn test_create_utxo_from_payload() {
let payload = sample_payload();
let utxo = UTXO::create_utxo_from_payload(payload.clone());
// Ensure hash is created and the UTXO fields are correctly assigned
assert_eq!(utxo.owner, payload.owner);
assert_eq!(utxo.asset, payload.asset);
assert!(utxo.nullifier.is_none());
}
#[test]
fn test_consume_utxo() {
let payload = sample_payload();
let mut utxo = UTXO::create_utxo_from_payload(payload);
let nullifier = sample_nullifier();
// First consumption should succeed
assert!(utxo.consume_utxo(nullifier.clone()).is_ok());
assert_eq!(utxo.nullifier, Some(nullifier));
// Second consumption should fail
let result = utxo.consume_utxo(sample_nullifier());
assert!(result.is_err());
}
#[test]
fn test_interpret_asset() {
let payload = sample_payload();
let utxo = UTXO::create_utxo_from_payload(payload);
// Interpret asset as TestAsset
let interpreted: TestAsset = utxo.interpret_asset().unwrap();
assert_eq!(
interpreted,
TestAsset {
id: 1,
name: "Test".to_string()
}
);
}
#[test]
fn test_interpret_invalid_asset() {
let mut payload = sample_payload();
payload.asset = vec![0, 1, 2, 3]; // Invalid data for deserialization
let utxo = UTXO::create_utxo_from_payload(payload);
// This should fail because the asset is not valid JSON for TestAsset
let result: Result<TestAsset> = utxo.interpret_asset();
assert!(result.is_err());
}
}

View File

@ -72,3 +72,118 @@ impl Default for UTXOSparseMerkleTree {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::utxo_core::{UTXOPayload, UTXO};
use storage::{merkle_tree_public::TreeHashType, AccountId};
fn sample_utxo_payload() -> UTXOPayload {
UTXOPayload {
owner: AccountId::default(),
asset: vec![1, 2, 3],
}
}
fn sample_utxo() -> UTXO {
UTXO::create_utxo_from_payload(sample_utxo_payload())
}
#[test]
fn test_utxo_sparse_merkle_tree_new() {
let smt = UTXOSparseMerkleTree::new();
assert!(smt.curr_root.is_none());
assert_eq!(smt.store.len(), 0);
}
#[test]
fn test_insert_item() {
let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo();
let result = smt.insert_item(utxo.clone());
// Test insertion is successful
assert!(result.is_ok());
// Test UTXO is now stored in the tree
assert_eq!(smt.store.get(&utxo.hash).unwrap().hash, utxo.hash);
// Test curr_root is updated
assert!(smt.curr_root.is_some());
}
#[test]
fn test_insert_items() {
let mut smt = UTXOSparseMerkleTree::new();
let utxo1 = sample_utxo();
let utxo2 = sample_utxo();
let result = smt.insert_items(vec![utxo1.clone(), utxo2.clone()]);
// Test insertion of multiple items is successful
assert!(result.is_ok());
// Test UTXOs are now stored in the tree
assert!(smt.store.get(&utxo1.hash).is_some());
assert!(smt.store.get(&utxo2.hash).is_some());
// Test curr_root is updated
assert!(smt.curr_root.is_some());
}
#[test]
fn test_get_item_exists() {
let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo();
smt.insert_item(utxo.clone()).unwrap();
// Test that the UTXO can be retrieved by hash
let retrieved_utxo = smt.get_item(utxo.hash).unwrap();
assert!(retrieved_utxo.is_some());
assert_eq!(retrieved_utxo.unwrap().hash, utxo.hash);
}
#[test]
fn test_get_item_not_exists() {
let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo();
// Insert one UTXO and try to fetch a different hash
smt.insert_item(utxo).unwrap();
let non_existent_hash = TreeHashType::default();
let result = smt.get_item(non_existent_hash).unwrap();
// Test that retrieval for a non-existent UTXO returns None
assert!(result.is_none());
}
#[test]
fn test_get_membership_proof() {
let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo();
smt.insert_item(utxo.clone()).unwrap();
// Fetch membership proof for the inserted UTXO
let proof = smt.get_membership_proof(utxo.hash).unwrap();
// Test proof is generated successfully
assert!(proof.is_some());
}
#[test]
fn test_get_membership_proof_not_exists() {
let mut smt = UTXOSparseMerkleTree::new();
// Try fetching proof for a non-existent UTXO hash
let non_existent_hash = TreeHashType::default();
let proof = smt.get_membership_proof(non_existent_hash).unwrap();
// Test no proof is generated for a non-existent UTXO
assert!(proof.is_none());
}
}