Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fastx client] Better Error Handling & Messaging - Part 1 #256

Merged
merged 10 commits into from
Jan 26, 2022
Prev Previous commit
Next Next commit
* added test for receiving tempered certificate
* check certificate order signature before receive_object
  • Loading branch information
patrickkuo committed Jan 26, 2022
commit 29043b6f87b501ce7460ca0b0ad104b44d7d7225
8 changes: 4 additions & 4 deletions fastpay_core/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,21 +791,20 @@ where
account: self.address,
};
// Sequentially try each authority in random order.
let mut authorities: Vec<AuthorityName> =
self.authority_clients.clone().into_keys().collect();
let mut authorities: Vec<&AuthorityName> = self.authority_clients.keys().collect();
// TODO: implement sampling according to stake distribution and using secure RNG. https://github.com/MystenLabs/fastnft/issues/128
authorities.shuffle(&mut rand::thread_rng());
// Authority could be byzantine, add timeout to avoid waiting forever.
for authority_name in authorities {
let authority = self.authority_clients.get(&authority_name).unwrap();
let authority = self.authority_clients.get(authority_name).unwrap();
let result = timeout(
AUTHORITY_REQUEST_TIMEOUT,
authority.handle_account_info_request(request.clone()),
)
.map_err(|_| FastPayError::ErrorWhileRequestingInformation)
.await?;
if let Ok(AccountInfoResponse { object_ids, .. }) = &result {
return Ok((authority_name, object_ids.clone()));
return Ok((*authority_name, object_ids.clone()));
}
}
Err(FastPayError::ErrorWhileRequestingInformation)
Expand Down Expand Up @@ -1040,6 +1039,7 @@ where
}

async fn receive_object(&mut self, certificate: &CertifiedOrder) -> Result<(), anyhow::Error> {
certificate.check(&self.committee)?;
match &certificate.order.kind {
OrderKind::Transfer(transfer) => {
fp_ensure!(
Expand Down
29 changes: 29 additions & 0 deletions fastpay_core/src/unit_tests/client_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1660,5 +1660,34 @@ async fn test_receive_object_error() -> Result<(), anyhow::Error> {
Some(FastPayError::IncorrectRecipientError)
));

// Test 2: Receive tempered certificate order.
let (transfer, sig) = match certificate.order {
Order {
kind: OrderKind::Transfer(t),
signature,
} => Some((t, signature)),
_ => None,
}
.unwrap();

let malformed_order = CertifiedOrder {
order: Order {
kind: OrderKind::Transfer(Transfer {
sender: client1.address,
recipient: Address::FastPay(client2.address),
object_ref: transfer.object_ref,
gas_payment: transfer.gas_payment,
}),
signature: sig,
},
signatures: certificate.signatures,
};

let result = client2.receive_object(&malformed_order).await;
assert!(matches!(
result.unwrap_err().downcast_ref(),
Some(FastPayError::InvalidSignature { .. })
));

Ok(())
}