Add storages to UserDiff

This commit is contained in:
Sosthene 2025-09-08 15:39:27 +02:00
parent 12f0fb23eb
commit c09135c4eb

View File

@ -104,6 +104,7 @@ pub struct UserDiff {
pub notify_user: bool, pub notify_user: bool,
pub need_validation: bool, pub need_validation: bool,
pub validation_status: DiffStatus, pub validation_status: DiffStatus,
pub storages: Vec<String>,
} }
#[derive(Debug, PartialEq, Tsify, Serialize, Deserialize, Default)] #[derive(Debug, PartialEq, Tsify, Serialize, Deserialize, Default)]
@ -705,17 +706,34 @@ fn create_diffs(device: &MutexGuard<Device>, process: &Process, new_state: &Proc
let our_id = device.get_pairing_commitment(); let our_id = device.get_pairing_commitment();
let fields_to_validate = if let Some(our_id) = our_id { let fields_to_validate: HashMap<String, Vec<String>> = if let Some(our_id) = our_id {
new_state.get_fields_to_validate_for_member(&our_id)? let mut relevant_fields = HashMap::new();
for (name, role) in new_state.roles.iter() {
if !role.members.contains(&our_id) {
// This role doesn't concern requester
continue;
}
let fields: Vec<String> = role
.validation_rules
.iter()
.flat_map(|rule| rule.fields.clone())
.collect();
relevant_fields.extend(fields.into_iter().map(|field| (field, role.storages.clone())));
}
relevant_fields
} else { } else {
// Device is unpaired, we just take all the fields in the `pairing` role // Device is unpaired, we just take all the fields in the `pairing` role
if let Some(pairing_role) = new_state.roles.get("pairing") { if let Some(pairing_role) = new_state.roles.get("pairing") {
pairing_role.validation_rules.iter().flat_map(|r| r.fields.clone()).collect() let mut relevant_fields = HashMap::new();
let fields: Vec<String> = pairing_role.validation_rules.iter().flat_map(|r| r.fields.clone()).collect();
relevant_fields.extend(fields.into_iter().map(|field| (field, pairing_role.storages.clone())));
relevant_fields
} else { } else {
return Err(AnyhowError::msg("Missing pairing role")) return Err(AnyhowError::msg("Missing pairing role"))
} }
}; };
let new_state_id = &new_state.state_id; let new_state_id = &new_state.state_id;
let new_public_data = &new_state.public_data; let new_public_data = &new_state.public_data;
@ -723,7 +741,7 @@ fn create_diffs(device: &MutexGuard<Device>, process: &Process, new_state: &Proc
let process_id = process.get_process_id()?.to_string(); let process_id = process.get_process_id()?.to_string();
let mut diffs = vec![]; let mut diffs = vec![];
for (field, hash) in new_state_commitments.iter() { for (field, hash) in new_state_commitments.iter() {
let need_validation = fields_to_validate.contains(field); let need_validation = fields_to_validate.contains_key(field);
diffs.push(UserDiff { diffs.push(UserDiff {
process_id: process_id.clone(), process_id: process_id.clone(),
state_id: new_state_id.to_lower_hex_string(), state_id: new_state_id.to_lower_hex_string(),
@ -734,6 +752,7 @@ fn create_diffs(device: &MutexGuard<Device>, process: &Process, new_state: &Proc
need_validation, need_validation,
validation_status: DiffStatus::None, validation_status: DiffStatus::None,
roles: new_state.roles.clone(), roles: new_state.roles.clone(),
storages: fields_to_validate.get(field).unwrap_or(&vec![]).clone(),
}); });
} }
@ -944,7 +963,7 @@ fn handle_prd(
let sp_wallet = local_device.get_sp_client(); let sp_wallet = local_device.get_sp_client();
let local_address = sp_wallet.get_receiving_address().to_string(); let local_address = sp_wallet.get_receiving_address().to_string();
let mut relevant_fields: HashSet<String> = HashSet::new(); let mut relevant_fields: HashMap<String, Vec<String>> = HashMap::new();
let shared_secrets = lock_shared_secrets()?; let shared_secrets = lock_shared_secrets()?;
for (name, role) in state.roles.iter() { for (name, role) in state.roles.iter() {
if !role.members.contains(&requester) { if !role.members.contains(&requester) {
@ -956,7 +975,7 @@ fn handle_prd(
.iter() .iter()
.flat_map(|rule| rule.fields.clone()) .flat_map(|rule| rule.fields.clone())
.collect(); .collect();
relevant_fields.extend(fields); relevant_fields.extend(fields.into_iter().map(|field| (field, role.storages.clone())));
} }
let sender = local_device.get_pairing_commitment().ok_or(AnyhowError::msg("Device not paired"))?; let sender = local_device.get_pairing_commitment().ok_or(AnyhowError::msg("Device not paired"))?;
@ -970,7 +989,7 @@ fn handle_prd(
state.pcd_commitment.clone(), state.pcd_commitment.clone(),
); );
full_prd.filter_keys(&relevant_fields); full_prd.filter_keys(&relevant_fields.iter().map(|(field, _)| field.clone()).collect());
let prd_msg = full_prd.to_network_msg(sp_wallet)?; let prd_msg = full_prd.to_network_msg(sp_wallet)?;
let addresses = members_list.0.get(&sender).ok_or(AnyhowError::msg("Unknown requester"))?.get_addresses(); let addresses = members_list.0.get(&sender).ok_or(AnyhowError::msg("Unknown requester"))?.get_addresses();
@ -991,7 +1010,7 @@ fn handle_prd(
let pcd_commitment = &state.pcd_commitment; let pcd_commitment = &state.pcd_commitment;
for (field, hash) in pcd_commitment.iter() { for (field, hash) in pcd_commitment.iter() {
// We only need field that are visible by requester // We only need field that are visible by requester
if !relevant_fields.contains(field.as_str()) { if !relevant_fields.contains_key(field.as_str()) {
continue; continue;
} }
let diff = UserDiff { let diff = UserDiff {
@ -999,6 +1018,7 @@ fn handle_prd(
state_id: state_id.to_lower_hex_string(), state_id: state_id.to_lower_hex_string(),
value_commitment: hash.to_lower_hex_string(), value_commitment: hash.to_lower_hex_string(),
field: field.to_owned(), field: field.to_owned(),
storages: relevant_fields.get(field.as_str()).unwrap().clone(),
..Default::default() ..Default::default()
}; };
diffs.push(diff); diffs.push(diff);
@ -1038,6 +1058,7 @@ fn handle_decrypted_message(
} }
} }
// TODO make separate functions for the decryption itself and the parsing to avoid copy and serialization cost
#[wasm_bindgen] #[wasm_bindgen]
pub fn parse_cipher(cipher_msg: String, members_list: OutPointMemberMap, processes: OutPointProcessMap) -> ApiResult<ApiReturn> { pub fn parse_cipher(cipher_msg: String, members_list: OutPointMemberMap, processes: OutPointProcessMap) -> ApiResult<ApiReturn> {
// Check that the cipher is not empty or too long // Check that the cipher is not empty or too long