Skip to content

Commit

Permalink
token-client: Check simulation results for error
Browse files Browse the repository at this point in the history
#### Problem

If the simulation for compute unit limit fails in the token-cli, it may
continue to try to broadcast a transaction since the error falls
through. Although that transaction should fail too, at least we don't
run the risk of broadcasting something known to be bad.

#### Summary of changes

Add an `err()` function on the simulation results, and abort if the
simulation for compute units fails.
  • Loading branch information
joncinque committed Nov 25, 2024
1 parent 4349310 commit b9aa695
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
13 changes: 13 additions & 0 deletions token/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub trait SimulateTransaction {
/// Trait for the output of a simulation
pub trait SimulationResult {
fn get_compute_units_consumed(&self) -> ProgramClientResult<u64>;
fn err(self) -> Option<ProgramClientError>;
}

/// Extends basic `SendTransaction` trait with function `send` where client is
Expand Down Expand Up @@ -78,6 +79,9 @@ impl SimulationResult for BanksTransactionResultWithSimulation {
.map(|x| x.units_consumed)
.ok_or("No simulation results found".into())
}
fn err(self) -> Option<ProgramClientError> {
self.result.and_then(|r| r.err().map(|e| e.into()))
}
}

impl SimulateTransaction for ProgramBanksClientProcessTransaction {
Expand Down Expand Up @@ -165,6 +169,15 @@ impl SimulationResult for RpcClientResponse {
.ok_or("No simulation results found".into()),
}
}
fn err(self) -> Option<ProgramClientError> {
match self {
// `Transaction` is the result of an offline simulation. The error
// should be properly handled by a caller that supports offline
// signing
Self::Signature(_) | Self::Transaction(_) => Some("Not a simulation result".into()),
Self::Simulation(simulation_result) => simulation_result.err.map(|e| e.into()),
}
}
}

impl SimulateTransaction for ProgramRpcClientSendTransaction {
Expand Down
3 changes: 3 additions & 0 deletions token/client/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@ where
let units_consumed = simulation_result
.get_compute_units_consumed()
.map_err(TokenError::Client)?;
if let Some(err) = simulation_result.err() {
return Err(TokenError::Client(err));
}
// Overwrite the compute unit limit instruction with the actual units consumed
let compute_unit_limit =
u32::try_from(units_consumed).map_err(|x| TokenError::Client(x.into()))?;
Expand Down

0 comments on commit b9aa695

Please sign in to comment.