Add create_diffs
This commit is contained in:
parent
2afc6c9a85
commit
166c7c993f
70
src/api.rs
70
src/api.rs
@ -772,6 +772,76 @@ fn confirm_prd(prd: &Prd, shared_secret: &AnkSharedSecretHash) -> AnyhowResult<S
|
||||
Ok(encrypt_with_key(shared_secret.as_byte_array(), prd_msg.as_bytes())?.to_lower_hex_string())
|
||||
}
|
||||
|
||||
fn create_diffs(process: &Process, new_state: &ProcessState) -> AnyhowResult<Vec<UserDiff>> {
|
||||
let new_state_commitments = new_state.pcd_commitment.as_object().ok_or(AnyhowError::msg("new_state commitments is not an object"))?;
|
||||
|
||||
let device = lock_local_device()?;
|
||||
let our_id = device.to_member();
|
||||
let is_pairing = device.get_pairing_commitment().is_none();
|
||||
|
||||
let fields_to_validate = if new_state.encrypted_pcd != Value::Null {
|
||||
new_state.get_fields_to_validate_for_member(&our_id)?
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let new_state_root = &new_state.merkle_root;
|
||||
let new_state_decrypted = match new_state.decrypt_pcd() {
|
||||
Ok(val) => val,
|
||||
Err(_) => Map::new()
|
||||
};
|
||||
|
||||
let mut diffs = vec![];
|
||||
if let Some(prev_state) = process.get_latest_commited_state() {
|
||||
// We first decrypt as much as we can of the prev_state
|
||||
let clear_prev_state = prev_state.decrypt_pcd()?;
|
||||
// We just make a diff for values that are different from previous state
|
||||
for (field, prev_hash) in prev_state.pcd_commitment.as_object().unwrap() {
|
||||
if let Some(new_hash) = new_state_commitments.get(field.as_str()) {
|
||||
if new_hash.as_str() == prev_hash.as_str() {
|
||||
continue;
|
||||
} else {
|
||||
// There's a diff
|
||||
let previous_value = clear_prev_state.get(field.as_str()).unwrap().clone();
|
||||
let new_value = if let Some(val) = new_state_decrypted.get(field.as_str()) { val.clone() } else { Value::Null };
|
||||
let need_validation = if (is_pairing && field.as_str() == "roles" && new_value != Value::Null) || fields_to_validate.contains(field) { true } else { false };
|
||||
diffs.push(UserDiff {
|
||||
new_state_merkle_root: new_state_root.to_owned(),
|
||||
value_commitment: new_hash.as_str().unwrap().to_string(),
|
||||
field: field.to_owned(),
|
||||
previous_value,
|
||||
new_value,
|
||||
notify_user: false,
|
||||
need_validation,
|
||||
validation_status: DiffStatus::None,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// We're missing a hash
|
||||
return Err(AnyhowError::msg(format!("No commitment for field {} in new state", field)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// All fields need a diff
|
||||
for (field, hash) in new_state_commitments {
|
||||
let new_value = if let Some(val) = new_state_decrypted.get(field.as_str()) { val.clone() } else { Value::Null };
|
||||
let need_validation = if (is_pairing && field.as_str() == "roles" && new_value != Value::Null) || fields_to_validate.contains(field) { true } else { false };
|
||||
diffs.push(UserDiff {
|
||||
new_state_merkle_root: new_state_root.to_owned(),
|
||||
value_commitment: hash.as_str().unwrap().to_string(),
|
||||
field: field.to_owned(),
|
||||
previous_value: Value::Null,
|
||||
new_value,
|
||||
notify_user: false,
|
||||
need_validation,
|
||||
validation_status: DiffStatus::None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(diffs)
|
||||
}
|
||||
|
||||
fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash) -> AnyhowResult<ApiReturn> {
|
||||
let local_device = lock_local_device()?;
|
||||
let local_member = local_device.to_member();
|
||||
|
Loading…
x
Reference in New Issue
Block a user