From dd13423c2b67e9ca1a1348a005bb09d9264b6807 Mon Sep 17 00:00:00 2001 From: NicolasCantu Date: Wed, 19 Mar 2025 11:47:19 +0100 Subject: [PATCH] Update tests --- src/pcd.rs | 175 +++++++++++++++++++------------------------------ src/process.rs | 56 +++++++++------- 2 files changed, 100 insertions(+), 131 deletions(-) diff --git a/src/pcd.rs b/src/pcd.rs index 1598c49..217a527 100644 --- a/src/pcd.rs +++ b/src/pcd.rs @@ -487,7 +487,7 @@ impl Roles { #[cfg(test)] mod tests { - use std::str::FromStr; + use std::{collections::HashMap, str::FromStr}; use serde_json::json; use sp_client::{ bitcoin::{secp256k1::SecretKey, Network}, @@ -548,6 +548,21 @@ mod tests { .unwrap() } + fn get_members_map(addresses: [String; 2]) -> HashMap { + let alice_address = &addresses[0]; + let bob_address = &addresses[1]; + HashMap::from([ + ( + OutPoint::from_str("b2f105a9df436d16b99e46453b15a0ffc584d136ceda35c0baea28e7e3ade8be:0").unwrap(), + Member::new(vec![SilentPaymentAddress::try_from(alice_address.as_str()).unwrap()]) + ), + ( + OutPoint::from_str("3cb9e3bf8ec72625c0347a665ab383fda9213d4544ff114ac800a9837b585897:0").unwrap(), + Member::new(vec![SilentPaymentAddress::try_from(bob_address.as_str()).unwrap()]) + ) + ]) + } + #[test] fn test_validation_rule_new() { // Valid input @@ -608,18 +623,12 @@ mod tests { let alice_proof = Proof::new(AnkHash::ValidationNo(validation_hash2), alice_spend_key); let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash1), bob_spend_key); - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; + let members_list = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address() + ]); + + let members: Vec<&Member> = members_list.values().collect(); // We test that the rule is satisfied with only bob proof let result = validation_rule.is_satisfied( @@ -677,18 +686,12 @@ mod tests { let proofs = vec![alice_proof, bob_proof]; - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; + let members_list = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address() + ]); + + let members: Vec<&Member> = members_list.values().collect(); // Test with empty members list let result = @@ -730,18 +733,12 @@ mod tests { let proofs = vec![alice_proof_1, alice_proof_2]; - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; + let members_list = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address() + ]); + + let members: Vec<&Member> = members_list.values().collect(); // Test case where both proofs are signed by Alice, but both Alice and Bob are passed as members let result = @@ -778,18 +775,12 @@ mod tests { let proofs = vec![alice_proof_1, alice_proof_2]; - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; + let members_list = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address() + ]); + + let members: Vec<&Member> = members_list.values().collect(); // Test case where quorum is 0.5, but Alice provides two proofs. This should fail since the quorum requires different members. let result = @@ -807,8 +798,7 @@ mod tests { let member = Member::new(vec![SilentPaymentAddress::try_from( alice_wallet.get_client().get_receiving_address(), ) - .unwrap()]) - .unwrap(); + .unwrap()]); let clear_state_value = json!({"field1": "value1", "field2": "value2"}); let pcd: BTreeMap = serde_json::from_value(clear_state_value).unwrap(); let public_data = BTreeMap::new(); @@ -837,19 +827,10 @@ mod tests { let alice_wallet = create_alice_wallet(); let bob_wallet = create_bob_wallet(); - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; - + let members = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address(), + ]); let fields = vec!["field1".to_string(), "field2".to_string()]; let validation_rule1 = ValidationRule::new(1.0, vec![fields[0].clone()], 0.5).unwrap(); let validation_rule2 = ValidationRule::new(1.0, vec![fields[1].clone()], 0.5).unwrap(); @@ -858,7 +839,7 @@ mod tests { // 2 rules, to modify each field, all members must agree let role_def = RoleDefinition { - members: members.clone(), + members: members.keys().map(|k| *k).collect(), validation_rules: rules.clone(), storages: vec![], }; @@ -889,26 +870,18 @@ mod tests { let modified_fields: Vec = new_state.as_object().unwrap().iter().map(|(key, _)| key.clone()).collect(); - assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs).is_ok()); + assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs, &OutPointMemberMap(members)).is_ok()); } #[test] fn test_no_rule_satisfied() { let alice_wallet = create_alice_wallet(); let bob_wallet = create_bob_wallet(); - - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; + + let members_list = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address() + ]); let fields = vec!["field1".to_string(), "field2".to_string()]; let validation_rule1 = ValidationRule::new(1.0, vec![fields[0].clone()], 0.5).unwrap(); @@ -918,7 +891,7 @@ mod tests { // 2 rules, to modify each field, all members must agree let role_def = RoleDefinition { - members: members.clone(), + members: members_list.keys().cloned().collect(), validation_rules: rules.clone(), storages: vec![], }; @@ -950,7 +923,7 @@ mod tests { let modified_fields: Vec = new_state.as_object().unwrap().iter().map(|(key, _)| key.clone()).collect(); - assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs).is_err()); + assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs, &OutPointMemberMap(members_list)).is_err()); } #[test] @@ -958,18 +931,10 @@ mod tests { let alice_wallet = create_alice_wallet(); let bob_wallet = create_bob_wallet(); - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; + let members = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address(), + ]); let fields = vec!["field1".to_string(), "field2".to_string()]; let validation_rule1 = ValidationRule::new(1.0, vec![fields[0].clone()], 0.5).unwrap(); @@ -979,7 +944,7 @@ mod tests { // 2 rules, to modify each field, all members must agree let role_def = RoleDefinition { - members: members.clone(), + members: members.keys().cloned().collect(), validation_rules: rules.clone(), storages: vec![], }; @@ -1011,7 +976,7 @@ mod tests { let modified_fields: Vec = new_state.as_object().unwrap().iter().map(|(key, _)| key.clone()).collect(); - assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs).is_ok()); + assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs, &OutPointMemberMap(members)).is_ok()); } #[test] @@ -1019,18 +984,10 @@ mod tests { let alice_wallet = create_alice_wallet(); let bob_wallet = create_bob_wallet(); - let members = vec![ - Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - Member::new(vec![SilentPaymentAddress::try_from( - bob_wallet.get_client().get_receiving_address(), - ) - .unwrap()]) - .unwrap(), - ]; + let members = get_members_map([ + alice_wallet.get_client().get_receiving_address(), + bob_wallet.get_client().get_receiving_address(), + ]); let fields = vec!["field1".to_string(), "field2".to_string()]; let validation_rule1 = ValidationRule::new(1.0, vec![fields[0].clone()], 0.5).unwrap(); @@ -1040,7 +997,7 @@ mod tests { // 2 rules, to modify each field, all members must agree let role_def = RoleDefinition { - members: members.clone(), + members: members.keys().cloned().collect(), validation_rules: rules.clone(), storages: vec![], }; @@ -1072,7 +1029,7 @@ mod tests { let modified_fields: Vec = new_state.as_object().unwrap().iter().map(|(key, _)| key.clone()).collect(); - assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs).is_err()); + assert!(role_def.is_satisfied(modified_fields, new_state_merkle_root, &proofs, &OutPointMemberMap(members)).is_err()); } #[test] diff --git a/src/process.rs b/src/process.rs index e1da12a..27cf2f2 100644 --- a/src/process.rs +++ b/src/process.rs @@ -9,7 +9,7 @@ use sp_client::bitcoin::{OutPoint, Transaction}; use tsify::Tsify; use crate::{ - pcd::{Member, Pcd, PcdCommitments, RoleDefinition, Roles}, serialization::{deserialize_hex, hex_array_btree, serialize_hex}, signature::{AnkHash, AnkValidationNoHash, AnkValidationYesHash, Proof}, MutexExt, SpecialRoles + pcd::{Member, Pcd, PcdCommitments, RoleDefinition, Roles}, serialization::{deserialize_hex, hex_array_btree, serialize_hex, OutPointMemberMap}, signature::{AnkHash, AnkValidationNoHash, AnkValidationYesHash, Proof}, MutexExt, SpecialRoles }; const OBLITERATION_MSG: [u8; 32] = [167, 164, 238, 168, 233, 235, 152, 107, 194, 162, 145, 42, 140, 11, 244, 71, 252, 67, 204, 207, 114, 85, 209, 80, 129, 190, 151, 172, 77, 174, 243, 1]; @@ -542,6 +542,10 @@ mod tests { use super::*; + const ALICE_BOB_PAIRING: &str = "fcd21fcf92c8ddd74bb2726138bee9951946ca03b10c1297accd67da159df82b:0"; + const CAROL_PAIRING: &str = "a4f3d2d5ca7af258e6a2c1cfe85b85d4e3f3d1387417fd64012d3c7bfb95a9e9:0"; + const DAVE_PAIRING: &str = "bd21f6acdd0e026e8c02298a51ec40dfaced34d95aec685f407ab5ac91b5f775:0"; + fn create_alice_wallet() -> SpWallet { SpWallet::new( SpClient::new( @@ -638,7 +642,7 @@ mod tests { .unwrap() } - fn dummy_process_state() -> ProcessState { + fn get_members_map() -> HashMap { let alice_wallet = create_alice_wallet(); let bob_wallet = create_bob_wallet(); let carol_wallet = create_carol_wallet(); @@ -657,10 +661,16 @@ mod tests { SilentPaymentAddress::try_from(dave_wallet.get_client().get_receiving_address()) .unwrap(); - let alice_bob = Member::new(vec![alice_address, bob_address]).unwrap(); - let carol = Member::new(vec![carol_address]).unwrap(); - let dave = Member::new(vec![dave_address]).unwrap(); + let members_map: HashMap = HashMap::from([ + (OutPoint::from_str(ALICE_BOB_PAIRING).unwrap(), Member::new(vec![alice_address, bob_address])), + (OutPoint::from_str(CAROL_PAIRING).unwrap(), Member::new(vec![carol_address])), + (OutPoint::from_str(DAVE_PAIRING).unwrap(), Member::new(vec![dave_address])), + ]); + members_map + } + + fn dummy_process_state() -> ProcessState { let validation_rule1 = ValidationRule::new(1.0, vec!["field1".to_owned()], 0.5).unwrap(); let validation_rule2 = ValidationRule::new(1.0, vec!["field2".to_owned()], 0.5).unwrap(); @@ -669,30 +679,30 @@ mod tests { let apophis_rule = ValidationRule::new(1.0, vec!["".to_owned()], 1.0).unwrap(); let role_def1 = RoleDefinition { - members: vec![alice_bob.clone()], + members: vec![OutPoint::from_str(ALICE_BOB_PAIRING).unwrap()], validation_rules: vec![validation_rule1], storages: vec![] }; let role_def2 = RoleDefinition { - members: vec![carol], + members: vec![OutPoint::from_str(CAROL_PAIRING).unwrap()], validation_rules: vec![validation_rule2], storages: vec![] }; let role_def_roles = RoleDefinition { - members: vec![alice_bob.clone()], + members: vec![OutPoint::from_str(ALICE_BOB_PAIRING).unwrap()], validation_rules: vec![validation_rule3], storages: vec![] }; let role_def_public_data = RoleDefinition { - members: vec![alice_bob], + members: vec![OutPoint::from_str(ALICE_BOB_PAIRING).unwrap()], validation_rules: vec![validation_rule4], storages: vec![] }; let role_def_apophis = RoleDefinition { - members: vec![dave], + members: vec![OutPoint::from_str(DAVE_PAIRING).unwrap()], validation_rules: vec![apophis_rule], storages: vec![] }; @@ -723,7 +733,8 @@ mod tests { #[test] fn test_error_no_proofs() { let state = dummy_process_state(); - let result = state.is_valid(None); + let members_map = get_members_map(); + let result = state.is_valid(None, &OutPointMemberMap(members_map)); assert!(result.is_err()); assert_eq!( result.unwrap_err().to_string(), @@ -740,7 +751,8 @@ mod tests { .unwrap(); let message_hash = state.get_message_hash(true).unwrap(); state.validation_tokens.push(Proof::new(message_hash, signing_key)); - let result = state.is_valid(Some(&state)); + let members_map = get_members_map(); + let result = state.is_valid(Some(&state), &OutPointMemberMap(members_map)); assert!(result.is_err()); assert_eq!( result.unwrap_err().to_string(), @@ -758,7 +770,7 @@ mod tests { .unwrap(); let message_hash = state.get_message_hash(true).unwrap(); state.validation_tokens.push(Proof::new(message_hash, signing_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_err()); assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs"); } @@ -775,7 +787,7 @@ mod tests { .unwrap(); let message_hash = state.get_message_hash(true).unwrap(); state.validation_tokens.push(Proof::new(message_hash, carol_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_err()); assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs"); } @@ -798,7 +810,7 @@ mod tests { let message_hash = state.get_message_hash(true).unwrap(); state.validation_tokens.push(Proof::new(message_hash, alice_key)); state.validation_tokens.push(Proof::new(message_hash, carol_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_ok()); } @@ -825,7 +837,7 @@ mod tests { state.validation_tokens.push(Proof::new(message_hash, alice_key)); state.validation_tokens.push(Proof::new(message_hash, bob_key)); state.validation_tokens.push(Proof::new(message_hash, carol_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_ok()); } @@ -853,7 +865,7 @@ mod tests { .unwrap(); let message_hash = empty_state.get_message_hash(true).unwrap(); state.validation_tokens.push(Proof::new(message_hash, carol_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_err()); } @@ -881,7 +893,7 @@ mod tests { .unwrap(); let message_hash = empty_state.get_message_hash(true).unwrap(); state.validation_tokens.push(Proof::new(message_hash, dave_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_ok()); } @@ -909,7 +921,7 @@ mod tests { state.validation_tokens.push(Proof::new(message_hash_yes, alice_key)); state.validation_tokens.push(Proof::new(message_hash_yes, bob_key)); state.validation_tokens.push(Proof::new(message_hash_no, carol_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_err()); assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs"); } @@ -938,7 +950,7 @@ mod tests { state.validation_tokens.push(Proof::new(message_hash_yes, alice_key)); state.validation_tokens.push(Proof::new(message_hash_no, bob_key)); state.validation_tokens.push(Proof::new(message_hash_yes, carol_key)); - let result = state.is_valid(None); + let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); assert!(result.is_ok()); } @@ -968,7 +980,7 @@ mod tests { new_state.validation_tokens.push(Proof::new(message_hash, alice_key)); new_state.validation_tokens.push(Proof::new(message_hash, bob_key)); new_state.validation_tokens.push(Proof::new(message_hash, carol_key)); - let result = new_state.is_valid(Some(&state)); + let result = new_state.is_valid(Some(&state), &OutPointMemberMap(get_members_map())); assert!(result.is_ok()); } @@ -986,7 +998,7 @@ mod tests { .unwrap(); let message_hash = new_state.get_message_hash(true).unwrap(); new_state.validation_tokens.push(Proof::new(message_hash, carol_key)); - let result = new_state.is_valid(Some(&state)); + let result = new_state.is_valid(Some(&state), &OutPointMemberMap(get_members_map())); assert!(result.is_err()); } }