diff --git a/common/src/escrow_accounts.rs b/common/src/escrow_accounts.rs index 1bd2818f..660a2714 100644 --- a/common/src/escrow_accounts.rs +++ b/common/src/escrow_accounts.rs @@ -11,11 +11,22 @@ use anyhow::Result; use ethers_core::types::U256; use eventuals::{timer, Eventual, EventualExt}; use serde::Deserialize; +use thiserror::Error; use tokio::time::sleep; use tracing::{error, warn}; use crate::prelude::{Query, SubgraphClient}; +#[derive(Error, Debug)] +pub enum EscrowAccountsError { + #[error("No signer found for sender {sender}")] + NoSignerFound { sender: Address }, + #[error("No balance found for sender {sender}")] + NoBalanceFound { sender: Address }, + #[error("No sender found for signer {signer}")] + NoSenderFound { signer: Address }, +} + #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct EscrowAccounts { senders_balances: HashMap, @@ -40,41 +51,40 @@ impl EscrowAccounts { } } - pub fn get_signers_for_sender(&self, sender: &Address) -> Result> { + pub fn get_signers_for_sender( + &self, + sender: &Address, + ) -> Result, EscrowAccountsError> { self.senders_to_signers .get(sender) .filter(|signers| !signers.is_empty()) - .ok_or(anyhow::format_err!( - "No signers found for sender {}.", - sender - )) + .ok_or(EscrowAccountsError::NoSignerFound { + sender: sender.to_owned(), + }) .map(|signers| signers.to_owned()) } - pub fn get_sender_for_signer(&self, signer: &Address) -> Result
{ + pub fn get_sender_for_signer(&self, signer: &Address) -> Result { self.signers_to_senders .get(signer) - .ok_or(anyhow::format_err!( - "Sender not found for receipt signer {}.", - signer - )) + .ok_or(EscrowAccountsError::NoSenderFound { + signer: signer.to_owned(), + }) .copied() } - pub fn get_balance_for_sender(&self, sender: &Address) -> Result { + pub fn get_balance_for_sender(&self, sender: &Address) -> Result { self.senders_balances .get(sender) - .ok_or(anyhow::format_err!( - "Balance not found for sender {}.", - sender - )) + .ok_or(EscrowAccountsError::NoBalanceFound { + sender: sender.to_owned(), + }) .copied() } - pub fn get_balance_for_signer(&self, signer: &Address) -> Result { + pub fn get_balance_for_signer(&self, signer: &Address) -> Result { self.get_sender_for_signer(signer) .and_then(|sender| self.get_balance_for_sender(&sender)) - .map_err(|e| anyhow::format_err!("Could not get balance for signer {}: {}", signer, e)) } pub fn get_senders(&self) -> HashSet
{ diff --git a/tap-agent/src/tap/escrow_adapter.rs b/tap-agent/src/tap/escrow_adapter.rs index 716af393..0b725774 100644 --- a/tap-agent/src/tap/escrow_adapter.rs +++ b/tap-agent/src/tap/escrow_adapter.rs @@ -27,8 +27,30 @@ pub struct EscrowAdapter { #[derive(Debug, Error)] pub enum AdapterError { - #[error("Error in EscrowAdapter: {error}")] - AdapterError { error: String }, + #[error("Could not get escrow accounts from eventual")] + EscrowEventualError { error: String }, + + #[error("Could not get available escrow for sender")] + AvailableEscrowError(#[from] indexer_common::escrow_accounts::EscrowAccountsError), + + #[error("Sender {sender} escrow balance is too large to fit in u128, could not get available escrow.")] + BalanceTooLarge { sender: Address }, + + #[error("Sender {sender} does not have enough escrow to subtract {fees} from {balance}.")] + NotEnoughEscrow { + sender: Address, + fees: u128, + balance: u128, + }, +} + +// Conversion from eventuals::error::Closed to AdapterError::EscrowEventualError +impl From for AdapterError { + fn from(e: eventuals::error::Closed) -> Self { + AdapterError::EscrowEventualError { + error: format!("{:?}", e), + } + } } impl EscrowAdapter { @@ -45,34 +67,16 @@ impl EscrowAdapterTrait for EscrowAdapter { type AdapterError = AdapterError; async fn get_available_escrow(&self, sender: Address) -> Result { - let escrow_accounts = - self.escrow_accounts - .value() - .await - .map_err(|e| AdapterError::AdapterError { - error: format!("Could not get escrow accounts from eventual: {:?}.", e), - })?; - - let sender = escrow_accounts - .get_sender_for_signer(&sender) - .map_err(|e| AdapterError::AdapterError { - error: format!("{}", e).to_string(), - })?; + let escrow_accounts = self.escrow_accounts.value().await?; - let balance = escrow_accounts - .get_balance_for_sender(&sender) - .map_err(|e| AdapterError::AdapterError { - error: format!("Could not get available escrow: {}", e).to_string(), - })? - .to_owned(); - let balance: u128 = balance.try_into().map_err(|_| AdapterError::AdapterError { - error: format!( - "Sender {} escrow balance is too large to fit in u128, \ - could not get available escrow.", - sender - ) - .to_string(), - })?; + let sender = escrow_accounts.get_sender_for_signer(&sender)?; + + let balance = escrow_accounts.get_balance_for_sender(&sender)?.to_owned(); + let balance: u128 = balance + .try_into() + .map_err(|_| AdapterError::BalanceTooLarge { + sender: sender.to_owned(), + })?; let fees = self .sender_pending_fees @@ -85,35 +89,19 @@ impl EscrowAdapterTrait for EscrowAdapter { } async fn subtract_escrow(&self, sender: Address, value: u128) -> Result<(), AdapterError> { - let escrow_accounts = - self.escrow_accounts - .value() - .await - .map_err(|e| AdapterError::AdapterError { - error: format!("Could not get escrow accounts from eventual: {:?}.", e), - })?; + let escrow_accounts = self.escrow_accounts.value().await?; let current_available_escrow = self.get_available_escrow(sender).await?; - let sender = escrow_accounts - .get_sender_for_signer(&sender) - .map_err(|e| AdapterError::AdapterError { - error: format!( - "Could not get available escrow for receipt signer {}: {}", - sender, e - ) - .to_string(), - })?; + let sender = escrow_accounts.get_sender_for_signer(&sender)?; let mut fees_write = self.sender_pending_fees.write().await; let fees = fees_write.entry(sender.to_owned()).or_insert(0); if current_available_escrow < value { - return Err(AdapterError::AdapterError { - error: format!( - "Sender {} does not have enough escrow to subtract {} from {}.", - sender, value, *fees - ) - .to_string(), + return Err(AdapterError::NotEnoughEscrow { + sender: sender.to_owned(), + fees: value, + balance: current_available_escrow, }); } *fees += value;