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] #[wasm_bindgen]
pub fn create_new_process( pub fn create_new_process(
init_state: JsValue, private_data: Pcd,
roles: JsValue, roles: Roles,
public_data: JsValue, public_data: Pcd,
relay_address: String, relay_address: String,
fee_rate: u32, fee_rate: u32,
members_list: OutPointMemberMap, members_list: OutPointMemberMap,
) -> ApiResult<ApiReturn> { ) -> 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 // 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)?;
@ -1157,7 +1153,7 @@ pub fn create_new_process(
let new_tx_msg = NewTxMessage::new(serialize(&transaction).to_lower_hex_string(), None); 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(); 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 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 encrypted_data = BTreeMap::new();
let mut rng = thread_rng(); 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 hash = pcd_commitment.get(field).ok_or(anyhow::Error::msg("Missing commitment"))?;
let key = generate_key(&mut rng); let key = generate_key(&mut rng);
let serialized = serde_json::to_string(plain_value)?; let serialized = serde_json::to_string(plain_value)?;
let cipher = encrypt_with_key(&key, serialized.as_bytes())?; 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()); encrypted_data.insert(hash.to_lower_hex_string(), cipher.to_lower_hex_string());
} }
new_state.keys = fields2keys;
process.insert_concurrent_state(new_state.clone())?; process.insert_concurrent_state(new_state.clone())?;
{ {
@ -1218,15 +1210,13 @@ pub fn create_new_process(
} }
#[wasm_bindgen] #[wasm_bindgen]
/// TODO allow modifications from user that doesn't have read access to all attributes
pub fn update_process( pub fn update_process(
mut process: Process, mut process: Process,
new_attributes: Pcd,
roles: Roles,
new_public_data: Pcd,
members_list: OutPointMemberMap, members_list: OutPointMemberMap,
) -> ApiResult<ApiReturn> { ) -> 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 process_id = process.get_process_id()?;
let prev_state = process.get_latest_commited_state() let prev_state = process.get_latest_commited_state()
@ -1237,9 +1227,6 @@ pub fn update_process(
prev_public_data.insert(field, value); 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( let mut new_state = ProcessState::new(
process.get_process_tip()?, process.get_process_tip()?,
new_attributes.clone(), 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> { 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 process_id = OutPoint::from_str(&process_id)?;
let local_device = lock_local_device()?; 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 sp_wallet = local_device.get_wallet();
let local_address = sp_wallet.get_client().get_receiving_address(); let local_address = sp_wallet.get_client().get_receiving_address();
let roles: Vec<Roles> = serde_wasm_bindgen::from_value(roles)?; 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(); let mut send_to: HashSet<SilentPaymentAddress> = HashSet::new();
for role in roles { for role in roles {
for (_, role_def) in role { for (_, role_def) in role {
let members = &role_def.members; let pairing_ids = &role_def.members;
if !members.contains(&sender) { if !pairing_ids.contains(&sender_pairing_id) {
continue; continue;
} }
for member in members { for pairing_id in pairing_ids {
for address in member.get_addresses() { if let Some(member) = members_list.0.get(pairing_id) {
if address == local_address { continue }; for address in member.get_addresses() {
send_to.insert(SilentPaymentAddress::try_from(address)?); 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] #[wasm_bindgen]
pub fn create_update_message( pub fn create_update_message(
process_id: String, process: Process,
state_id: String, state_id: String,
members_list: OutPointMemberMap members_list: OutPointMemberMap
) -> ApiResult<ApiReturn> { ) -> ApiResult<ApiReturn> {
let mut processes = lock_processes()?; let process_id = process.get_process_id()?;
let process_id = OutPoint::from_str(&process_id)?;
let state_id: [u8; 32] = Vec::from_hex(&state_id)?.try_into().map_err(|_| ApiError::new("Invalid state_id".to_owned()))?; 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 update_state = process.get_state_for_id(&state_id)?;
let local_device = lock_local_device()?; let local_device = lock_local_device()?;
@ -1397,7 +1381,12 @@ pub fn create_update_message(
.iter() .iter()
.flat_map(|rule| rule.fields.clone()) .flat_map(|rule| rule.fields.clone())
.collect(); .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 // Check that we have a shared_secret with all members
if let Some(no_secret_address) = member.get_addresses().iter() 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()) .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 // We ignore it if we don't have a secret with ourselves
if *no_secret_address != local_address { if *no_secret_address != local_address {
// for now we return an error to keep it simple // 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) { if !all_members.contains_key(&member) {