From 191019beaa97029e0e73be2787ed8fd465c0cd55 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:36:10 +0200 Subject: [PATCH 01/14] setup for core --- storage/src/nullifier.rs | 2 +- utxo/src/utxo_core.rs | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/storage/src/nullifier.rs b/storage/src/nullifier.rs index 050c1804..5033fa60 100644 --- a/storage/src/nullifier.rs +++ b/storage/src/nullifier.rs @@ -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, diff --git a/utxo/src/utxo_core.rs b/utxo/src/utxo_core.rs index d0765988..432a012e 100644 --- a/utxo/src/utxo_core.rs +++ b/utxo/src/utxo_core.rs @@ -6,7 +6,7 @@ use storage::{merkle_tree_public::TreeHashType, nullifier::UTXONullifier, Accoun ///Raw asset data pub type Asset = Vec; -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Clone)] ///Container for raw utxo payload pub struct UTXO { pub hash: TreeHashType, @@ -53,3 +53,36 @@ 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(), + } + } + + +} From 85561bf4ddeca159a725e59d6ccc82799e421819 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:36:36 +0200 Subject: [PATCH 02/14] add test_create_utxo_from_payload --- utxo/src/utxo_core.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/utxo/src/utxo_core.rs b/utxo/src/utxo_core.rs index 432a012e..bf20d4f3 100644 --- a/utxo/src/utxo_core.rs +++ b/utxo/src/utxo_core.rs @@ -84,5 +84,16 @@ mod tests { } } + #[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()); + } + } From 19c915d3547a856b8e7b662ecab45fa5ac6c9d95 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:36:49 +0200 Subject: [PATCH 03/14] add test_consume_utxo --- utxo/src/utxo_core.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/utxo/src/utxo_core.rs b/utxo/src/utxo_core.rs index bf20d4f3..250daedc 100644 --- a/utxo/src/utxo_core.rs +++ b/utxo/src/utxo_core.rs @@ -95,5 +95,20 @@ mod tests { 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()); + } } From 150652c7791a86a950600fb98dd788664322c66f Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:37:02 +0200 Subject: [PATCH 04/14] add test_interpret_asset --- utxo/src/utxo_core.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/utxo/src/utxo_core.rs b/utxo/src/utxo_core.rs index 250daedc..1be43226 100644 --- a/utxo/src/utxo_core.rs +++ b/utxo/src/utxo_core.rs @@ -111,4 +111,16 @@ mod tests { 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() }); + } + + } From 85102cb8939e90c62c3aa54e0ca7aaf761adaa84 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:37:11 +0200 Subject: [PATCH 05/14] add test_interpret_invalid_asset --- utxo/src/utxo_core.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/utxo/src/utxo_core.rs b/utxo/src/utxo_core.rs index 1be43226..3e70d998 100644 --- a/utxo/src/utxo_core.rs +++ b/utxo/src/utxo_core.rs @@ -122,5 +122,14 @@ mod tests { 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 = utxo.interpret_asset(); + assert!(result.is_err()); + } } From e4752000d497f419d6e071c2b2aa6a2a9e239052 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:38:15 +0200 Subject: [PATCH 06/14] setup for utxo tree --- utxo/src/utxo_tree.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index 147c4580..6c265e6c 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -72,3 +72,23 @@ impl Default for UTXOSparseMerkleTree { Self::new() } } + +#[cfg(test)] +mod tests { + use super::*; + use storage::{merkle_tree_public::TreeHashType, AccountId}; + use crate::utxo_core::{UTXO, UTXOPayload}; + + 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()) + } + + +} From fef23fb3b5a42638d262d0e1ee8bc9a4d4144ddb Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:38:30 +0200 Subject: [PATCH 07/14] add test_utxo_sparse_merkle_tree_new --- utxo/src/utxo_tree.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index 6c265e6c..582bb5f2 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -90,5 +90,11 @@ mod tests { 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); + } } From 887a8d960027e76c1691be24b1f5c17c29afbe4e Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:38:47 +0200 Subject: [PATCH 08/14] add test_insert_item --- utxo/src/utxo_tree.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index 582bb5f2..8d9d126f 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -97,4 +97,22 @@ mod tests { 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()); + } + + } From c14b5a59be3663e3422e2501ecca74cc174e4483 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:39:03 +0200 Subject: [PATCH 09/14] add test_insert_items --- utxo/src/utxo_tree.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index 8d9d126f..b9ffa53e 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -114,5 +114,23 @@ mod tests { 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()); + } } From e96b2c58c737fdd4ca3fed5fd14cd3453a00c649 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:39:20 +0200 Subject: [PATCH 10/14] add test_get_item_exists --- utxo/src/utxo_tree.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index b9ffa53e..8b28de1e 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -133,4 +133,17 @@ mod tests { 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); + } + } From 552b285b2f6bbcdbb74ee39577b2d345423dc23d Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:39:33 +0200 Subject: [PATCH 11/14] add test_get_item_not_exists --- utxo/src/utxo_tree.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index 8b28de1e..462ed9fa 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -146,4 +146,19 @@ mod tests { 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()); + } + } From dd755f4ba3a0d13ab86d05cc35a056ce41b4619f Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:39:45 +0200 Subject: [PATCH 12/14] add test_get_membership_proof --- utxo/src/utxo_tree.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index 462ed9fa..b696411e 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -161,4 +161,19 @@ mod tests { 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()); + } + + } From 4de3f95f1f6fca660266749902a21dc3a1fe0457 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:39:55 +0200 Subject: [PATCH 13/14] add test_get_membership_proof_not_exists --- utxo/src/utxo_tree.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index b696411e..9e78aff4 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -175,5 +175,15 @@ mod tests { 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()); + } } From 93216a16eaca02fd8ca827a5729f5348eb672676 Mon Sep 17 00:00:00 2001 From: Rostyslav Tyshko Date: Fri, 25 Oct 2024 00:53:06 +0200 Subject: [PATCH 14/14] fmt --- utxo/src/utxo_core.rs | 14 ++++++++++++-- utxo/src/utxo_tree.rs | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/utxo/src/utxo_core.rs b/utxo/src/utxo_core.rs index 3e70d998..834c4c1c 100644 --- a/utxo/src/utxo_core.rs +++ b/utxo/src/utxo_core.rs @@ -80,7 +80,11 @@ mod tests { fn sample_payload() -> UTXOPayload { UTXOPayload { owner: sample_account(), - asset: serde_json::to_vec(&TestAsset { id: 1, name: "Test".to_string() }).unwrap(), + asset: serde_json::to_vec(&TestAsset { + id: 1, + name: "Test".to_string(), + }) + .unwrap(), } } @@ -119,7 +123,13 @@ mod tests { // Interpret asset as TestAsset let interpreted: TestAsset = utxo.interpret_asset().unwrap(); - assert_eq!(interpreted, TestAsset { id: 1, name: "Test".to_string() }); + assert_eq!( + interpreted, + TestAsset { + id: 1, + name: "Test".to_string() + } + ); } #[test] diff --git a/utxo/src/utxo_tree.rs b/utxo/src/utxo_tree.rs index 9e78aff4..b391fc0b 100644 --- a/utxo/src/utxo_tree.rs +++ b/utxo/src/utxo_tree.rs @@ -76,8 +76,8 @@ impl Default for UTXOSparseMerkleTree { #[cfg(test)] mod tests { use super::*; + use crate::utxo_core::{UTXOPayload, UTXO}; use storage::{merkle_tree_public::TreeHashType, AccountId}; - use crate::utxo_core::{UTXO, UTXOPayload}; fn sample_utxo_payload() -> UTXOPayload { UTXOPayload {