Optimisation and api simplification

This commit is contained in:
NicolasCantu 2025-03-26 12:43:15 +01:00
parent 4e8ac88336
commit f7e5c1e2e7

View File

@ -1126,17 +1126,13 @@ pub fn create_connect_transaction(addresses: Vec<String>, fee_rate: u32) -> ApiR
#[wasm_bindgen]
pub fn create_new_process(
init_state: JsValue,
roles: JsValue,
public_data: JsValue,
private_data: Pcd,
roles: Roles,
public_data: Pcd,
relay_address: String,
fee_rate: u32,
members_list: OutPointMemberMap,
) -> ApiResult<ApiReturn> {
let init_state: Pcd = serde_wasm_bindgen::from_value(init_state)?;
let roles: Roles = serde_wasm_bindgen::from_value(roles)?;
let public_data: Pcd = serde_wasm_bindgen::from_value(public_data)?;
// We create a transaction that spends to the relay address
let psbt = create_transaction_for_addresses(vec![relay_address.clone()], fee_rate)?;
@ -1157,7 +1153,7 @@ pub fn create_new_process(
let new_tx_msg = NewTxMessage::new(serialize(&transaction).to_lower_hex_string(), None);
let mut new_state = ProcessState::new(process_id, init_state.clone(), public_data.clone(), roles.clone())?;
let mut new_state = ProcessState::new(process_id, private_data.clone(), public_data.clone(), roles.clone())?;
let pcd_commitment = new_state.pcd_commitment.clone();
@ -1165,22 +1161,18 @@ pub fn create_new_process(
let diffs = create_diffs(&process, &new_state, &members_list)?;
let all_fields: Vec<String> = init_state.iter().map(|(field, _)| field.clone()).collect();
let mut fields2keys = BTreeMap::new();
let mut encrypted_data = BTreeMap::new();
let mut rng = thread_rng();
for (field, plain_value) in init_state.iter() {
for (field, plain_value) in private_data.iter() {
let hash = pcd_commitment.get(field).ok_or(anyhow::Error::msg("Missing commitment"))?;
let key = generate_key(&mut rng);
let serialized = serde_json::to_string(plain_value)?;
let cipher = encrypt_with_key(&key, serialized.as_bytes())?;
fields2keys.insert(field.to_owned(), key);
new_state.keys.insert(field.to_owned(), key);
encrypted_data.insert(hash.to_lower_hex_string(), cipher.to_lower_hex_string());
}
new_state.keys = fields2keys;
process.insert_concurrent_state(new_state.clone())?;
{
@ -1218,15 +1210,13 @@ pub fn create_new_process(
}
#[wasm_bindgen]
/// TODO allow modifications from user that doesn't have read access to all attributes
pub fn update_process(
mut process: Process,
new_attributes: Pcd,
roles: Roles,
new_public_data: Pcd,
members_list: OutPointMemberMap,
) -> ApiResult<ApiReturn> {
let new_attributes: Pcd = serde_wasm_bindgen::from_value(new_attributes)?;
let roles: Roles = serde_wasm_bindgen::from_value(roles)?;
let new_public_data: Pcd = serde_wasm_bindgen::from_value(new_public_data)?;
let process_id = process.get_process_id()?;
let prev_state = process.get_latest_commited_state()
@ -1237,9 +1227,6 @@ pub fn update_process(
prev_public_data.insert(field, value);
}
// We expect the whole set of attributes for now, even if value doesn't change since previous state
// We rehash everything with the new txid, so we need the clear value
// eventually we would like to be able to create partial states even if we don't have read access to some attributes
let mut new_state = ProcessState::new(
process.get_process_tip()?,
new_attributes.clone(),
@ -1312,7 +1299,7 @@ pub fn update_process(
pub fn request_data(process_id: String, state_ids_str: Vec<String>, roles: JsValue, members_list: OutPointMemberMap) -> ApiResult<ApiReturn> {
let process_id = OutPoint::from_str(&process_id)?;
let local_device = lock_local_device()?;
let sender = local_device.to_member();
let sender_pairing_id = local_device.get_pairing_commitment().ok_or(ApiError::new("Device not paired".to_owned()))?;
let sp_wallet = local_device.get_wallet();
let local_address = sp_wallet.get_client().get_receiving_address();
let roles: Vec<Roles> = serde_wasm_bindgen::from_value(roles)?;
@ -1329,14 +1316,16 @@ pub fn request_data(process_id: String, state_ids_str: Vec<String>, roles: JsVal
let mut send_to: HashSet<SilentPaymentAddress> = HashSet::new();
for role in roles {
for (_, role_def) in role {
let members = &role_def.members;
if !members.contains(&sender) {
let pairing_ids = &role_def.members;
if !pairing_ids.contains(&sender_pairing_id) {
continue;
}
for member in members {
for address in member.get_addresses() {
if address == local_address { continue };
send_to.insert(SilentPaymentAddress::try_from(address)?);
for pairing_id in pairing_ids {
if let Some(member) = members_list.0.get(pairing_id) {
for address in member.get_addresses() {
if address == local_address { continue };
send_to.insert(SilentPaymentAddress::try_from(address)?);
}
}
}
}
@ -1370,18 +1359,13 @@ pub fn request_data(process_id: String, state_ids_str: Vec<String>, roles: JsVal
#[wasm_bindgen]
pub fn create_update_message(
process_id: String,
process: Process,
state_id: String,
members_list: OutPointMemberMap
) -> ApiResult<ApiReturn> {
let mut processes = lock_processes()?;
let process_id = OutPoint::from_str(&process_id)?;
let process_id = process.get_process_id()?;
let state_id: [u8; 32] = Vec::from_hex(&state_id)?.try_into().map_err(|_| ApiError::new("Invalid state_id".to_owned()))?;
let process = processes.get_mut(&process_id)
.ok_or(ApiError::new("Unknown process".to_owned()))?;
let update_state = process.get_state_for_id(&state_id)?;
let local_device = lock_local_device()?;
@ -1397,7 +1381,12 @@ pub fn create_update_message(
.iter()
.flat_map(|rule| rule.fields.clone())
.collect();
for member in &role.members {
for pairing_id in &role.members {
let member = if let Some(member) = members_list.0.get(pairing_id) {
member
} else {
continue;
};
// Check that we have a shared_secret with all members
if let Some(no_secret_address) = member.get_addresses().iter()
.find(|a| shared_secrets.get_secret_for_address(a.as_str().try_into().unwrap()).is_none())
@ -1405,7 +1394,7 @@ pub fn create_update_message(
// We ignore it if we don't have a secret with ourselves
if *no_secret_address != local_address {
// for now we return an error to keep it simple
return Err(ApiError::new(format!("No shared secret for all addresses of {:?}\nPlease first connect", member)));
return Err(ApiError::new(format!("No shared secret for all addresses of {:?}\nPlease first connect", pairing_id)));
}
}
if !all_members.contains_key(&member) {