Update process tests

This commit is contained in:
NicolasCantu 2025-03-26 12:38:30 +01:00
parent 0175c793bb
commit a686870e08

View File

@ -250,6 +250,7 @@ impl ProcessState {
/// A process is basically a succession of states /// A process is basically a succession of states
/// The latest state MUST be an empty state with only the commited_in field set at the last unspent outpoint /// The latest state MUST be an empty state with only the commited_in field set at the last unspent outpoint
/// Commiting this last empty state in a transaction is called obliterating a process, basically terminating it
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize, Tsify)] #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize, Tsify)]
#[tsify(into_wasm_abi, from_wasm_abi)] #[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Process { pub struct Process {
@ -755,6 +756,51 @@ mod tests {
ProcessState::new(outpoint, Pcd::new(clear_pcd), Pcd::new(public_data), Roles::new(roles)).unwrap() ProcessState::new(outpoint, Pcd::new(clear_pcd), Pcd::new(public_data), Roles::new(roles)).unwrap()
} }
fn create_pairing_process_one() -> ProcessState {
let carol_wallet = create_carol_wallet();
let carol_address = carol_wallet.get_client().get_receiving_address();
let pairing_rule =
ValidationRule::new(1.0, vec![PAIREDADDRESSES.to_owned()], 1.0).unwrap();
let pairing_role_def = RoleDefinition {
members: vec![],
validation_rules: vec![pairing_rule],
storages: vec![]
};
let outpoint = OutPoint::from_str("8425e9749957fd8ca83460c21718be4017692fd3ae61cbb0f0d401e7a5ddce6a:0").unwrap();
let private_data = BTreeMap::from([("description".to_owned(), Value::String("pairing".to_owned()))]);
let paired_addresses = Value::Array(vec![carol_address.try_into().unwrap()]);
ProcessState::new(outpoint, Pcd::new(private_data), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), Roles::new(BTreeMap::from([(PAIRING.to_owned(), pairing_role_def)]))).unwrap()
}
fn create_pairing_process_two() -> ProcessState {
let carol_wallet = create_carol_wallet();
let carol_address = carol_wallet.get_client().get_receiving_address();
let dave_wallet = create_dave_wallet();
let dave_address = dave_wallet.get_client().get_receiving_address();
let pairing_rule =
ValidationRule::new(1.0, vec![PAIREDADDRESSES.to_owned()], 1.0).unwrap();
let pairing_role_def = RoleDefinition {
members: vec![],
validation_rules: vec![pairing_rule],
storages: vec![]
};
let outpoint = OutPoint::from_str("8425e9749957fd8ca83460c21718be4017692fd3ae61cbb0f0d401e7a5ddce6a:0").unwrap();
let private_data = BTreeMap::from([("description".to_owned(), Value::String("pairing".to_owned()))]);
let paired_addresses = Value::Array(vec![
carol_address.try_into().unwrap(),
dave_address.try_into().unwrap()
]);
ProcessState::new(outpoint, Pcd::new(private_data), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), Roles::new(BTreeMap::from([(PAIRING.to_owned(), pairing_role_def)]))).unwrap()
}
#[test] #[test]
fn test_error_no_proofs() { fn test_error_no_proofs() {
let state = dummy_process_state(); let state = dummy_process_state();
@ -767,24 +813,6 @@ mod tests {
); );
} }
#[test]
fn test_error_identical_previous_state() {
let mut state = dummy_process_state();
// We sign with a random key
let signing_key =
SecretKey::from_str("39b2a765dc93e02da04a0e9300224b4f99fa7b83cfae49036dff58613fd3277c")
.unwrap();
let message_hash = state.get_message_hash(true).unwrap();
state.validation_tokens.push(Proof::new(message_hash, signing_key));
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(),
"State is identical to the previous state"
);
}
#[test] #[test]
/// We provide a proof signed with a key that is not the spending key for either alice or bob /// We provide a proof signed with a key that is not the spending key for either alice or bob
fn test_error_invalid_proof() { fn test_error_invalid_proof() {
@ -839,6 +867,171 @@ mod tests {
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[test]
fn test_valid_pairing() {
let mut pairing_first_state = create_pairing_process_one();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let message_hash = pairing_first_state.get_message_hash(true).unwrap();
pairing_first_state.validation_tokens.push(Proof::new(message_hash, carol_key));
let result = pairing_first_state.is_valid(None, &OutPointMemberMap(get_members_map()));
assert!(result.is_ok());
}
#[test]
fn test_error_pairing_wrong_proof() {
let mut pairing_first_state = create_pairing_process_one();
let alice_key: SecretKey = create_alice_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let message_hash = pairing_first_state.get_message_hash(true).unwrap();
pairing_first_state.validation_tokens.push(Proof::new(message_hash, alice_key));
let result = pairing_first_state.is_valid(None, &OutPointMemberMap(get_members_map()));
assert!(result.is_err());
}
#[test]
fn test_valid_pairing_add_device() {
let pairing_state = create_pairing_process_one();
let mut paired_addresses = pairing_state.public_data.get(PAIREDADDRESSES).unwrap().clone();
let mut pairing_process = Process::new(pairing_state.commited_in);
pairing_process.insert_concurrent_state(pairing_state).unwrap();
let new_commitment = OutPoint::from_str("7f1a6d8923d6ee58a075c0e99e25472bb22a3eea221739281c2beaf829f03f27:0").unwrap();
pairing_process.update_states_tip(new_commitment).unwrap();
let members_list = &OutPointMemberMap(HashMap::from(
[
(
pairing_process.get_process_id().unwrap(),
Member::new(
paired_addresses.as_array().unwrap().into_iter().map(|a| a.as_str().unwrap().try_into().unwrap()).collect()
))
])
);
// Add Dave address
let dave_address = create_dave_wallet().get_client().get_receiving_address();
paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address));
let roles = &pairing_process.get_latest_commited_state().unwrap().roles;
let mut add_device_state = ProcessState::new(new_commitment, Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), roles.clone()).unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let message_hash = add_device_state.get_message_hash(true).unwrap();
add_device_state.validation_tokens.push(Proof::new(message_hash, carol_key));
let result = add_device_state.is_valid(pairing_process.get_latest_commited_state(), members_list);
assert!(result.is_ok());
}
#[test]
fn test_valid_pairing_rm_device() {
let pairing_state = create_pairing_process_two();
let paired_addresses = pairing_state.public_data.get(PAIREDADDRESSES).unwrap().clone();
let mut pairing_process = Process::new(pairing_state.commited_in);
pairing_process.insert_concurrent_state(pairing_state).unwrap();
let new_commitment = OutPoint::from_str("7f1a6d8923d6ee58a075c0e99e25472bb22a3eea221739281c2beaf829f03f27:0").unwrap();
pairing_process.update_states_tip(new_commitment).unwrap();
let members_list = &OutPointMemberMap(HashMap::from(
[
(
pairing_process.get_process_id().unwrap(),
Member::new(
paired_addresses.as_array().unwrap().into_iter().map(|a| a.as_str().unwrap().try_into().unwrap()).collect()
))
])
);
// Remove Dave address
let dave_address = create_dave_wallet().get_client().get_receiving_address();
let paired_addresses = extract_paired_addresses(&paired_addresses).unwrap();
let filtered_paired_addresses = Value::from_iter(paired_addresses.into_iter().filter_map(|a| {
if a.to_string() != dave_address {
Some(a.to_string())
} else {
None
}
}));
let roles = &pairing_process.get_latest_commited_state().unwrap().roles;
let mut rm_device_state = ProcessState::new(
new_commitment,
Pcd::new(BTreeMap::new()),
Pcd::new(
BTreeMap::from([(PAIREDADDRESSES.to_owned(), filtered_paired_addresses)])
),
roles.clone()
).unwrap();
// We need both devices to agree to remove one
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let dave_key: SecretKey = create_dave_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let message_hash = rm_device_state.get_message_hash(true).unwrap();
rm_device_state.validation_tokens.push(Proof::new(message_hash, carol_key));
rm_device_state.validation_tokens.push(Proof::new(message_hash, dave_key));
let result = rm_device_state.is_valid(pairing_process.get_latest_commited_state(), members_list);
assert!(result.is_ok());
}
/// We check that Dave can't add himself to the pairing
#[test]
fn test_error_pairing_add_device_wrong_signature() {
let pairing_state = create_pairing_process_one();
let mut paired_addresses = pairing_state.public_data.get(PAIREDADDRESSES).unwrap().clone();
let mut pairing_process = Process::new(pairing_state.commited_in);
pairing_process.insert_concurrent_state(pairing_state).unwrap();
let new_commitment = OutPoint::from_str("7f1a6d8923d6ee58a075c0e99e25472bb22a3eea221739281c2beaf829f03f27:0").unwrap();
pairing_process.update_states_tip(new_commitment).unwrap();
let members_list = &OutPointMemberMap(HashMap::from(
[
(
pairing_process.get_process_id().unwrap(),
Member::new(
paired_addresses.as_array().unwrap().into_iter().map(|a| a.as_str().unwrap().try_into().unwrap()).collect()
))
])
);
// Add Dave address
let dave_address = create_dave_wallet().get_client().get_receiving_address();
paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address));
let roles = &pairing_process.get_latest_commited_state().unwrap().roles;
let mut add_device_state = ProcessState::new(new_commitment, Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), roles.clone()).unwrap();
let dave_key: SecretKey = create_dave_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let message_hash = add_device_state.get_message_hash(true).unwrap();
add_device_state.validation_tokens.push(Proof::new(message_hash, dave_key));
let result = add_device_state.is_valid(pairing_process.get_latest_commited_state(), members_list);
assert!(result.is_err());
}
#[test] #[test]
/// everyone signs for everything /// everyone signs for everything
fn test_valid_all_signatures() { fn test_valid_all_signatures() {
@ -897,7 +1090,7 @@ mod tests {
#[test] #[test]
/// Dave signs to obliterate the process /// Dave signs to obliterate the process
fn test_valid_obliteration() { fn test_valid_obliteration() {
let mut state = dummy_process_state(); let state = dummy_process_state();
let mut process = Process::new(state.commited_in); let mut process = Process::new(state.commited_in);
process.insert_concurrent_state(state.clone()).unwrap(); process.insert_concurrent_state(state.clone()).unwrap();
// We simulate a first commitment // We simulate a first commitment
@ -909,16 +1102,16 @@ mod tests {
, 0 , 0
) )
).unwrap(); ).unwrap();
// Now we take the last empty state and try to invalidate it // Now we take the last empty state and try to commit it to invalidate the whole process
let empty_state = process.get_state_for_id(&[0u8; 32]).unwrap(); let empty_state = process.get_state_for_id_mut(&[0u8; 32]).unwrap();
let dave_key: SecretKey = create_dave_wallet() let dave_key: SecretKey = create_dave_wallet()
.get_client() .get_client()
.get_spend_key() .get_spend_key()
.try_into() .try_into()
.unwrap(); .unwrap();
let message_hash = empty_state.get_message_hash(true).unwrap(); let message_hash = empty_state.get_message_hash(true).unwrap();
state.validation_tokens.push(Proof::new(message_hash, dave_key)); empty_state.validation_tokens.push(Proof::new(message_hash, dave_key));
let result = state.is_valid(None, &OutPointMemberMap(get_members_map())); let result = empty_state.is_valid(Some(&state), &OutPointMemberMap(get_members_map()));
assert!(result.is_ok()); assert!(result.is_ok());
} }