Add PcdUpdates and UserDiff
This commit is contained in:
parent
ed7c5e5b0c
commit
f95b6473e5
91
src/api.rs
91
src/api.rs
@ -52,7 +52,7 @@ use sdk_common::sp_client::silentpayments::{
|
|||||||
use sdk_common::{signature, MutexExt, MAX_PRD_PAYLOAD_SIZE};
|
use sdk_common::{signature, MutexExt, MAX_PRD_PAYLOAD_SIZE};
|
||||||
use serde_json::{Error as SerdeJsonError, Map, Value};
|
use serde_json::{Error as SerdeJsonError, Map, Value};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{de, Deserialize, Serialize};
|
||||||
use tsify::{JsValueSerdeExt, Tsify};
|
use tsify::{JsValueSerdeExt, Tsify};
|
||||||
use wasm_bindgen::convert::{FromWasmAbi, VectorFromWasmAbi};
|
use wasm_bindgen::convert::{FromWasmAbi, VectorFromWasmAbi};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
@ -96,7 +96,6 @@ pub struct ApiReturn {
|
|||||||
pub new_tx_to_send: Option<NewTxMessage>,
|
pub new_tx_to_send: Option<NewTxMessage>,
|
||||||
pub ciphers_to_send: Vec<String>,
|
pub ciphers_to_send: Vec<String>,
|
||||||
pub commit_to_send: Option<CommitMessage>,
|
pub commit_to_send: Option<CommitMessage>,
|
||||||
pub decrypted_pcds: HashMap<String, Value>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ApiResult<T: FromWasmAbi> = Result<T, ApiError>;
|
pub type ApiResult<T: FromWasmAbi> = Result<T, ApiError>;
|
||||||
@ -1572,31 +1571,53 @@ pub fn create_faucet_msg() -> ApiResult<String> {
|
|||||||
Ok(faucet_msg.to_string())
|
Ok(faucet_msg.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Tsify, Serialize, Deserialize, Default)]
|
||||||
|
#[tsify(into_wasm_abi)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct UserDiff {
|
||||||
|
new_state_merkle_root: String, // TODO add a merkle proof that the new_value belongs to that state
|
||||||
|
field: String,
|
||||||
|
previous_value: Value,
|
||||||
|
new_value: Value,
|
||||||
|
notify_user: bool,
|
||||||
|
need_validation: bool,
|
||||||
|
proof: Option<Proof>, // This is only validation (or refusal) for that specific diff, not the whole state. It can't be commited as such
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Tsify, Serialize, Deserialize, Default)]
|
||||||
|
#[tsify(into_wasm_abi)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct PcdUpdates {
|
||||||
|
pub previous_pcd: Option<Value>, // We don't have a previous state for creation
|
||||||
|
pub decrypted_pcds: HashMap<String, Value>, // Key is the merkle root of the whole state
|
||||||
|
pub modified_values: Vec<UserDiff>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Get active update proposals for a given process outpoint
|
/// Get active update proposals for a given process outpoint
|
||||||
/// Returns a vector with the latest commited state first, if any, and all active proposals
|
/// Returns a vector with the latest commited state first, if any, and all active proposals
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn get_update_proposals(process_outpoint: String) -> ApiResult<ApiReturn> {
|
pub fn get_update_proposals(process_outpoint: String) -> ApiResult<PcdUpdates> {
|
||||||
let outpoint = OutPoint::from_str(&process_outpoint)?;
|
let outpoint = OutPoint::from_str(&process_outpoint)?;
|
||||||
|
|
||||||
let mut processes = lock_processes()?;
|
let mut processes = lock_processes()?;
|
||||||
|
|
||||||
// TODO: We clone the process to prevent double borrowing issue, this can certainly be improved
|
|
||||||
let relevant_process = processes
|
let relevant_process = processes
|
||||||
.get(&outpoint)
|
.get(&outpoint)
|
||||||
.ok_or(ApiError::new("process not found".to_owned()))?;
|
.ok_or(ApiError::new("process not found".to_owned()))?;
|
||||||
|
|
||||||
let mut decrypted_pcds = HashMap::new();
|
let mut decrypted_pcds = HashMap::new();
|
||||||
|
let mut modified_values = Vec::new();
|
||||||
|
|
||||||
// We first push the last commited state, if any
|
let previous_pcd = match relevant_process.get_latest_commited_state() {
|
||||||
match relevant_process.get_latest_commited_state() {
|
|
||||||
Some(state) => {
|
Some(state) => {
|
||||||
let mut decrypted_pcd = Map::new();
|
let mut decrypted_pcd = Map::new();
|
||||||
state.encrypted_pcd.decrypt_fields(&state.keys, &mut decrypted_pcd);
|
state.encrypted_pcd.decrypt_fields(&state.pcd_commitment.to_value_object()?, &state.keys, &mut decrypted_pcd);
|
||||||
let root = <Value as Pcd>::create_merkle_tree(&state.pcd_commitment)?.root().unwrap();
|
Some(Value::Object(decrypted_pcd))
|
||||||
decrypted_pcds.insert(root.to_lower_hex_string(), Value::Object(decrypted_pcd));
|
|
||||||
}
|
|
||||||
None => ()
|
|
||||||
}
|
}
|
||||||
|
None => None
|
||||||
|
};
|
||||||
|
|
||||||
|
let member = lock_local_device()?.to_member();
|
||||||
|
|
||||||
for state in relevant_process.get_latest_concurrent_states()? {
|
for state in relevant_process.get_latest_concurrent_states()? {
|
||||||
if state.encrypted_pcd == Value::Null {
|
if state.encrypted_pcd == Value::Null {
|
||||||
@ -1604,14 +1625,52 @@ pub fn get_update_proposals(process_outpoint: String) -> ApiResult<ApiReturn> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fields_to_validate = state.get_fields_to_validate_for_member(&member)?;
|
||||||
|
|
||||||
let mut decrypted_pcd = Map::new();
|
let mut decrypted_pcd = Map::new();
|
||||||
state.encrypted_pcd.decrypt_fields(&state.keys, &mut decrypted_pcd)?;
|
state.encrypted_pcd.decrypt_fields(&state.pcd_commitment.to_value_object()?, &state.keys, &mut decrypted_pcd)?;
|
||||||
let root = <Value as Pcd>::create_merkle_tree(&state.pcd_commitment)?.root().unwrap();
|
let root = state.pcd_commitment.create_merkle_tree()?.root_hex().unwrap();
|
||||||
decrypted_pcds.insert(root.to_lower_hex_string(), Value::Object(decrypted_pcd));
|
|
||||||
|
if let Some(ref previous_state) = previous_pcd {
|
||||||
|
for (key, value) in &decrypted_pcd {
|
||||||
|
let previous_value = previous_state.get(key).or_else(|| Some(&Value::Null)).unwrap();
|
||||||
|
if previous_value == value { continue; }
|
||||||
|
let need_validation = if fields_to_validate.iter().any(|f| *key == **f) { true } else { false };
|
||||||
|
let notify_user = if need_validation { true } else if !value.is_hex_string() { true } else { false };
|
||||||
|
let diff = UserDiff {
|
||||||
|
new_state_merkle_root: root.clone(),
|
||||||
|
field: key.to_owned(),
|
||||||
|
previous_value: previous_value.clone(),
|
||||||
|
new_value: value.clone(),
|
||||||
|
need_validation,
|
||||||
|
notify_user,
|
||||||
|
proof: None
|
||||||
|
};
|
||||||
|
modified_values.push(diff);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (key, value) in &decrypted_pcd {
|
||||||
|
let need_validation = if fields_to_validate.iter().any(|f| *key == **f) { true } else { false };
|
||||||
|
let notify_user = if need_validation { true } else if !value.is_hex_string() { true } else { false };
|
||||||
|
let diff = UserDiff {
|
||||||
|
new_state_merkle_root: root.clone(),
|
||||||
|
field: key.to_owned(),
|
||||||
|
previous_value: Value::Null,
|
||||||
|
new_value: value.clone(),
|
||||||
|
need_validation,
|
||||||
|
notify_user,
|
||||||
|
proof: None
|
||||||
|
};
|
||||||
|
modified_values.push(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ApiReturn {
|
}
|
||||||
|
decrypted_pcds.insert(root, Value::Object(decrypted_pcd));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(PcdUpdates {
|
||||||
|
previous_pcd,
|
||||||
decrypted_pcds,
|
decrypted_pcds,
|
||||||
..Default::default()
|
modified_values,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user