Add UpdatedProcess type

This commit is contained in:
Sosthene 2024-11-26 22:55:31 +01:00
parent e90473d8be
commit 041cf55f58
2 changed files with 102 additions and 46 deletions

View File

@ -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<ProcessState>,
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<SecretsStore>,
pub updated_process: Option<(String, Process)>,
pub updated_process: Option<UpdatedProcess>,
pub new_tx_to_send: Option<NewTxMessage>,
pub ciphers_to_send: Vec<String>,
pub commit_to_send: Option<CommitMessage>,
@ -729,11 +740,11 @@ fn confirm_prd(prd: &Prd, shared_secret: &AnkSharedSecretHash) -> AnyhowResult<S
let outpoint = OutPoint::from_str(&prd.root_commitment)?;
let local_device = lock_local_device()?;
let member = local_device.to_member();
let sender = local_device.to_member();
let prd_confirm = Prd::new_confirm(outpoint, member, prd.pcd_commitments.clone());
let prd_confirm = Prd::new_confirm(outpoint, sender, prd.pcd_commitments.clone());
debug!("Sending confirm prd: {:?}", prd_confirm);
// debug!("Sending confirm prd: {:?}", prd_confirm);
let prd_msg = prd_confirm.to_network_msg(local_device.get_wallet())?;
@ -799,6 +810,7 @@ fn handle_prd(
prd: Prd,
secret: AnkSharedSecretHash
) -> AnyhowResult<ApiReturn> {
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<ApiReturn> {
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 = <Value as Pcd>::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()
})
}

View File

@ -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 = <Value as Pcd>::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();