From 041cf55f58de343c58231000eaad8f761bac6575 Mon Sep 17 00:00:00 2001 From: Sosthene Date: Tue, 26 Nov 2024 22:55:31 +0100 Subject: [PATCH] Add UpdatedProcess type --- src/api.rs | 105 ++++++++++++++++++++++++++++++++++++----------- tests/pairing.rs | 43 +++++++++---------- 2 files changed, 102 insertions(+), 46 deletions(-) diff --git a/src/api.rs b/src/api.rs index a26eeac..0d93712 100644 --- a/src/api.rs +++ b/src/api.rs @@ -77,11 +77,22 @@ use crate::user::{lock_local_device, set_new_device, LOCAL_DEVICE}; use crate::wallet::{generate_sp_wallet, lock_freezed_utxos}; #[derive(Debug, PartialEq, Tsify, Serialize, Deserialize, Default)] -#[tsify(into_wasm_abi, from_wasm_abi)] +#[tsify(into_wasm_abi)] +#[allow(non_camel_case_types)] +pub struct UpdatedProcess { + pub commitment_tx: OutPoint, + pub current_process: Process, + pub new_state: Option, + pub modified_state: Option<(ProcessState, ProcessState)>, // first the previous state, then the current one + pub user_validation_required: bool, +} + +#[derive(Debug, PartialEq, Tsify, Serialize, Deserialize, Default)] +#[tsify(into_wasm_abi)] #[allow(non_camel_case_types)] pub struct ApiReturn { pub secrets: Option, - pub updated_process: Option<(String, Process)>, + pub updated_process: Option, pub new_tx_to_send: Option, pub ciphers_to_send: Vec, pub commit_to_send: Option, @@ -729,11 +740,11 @@ fn confirm_prd(prd: &Prd, shared_secret: &AnkSharedSecretHash) -> AnyhowResult AnyhowResult { + debug!("handle_prd: {:#?}", prd); // Connect is a bit different here because there's no associated process // Let's handle that case separately if prd.prd_type == PrdType::Connect { @@ -820,7 +832,7 @@ fn handle_prd( PrdType::Confirm => { // It must match a prd we sent previously // We send the whole data in a pcd - debug!("Received confirm prd {:#?}", prd); + debug!("Received confirm prd with commitments {:#?}", prd.pcd_commitments); let relevant_state = relevant_process .get_latest_concurrent_states()? .into_iter() @@ -877,19 +889,25 @@ fn handle_prd( } } - // This should never happen since we sent a message to get a confirmation back + // This should never happen if ciphers.is_empty() { return Err(anyhow::Error::msg(format!("No available secrets for member {:?}", member))); } + let updated_process = UpdatedProcess { + commitment_tx: outpoint, + current_process: relevant_process.clone(), + ..Default::default() + }; + return Ok(ApiReturn { ciphers_to_send: ciphers, - updated_process: Some((outpoint.to_string(), relevant_process.clone())), + updated_process: Some(updated_process), ..Default::default() }); } PrdType::Response => { - let mut updated_state = relevant_process + let mut to_update = relevant_process .get_latest_concurrent_states_mut()? .into_iter() .find(|r| { @@ -898,12 +916,21 @@ fn handle_prd( .ok_or(anyhow::Error::msg("Original request not found"))?; // Once we found the prd update, we can add the received proofs as validation tokens - updated_state + let previous_state = to_update.clone(); + + to_update .validation_tokens .extend(prd.validation_tokens); + let updated_state = to_update.clone(); + // We must return an update of the process - let updated_process = (prd.root_commitment, relevant_process.clone()); + let updated_process = UpdatedProcess { + commitment_tx: OutPoint::from_str(&prd.root_commitment)?, + current_process: relevant_process.clone(), + modified_state: Some((previous_state, updated_state.clone())), + ..Default::default() + }; return Ok(ApiReturn { updated_process: Some(updated_process), @@ -943,10 +970,18 @@ fn handle_pcd(pcd: Value) -> AnyhowResult { keys: updated_prd.keys, validation_tokens: vec![] }; - process.insert_concurrent_state(new_state)?; + process.insert_concurrent_state(new_state.clone())?; process.prune_impending_requests(); + + let udpated_process = UpdatedProcess { + commitment_tx: *outpoint, + current_process: process.clone(), + new_state: Some(new_state), + ..Default::default() + }; + return Ok(ApiReturn { - updated_process: Some((outpoint.to_string(), process.clone())), + updated_process: Some(udpated_process), ..Default::default() }); } @@ -1159,7 +1194,7 @@ pub fn create_new_process( validation_tokens: vec![], }; - process.insert_concurrent_state(process_state)?; + process.insert_concurrent_state(process_state.clone())?; { let mut processes = lock_processes()?; @@ -1172,10 +1207,17 @@ pub fn create_new_process( let commit_msg = CommitMessage::new_first_commitment(transaction, Value::Object(fields_commitment), roles); + let updated_process = UpdatedProcess { + commitment_tx: outpoint, + current_process: process, + new_state: Some(process_state), + ..Default::default() + }; + Ok(ApiReturn { secrets: Some(secrets_return), commit_to_send: Some(commit_msg), - updated_process: Some((outpoint.to_string(), process)), + updated_process: Some(updated_process), ..Default::default() }) } @@ -1222,12 +1264,6 @@ pub fn update_process( let encrypted_pcd = Value::Object(fields2cipher); - // We create an encrypted values merkle root - let new_state_encrypted_commitments = encrypted_pcd.hash_fields(OutPoint::null())?; - let new_state_encrypted_root = ::create_merkle_tree(&Value::Object(new_state_encrypted_commitments.clone()))?.root().unwrap(); - - let to_update = process.get_latest_state().unwrap(); // This is an empty state with `commited_in` set as the last unspent output - let device = lock_local_device()?; let new_state = ProcessState { @@ -1239,10 +1275,17 @@ pub fn update_process( }; // Add the new state to the process - process.insert_concurrent_state(new_state)?; + process.insert_concurrent_state(new_state.clone())?; + + let updated_process = UpdatedProcess { + commitment_tx: outpoint, + current_process: process.clone(), + new_state: Some(new_state), + ..Default::default() + }; Ok(ApiReturn { - updated_process: Some((init_commitment, process.clone())), + updated_process: Some(updated_process), ..Default::default() }) } @@ -1350,8 +1393,14 @@ pub fn create_update_message( process.insert_impending_request(full_prd); + let updated_process = UpdatedProcess { + commitment_tx: outpoint, + current_process: process.clone(), + ..Default::default() + }; + Ok(ApiReturn { - updated_process: Some((outpoint.to_string(), process.clone())), + updated_process: Some(updated_process), ciphers_to_send: ciphers, ..Default::default() }) @@ -1396,8 +1445,14 @@ fn add_validation_token(init_commitment: String, merkle_root_hex: String, approv update_state.validation_tokens.push(proof); + let updated_process = UpdatedProcess { + commitment_tx: OutPoint::from_str(&init_commitment)?, + current_process: process.clone(), + ..Default::default() + }; + Ok(ApiReturn { - updated_process: Some((init_commitment, process.clone())), + updated_process: Some(updated_process), ..Default::default() }) } diff --git a/tests/pairing.rs b/tests/pairing.rs index 8e446ae..2fc9d31 100644 --- a/tests/pairing.rs +++ b/tests/pairing.rs @@ -9,6 +9,7 @@ use sdk_common::log::debug; use sdk_common::pcd::{Member, Pcd}; use sdk_common::sp_client::bitcoin::hex::DisplayHex; use sdk_common::secrets::SecretsStore; +use sdk_common::sp_client::bitcoin::OutPoint; use serde_json::{json, Value}; use wasm_bindgen_test::*; @@ -179,21 +180,21 @@ fn test_pairing() { } } - let (outpoint, new_process) = create_process_return.updated_process.unwrap(); - alice_process_cache.insert(outpoint.clone(), new_process); + let updated_process = create_process_return.updated_process.unwrap(); + alice_process_cache.insert(updated_process.commitment_tx, updated_process.current_process); // We send the commit_msg to the relay we got the address from // now we create prd update for this new process debug!("Alice sends an update prd to Bob"); let root = ::create_merkle_tree(&commit_msg.pcd_commitment).unwrap().root().unwrap(); - let create_update_return = create_update_message(outpoint, root.to_lower_hex_string()).unwrap(); + let create_update_return = create_update_message(updated_process.commitment_tx.to_string(), root.to_lower_hex_string()).unwrap(); - let (root_outpoint, alice_init_process) = create_update_return.updated_process.unwrap(); - alice_process_cache.insert(root_outpoint.clone(), alice_init_process); + let updated_process = create_update_return.updated_process.unwrap(); + alice_process_cache.insert(updated_process.commitment_tx, updated_process.current_process); debug!("Alice pairs her device"); - pair_device(root_outpoint, vec![helper_get_bob_address()]).unwrap(); + pair_device(updated_process.commitment_tx.to_string(), vec![helper_get_bob_address()]).unwrap(); let alice_to_bob_cipher = &create_update_return.ciphers_to_send[0]; @@ -208,9 +209,9 @@ fn test_pairing() { debug!("Bob receives the update prd"); let bob_parsed_return = parse_cipher(alice_to_bob_cipher.to_owned()).unwrap(); - let (root_commitment, relevant_process) = bob_parsed_return.updated_process.unwrap(); + let updated_process = bob_parsed_return.updated_process.unwrap(); - bob_process_cache.insert(root_commitment.clone(), relevant_process); + bob_process_cache.insert(updated_process.commitment_tx, updated_process.current_process); let prd_confirm_cipher = bob_parsed_return.ciphers_to_send.iter().next().unwrap(); @@ -238,7 +239,7 @@ fn test_pairing() { let commit_msg = alice_parsed_confirm.commit_to_send.unwrap(); // Take the relevant state out of the process - let relevant_process = alice_process_cache.get(&commit_msg.init_tx).unwrap(); + let relevant_process = alice_process_cache.get(&OutPoint::from_str(&commit_msg.init_tx).unwrap()).unwrap(); let concurrent_states = relevant_process.get_latest_concurrent_states().unwrap(); let relevant_state = concurrent_states.into_iter().find(|s| s.pcd_commitment == commit_msg.pcd_commitment).unwrap(); @@ -248,11 +249,11 @@ fn test_pairing() { // Alice can also sign her response and send it to Bob let validate_state_return = validate_state(commit_msg.init_tx, root.to_lower_hex_string()).unwrap(); - let (outpoint, validated_process) = validate_state_return.updated_process.unwrap(); + let updated_process = validate_state_return.updated_process.unwrap(); - alice_process_cache.insert(outpoint.clone(), validated_process); + alice_process_cache.insert(updated_process.commitment_tx, updated_process.current_process); - let alice_response = create_response_prd(outpoint, root.to_lower_hex_string()).unwrap(); + let alice_response = create_response_prd(updated_process.commitment_tx.to_string(), root.to_lower_hex_string()).unwrap(); // ======================= Bob reset_device().unwrap(); @@ -263,17 +264,17 @@ fn test_pairing() { debug!("Bob parses Alice's pcd"); let bob_parsed_pcd_return = parse_cipher(bob_received_pcd).unwrap(); - let (root_outpoint, updated_process) = bob_parsed_pcd_return.updated_process.unwrap(); + let updated_process = bob_parsed_pcd_return.updated_process.unwrap(); // Here we would update our database bob_process_cache.insert( - root_outpoint.clone(), - updated_process + updated_process.commitment_tx, + updated_process.current_process ); // At this point, user must validate the pairing proposal received from Alice // We decrypt the content of the pcd so that we can display to user what matters - let alice_proposal = get_update_proposals(root_outpoint.clone()).unwrap().decrypted_pcds; + let alice_proposal = get_update_proposals(updated_process.commitment_tx.to_string()).unwrap().decrypted_pcds; debug!("Alice proposal: {:#?}", alice_proposal); @@ -312,18 +313,18 @@ fn test_pairing() { // If user is ok, we can add our own validation token // Get the whole commitment from the process - let bob_validated_process = validate_state(root_outpoint.clone(), pcd_commitment_root.to_string()).unwrap(); + let bob_validated_process = validate_state(updated_process.commitment_tx.to_string(), pcd_commitment_root.to_string()).unwrap(); - let (_, validated_process) = bob_validated_process.updated_process.unwrap(); + let updated_process = bob_validated_process.updated_process.unwrap(); - bob_process_cache.insert(root_outpoint.clone(), validated_process); + bob_process_cache.insert(updated_process.commitment_tx, updated_process.current_process); - let bob_response = create_response_prd(root_outpoint.clone(), pcd_commitment_root.to_string()).unwrap(); + let bob_response = create_response_prd(updated_process.commitment_tx.to_string(), pcd_commitment_root.to_string()).unwrap(); let ciphers = bob_response.ciphers_to_send; // We would send it to Alice to let her know we agree debug!("Bob pairs device with Alice"); - pair_device(root_outpoint, proposal_members).unwrap(); + pair_device(updated_process.commitment_tx.to_string(), proposal_members).unwrap(); // We can also check alice response let parsed_alice_response = parse_cipher(alice_response.ciphers_to_send[0].clone()).unwrap();