Refactoring of the response api
This commit is contained in:
parent
ad632e40ce
commit
e90473d8be
89
src/api.rs
89
src/api.rs
@ -889,7 +889,6 @@ fn handle_prd(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
PrdType::Response => {
|
PrdType::Response => {
|
||||||
// We must know of a prd update that the response answers to
|
|
||||||
let mut updated_state = relevant_process
|
let mut updated_state = relevant_process
|
||||||
.get_latest_concurrent_states_mut()?
|
.get_latest_concurrent_states_mut()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -1251,7 +1250,7 @@ pub fn update_process(
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn create_update_message(
|
pub fn create_update_message(
|
||||||
init_commitment: String,
|
init_commitment: String,
|
||||||
pcd_commitment: String,
|
merkle_root_hex: String,
|
||||||
) -> ApiResult<ApiReturn> {
|
) -> ApiResult<ApiReturn> {
|
||||||
let mut processes = lock_processes()?;
|
let mut processes = lock_processes()?;
|
||||||
|
|
||||||
@ -1260,18 +1259,17 @@ pub fn create_update_message(
|
|||||||
let process = processes.get_mut(&outpoint)
|
let process = processes.get_mut(&outpoint)
|
||||||
.ok_or(ApiError::new("Unknown process".to_owned()))?;
|
.ok_or(ApiError::new("Unknown process".to_owned()))?;
|
||||||
|
|
||||||
let latest_states = process.get_latest_concurrent_states()?;
|
let mut merkle_root_bin = [0u8; 32];
|
||||||
// This is a map of keys to hash of the clear values
|
let merkle_root_vec = Vec::from_hex(&merkle_root_hex)?;
|
||||||
let new_state_commitments = <Value as Pcd>::from_string(&pcd_commitment)?;
|
|
||||||
|
|
||||||
let update_state: &ProcessState;
|
if merkle_root_vec.len() != 32 {
|
||||||
if let Some(state) = latest_states.into_iter().find(|state| state.pcd_commitment == new_state_commitments)
|
return Err(ApiError::new("merkle root must be 32B long".to_owned()));
|
||||||
{
|
|
||||||
update_state = state;
|
|
||||||
} else {
|
|
||||||
return Err(ApiError::new("Can't find the state to update".to_owned()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
merkle_root_bin.copy_from_slice(&merkle_root_vec);
|
||||||
|
|
||||||
|
let update_state = process.get_state_for_commitments_root(merkle_root_bin)?;
|
||||||
|
|
||||||
// We must have at least the key for the roles field, otherwise we don't know who to send the message to
|
// We must have at least the key for the roles field, otherwise we don't know who to send the message to
|
||||||
let clear_state = update_state.decrypt_pcd().as_object().unwrap().clone();
|
let clear_state = update_state.decrypt_pcd().as_object().unwrap().clone();
|
||||||
|
|
||||||
@ -1322,7 +1320,7 @@ pub fn create_update_message(
|
|||||||
serde_json::to_string(&sender)?,
|
serde_json::to_string(&sender)?,
|
||||||
serialize(&encrypted_pcd_merkle_root).to_lower_hex_string(),
|
serialize(&encrypted_pcd_merkle_root).to_lower_hex_string(),
|
||||||
update_state.keys.clone(),
|
update_state.keys.clone(),
|
||||||
new_state_commitments
|
update_state.pcd_commitment.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut ciphers = vec![];
|
let mut ciphers = vec![];
|
||||||
@ -1360,9 +1358,54 @@ pub fn create_update_message(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn create_response_message(init_commitment: String, pcd_commitment: String, approval: bool) -> ApiResult<ApiReturn> {
|
pub fn validate_state(init_commitment: String, merkle_root_hex: String) -> ApiResult<ApiReturn> {
|
||||||
|
add_validation_token(init_commitment, merkle_root_hex, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn refuse_state(init_commitment: String, merkle_root_hex: String) -> ApiResult<ApiReturn> {
|
||||||
|
add_validation_token(init_commitment, merkle_root_hex, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_validation_token(init_commitment: String, merkle_root_hex: String, approval: bool) -> ApiResult<ApiReturn> {
|
||||||
let mut merkle_root = [0u8; 32];
|
let mut merkle_root = [0u8; 32];
|
||||||
let pcd_commitment_vec = Vec::from_hex(&pcd_commitment)?;
|
let pcd_commitment_vec = Vec::from_hex(&merkle_root_hex)?;
|
||||||
|
if pcd_commitment_vec.len() != 32 {
|
||||||
|
return Err(ApiError::new("pcd_commitment must be 32B long".to_owned()));
|
||||||
|
}
|
||||||
|
merkle_root.copy_from_slice(&pcd_commitment_vec);
|
||||||
|
|
||||||
|
let mut processes = lock_processes()?;
|
||||||
|
|
||||||
|
let outpoint = OutPoint::from_str(&init_commitment)?;
|
||||||
|
|
||||||
|
let process = processes.get_mut(&outpoint)
|
||||||
|
.ok_or(ApiError::new("Unknown process".to_owned()))?;
|
||||||
|
|
||||||
|
let update_state: &mut ProcessState = process.get_state_for_commitments_root(merkle_root)?;
|
||||||
|
|
||||||
|
let message_hash = if approval {
|
||||||
|
AnkHash::ValidationYes(AnkValidationYesHash::from_byte_array(merkle_root))
|
||||||
|
} else {
|
||||||
|
AnkHash::ValidationNo(AnkValidationNoHash::from_byte_array(merkle_root))
|
||||||
|
};
|
||||||
|
|
||||||
|
let local_device = lock_local_device()?;
|
||||||
|
let sp_wallet = local_device.get_wallet();
|
||||||
|
let proof = Proof::new(message_hash, sp_wallet.get_client().get_spend_key().try_into()?);
|
||||||
|
|
||||||
|
update_state.validation_tokens.push(proof);
|
||||||
|
|
||||||
|
Ok(ApiReturn {
|
||||||
|
updated_process: Some((init_commitment, process.clone())),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn create_response_prd(init_commitment: String, merkle_root_hex: String) -> ApiResult<ApiReturn> {
|
||||||
|
let mut merkle_root = [0u8; 32];
|
||||||
|
let pcd_commitment_vec = Vec::from_hex(&merkle_root_hex)?;
|
||||||
if pcd_commitment_vec.len() != 32 {
|
if pcd_commitment_vec.len() != 32 {
|
||||||
return Err(ApiError::new("pcd_commitment must be 32B long".to_owned()));
|
return Err(ApiError::new("pcd_commitment must be 32B long".to_owned()));
|
||||||
}
|
}
|
||||||
@ -1383,7 +1426,6 @@ pub fn create_response_message(init_commitment: String, pcd_commitment: String,
|
|||||||
let roles = Value::Object(clear_state).extract_roles()?;
|
let roles = Value::Object(clear_state).extract_roles()?;
|
||||||
|
|
||||||
let local_device = lock_local_device()?;
|
let local_device = lock_local_device()?;
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
@ -1396,7 +1438,6 @@ pub fn create_response_message(init_commitment: String, pcd_commitment: String,
|
|||||||
.flat_map(|rule| rule.fields.clone())
|
.flat_map(|rule| rule.fields.clone())
|
||||||
.collect();
|
.collect();
|
||||||
for member in role.members {
|
for member in role.members {
|
||||||
debug!("member: {:?}", member);
|
|
||||||
// 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())
|
||||||
@ -1414,20 +1455,17 @@ pub fn create_response_message(init_commitment: String, pcd_commitment: String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let our_key = SilentPaymentAddress::try_from(local_address.as_str())?.get_spend_key();
|
||||||
|
let proof = update_state.validation_tokens.iter().find(|t| t.get_key() == our_key)
|
||||||
|
.ok_or(ApiError::new("We haven't added our validation token yet".to_owned()))?;
|
||||||
|
|
||||||
let sender: Member = local_device
|
let sender: Member = local_device
|
||||||
.to_member();
|
.to_member();
|
||||||
|
|
||||||
let message_hash = if approval {
|
|
||||||
AnkHash::ValidationYes(AnkValidationYesHash::from_byte_array(merkle_root))
|
|
||||||
} else {
|
|
||||||
AnkHash::ValidationNo(AnkValidationNoHash::from_byte_array(merkle_root))
|
|
||||||
};
|
|
||||||
let proof = Proof::new(message_hash, sp_wallet.get_client().get_spend_key().try_into()?);
|
|
||||||
|
|
||||||
let response_prd = Prd::new_response(
|
let response_prd = Prd::new_response(
|
||||||
outpoint,
|
outpoint,
|
||||||
serde_json::to_string(&sender)?,
|
serde_json::to_string(&sender)?,
|
||||||
vec![proof],
|
vec![*proof],
|
||||||
update_state.pcd_commitment.clone(),
|
update_state.pcd_commitment.clone(),
|
||||||
);
|
);
|
||||||
let prd_msg = response_prd.to_network_msg(sp_wallet)?;
|
let prd_msg = response_prd.to_network_msg(sp_wallet)?;
|
||||||
@ -1453,10 +1491,7 @@ pub fn create_response_message(init_commitment: String, pcd_commitment: String,
|
|||||||
return Err(ApiError::new("Empty ciphers list".to_owned()));
|
return Err(ApiError::new("Empty ciphers list".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
update_state.validation_tokens.push(proof);
|
|
||||||
|
|
||||||
Ok(ApiReturn {
|
Ok(ApiReturn {
|
||||||
updated_process: Some((outpoint.to_string(), process.clone())),
|
|
||||||
ciphers_to_send: ciphers,
|
ciphers_to_send: ciphers,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use sdk_client::api::{
|
use sdk_client::api::{
|
||||||
create_device_from_sp_wallet, create_new_process, create_response_message, create_update_message, dump_device, get_address, get_update_proposals, pair_device, parse_cipher, reset_device, restore_device, set_process_cache, set_shared_secrets, setup
|
create_device_from_sp_wallet, create_new_process, create_response_prd, create_update_message, dump_device, get_address, get_update_proposals, pair_device, parse_cipher, reset_device, restore_device, set_process_cache, set_shared_secrets, setup, validate_state
|
||||||
};
|
};
|
||||||
use sdk_common::crypto::AnkSharedSecretHash;
|
use sdk_common::crypto::AnkSharedSecretHash;
|
||||||
use sdk_common::log::debug;
|
use sdk_common::log::debug;
|
||||||
@ -185,25 +185,17 @@ fn test_pairing() {
|
|||||||
// We send the commit_msg to the relay we got the address from
|
// We send the commit_msg to the relay we got the address from
|
||||||
|
|
||||||
// now we create prd update for this new process
|
// now we create prd update for this new process
|
||||||
let create_update_return = create_update_message(outpoint, commit_msg.pcd_commitment.to_string()).unwrap();
|
debug!("Alice sends an update prd to Bob");
|
||||||
|
let root = <Value as Pcd>::create_merkle_tree(&commit_msg.pcd_commitment).unwrap().root().unwrap();
|
||||||
|
let create_update_return = create_update_message(outpoint, root.to_lower_hex_string()).unwrap();
|
||||||
|
|
||||||
let (root_outpoint, alice_init_process) = create_update_return.updated_process.unwrap();
|
let (root_outpoint, alice_init_process) = create_update_return.updated_process.unwrap();
|
||||||
alice_process_cache.insert(root_outpoint.clone(), alice_init_process);
|
alice_process_cache.insert(root_outpoint.clone(), alice_init_process);
|
||||||
|
|
||||||
debug!("Alice pairs her device");
|
debug!("Alice pairs her device");
|
||||||
// we can update our local device now, first with an empty txid
|
|
||||||
pair_device(root_outpoint, vec![helper_get_bob_address()]).unwrap();
|
pair_device(root_outpoint, vec![helper_get_bob_address()]).unwrap();
|
||||||
|
|
||||||
debug!("Alice sends an update prd to Bob");
|
let alice_to_bob_cipher = &create_update_return.ciphers_to_send[0];
|
||||||
let alice_pairing_return =
|
|
||||||
create_update_message(alice_process_cache.keys().next().unwrap().to_owned(), commit_msg.pcd_commitment.to_string()).unwrap();
|
|
||||||
|
|
||||||
// debug!("{:#?}", alice_pairing_return);
|
|
||||||
|
|
||||||
let (root_outpoint, alice_init_process) = alice_pairing_return.updated_process.unwrap();
|
|
||||||
alice_process_cache.insert(root_outpoint.clone(), alice_init_process.clone());
|
|
||||||
|
|
||||||
let alice_to_bob_cipher = &alice_pairing_return.ciphers_to_send[0];
|
|
||||||
|
|
||||||
// this is only for testing, as we're playing both parts
|
// this is only for testing, as we're playing both parts
|
||||||
let alice_device = dump_device().unwrap();
|
let alice_device = dump_device().unwrap();
|
||||||
@ -254,11 +246,13 @@ fn test_pairing() {
|
|||||||
let root = <Value as Pcd>::create_merkle_tree(&relevant_state.pcd_commitment).unwrap().root().unwrap();
|
let root = <Value as Pcd>::create_merkle_tree(&relevant_state.pcd_commitment).unwrap().root().unwrap();
|
||||||
|
|
||||||
// Alice can also sign her response and send it to Bob
|
// Alice can also sign her response and send it to Bob
|
||||||
let alice_response = create_response_message(commit_msg.init_tx, root.to_lower_hex_string(), true).unwrap();
|
let validate_state_return = validate_state(commit_msg.init_tx, root.to_lower_hex_string()).unwrap();
|
||||||
|
|
||||||
let (outpoint, updated_process) = alice_response.updated_process.unwrap();
|
let (outpoint, validated_process) = validate_state_return.updated_process.unwrap();
|
||||||
|
|
||||||
alice_process_cache.insert(outpoint, updated_process);
|
alice_process_cache.insert(outpoint.clone(), validated_process);
|
||||||
|
|
||||||
|
let alice_response = create_response_prd(outpoint, root.to_lower_hex_string()).unwrap();
|
||||||
|
|
||||||
// ======================= Bob
|
// ======================= Bob
|
||||||
reset_device().unwrap();
|
reset_device().unwrap();
|
||||||
@ -318,16 +312,16 @@ fn test_pairing() {
|
|||||||
|
|
||||||
// If user is ok, we can add our own validation token
|
// If user is ok, we can add our own validation token
|
||||||
// Get the whole commitment from the process
|
// Get the whole commitment from the process
|
||||||
let bob_response = create_response_message(root_outpoint, pcd_commitment_root.to_string(), true).unwrap();
|
let bob_validated_process = validate_state(root_outpoint.clone(), pcd_commitment_root.to_string()).unwrap();
|
||||||
|
|
||||||
|
let (_, validated_process) = bob_validated_process.updated_process.unwrap();
|
||||||
|
|
||||||
|
bob_process_cache.insert(root_outpoint.clone(), validated_process);
|
||||||
|
|
||||||
|
let bob_response = create_response_prd(root_outpoint.clone(), pcd_commitment_root.to_string()).unwrap();
|
||||||
|
|
||||||
let (root_outpoint, updated_process) = bob_response.updated_process.unwrap();
|
|
||||||
let ciphers = bob_response.ciphers_to_send; // We would send it to Alice to let her know we agree
|
let ciphers = bob_response.ciphers_to_send; // We would send it to Alice to let her know we agree
|
||||||
|
|
||||||
bob_process_cache.insert(
|
|
||||||
root_outpoint.clone(),
|
|
||||||
updated_process,
|
|
||||||
);
|
|
||||||
|
|
||||||
debug!("Bob pairs device with Alice");
|
debug!("Bob pairs device with Alice");
|
||||||
pair_device(root_outpoint, proposal_members).unwrap();
|
pair_device(root_outpoint, proposal_members).unwrap();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user