Update ProcessState with descriptions
This commit is contained in:
parent
40dbc1b2ba
commit
f899719cc1
61
src/api.rs
61
src/api.rs
@ -90,9 +90,11 @@ pub enum DiffStatus {
|
||||
#[tsify(into_wasm_abi)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct UserDiff {
|
||||
pub process_id: String,
|
||||
pub new_state_merkle_root: String, // TODO add a merkle proof that the new_value belongs to that state
|
||||
pub value_commitment: String,
|
||||
pub field: String,
|
||||
pub description: Option<String>,
|
||||
pub previous_value: Value,
|
||||
pub new_value: Value,
|
||||
pub notify_user: bool,
|
||||
@ -711,24 +713,30 @@ fn create_diffs(process: &Process, new_state: &ProcessState) -> AnyhowResult<Vec
|
||||
Err(_) => Map::new()
|
||||
};
|
||||
|
||||
let new_state_descriptions = &new_state.descriptions;
|
||||
|
||||
let process_id = process.get_process_id()?.to_string();
|
||||
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() {
|
||||
let description = new_state_descriptions.get(field).map(|d| d.to_string());
|
||||
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 };
|
||||
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 {
|
||||
process_id: process_id.clone(),
|
||||
new_state_merkle_root: new_state_root.to_owned(),
|
||||
value_commitment: new_hash.as_str().unwrap().to_string(),
|
||||
field: field.to_owned(),
|
||||
description,
|
||||
previous_value,
|
||||
new_value,
|
||||
notify_user: false,
|
||||
@ -744,12 +752,15 @@ fn create_diffs(process: &Process, new_state: &ProcessState) -> AnyhowResult<Vec
|
||||
} else {
|
||||
// All fields need a diff
|
||||
for (field, hash) in new_state_commitments {
|
||||
let description = new_state_descriptions.get(field).map(|d| d.to_string());
|
||||
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 {
|
||||
process_id: process_id.clone(),
|
||||
new_state_merkle_root: new_state_root.to_owned(),
|
||||
value_commitment: hash.as_str().unwrap().to_string(),
|
||||
field: field.to_owned(),
|
||||
description,
|
||||
previous_value: Value::Null,
|
||||
new_value,
|
||||
notify_user: false,
|
||||
@ -1145,26 +1156,16 @@ pub fn create_connect_transaction(members_str: Vec<String>, fee_rate: u32) -> Ap
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn create_new_process(
|
||||
init_state: String,
|
||||
init_state_str: String,
|
||||
descriptions_str: Option<String>,
|
||||
relay_address: String,
|
||||
fee_rate: u32,
|
||||
) -> ApiResult<ApiReturn> {
|
||||
let pcd = <Value as Pcd>::new_from_string(&init_state)?;
|
||||
let init_state = <Value as Pcd>::new_from_string(&init_state_str)?;
|
||||
let descriptions = if let Some(d) = descriptions_str { <Value as Pcd>::new_from_string(&d)? } else { Value::Object(Map::new()) };
|
||||
|
||||
// check that we have a proper roles map
|
||||
let roles = pcd.extract_roles()?;
|
||||
|
||||
// We create the encryption keys for each field and encrypt them
|
||||
let mut fields2keys = Map::new();
|
||||
let mut fields2cipher = Map::new();
|
||||
let fields_to_encrypt: Vec<String> = pcd
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.keys()
|
||||
.map(|k| k.clone())
|
||||
.collect();
|
||||
|
||||
pcd.encrypt_fields(&fields_to_encrypt, &mut fields2keys, &mut fields2cipher);
|
||||
let roles = init_state.extract_roles()?;
|
||||
|
||||
// We create a transaction that spends to the relay address
|
||||
let psbt = create_transaction_for_addresses(vec![relay_address.clone()], fee_rate)?;
|
||||
@ -1184,26 +1185,13 @@ pub fn create_new_process(
|
||||
// We now have the outpoint that will serve as id for the whole process
|
||||
let outpoint = OutPoint::new(transaction.txid(), 0);
|
||||
|
||||
// We now need a hash that commits to the clear value of each field + the process id (or outpoint)
|
||||
let pcd_commitment = Value::Object(pcd.hash_all_fields(outpoint)?);
|
||||
|
||||
let merkle_root = pcd_commitment.create_merkle_tree()?.root().ok_or(ApiError::new("Invalid merkle tree".to_owned()))?.to_lower_hex_string();
|
||||
let new_state = ProcessState::new(outpoint, init_state.to_value_object()?, descriptions.to_value_object()?)?;
|
||||
|
||||
let mut process = Process::new(outpoint);
|
||||
|
||||
// We now create the first process state with all that data
|
||||
let process_state = ProcessState {
|
||||
commited_in: outpoint,
|
||||
pcd_commitment: pcd_commitment.clone(),
|
||||
merkle_root: merkle_root.clone(),
|
||||
encrypted_pcd: Value::Object(fields2cipher.clone()),
|
||||
keys: fields2keys.clone(),
|
||||
validation_tokens: vec![],
|
||||
};
|
||||
let diffs = create_diffs(&process, &new_state)?;
|
||||
|
||||
let diffs = create_diffs(&process, &process_state)?;
|
||||
|
||||
process.insert_concurrent_state(process_state.clone())?;
|
||||
process.insert_concurrent_state(new_state.clone())?;
|
||||
|
||||
{
|
||||
let mut processes = lock_processes()?;
|
||||
@ -1214,7 +1202,7 @@ pub fn create_new_process(
|
||||
processes.insert(outpoint.clone(), process.clone());
|
||||
}
|
||||
|
||||
let commit_msg = CommitMessage::new_first_commitment(transaction, pcd_commitment, roles);
|
||||
let commit_msg = CommitMessage::new_first_commitment(transaction, new_state.pcd_commitment, roles);
|
||||
|
||||
let updated_process = UpdatedProcess {
|
||||
commitment_tx: outpoint,
|
||||
@ -1246,10 +1234,11 @@ pub fn update_process(
|
||||
.ok_or(ApiError::new("Process must have at least one state already commited".to_owned()))?;
|
||||
|
||||
let last_state_commitments = &prev_state.pcd_commitment;
|
||||
let last_state_descriptions = &prev_state.descriptions;
|
||||
|
||||
let clear_new_state = Value::from_str(&new_state_str)?.to_value_object()?;
|
||||
|
||||
let new_state = ProcessState::new(prev_state.commited_in, clear_new_state.clone())?;
|
||||
let new_state = ProcessState::new(prev_state.commited_in, clear_new_state.clone(), last_state_descriptions.clone())?;
|
||||
|
||||
// We compare the new state with the previous one
|
||||
let last_state_merkle_root = &prev_state.merkle_root;
|
||||
@ -1373,8 +1362,6 @@ pub fn create_update_message(
|
||||
return Err(ApiError::new("Empty ciphers list".to_owned()));
|
||||
}
|
||||
|
||||
process.insert_impending_request(full_prd);
|
||||
|
||||
let updated_process = UpdatedProcess {
|
||||
commitment_tx: outpoint,
|
||||
current_process: process.clone(),
|
||||
|
@ -166,7 +166,7 @@ fn test_pairing() {
|
||||
});
|
||||
|
||||
debug!("Alice creates the pairing process");
|
||||
let create_process_return = create_new_process(pairing_init_state.to_string(), RELAY_ADDRESS.to_owned(), 1).unwrap();
|
||||
let create_process_return = create_new_process(pairing_init_state.to_string(), None, RELAY_ADDRESS.to_owned(), 1).unwrap();
|
||||
|
||||
let commit_msg = create_process_return.commit_to_send.unwrap();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user