diff --git a/src/process.rs b/src/process.rs index 9748c80..7180a7c 100644 --- a/src/process.rs +++ b/src/process.rs @@ -2,8 +2,8 @@ use std::{ collections::{BTreeMap, HashMap, HashSet}, str::FromStr, sync::{Mutex, MutexGuard, OnceLock} }; +use ciborium::from_reader; use serde::{Deserialize, Serialize}; -use serde_json::Value; use sp_client::{bitcoin::{OutPoint, Transaction}, silentpayments::SilentPaymentAddress}; use tsify::Tsify; @@ -11,17 +11,6 @@ use crate::{ pcd::{Member, Pcd, PcdCommitments, RoleDefinition, Roles, ValidationRule}, serialization::{deserialize_hex, hex_array_btree, serialize_hex, OutPointMemberMap}, signature::{AnkHash, AnkValidationNoHash, AnkValidationYesHash, Proof}, MutexExt, SpecialRoles, APOPHIS, PAIREDADDRESSES, PAIRING }; -fn extract_paired_addresses(paired_addresses: &Value) -> anyhow::Result> { - let array = paired_addresses.as_array().ok_or(anyhow::Error::msg("pairedAddresses is not an array"))?; - let sp_array: anyhow::Result> = array.into_iter().map(|value| { - let str = value.as_str().ok_or(anyhow::Error::msg("array contains a non string value"))?; - let sp_address = SilentPaymentAddress::try_from(str)?; - Ok(sp_address) - }) - .collect(); - sp_array -} - #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, Tsify)] #[tsify(into_wasm_abi, from_wasm_abi)] pub struct ProcessState { @@ -43,6 +32,7 @@ pub struct ProcessState { impl ProcessState { pub fn new(commited_in: OutPoint, private_data: Pcd, public_data: Pcd, roles: Roles) -> anyhow::Result { + // TODO check that we don't have duplicated field names in private and public data, nor a "roles" field name let all_attributes = Pcd::new(private_data.clone().into_iter().chain(public_data.clone()).collect()); let pcd_commitment = PcdCommitments::new(&commited_in, &all_attributes, &roles)?; @@ -61,15 +51,19 @@ impl ProcessState { Ok(res) } - pub fn update_value(&mut self, key: &str, new_value: &Value) -> anyhow::Result<()> { + pub fn update_value(&mut self, key: &str, new_value: &[u8]) -> anyhow::Result<()> { // Update the commitment - self.pcd_commitment.update_with_value(&self.commited_in, key, new_value)?; + let mut updated_commitments = self.pcd_commitment.clone(); + updated_commitments.update_with_value(&self.commited_in, key, new_value)?; // Update merkle tree - let merkle_tree = self.pcd_commitment.create_merkle_tree()?; + let merkle_tree = updated_commitments.create_merkle_tree()?; // Update state_id self.state_id = merkle_tree.root().ok_or_else(|| anyhow::Error::msg("Invalid merkle tree"))?; + + // Everything is ok, we can update the state + self.pcd_commitment = updated_commitments; Ok(()) } @@ -139,7 +133,7 @@ impl ProcessState { // TODO check that it matches what we have in the commitment here or somewhere else? - let updated_member = Member::new(serde_json::from_value(updated_addresses.clone())?); + let updated_member = Member::new(from_reader(updated_addresses.as_slice())?); let previous_member = Member::new(previous_addresses); let members = if previous_member.get_addresses().is_empty() { @@ -171,7 +165,7 @@ impl ProcessState { if self.pcd_commitment.contains_key(PAIREDADDRESSES) { if let Some(prev_state) = previous_state { let prev_paired_addresses = prev_state.public_data.get(PAIREDADDRESSES).ok_or(anyhow::Error::msg("Missing pairedAddresses"))?; - let paired_addresses = extract_paired_addresses(prev_paired_addresses)?; + let paired_addresses = from_reader(prev_paired_addresses.as_slice())?; return self.handle_pairing(pairing_role.clone(), paired_addresses); } else { // We are in a creation