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)]
|
#[tsify(into_wasm_abi)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub struct UserDiff {
|
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 new_state_merkle_root: String, // TODO add a merkle proof that the new_value belongs to that state
|
||||||
pub value_commitment: String,
|
pub value_commitment: String,
|
||||||
pub field: String,
|
pub field: String,
|
||||||
|
pub description: Option<String>,
|
||||||
pub previous_value: Value,
|
pub previous_value: Value,
|
||||||
pub new_value: Value,
|
pub new_value: Value,
|
||||||
pub notify_user: bool,
|
pub notify_user: bool,
|
||||||
@ -711,24 +713,30 @@ fn create_diffs(process: &Process, new_state: &ProcessState) -> AnyhowResult<Vec
|
|||||||
Err(_) => Map::new()
|
Err(_) => Map::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let new_state_descriptions = &new_state.descriptions;
|
||||||
|
|
||||||
|
let process_id = process.get_process_id()?.to_string();
|
||||||
let mut diffs = vec![];
|
let mut diffs = vec![];
|
||||||
if let Some(prev_state) = process.get_latest_commited_state() {
|
if let Some(prev_state) = process.get_latest_commited_state() {
|
||||||
// We first decrypt as much as we can of the prev_state
|
// We first decrypt as much as we can of the prev_state
|
||||||
let clear_prev_state = prev_state.decrypt_pcd()?;
|
let clear_prev_state = prev_state.decrypt_pcd()?;
|
||||||
// We just make a diff for values that are different from previous state
|
// 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() {
|
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 let Some(new_hash) = new_state_commitments.get(field.as_str()) {
|
||||||
if new_hash.as_str() == prev_hash.as_str() {
|
if new_hash.as_str() == prev_hash.as_str() {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// There's a diff
|
// There's a diff
|
||||||
let previous_value = clear_prev_state.get(field.as_str()).unwrap().clone();
|
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 {
|
diffs.push(UserDiff {
|
||||||
|
process_id: process_id.clone(),
|
||||||
new_state_merkle_root: new_state_root.to_owned(),
|
new_state_merkle_root: new_state_root.to_owned(),
|
||||||
value_commitment: new_hash.as_str().unwrap().to_string(),
|
value_commitment: new_hash.as_str().unwrap().to_string(),
|
||||||
field: field.to_owned(),
|
field: field.to_owned(),
|
||||||
|
description,
|
||||||
previous_value,
|
previous_value,
|
||||||
new_value,
|
new_value,
|
||||||
notify_user: false,
|
notify_user: false,
|
||||||
@ -744,12 +752,15 @@ fn create_diffs(process: &Process, new_state: &ProcessState) -> AnyhowResult<Vec
|
|||||||
} else {
|
} else {
|
||||||
// All fields need a diff
|
// All fields need a diff
|
||||||
for (field, hash) in new_state_commitments {
|
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 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 };
|
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 {
|
diffs.push(UserDiff {
|
||||||
|
process_id: process_id.clone(),
|
||||||
new_state_merkle_root: new_state_root.to_owned(),
|
new_state_merkle_root: new_state_root.to_owned(),
|
||||||
value_commitment: hash.as_str().unwrap().to_string(),
|
value_commitment: hash.as_str().unwrap().to_string(),
|
||||||
field: field.to_owned(),
|
field: field.to_owned(),
|
||||||
|
description,
|
||||||
previous_value: Value::Null,
|
previous_value: Value::Null,
|
||||||
new_value,
|
new_value,
|
||||||
notify_user: false,
|
notify_user: false,
|
||||||
@ -1145,26 +1156,16 @@ pub fn create_connect_transaction(members_str: Vec<String>, fee_rate: u32) -> Ap
|
|||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn create_new_process(
|
pub fn create_new_process(
|
||||||
init_state: String,
|
init_state_str: String,
|
||||||
|
descriptions_str: Option<String>,
|
||||||
relay_address: String,
|
relay_address: String,
|
||||||
fee_rate: u32,
|
fee_rate: u32,
|
||||||
) -> ApiResult<ApiReturn> {
|
) -> 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
|
// check that we have a proper roles map
|
||||||
let roles = pcd.extract_roles()?;
|
let roles = init_state.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);
|
|
||||||
|
|
||||||
// We create a transaction that spends to the relay address
|
// We create a transaction that spends to the relay address
|
||||||
let psbt = create_transaction_for_addresses(vec![relay_address.clone()], fee_rate)?;
|
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
|
// We now have the outpoint that will serve as id for the whole process
|
||||||
let outpoint = OutPoint::new(transaction.txid(), 0);
|
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 new_state = ProcessState::new(outpoint, init_state.to_value_object()?, descriptions.to_value_object()?)?;
|
||||||
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 mut process = Process::new(outpoint);
|
let mut process = Process::new(outpoint);
|
||||||
|
|
||||||
// We now create the first process state with all that data
|
let diffs = create_diffs(&process, &new_state)?;
|
||||||
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, &process_state)?;
|
process.insert_concurrent_state(new_state.clone())?;
|
||||||
|
|
||||||
process.insert_concurrent_state(process_state.clone())?;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut processes = lock_processes()?;
|
let mut processes = lock_processes()?;
|
||||||
@ -1214,7 +1202,7 @@ pub fn create_new_process(
|
|||||||
processes.insert(outpoint.clone(), process.clone());
|
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 {
|
let updated_process = UpdatedProcess {
|
||||||
commitment_tx: outpoint,
|
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()))?;
|
.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_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 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
|
// We compare the new state with the previous one
|
||||||
let last_state_merkle_root = &prev_state.merkle_root;
|
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()));
|
return Err(ApiError::new("Empty ciphers list".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
process.insert_impending_request(full_prd);
|
|
||||||
|
|
||||||
let updated_process = UpdatedProcess {
|
let updated_process = UpdatedProcess {
|
||||||
commitment_tx: outpoint,
|
commitment_tx: outpoint,
|
||||||
current_process: process.clone(),
|
current_process: process.clone(),
|
||||||
|
@ -166,7 +166,7 @@ fn test_pairing() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
debug!("Alice creates the pairing process");
|
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();
|
let commit_msg = create_process_return.commit_to_send.unwrap();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user