Refactor prd connect logic
This commit is contained in:
parent
e06917a5ac
commit
d2842831cb
46
src/api.rs
46
src/api.rs
@ -574,13 +574,11 @@ fn handle_transaction(
|
|||||||
public_data: PublicKey,
|
public_data: PublicKey,
|
||||||
) -> AnyhowResult<ApiReturn> {
|
) -> AnyhowResult<ApiReturn> {
|
||||||
let b_scan: SecretKey;
|
let b_scan: SecretKey;
|
||||||
let local_member: Member;
|
|
||||||
let sp_wallet: SpClient;
|
let sp_wallet: SpClient;
|
||||||
{
|
{
|
||||||
let local_device = lock_local_device()?;
|
let local_device = lock_local_device()?;
|
||||||
sp_wallet = local_device.get_sp_client().clone();
|
sp_wallet = local_device.get_sp_client().clone();
|
||||||
b_scan = local_device.get_sp_client().get_scan_key();
|
b_scan = local_device.get_sp_client().get_scan_key();
|
||||||
local_member = local_device.to_member();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basically a transaction that destroyed utxo is a transaction we sent.
|
// Basically a transaction that destroyed utxo is a transaction we sent.
|
||||||
@ -610,7 +608,7 @@ fn handle_transaction(
|
|||||||
let secret_hash = AnkMessageHash::from_message(shared_secret.as_byte_array());
|
let secret_hash = AnkMessageHash::from_message(shared_secret.as_byte_array());
|
||||||
|
|
||||||
// We still don't know who sent it, so we reply with a `Connect` prd
|
// We still don't know who sent it, so we reply with a `Connect` prd
|
||||||
let prd_connect = Prd::new_connect(local_member, secret_hash, None);
|
let prd_connect = Prd::new_connect(None, secret_hash, None);
|
||||||
|
|
||||||
let msg = prd_connect.to_network_msg(&sp_wallet)?;
|
let msg = prd_connect.to_network_msg(&sp_wallet)?;
|
||||||
|
|
||||||
@ -741,29 +739,35 @@ fn create_diffs(device: &MutexGuard<Device>, process: &Process, new_state: &Proc
|
|||||||
Ok(diffs)
|
Ok(diffs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash) -> AnyhowResult<ApiReturn> {
|
fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash, members_list: &OutPointMemberMap) -> AnyhowResult<ApiReturn> {
|
||||||
let local_device = lock_local_device()?;
|
let local_device = lock_local_device()?;
|
||||||
let local_member = local_device.to_member();
|
let local_address = local_device.get_address();
|
||||||
let sp_wallet = local_device.get_sp_client();
|
let sp_wallet = local_device.get_sp_client();
|
||||||
let secret_hash = AnkMessageHash::from_message(secret.as_byte_array());
|
let secret_hash = AnkMessageHash::from_message(secret.as_byte_array());
|
||||||
let mut shared_secrets = lock_shared_secrets()?;
|
let mut shared_secrets = lock_shared_secrets()?;
|
||||||
if let Some(prev_proof) = prd.validation_tokens.get(0) {
|
if let Some(prev_proof) = prd.validation_tokens.get(0) {
|
||||||
|
// We are receiving this as an answer to a prd connect we sent
|
||||||
|
if prd.proof.is_none() {
|
||||||
|
return Err(anyhow::Error::msg("Missing proof"));
|
||||||
|
}
|
||||||
|
|
||||||
// check that the proof is valid
|
// check that the proof is valid
|
||||||
prev_proof.verify()?;
|
prev_proof.verify()?;
|
||||||
// Check it's signed with our key
|
// Check it's signed with our key
|
||||||
let local_address = SilentPaymentAddress::try_from(sp_wallet.get_receiving_address())?;
|
|
||||||
if prev_proof.get_key() != local_address.get_spend_key() {
|
if prev_proof.get_key() != local_address.get_spend_key() {
|
||||||
return Err(anyhow::Error::msg("Previous proof of a prd connect isn't signed by us"));
|
return Err(anyhow::Error::msg("Previous proof of a prd connect isn't signed by us"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check it signs a prd connect that contains the commitment to the shared secret
|
// Check it signs a prd connect that contains the commitment to the shared secret
|
||||||
let empty_prd = Prd::new_connect(local_member, secret_hash, None);
|
let empty_prd = Prd::new_connect(None, secret_hash, None);
|
||||||
let msg = AnkMessageHash::from_message(empty_prd.to_string().as_bytes());
|
let msg = AnkMessageHash::from_message(empty_prd.to_string().as_bytes());
|
||||||
if *msg.as_byte_array() != prev_proof.get_message() {
|
if *msg.as_byte_array() != prev_proof.get_message() {
|
||||||
return Err(anyhow::Error::msg("Previous proof signs another message"));
|
return Err(anyhow::Error::msg("Previous proof signs another message"));
|
||||||
}
|
}
|
||||||
// Now we can confirm the secret and link it to an address
|
|
||||||
let proof = prd.proof.unwrap();
|
// If sender provided its pairing id we can confirm the secret and link it to an address
|
||||||
let actual_sender = prd.sender.get_address_for_key(&proof.get_key())
|
if prd.sender.is_some() {
|
||||||
|
let actual_sender = members_list.0.get(&prd.sender.unwrap()).ok_or(anyhow::Error::msg("Sender not found"))?.get_address_for_key(&prd.proof.unwrap().get_key())
|
||||||
.ok_or(anyhow::Error::msg("Signer of the proof is not part of sender"))?;
|
.ok_or(anyhow::Error::msg("Signer of the proof is not part of sender"))?;
|
||||||
shared_secrets.confirm_secret_for_address(secret, actual_sender.clone().try_into()?);
|
shared_secrets.confirm_secret_for_address(secret, actual_sender.clone().try_into()?);
|
||||||
let mut secrets_return = SecretsStore::new();
|
let mut secrets_return = SecretsStore::new();
|
||||||
@ -773,22 +777,26 @@ fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash) -> AnyhowResult<Api
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let proof = prd.proof.unwrap();
|
// otherwise we can't confirm the secret so we just do nothing
|
||||||
let actual_sender = prd.sender.get_address_for_key(&proof.get_key())
|
return Ok(ApiReturn::default());
|
||||||
.ok_or(anyhow::Error::msg("Signer of the proof is not part of sender"))?;
|
}
|
||||||
|
} else {
|
||||||
|
// We sent a transaction to some address and they answer with a prd connect
|
||||||
|
if prd.proof.is_none() {
|
||||||
|
return Err(anyhow::Error::msg("Missing proof"));
|
||||||
|
}
|
||||||
|
|
||||||
shared_secrets.confirm_secret_for_address(secret, actual_sender.clone().try_into()?);
|
// TODO check that the key in the proof match what we have in the secret store
|
||||||
|
|
||||||
let mut secrets_return = SecretsStore::new();
|
let sender = local_device.get_pairing_commitment();
|
||||||
secrets_return.confirm_secret_for_address(secret, actual_sender.try_into()?);
|
|
||||||
|
|
||||||
let prd_connect = Prd::new_connect(local_member, secret_hash, prd.proof);
|
// We create a prd connect with their own proof in validation tokens so that they can be sure who they're sharing the secret with
|
||||||
|
let prd_connect = Prd::new_connect(sender, secret_hash, prd.proof);
|
||||||
let msg = prd_connect.to_network_msg(sp_wallet)?;
|
let msg = prd_connect.to_network_msg(sp_wallet)?;
|
||||||
let cipher = encrypt_with_key(secret.as_byte_array(), msg.as_bytes())?;
|
let cipher = encrypt_with_key(secret.as_byte_array(), msg.as_bytes())?;
|
||||||
|
|
||||||
return Ok(ApiReturn {
|
return Ok(ApiReturn {
|
||||||
ciphers_to_send: vec![cipher.to_lower_hex_string()],
|
ciphers_to_send: vec![cipher.to_lower_hex_string()],
|
||||||
secrets: Some(secrets_return),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -804,7 +812,7 @@ fn handle_prd(
|
|||||||
// Connect is a bit different here because there's no associated process
|
// Connect is a bit different here because there's no associated process
|
||||||
// Let's handle that case separately
|
// Let's handle that case separately
|
||||||
if prd.prd_type == PrdType::Connect {
|
if prd.prd_type == PrdType::Connect {
|
||||||
return handle_prd_connect(prd, secret);
|
return handle_prd_connect(prd, secret, members_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
let outpoint = prd.process_id;
|
let outpoint = prd.process_id;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user