refactor: Replace global address lookup table cache with direct fetch approach
Replace the global AddressLookupTableCache with a direct fetch function to simplify address lookup table management. This change improves code maintainability by removing global state and makes the API more explicit. Key changes: - Remove AddressLookupTableCache and AddressLookupManager - Add new fetch_address_lookup_table_account function - Update TradeBuyParams and TradeSellParams to use AddressLookupTableAccount instead of Pubkey - Update all examples to use the new direct fetch approach - Update documentation to reflect the simplified workflow
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use solana_sdk::{message::AddressLookupTableAccount, pubkey::Pubkey};
|
||||
|
||||
use crate::common::{
|
||||
address_lookup_cache::{get_address_lookup_table_account, AddressLookupTableCache},
|
||||
SolanaRpcClient,
|
||||
};
|
||||
|
||||
/// Get address lookup table account list
|
||||
/// If lookup_table_key is provided, get the corresponding account, otherwise return empty list
|
||||
pub async fn get_address_lookup_table_accounts(
|
||||
rpc: Option<Arc<SolanaRpcClient>>,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
) -> Vec<AddressLookupTableAccount> {
|
||||
match lookup_table_key {
|
||||
Some(key) => {
|
||||
let account = get_address_lookup_table_account(&key).await;
|
||||
if account.addresses.len() == 0 {
|
||||
if rpc.is_some() {
|
||||
let _ = AddressLookupTableCache::get_instance()
|
||||
.set_address_lookup_table(rpc.unwrap(), &key)
|
||||
.await;
|
||||
let new_account = get_address_lookup_table_account(&key).await;
|
||||
if new_account.addresses.len() == 0 {
|
||||
return Vec::new();
|
||||
} else {
|
||||
return vec![new_account];
|
||||
}
|
||||
} else {
|
||||
return Vec::new();
|
||||
}
|
||||
}
|
||||
return vec![account];
|
||||
}
|
||||
None => Vec::new(),
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
pub mod nonce_manager;
|
||||
pub mod transaction_builder;
|
||||
pub mod compute_budget_manager;
|
||||
pub mod address_lookup_manager;
|
||||
pub mod utils;
|
||||
pub mod wsol_manager;
|
||||
|
||||
@@ -9,6 +8,5 @@ pub mod wsol_manager;
|
||||
pub use nonce_manager::*;
|
||||
pub use transaction_builder::*;
|
||||
pub use compute_budget_manager::*;
|
||||
pub use address_lookup_manager::*;
|
||||
pub use utils::*;
|
||||
pub use wsol_manager::*;
|
||||
@@ -1,17 +1,11 @@
|
||||
use solana_hash::Hash;
|
||||
use solana_sdk::{
|
||||
instruction::Instruction,
|
||||
native_token::sol_str_to_lamports,
|
||||
pubkey::Pubkey,
|
||||
signature::Keypair,
|
||||
signer::Signer,
|
||||
transaction::VersionedTransaction,
|
||||
instruction::Instruction, message::AddressLookupTableAccount, native_token::sol_str_to_lamports, pubkey::Pubkey, signature::Keypair, signer::Signer, transaction::VersionedTransaction
|
||||
};
|
||||
use solana_system_interface::instruction::transfer;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{
|
||||
address_lookup_manager::get_address_lookup_table_accounts,
|
||||
compute_budget_manager::compute_budget_instructions,
|
||||
nonce_manager::{add_nonce_instruction, get_transaction_blockhash},
|
||||
};
|
||||
@@ -27,7 +21,7 @@ pub async fn build_transaction(
|
||||
unit_limit: u32,
|
||||
unit_price: u64,
|
||||
business_instructions: Vec<Instruction>,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
address_lookup_table_account: Option<AddressLookupTableAccount>,
|
||||
recent_blockhash: Option<Hash>,
|
||||
data_size_limit: u32,
|
||||
middleware_manager: Option<Arc<MiddlewareManager>>,
|
||||
@@ -72,15 +66,11 @@ pub async fn build_transaction(
|
||||
// Get blockhash for transaction
|
||||
let blockhash = get_transaction_blockhash(recent_blockhash, durable_nonce.clone());
|
||||
|
||||
// Get address lookup table accounts
|
||||
let address_lookup_table_accounts =
|
||||
get_address_lookup_table_accounts(rpc, lookup_table_key).await;
|
||||
|
||||
// Build transaction
|
||||
build_versioned_transaction(
|
||||
payer,
|
||||
instructions,
|
||||
address_lookup_table_accounts,
|
||||
address_lookup_table_account,
|
||||
blockhash,
|
||||
middleware_manager,
|
||||
protocol_name,
|
||||
@@ -93,7 +83,7 @@ pub async fn build_transaction(
|
||||
async fn build_versioned_transaction(
|
||||
payer: Arc<Keypair>,
|
||||
instructions: Vec<Instruction>,
|
||||
address_lookup_table_accounts: Vec<solana_sdk::message::AddressLookupTableAccount>,
|
||||
address_lookup_table_account: Option<AddressLookupTableAccount>,
|
||||
blockhash: Hash,
|
||||
middleware_manager: Option<Arc<MiddlewareManager>>,
|
||||
protocol_name: &str,
|
||||
@@ -111,16 +101,11 @@ async fn build_versioned_transaction(
|
||||
|
||||
// 使用预分配的交易构建器以降低延迟
|
||||
let mut builder = acquire_builder();
|
||||
let lookup_table_key = if !address_lookup_table_accounts.is_empty() {
|
||||
address_lookup_table_accounts.first().map(|a| a.key)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let versioned_msg = builder.build_zero_alloc(
|
||||
&payer.pubkey(),
|
||||
&full_instructions,
|
||||
lookup_table_key,
|
||||
address_lookup_table_account,
|
||||
blockhash,
|
||||
);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use solana_hash::Hash;
|
||||
use solana_sdk::message::AddressLookupTableAccount;
|
||||
use solana_sdk::{
|
||||
instruction::Instruction, pubkey::Pubkey, signature::Keypair, signature::Signature,
|
||||
};
|
||||
@@ -96,7 +97,7 @@ pub async fn execute_parallel(
|
||||
payer: Arc<Keypair>,
|
||||
rpc: Option<Arc<SolanaRpcClient>>,
|
||||
instructions: Vec<Instruction>,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
address_lookup_table_account: Option<AddressLookupTableAccount>,
|
||||
recent_blockhash: Option<Hash>,
|
||||
durable_nonce: Option<DurableNonceInfo>,
|
||||
data_size_limit: u32,
|
||||
@@ -168,6 +169,7 @@ pub async fn execute_parallel(
|
||||
let unit_price = gas_fee_strategy_config.2.cu_price;
|
||||
let rpc = rpc.clone();
|
||||
let durable_nonce = durable_nonce.clone();
|
||||
let address_lookup_table_account = address_lookup_table_account.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let _task_start = Instant::now();
|
||||
@@ -182,7 +184,7 @@ pub async fn execute_parallel(
|
||||
unit_limit,
|
||||
unit_price,
|
||||
instructions.as_ref().clone(),
|
||||
lookup_table_key,
|
||||
address_lookup_table_account,
|
||||
recent_blockhash,
|
||||
data_size_limit,
|
||||
middleware_manager,
|
||||
|
||||
@@ -87,7 +87,7 @@ impl TradeExecutor for GenericTradeExecutor {
|
||||
params.payer,
|
||||
params.rpc,
|
||||
final_instructions,
|
||||
params.lookup_table_key,
|
||||
params.address_lookup_table_account,
|
||||
params.recent_blockhash,
|
||||
params.durable_nonce,
|
||||
if is_buy { params.data_size_limit } else { 0 },
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
pub mod params;
|
||||
pub mod traits;
|
||||
pub mod executor;
|
||||
pub mod parallel;
|
||||
pub mod async_executor;
|
||||
pub mod transaction_pool;
|
||||
pub mod execution;
|
||||
@@ -8,6 +8,7 @@ use crate::swqos::{SwqosClient, TradeType};
|
||||
use crate::trading::common::get_multi_token_balances;
|
||||
use crate::trading::MiddlewareManager;
|
||||
use solana_hash::Hash;
|
||||
use solana_sdk::message::AddressLookupTableAccount;
|
||||
use solana_sdk::{pubkey::Pubkey, signature::Keypair};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -23,7 +24,7 @@ pub struct SwapParams {
|
||||
pub output_token_program: Option<Pubkey>,
|
||||
pub input_amount: Option<u64>,
|
||||
pub slippage_basis_points: Option<u64>,
|
||||
pub lookup_table_key: Option<Pubkey>,
|
||||
pub address_lookup_table_account: Option<AddressLookupTableAccount>,
|
||||
pub recent_blockhash: Option<Hash>,
|
||||
pub data_size_limit: u32,
|
||||
pub wait_transaction_confirmed: bool,
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use once_cell::sync::Lazy;
|
||||
use solana_sdk::{
|
||||
instruction::Instruction,
|
||||
message::{v0, VersionedMessage, Message},
|
||||
pubkey::Pubkey,
|
||||
hash::Hash,
|
||||
hash::Hash, instruction::Instruction, message::{v0, AddressLookupTableAccount, Message, VersionedMessage}, pubkey::Pubkey
|
||||
};
|
||||
use std::sync::Arc;
|
||||
/// 预分配的交易构建器
|
||||
@@ -68,7 +65,7 @@ impl PreallocatedTxBuilder {
|
||||
&mut self,
|
||||
payer: &Pubkey,
|
||||
instructions: &[Instruction],
|
||||
lookup_table: Option<Pubkey>,
|
||||
address_lookup_table_account: Option<AddressLookupTableAccount>,
|
||||
recent_blockhash: Hash,
|
||||
) -> VersionedMessage {
|
||||
// 重用已分配的 vector
|
||||
@@ -76,24 +73,32 @@ impl PreallocatedTxBuilder {
|
||||
self.instructions.extend_from_slice(instructions);
|
||||
|
||||
// ✅ 如果有查找表,使用 V0 消息
|
||||
if let Some(table_key) = lookup_table {
|
||||
self.lookup_tables.push(v0::MessageAddressTableLookup {
|
||||
account_key: table_key,
|
||||
writable_indexes: vec![],
|
||||
readonly_indexes: vec![],
|
||||
});
|
||||
if let Some(address_lookup_table_account) = address_lookup_table_account {
|
||||
// self.lookup_tables.push(v0::MessageAddressTableLookup {
|
||||
// account_key: table_key,
|
||||
// writable_indexes: vec![],
|
||||
// readonly_indexes: vec![],
|
||||
// });
|
||||
|
||||
// 使用 Message::new 创建 legacy 消息,然后提取编译后的指令
|
||||
let legacy_msg = Message::new(&self.instructions, Some(payer));
|
||||
// // 使用 Message::new 创建 legacy 消息,然后提取编译后的指令
|
||||
// let legacy_msg = Message::new(&self.instructions, Some(payer));
|
||||
|
||||
// 构建 V0 消息
|
||||
let message = v0::Message {
|
||||
header: legacy_msg.header,
|
||||
account_keys: legacy_msg.account_keys,
|
||||
// // 构建 V0 消息
|
||||
// let message = v0::Message {
|
||||
// header: legacy_msg.header,
|
||||
// account_keys: legacy_msg.account_keys,
|
||||
// recent_blockhash,
|
||||
// instructions: legacy_msg.instructions,
|
||||
// address_table_lookups: self.lookup_tables.clone(),
|
||||
// };
|
||||
|
||||
let message = v0::Message::try_compile(
|
||||
payer,
|
||||
&self.instructions,
|
||||
&[address_lookup_table_account],
|
||||
recent_blockhash,
|
||||
instructions: legacy_msg.instructions,
|
||||
address_table_lookups: self.lookup_tables.clone(),
|
||||
};
|
||||
).expect("v0 message compile failed");
|
||||
|
||||
|
||||
VersionedMessage::V0(message)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user