Fix trade execution correctness and release 4.0.11
This commit is contained in:
@@ -3,7 +3,9 @@ use once_cell::sync::Lazy;
|
||||
use smallvec::SmallVec;
|
||||
use solana_compute_budget_interface::ComputeBudgetInstruction;
|
||||
use solana_sdk::instruction::Instruction;
|
||||
use std::sync::Arc;
|
||||
use std::{hash::Hash, sync::Arc};
|
||||
|
||||
const MAX_COMPUTE_BUDGET_CACHE_SIZE: usize = 4_096;
|
||||
|
||||
/// Cache key containing all parameters for compute budget instructions
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
@@ -17,6 +19,22 @@ struct ComputeBudgetCacheKey {
|
||||
static COMPUTE_BUDGET_CACHE: Lazy<DashMap<ComputeBudgetCacheKey, Arc<SmallVec<[Instruction; 2]>>>> =
|
||||
Lazy::new(|| DashMap::new());
|
||||
|
||||
#[inline]
|
||||
fn prune_cache<K, V>(cache: &DashMap<K, V>, max_size: usize)
|
||||
where
|
||||
K: Eq + Hash + Clone,
|
||||
{
|
||||
let len = cache.len();
|
||||
if len <= max_size {
|
||||
return;
|
||||
}
|
||||
let remove_count = (len - max_size).max(max_size / 16).min(len);
|
||||
let keys: Vec<K> = cache.iter().take(remove_count).map(|entry| entry.key().clone()).collect();
|
||||
for key in keys {
|
||||
cache.remove(&key);
|
||||
}
|
||||
}
|
||||
|
||||
/// Extend `instructions` with compute budget instructions; on cache hit extends from cached Arc (no SmallVec clone).
|
||||
#[inline(always)]
|
||||
pub fn extend_compute_budget_instructions(
|
||||
@@ -41,6 +59,7 @@ pub fn extend_compute_budget_instructions(
|
||||
let arc = Arc::new(insts);
|
||||
instructions.extend(arc.iter().cloned());
|
||||
COMPUTE_BUDGET_CACHE.insert(cache_key, arc);
|
||||
prune_cache(&COMPUTE_BUDGET_CACHE, MAX_COMPUTE_BUDGET_CACHE_SIZE);
|
||||
}
|
||||
|
||||
/// Returns compute budget instructions (allocates on cache hit; prefer `extend_compute_budget_instructions` on hot path).
|
||||
@@ -59,5 +78,6 @@ pub fn compute_budget_instructions(unit_price: u64, unit_limit: u32) -> SmallVec
|
||||
}
|
||||
let arc = Arc::new(insts.clone());
|
||||
COMPUTE_BUDGET_CACHE.insert(cache_key, arc);
|
||||
prune_cache(&COMPUTE_BUDGET_CACHE, MAX_COMPUTE_BUDGET_CACHE_SIZE);
|
||||
insts
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use anyhow::anyhow;
|
||||
use solana_hash::Hash;
|
||||
use solana_message::AddressLookupTableAccount;
|
||||
use solana_sdk::{
|
||||
@@ -93,19 +94,19 @@ fn build_versioned_transaction(
|
||||
// 使用预分配的交易构建器以降低延迟
|
||||
let mut builder = acquire_builder();
|
||||
|
||||
let versioned_msg = builder.build_zero_alloc(
|
||||
let build_result = builder.build_zero_alloc(
|
||||
&payer.pubkey(),
|
||||
&full_instructions,
|
||||
address_lookup_table_account,
|
||||
blockhash,
|
||||
);
|
||||
release_builder(builder);
|
||||
let versioned_msg = build_result?;
|
||||
|
||||
let msg_bytes = versioned_msg.serialize();
|
||||
let signature = payer.as_ref().try_sign_message(&msg_bytes).expect("sign failed");
|
||||
let signature =
|
||||
payer.as_ref().try_sign_message(&msg_bytes).map_err(|e| anyhow!("sign failed: {e}"))?;
|
||||
let tx = VersionedTransaction { signatures: vec![signature], message: versioned_msg };
|
||||
|
||||
// 归还构建器到池
|
||||
release_builder(builder);
|
||||
|
||||
Ok(tx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user