diff --git a/token/client/src/client.rs b/token/client/src/client.rs index 12f3faf17a4..0ead22863e6 100644 --- a/token/client/src/client.rs +++ b/token/client/src/client.rs @@ -26,6 +26,7 @@ pub trait SimulateTransaction { /// Trait for the output of a simulation pub trait SimulationResult { fn get_compute_units_consumed(&self) -> ProgramClientResult; + fn err(self) -> Option; } /// Extends basic `SendTransaction` trait with function `send` where client is @@ -78,6 +79,9 @@ impl SimulationResult for BanksTransactionResultWithSimulation { .map(|x| x.units_consumed) .ok_or("No simulation results found".into()) } + fn err(self) -> Option { + self.result.and_then(|r| r.err().map(|e| e.into())) + } } impl SimulateTransaction for ProgramBanksClientProcessTransaction { @@ -165,6 +169,15 @@ impl SimulationResult for RpcClientResponse { .ok_or("No simulation results found".into()), } } + fn err(self) -> Option { + 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 { diff --git a/token/client/src/token.rs b/token/client/src/token.rs index 20cae87c1fe..7e41ea447c9 100644 --- a/token/client/src/token.rs +++ b/token/client/src/token.rs @@ -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()))?;