in fastpay_core/src/authority.rs [82:130]
fn handle_transfer_order(
&mut self,
order: TransferOrder,
) -> Result<AccountInfoResponse, FastPayError> {
// Check the sender's signature and retrieve the transfer data.
fp_ensure!(
self.in_shard(&order.transfer.sender),
FastPayError::WrongShard
);
order.check_signature()?;
let transfer = &order.transfer;
let sender = transfer.sender;
fp_ensure!(
transfer.sequence_number <= SequenceNumber::max(),
FastPayError::InvalidSequenceNumber
);
fp_ensure!(
transfer.amount > Amount::zero(),
FastPayError::IncorrectTransferAmount
);
match self.accounts.get_mut(&sender) {
None => fp_bail!(FastPayError::UnknownSenderAccount),
Some(account) => {
if let Some(pending_confirmation) = &account.pending_confirmation {
fp_ensure!(
&pending_confirmation.value.transfer == transfer,
FastPayError::PreviousTransferMustBeConfirmedFirst {
pending_confirmation: pending_confirmation.value.clone()
}
);
// This exact transfer order was already signed. Return the previous value.
return Ok(account.make_account_info(sender));
}
fp_ensure!(
account.next_sequence_number == transfer.sequence_number,
FastPayError::UnexpectedSequenceNumber
);
fp_ensure!(
account.balance >= transfer.amount.into(),
FastPayError::InsufficientFunding {
current_balance: account.balance
}
);
let signed_order = SignedTransferOrder::new(order, self.name, &self.secret);
account.pending_confirmation = Some(signed_order);
Ok(account.make_account_info(sender))
}
}
}