diff --git a/bin/settler/src/settle.rs b/bin/settler/src/settle.rs index 13e154868..4fc7a07bf 100644 --- a/bin/settler/src/settle.rs +++ b/bin/settler/src/settle.rs @@ -285,6 +285,7 @@ impl<'a> SettleBatchProcessor<'a> { payer: fee_payer.pubkey(), signers: vec![fee_payer], config: client.config().transaction_builder_config.clone(), + additional_cus: vec![], } .transaction_with_blockhash(self.blockhash) } diff --git a/lib/client/src/client.rs b/lib/client/src/client.rs index 4afd1cd6f..ecb6673e3 100644 --- a/lib/client/src/client.rs +++ b/lib/client/src/client.rs @@ -395,6 +395,7 @@ impl MangoClient { payer: payer.pubkey(), signers: vec![owner, payer], config: client.config.transaction_builder_config.clone(), + additional_cus: vec![], } .send_and_confirm(&client) .await?; @@ -2395,6 +2396,7 @@ impl MangoClient { payer: fee_payer.pubkey(), signers: vec![fee_payer], config: self.client.config.transaction_builder_config.clone(), + additional_cus: vec![], }) } @@ -2409,6 +2411,7 @@ impl MangoClient { payer: fee_payer.pubkey(), signers: vec![fee_payer], config: self.client.config.transaction_builder_config.clone(), + additional_cus: vec![], } .simulate(&self.client) .await @@ -2518,6 +2521,7 @@ pub struct TransactionBuilder { pub signers: Vec>, pub payer: Pubkey, pub config: TransactionBuilderConfig, + pub additional_cus: Vec, } pub type SimulateTransactionResponse = @@ -2558,10 +2562,15 @@ impl TransactionBuilder { let cu_per_ix = self.config.compute_budget_per_instruction.unwrap_or(0); if !has_compute_unit_limit && cu_per_ix > 0 { - let ix_count: u32 = (ixs.len() - cu_instructions).try_into().unwrap(); + let ix_count: u32 = (ixs.len() - cu_instructions - self.additional_cus.len()) + .try_into() + .unwrap(); + let additional_cu_sum: u32 = self.additional_cus.iter().sum(); ixs.insert( 0, - ComputeBudgetInstruction::set_compute_unit_limit(cu_per_ix * ix_count), + ComputeBudgetInstruction::set_compute_unit_limit( + cu_per_ix * ix_count + additional_cu_sum, + ), ); } @@ -2649,8 +2658,10 @@ impl TransactionBuilder { } pub fn append(&mut self, prepared_instructions: PreparedInstructions) { - self.instructions - .extend(prepared_instructions.to_instructions()); + // Do NOT use to instruction s it would add a CU limit + // That CU limit would overwrite the one computed by the transaction builder + self.instructions.extend(prepared_instructions.instructions); + self.additional_cus.push(prepared_instructions.cu); } } diff --git a/lib/client/src/swap/jupiter_v6.rs b/lib/client/src/swap/jupiter_v6.rs index 62ee8ade1..c42df8b86 100644 --- a/lib/client/src/swap/jupiter_v6.rs +++ b/lib/client/src/swap/jupiter_v6.rs @@ -204,6 +204,7 @@ impl<'a> JupiterV6<'a> { .send() .await .context("quote request to jupiter")?; + let quote: QuoteResponse = util::http_error_handling(response).await.with_context(|| { format!("error requesting jupiter route between {input_mint} and {output_mint}") @@ -392,6 +393,7 @@ impl<'a> JupiterV6<'a> { .config() .transaction_builder_config .clone(), + additional_cus: vec![], }) } diff --git a/lib/client/src/swap/sanctum.rs b/lib/client/src/swap/sanctum.rs index d93ca4d2f..0096289d7 100644 --- a/lib/client/src/swap/sanctum.rs +++ b/lib/client/src/swap/sanctum.rs @@ -321,6 +321,7 @@ impl<'a> Sanctum<'a> { .config() .transaction_builder_config .clone(), + additional_cus: vec![], }) } diff --git a/lib/client/src/util.rs b/lib/client/src/util.rs index cd562e33c..8c81282e7 100644 --- a/lib/client/src/util.rs +++ b/lib/client/src/util.rs @@ -3,6 +3,7 @@ use solana_sdk::instruction::Instruction; use anchor_lang::prelude::{AccountMeta, Pubkey}; use anyhow::Context; +use tracing::warn; /// Some Result<> types don't convert to anyhow::Result nicely. Force them through stringification. pub trait AnyhowWrap { @@ -80,8 +81,15 @@ pub async fn http_error_handling( if !status.is_success() { anyhow::bail!("http request failed, status: {status}, body: {response_text}"); } - serde_json::from_str::(&response_text) - .with_context(|| format!("response has unexpected format, body: {response_text}")) + let object = serde_json::from_str::(&response_text); + + match object { + Ok(o) => Ok(o), + Err(e) => { + warn!("{}", e); + anyhow::bail!("response has unexpected format, body: {response_text}") + } + } } pub fn to_readonly_account_meta(pubkey: Pubkey) -> AccountMeta {