Skip to content

Commit

Permalink
Removes fee panics from sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
grarco committed Sep 8, 2023
1 parent 9b67281 commit 6c5f80e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 52 deletions.
119 changes: 69 additions & 50 deletions shared/src/ledger/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,11 @@ pub async fn aux_signing_data<
};

if fee_payer == masp_tx_key().to_public() {
panic!(
return Err(Error::Tx(TxError::Other(
"The gas payer cannot be the MASP, please provide a different gas \
payer."
);
.to_string(),
)));
}

Ok(SigningTxData {
Expand All @@ -301,18 +302,18 @@ pub async fn solve_pow_challenge<C: crate::ledger::queries::Client + Sync>(
total_fee: Amount,
balance: Amount,
source: Address,
) -> Option<crate::core::ledger::testnet_pow::Solution> {
) -> Result<Option<crate::core::ledger::testnet_pow::Solution>, Error> {
let is_bal_sufficient = total_fee <= balance;
if !is_bal_sufficient {
let token_addr = args.fee_token.clone();
let err_msg = format!(
"The wrapper transaction source doesn't have enough balance to \
pay fee {}, got {}.",
format_denominated_amount(client, &token_addr, total_fee).await,
format_denominated_amount(client, &token_addr, balance).await,
);
if !args.force && cfg!(feature = "mainnet") {
panic!("{}", err_msg);
let fee_amount =
format_denominated_amount(client, &token_addr, total_fee).await;
let balance =
format_denominated_amount(client, &token_addr, balance).await;
return Err(Error::Tx(TxError::BalanceTooLowForFees(
source, token_addr, fee_amount, balance,
)));
}
}
// A PoW solution can be used to allow zero-fee testnet transactions
Expand All @@ -325,9 +326,9 @@ pub async fn solve_pow_challenge<C: crate::ledger::queries::Client + Sync>(

// Solve the solution, this blocks until a solution is found
let solution = challenge.solve();
Some(solution)
Ok(Some(solution))
} else {
None
Ok(None)
}
}

Expand All @@ -339,7 +340,7 @@ pub async fn update_pow_challenge<C: crate::ledger::queries::Client + Sync>(
tx: &mut Tx,
requires_pow: bool,
source: Address,
) {
) -> Result<(), Error> {
let gas_cost_key = parameter_storage::get_gas_cost_key();
let minimum_fee = match rpc::query_storage_value::<
C,
Expand All @@ -349,16 +350,17 @@ pub async fn update_pow_challenge<C: crate::ledger::queries::Client + Sync>(
.and_then(|map| {
map.get(&args.fee_token)
.map(ToOwned::to_owned)
.ok_or_else(|| Error::Other("no fee found".to_string()))
.ok_or_else(|| {
Error::Other(format!(
"Could not retrieve from storage the gas cost for token {}",
args.fee_token
))
})
}) {
Ok(amount) => amount,
Err(_e) => {
eprintln!(
"Could not retrieve the gas cost for token {}",
args.fee_token
);
Err(e) => {
if !args.force {
panic!();
return Err(e);
} else {
token::Amount::default()
}
Expand Down Expand Up @@ -408,13 +410,15 @@ pub async fn update_pow_challenge<C: crate::ledger::queries::Client + Sync>(
balance,
source,
)
.await;
.await?;
wrapper.fee = Fee {
amount_per_gas_unit: fee_amount,
token: args.fee_token.clone(),
};
wrapper.pow_solution = pow_solution;
}

Ok(())
}

/// Informations about the post-tx balance of the tx's source. Used to correctly
Expand Down Expand Up @@ -444,7 +448,7 @@ pub async fn wrap_tx<
epoch: Epoch,
fee_payer: common::PublicKey,
#[cfg(not(feature = "mainnet"))] requires_pow: bool,
) -> Option<Epoch> {
) -> Result<Option<Epoch>, Error> {
let fee_payer_address = Address::from(&fee_payer);
// Validate fee amount and token
let gas_cost_key = parameter_storage::get_gas_cost_key();
Expand All @@ -456,16 +460,17 @@ pub async fn wrap_tx<
.and_then(|map| {
map.get(&args.fee_token)
.map(ToOwned::to_owned)
.ok_or_else(|| Error::Other("no fee found".to_string()))
.ok_or_else(|| {
Error::Other(format!(
"Could not retrieve from storage the gas cost for token {}",
args.fee_token
))
})
}) {
Ok(amount) => amount,
Err(_e) => {
eprintln!(
"Could not retrieve the gas cost for token {}",
args.fee_token
);
Err(e) => {
if !args.force {
panic!();
return Err(e);
} else {
token::Amount::default()
}
Expand Down Expand Up @@ -587,48 +592,62 @@ pub async fn wrap_tx<
&& !args.force
&& cfg!(feature = "mainnet")
{
panic!(
"Fee unshielding descriptions exceed the limit"
);
return Err(Error::Tx(
TxError::FeeUnshieldingError(format!(
"Descriptions exceed the limit: found \
{descriptions}, limit \
{descriptions_limit}"
)),
));
}

updated_balance += total_fee;
(Some(transaction), Some(unshielding_epoch))
}
Ok(None) => {
eprintln!("Missing unshielding transaction");
if !args.force && cfg!(feature = "mainnet") {
panic!();
return Err(Error::Tx(
TxError::FeeUnshieldingError(
"Missing unshielding transaction"
.to_string(),
),
));
}

(None, None)
}
Err(e) => {
eprintln!("Error in fee unshielding generation: {}", e);
if !args.force && cfg!(feature = "mainnet") {
panic!();
return Err(Error::Tx(
TxError::FeeUnshieldingError(e.to_string()),
));
}

(None, None)
}
}
} else {
let token_addr = args.fee_token.clone();
let err_msg = format!(
"The wrapper transaction source doesn't have enough \
balance to pay fee {}, balance: {}.",
format_denominated_amount(client, &token_addr, total_fee)
.await,
format_denominated_amount(
if !args.force && cfg!(feature = "mainnet") {
let fee_amount = format_denominated_amount(
client,
&token_addr,
updated_balance
total_fee,
)
.await,
);
eprintln!("{}", err_msg);
if !args.force && cfg!(feature = "mainnet") {
panic!("{}", err_msg);
.await;

let balance = format_denominated_amount(
client,
&token_addr,
updated_balance,
)
.await;
return Err(Error::Tx(TxError::BalanceTooLowForFees(
fee_payer_address,
token_addr,
fee_amount,
balance,
)));
}

(None, None)
Expand Down Expand Up @@ -662,7 +681,7 @@ pub async fn wrap_tx<
updated_balance,
fee_payer_address,
)
.await;
.await?;

tx.add_wrapper(
Fee {
Expand All @@ -678,7 +697,7 @@ pub async fn wrap_tx<
unshield_section_hash,
);

unshielding_epoch
Ok(unshielding_epoch)
}

#[allow(clippy::result_large_err)]
Expand Down
4 changes: 2 additions & 2 deletions shared/src/ledger/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ pub async fn prepare_tx<
if !args.dry_run {
let epoch = rpc::query_epoch(client).await?;

Ok(signing::wrap_tx(
signing::wrap_tx(
client,
shielded,
tx,
Expand All @@ -174,7 +174,7 @@ pub async fn prepare_tx<
#[cfg(not(feature = "mainnet"))]
requires_pow,
)
.await)
.await
} else {
Ok(None)
}
Expand Down
9 changes: 9 additions & 0 deletions shared/src/types/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ pub enum TxError {
to be transferred. Amount to transfer is {2} and the balance is {3}."
)]
BalanceTooLow(Address, Address, String, String),
/// Balance is too low for fee payment
#[error(
"The balance of the source {0} of token {1} is lower than the amount \
required for fees. Amount of the fees is {2} and the balance is {3}."
)]
BalanceTooLowForFees(Address, Address, String, String),
/// Token Address does not exist on chain
#[error("The token address {0} doesn't exist on chain.")]
TokenDoesNotExist(Address),
Expand All @@ -213,6 +219,9 @@ pub enum TxError {
/// No Balance found for token
#[error("{0}")]
MaspError(String),
/// Error in the fee unshielding transaction
#[error("Error in fee unshielding: {0}")]
FeeUnshieldingError(String),
/// Wasm validation failed
#[error("Validity predicate code validation failed with {0}")]
WasmValidationFailure(WasmValidationError),
Expand Down

0 comments on commit 6c5f80e

Please sign in to comment.