diff --git a/src/process.rs b/src/process.rs index 0d2e4bd..ef35fd0 100644 --- a/src/process.rs +++ b/src/process.rs @@ -20,6 +20,7 @@ use crate::{ pub struct ProcessState { pub commited_in: OutPoint, pub pcd_commitment: Value, // If we can't modify a field, we just copy the previous value + pub merkle_root: String, // the root of the tree created with all the commitments. Serves as an unique id for a state too pub encrypted_pcd: Value, // Some fields may be clear, if the owner of the process decides so pub keys: Map, // We may not always have all the keys pub validation_tokens: Vec, // Signature of the hash of the encrypted pcd tagged with some decision like "yes" or "no" @@ -31,14 +32,20 @@ impl ProcessState { let mut encrypted = Map::new(); let clear_pcd = Value::Object(clear_state); - let commitments = clear_pcd.hash_all_fields(commited_in)?; + + let sorted_pcd = Value::Object(clear_pcd.to_sorted_key_values()?); - let keys_to_encrypt: Vec = commitments.keys().map(|k| k.clone()).collect(); - clear_pcd.encrypt_fields(&keys_to_encrypt, &mut keys, &mut encrypted)?; + let pcd_commitment = Value::Object(sorted_pcd.hash_all_fields(commited_in)?); + + let merkle_root = pcd_commitment.create_merkle_tree()?.root().ok_or(anyhow::Error::msg("Invalid merkle tree"))?.to_lower_hex_string(); + + let keys_to_encrypt: Vec = pcd_commitment.as_object().unwrap().keys().map(|k| k.clone()).collect(); + sorted_pcd.encrypt_fields(&keys_to_encrypt, &mut keys, &mut encrypted)?; let res = Self { commited_in, - pcd_commitment: Value::Object(commitments), + pcd_commitment, + merkle_root, encrypted_pcd: Value::Object(encrypted), keys, validation_tokens: vec![],