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:
@@ -150,7 +150,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(params.clone()),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(params.clone()),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
|
||||
@@ -15,36 +15,11 @@ Address Lookup Tables are a Solana feature that allows you to store frequently u
|
||||
|
||||
## 🛠️ Implementation
|
||||
|
||||
### 1. Setting up Address Lookup Table Cache
|
||||
|
||||
The SDK provides a global cache to manage address lookup tables:
|
||||
|
||||
```rust
|
||||
use sol_trade_sdk::common::address_lookup_cache::AddressLookupTableCache;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use std::str::FromStr;
|
||||
|
||||
/// Setup lookup table cache
|
||||
async fn setup_lookup_table_cache(
|
||||
client: Arc<SolanaRpcClient>,
|
||||
lookup_table_address: Pubkey,
|
||||
) -> AnyResult<()> {
|
||||
AddressLookupTableCache::get_instance()
|
||||
.set_address_lookup_table(client, &lookup_table_address)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to set address lookup table: {}", e))?;
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Using Lookup Tables in Trade Parameters
|
||||
|
||||
Include lookup tables in your trade parameters:
|
||||
|
||||
```rust
|
||||
// Initialize lookup table
|
||||
let lookup_table_key = Pubkey::from_str("your_lookup_table_address_here").unwrap();
|
||||
setup_lookup_table_cache(client.rpc.clone(), lookup_table_key).await?;
|
||||
let lookup_table_key = Pubkey::from_str("use_your_lookup_table_key_here").unwrap();
|
||||
let address_lookup_table_account = fetch_address_lookup_table_account(&client.rpc, &lookup_table_key).await.ok();
|
||||
|
||||
// Include lookup table in trade parameters
|
||||
let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
@@ -54,7 +29,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
slippage_basis_points: Some(100),
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(PumpFunParams::from_trade(&trade_info, None)),
|
||||
lookup_table_key: Some(lookup_table_key), // Include lookup table
|
||||
address_lookup_table_account: address_lookup_table_account, // Include lookup table
|
||||
wait_transaction_confirmed: true,
|
||||
create_wsol_ata: false,
|
||||
close_wsol_ata: false,
|
||||
@@ -78,7 +53,6 @@ client.buy(buy_params).await?;
|
||||
## ⚠️ Important Notes
|
||||
|
||||
1. **Lookup Table Address**: Must provide a valid address lookup table address
|
||||
2. **Cache Management**: SDK automatically manages lookup table cache
|
||||
3. **RPC Compatibility**: Ensure your RPC provider supports lookup tables
|
||||
4. **Network Specific**: Lookup tables are network-specific (mainnet/devnet/testnet)
|
||||
5. **Testing**: Always test on devnet before using on mainnet
|
||||
|
||||
@@ -15,36 +15,11 @@
|
||||
|
||||
## 🛠️ 实现方法
|
||||
|
||||
### 1. 设置地址查找表缓存
|
||||
|
||||
SDK 提供了一个全局缓存来管理地址查找表:
|
||||
|
||||
```rust
|
||||
use sol_trade_sdk::common::address_lookup_cache::AddressLookupTableCache;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use std::str::FromStr;
|
||||
|
||||
/// 设置查找表缓存
|
||||
async fn setup_lookup_table_cache(
|
||||
client: Arc<SolanaRpcClient>,
|
||||
lookup_table_address: Pubkey,
|
||||
) -> AnyResult<()> {
|
||||
AddressLookupTableCache::get_instance()
|
||||
.set_address_lookup_table(client, &lookup_table_address)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to set address lookup table: {}", e))?;
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 在交易参数中使用查找表
|
||||
|
||||
在您的交易参数中包含查找表:
|
||||
|
||||
```rust
|
||||
// 初始化查找表
|
||||
let lookup_table_key = Pubkey::from_str("your_lookup_table_address_here").unwrap();
|
||||
setup_lookup_table_cache(client.rpc.clone(), lookup_table_key).await?;
|
||||
let lookup_table_key = Pubkey::from_str("use_your_lookup_table_key_here").unwrap();
|
||||
let address_lookup_table_account = fetch_address_lookup_table_account(&client.rpc, &lookup_table_key).await.ok();
|
||||
|
||||
// 在交易参数中包含查找表
|
||||
let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
@@ -54,7 +29,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
slippage_basis_points: Some(100),
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(PumpFunParams::from_trade(&trade_info, None)),
|
||||
lookup_table_key: Some(lookup_table_key), // 包含查找表
|
||||
address_lookup_table_account: address_lookup_table_account, // 包含查找表
|
||||
wait_transaction_confirmed: true,
|
||||
create_wsol_ata: false,
|
||||
close_wsol_ata: false,
|
||||
@@ -78,7 +53,6 @@ client.buy(buy_params).await?;
|
||||
## ⚠️ 重要注意事项
|
||||
|
||||
1. **查找表地址**: 必须提供有效的地址查找表地址
|
||||
2. **缓存管理**: SDK 自动管理查找表缓存
|
||||
3. **RPC 兼容性**: 确保您的 RPC 提供商支持查找表
|
||||
4. **网络**: 查找表是特定于网络的(主网/开发网/测试网)
|
||||
5. **测试**: 在主网使用前请务必在开发网测试
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
slippage_basis_points: Some(100),
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(PumpFunParams::from_trade(&trade_info, None)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_wsol_ata: false,
|
||||
close_wsol_ata: false,
|
||||
|
||||
@@ -57,7 +57,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
|
||||
slippage_basis_points: Some(100),
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(PumpFunParams::from_trade(&trade_info, None)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_wsol_ata: false,
|
||||
close_wsol_ata: false,
|
||||
|
||||
@@ -29,7 +29,7 @@ The `TradeBuyParams` struct contains all parameters required for executing buy o
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `lookup_table_key` | `Option<Pubkey>` | ❌ | Address lookup table key for transaction optimization |
|
||||
| `address_lookup_table_account` | `Option<AddressLookupTableAccount>` | ❌ | Address lookup table for transaction optimization |
|
||||
| `wait_transaction_confirmed` | `bool` | ✅ | Whether to wait for transaction confirmation |
|
||||
| `create_input_token_ata` | `bool` | ✅ | Whether to create input token Associated Token Account |
|
||||
| `close_input_token_ata` | `bool` | ✅ | Whether to close input token ATA after transaction |
|
||||
@@ -60,7 +60,7 @@ The `TradeSellParams` struct contains all parameters required for executing sell
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `lookup_table_key` | `Option<Pubkey>` | ❌ | Address lookup table key for transaction optimization |
|
||||
| `address_lookup_table_account` | `Option<Pubkey>` | ❌ | Address lookup table for transaction optimization |
|
||||
| `wait_transaction_confirmed` | `bool` | ✅ | Whether to wait for transaction confirmation |
|
||||
| `create_output_token_ata` | `bool` | ✅ | Whether to create output token Associated Token Account |
|
||||
| `close_output_token_ata` | `bool` | ✅ | Whether to close output token ATA after transaction |
|
||||
@@ -100,7 +100,7 @@ These parameters control automatic account creation and management:
|
||||
|
||||
These parameters enable advanced optimizations:
|
||||
|
||||
- **lookup_table_key**: Use address lookup tables for reduced transaction size
|
||||
- **address_lookup_table_account**: Use address lookup tables for reduced transaction size
|
||||
- **open_seed_optimize**: Use seed-based account creation for lower CU consumption
|
||||
|
||||
### 🔄 Token Type Parameters
|
||||
@@ -134,8 +134,7 @@ The account management parameters provide granular control:
|
||||
|
||||
### 🔍 Address Lookup Tables
|
||||
|
||||
Before using `lookup_table_key`:
|
||||
- Initialize `AddressLookupTableCache` to manage cached lookup tables
|
||||
Before using `address_lookup_table_account`:
|
||||
- Lookup tables reduce transaction size and improve success rates
|
||||
- Particularly beneficial for complex transactions with many account references
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
| 参数 | 类型 | 必需 | 描述 |
|
||||
|------|------|------|------|
|
||||
| `lookup_table_key` | `Option<Pubkey>` | ❌ | 用于交易优化的地址查找表键 |
|
||||
| `address_lookup_table_account` | `Option<Pubkey>` | ❌ | 用于交易优化的地址查找表 |
|
||||
| `wait_transaction_confirmed` | `bool` | ✅ | 是否等待交易确认 |
|
||||
| `create_input_token_ata` | `bool` | ✅ | 是否创建输入代币关联代币账户 |
|
||||
| `close_input_token_ata` | `bool` | ✅ | 交易后是否关闭输入代币 ATA |
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
| 参数 | 类型 | 必需 | 描述 |
|
||||
|------|------|------|------|
|
||||
| `lookup_table_key` | `Option<Pubkey>` | ❌ | 用于交易优化的地址查找表键 |
|
||||
| `address_lookup_table_account` | `Option<AddressLookupTableAccount>` | ❌ | 用于交易优化的地址查找表 |
|
||||
| `wait_transaction_confirmed` | `bool` | ✅ | 是否等待交易确认 |
|
||||
| `create_output_token_ata` | `bool` | ✅ | 是否创建输出代币关联代币账户 |
|
||||
| `close_output_token_ata` | `bool` | ✅ | 交易后是否关闭输出代币 ATA |
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
这些参数启用高级优化:
|
||||
|
||||
- **lookup_table_key**: 使用地址查找表减少交易大小
|
||||
- **address_lookup_table_account**: 使用地址查找表减少交易大小
|
||||
- **open_seed_optimize**: 使用基于 seed 的账户创建以降低 CU 消耗
|
||||
|
||||
### 🔄 代币类型参数
|
||||
@@ -134,8 +134,7 @@
|
||||
|
||||
### 🔍 地址查找表
|
||||
|
||||
使用 `lookup_table_key` 之前:
|
||||
- 初始化 `AddressLookupTableCache` 来管理缓存的查找表
|
||||
使用 `address_lookup_table_account` 之前:
|
||||
- 查找表减少交易大小并提高成功率
|
||||
- 对于有许多账户引用的复杂交易特别有益
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use sol_trade_sdk::common::address_lookup_cache::AddressLookupTableCache;
|
||||
use sol_trade_sdk::common::SolanaRpcClient;
|
||||
use sol_trade_sdk::common::address_lookup::fetch_address_lookup_table_account;
|
||||
use sol_trade_sdk::common::TradeConfig;
|
||||
use sol_trade_sdk::{
|
||||
common::AnyResult,
|
||||
@@ -97,18 +96,6 @@ fn create_event_callback() -> impl Fn(Box<dyn UnifiedEvent>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup lookup table cache
|
||||
async fn setup_lookup_table_cache(
|
||||
client: Arc<SolanaRpcClient>,
|
||||
lookup_table_address: Pubkey,
|
||||
) -> AnyResult<()> {
|
||||
AddressLookupTableCache::get_instance()
|
||||
.set_address_lookup_table(client, &lookup_table_address)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to set address lookup table: {}", e))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create SolanaTrade client
|
||||
/// Initializes a new SolanaTrade client with configuration
|
||||
async fn create_solana_trade_client() -> AnyResult<SolanaTrade> {
|
||||
@@ -136,8 +123,8 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
|
||||
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||
|
||||
let lookup_table_key = Pubkey::from_str("use_your_lookup_table_key_here").unwrap();
|
||||
// Setup lookup table cache
|
||||
setup_lookup_table_cache(client.rpc.clone(), lookup_table_key).await?;
|
||||
let address_lookup_table_account =
|
||||
fetch_address_lookup_table_account(&client.rpc, &lookup_table_key).await.ok();
|
||||
|
||||
// Buy tokens
|
||||
println!("Buying tokens from PumpFun...");
|
||||
@@ -161,7 +148,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
|
||||
trade_info.real_sol_reserves,
|
||||
None,
|
||||
)),
|
||||
lookup_table_key: Some(lookup_table_key), // you still need to update the AddressLookupTableCache
|
||||
address_lookup_table_account: address_lookup_table_account,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: false,
|
||||
close_input_token_ata: false,
|
||||
|
||||
@@ -156,7 +156,7 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()>
|
||||
trade_info.creator_associated_account,
|
||||
trade_info.global_config,
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: false,
|
||||
@@ -199,7 +199,7 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()>
|
||||
trade_info.creator_associated_account,
|
||||
trade_info.global_config,
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
open_seed_optimize: false,
|
||||
with_tip: false,
|
||||
|
||||
@@ -126,7 +126,7 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<
|
||||
trade_info.creator_associated_account,
|
||||
trade_info.global_config,
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -162,7 +162,7 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<
|
||||
trade_info.creator_associated_account,
|
||||
trade_info.global_config,
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
@@ -622,7 +622,7 @@ async fn handle_buy_pumpfun(
|
||||
slippage_basis_points: slippage,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: false,
|
||||
close_input_token_ata: false,
|
||||
@@ -672,7 +672,7 @@ async fn handle_buy_pumpswap(
|
||||
slippage_basis_points: slippage,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: false,
|
||||
@@ -721,7 +721,7 @@ async fn handle_buy_bonk(
|
||||
slippage_basis_points: slippage,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: false,
|
||||
@@ -774,7 +774,7 @@ async fn handle_buy_raydium_v4(
|
||||
slippage_basis_points: slippage,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: false,
|
||||
@@ -827,7 +827,7 @@ async fn handle_buy_raydium_cpmm(
|
||||
slippage_basis_points: slippage,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: false,
|
||||
@@ -991,7 +991,7 @@ async fn handle_sell_pumpfun(
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: false,
|
||||
@@ -1044,7 +1044,7 @@ async fn handle_sell_pumpswap(
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: false,
|
||||
@@ -1096,7 +1096,7 @@ async fn handle_sell_bonk(
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: false,
|
||||
@@ -1151,7 +1151,7 @@ async fn handle_sell_raydium_v4(
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: false,
|
||||
@@ -1206,7 +1206,7 @@ async fn handle_sell_raydium_cpmm(
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(param),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: false,
|
||||
|
||||
@@ -35,7 +35,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
extension_params: Box::new(
|
||||
MeteoraDammV2Params::from_pool_address_by_rpc(&client.rpc, &pool).await?,
|
||||
),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -67,7 +67,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
extension_params: Box::new(
|
||||
MeteoraDammV2Params::from_pool_address_by_rpc(&client.rpc, &pool).await?,
|
||||
),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
@@ -92,7 +92,7 @@ async fn test_middleware() -> AnyResult<()> {
|
||||
extension_params: Box::new(
|
||||
PumpSwapParams::from_pool_address_by_rpc(&client.rpc, &pool_address).await?,
|
||||
),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
|
||||
@@ -148,7 +148,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
|
||||
trade_info.real_sol_reserves,
|
||||
None,
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: false,
|
||||
close_input_token_ata: false,
|
||||
|
||||
@@ -144,7 +144,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
|
||||
trade_info.real_sol_reserves,
|
||||
None,
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: false,
|
||||
close_input_token_ata: false,
|
||||
@@ -186,7 +186,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
|
||||
trade_info.real_sol_reserves,
|
||||
Some(true),
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: false,
|
||||
close_output_token_ata: false,
|
||||
|
||||
@@ -110,7 +110,7 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
|
||||
trade_info.creator_vault,
|
||||
None,
|
||||
)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -141,7 +141,7 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(PumpFunParams::immediate_sell(trade_info.creator_vault, true)),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
@@ -35,7 +35,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
extension_params: Box::new(
|
||||
PumpSwapParams::from_pool_address_by_rpc(&client.rpc, &pool).await?,
|
||||
),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -66,7 +66,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
extension_params: Box::new(
|
||||
PumpSwapParams::from_pool_address_by_rpc(&client.rpc, &pool).await?,
|
||||
),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
@@ -194,7 +194,7 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) -
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(params.clone()),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -227,7 +227,7 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) -
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(params.clone()),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
@@ -150,7 +150,7 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(params),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -182,7 +182,7 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(params),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
@@ -141,7 +141,7 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(buy_params),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -175,7 +175,7 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
with_tip: false,
|
||||
extension_params: Box::new(sell_params),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
@@ -34,7 +34,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
extension_params: Box::new(
|
||||
PumpSwapParams::from_pool_address_by_rpc(&client.rpc, &pool).await?,
|
||||
),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
@@ -73,7 +73,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
extension_params: Box::new(
|
||||
PumpSwapParams::from_pool_address_by_rpc(&client.rpc, &pool).await?,
|
||||
),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: true,
|
||||
create_output_token_ata: true,
|
||||
close_output_token_ata: true,
|
||||
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
use crate::common::SolanaRpcClient;
|
||||
use anyhow::Result;
|
||||
use solana_address_lookup_table_interface::state::AddressLookupTable;
|
||||
use solana_sdk::{
|
||||
message::{v0, AddressLookupTableAccount},
|
||||
pubkey::Pubkey,
|
||||
};
|
||||
|
||||
pub async fn fetch_address_lookup_table_account(
|
||||
rpc: &SolanaRpcClient,
|
||||
lookup_table_address: &Pubkey,
|
||||
) -> Result<AddressLookupTableAccount, anyhow::Error> {
|
||||
let account = rpc.get_account(lookup_table_address).await?;
|
||||
let lookup_table = AddressLookupTable::deserialize(&account.data)?;
|
||||
let address_lookup_table_account = AddressLookupTableAccount {
|
||||
key: *lookup_table_address,
|
||||
addresses: lookup_table.addresses.to_vec(),
|
||||
};
|
||||
Ok(address_lookup_table_account)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn extract_lookup_table_indexes(
|
||||
instructions: &[solana_sdk::instruction::Instruction],
|
||||
lookup_table_account: &AddressLookupTableAccount,
|
||||
) -> Option<v0::MessageAddressTableLookup> {
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
// 构建地址到索引的映射(O(1) 查找)
|
||||
let addr_to_index: HashMap<&Pubkey, u8> = lookup_table_account
|
||||
.addresses
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, addr)| u8::try_from(idx).ok().map(|i| (addr, i)))
|
||||
.collect();
|
||||
|
||||
// 收集所有需要的账户及其权限
|
||||
let mut writable_indexes = Vec::new();
|
||||
let mut readonly_indexes = Vec::new();
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
for instruction in instructions {
|
||||
for account_meta in &instruction.accounts {
|
||||
// 跳过已处理的账户
|
||||
if !seen.insert(&account_meta.pubkey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 在查找表中查找账户
|
||||
if let Some(&index) = addr_to_index.get(&account_meta.pubkey) {
|
||||
if account_meta.is_writable {
|
||||
writable_indexes.push(index);
|
||||
} else {
|
||||
readonly_indexes.push(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到任何账户,返回 None
|
||||
if writable_indexes.is_empty() && readonly_indexes.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(v0::MessageAddressTableLookup {
|
||||
account_key: lookup_table_account.key,
|
||||
writable_indexes,
|
||||
readonly_indexes,
|
||||
})
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
use dashmap::DashMap;
|
||||
use solana_address_lookup_table_interface::state::AddressLookupTable;
|
||||
use solana_sdk::{message::AddressLookupTableAccount, pubkey::Pubkey};
|
||||
use std::{
|
||||
error::Error,
|
||||
sync::{Arc, OnceLock},
|
||||
};
|
||||
|
||||
use crate::common::SolanaRpcClient;
|
||||
|
||||
/// AddressLookupTableInfo struct, stores address lookup table related information
|
||||
#[derive(Clone)]
|
||||
pub struct AddressLookupTableInfo {
|
||||
/// Address lookup table account address
|
||||
pub lookup_table_address: Option<Pubkey>,
|
||||
/// Address lookup table content
|
||||
pub address_lookup_table: Option<AddressLookupTableAccount>,
|
||||
}
|
||||
|
||||
/// AddressLookupTableCache singleton for storing and managing address lookup tables
|
||||
pub struct AddressLookupTableCache {
|
||||
/// Lock-free hash map supporting high concurrent access
|
||||
tables: DashMap<Pubkey, AddressLookupTableInfo>,
|
||||
}
|
||||
|
||||
// Use static OnceLock to ensure thread safety of singleton pattern
|
||||
static ADDRESS_LOOKUP_TABLE_CACHE: OnceLock<Arc<AddressLookupTableCache>> = OnceLock::new();
|
||||
|
||||
impl AddressLookupTableCache {
|
||||
/// Get AddressLookupTableCache singleton instance
|
||||
pub fn get_instance() -> Arc<AddressLookupTableCache> {
|
||||
ADDRESS_LOOKUP_TABLE_CACHE
|
||||
.get_or_init(|| Arc::new(AddressLookupTableCache { tables: DashMap::new() }))
|
||||
.clone()
|
||||
}
|
||||
|
||||
/// Get lookup table information
|
||||
pub async fn set_address_lookup_table(
|
||||
&self,
|
||||
client: Arc<SolanaRpcClient>,
|
||||
lookup_table_address: &Pubkey,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let account = client.get_account(lookup_table_address).await?;
|
||||
let lookup_table = AddressLookupTable::deserialize(&account.data)?;
|
||||
let address_lookup_table_account = AddressLookupTableAccount {
|
||||
key: *lookup_table_address,
|
||||
addresses: lookup_table.addresses.to_vec(),
|
||||
};
|
||||
self.add_or_update_table(lookup_table_address.clone(), Some(address_lookup_table_account));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add or update address lookup table information - lock-free implementation
|
||||
fn add_or_update_table(
|
||||
&self,
|
||||
lookup_table_address: Pubkey,
|
||||
address_lookup_table: Option<AddressLookupTableAccount>,
|
||||
) {
|
||||
if let Some(mut entry) = self.tables.get_mut(&lookup_table_address) {
|
||||
// Update existing table
|
||||
if let Some(table) = address_lookup_table {
|
||||
entry.address_lookup_table = Some(table);
|
||||
}
|
||||
} else {
|
||||
// Add new table
|
||||
self.tables.insert(
|
||||
lookup_table_address,
|
||||
AddressLookupTableInfo {
|
||||
lookup_table_address: Some(lookup_table_address),
|
||||
address_lookup_table,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get table content - high-performance lock-free implementation
|
||||
fn get_table_content(&self, lookup_table_address: &Pubkey) -> AddressLookupTableAccount {
|
||||
let result = self
|
||||
.tables
|
||||
.get(lookup_table_address)
|
||||
.and_then(|entry| entry.address_lookup_table.clone())
|
||||
.unwrap_or_else(|| AddressLookupTableAccount {
|
||||
key: *lookup_table_address,
|
||||
addresses: Vec::new(),
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get address lookup table account
|
||||
pub async fn get_address_lookup_table_account(
|
||||
lookup_table_address: &Pubkey,
|
||||
) -> AddressLookupTableAccount {
|
||||
let cache = AddressLookupTableCache::get_instance();
|
||||
cache.get_table_content(lookup_table_address)
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,3 @@
|
||||
pub mod address_lookup_cache;
|
||||
pub mod bonding_curve;
|
||||
pub mod fast_fn;
|
||||
pub mod fast_timing;
|
||||
@@ -11,6 +10,7 @@ pub mod spl_token;
|
||||
pub mod spl_token_2022;
|
||||
pub mod subscription_handle;
|
||||
pub mod types;
|
||||
pub mod address_lookup;
|
||||
|
||||
pub use gas_fee_strategy::*;
|
||||
pub use types::*;
|
||||
|
||||
+5
-4
@@ -29,6 +29,7 @@ use common::SolanaRpcClient;
|
||||
use parking_lot::Mutex;
|
||||
use rustls::crypto::{ring::default_provider, CryptoProvider};
|
||||
use solana_sdk::hash::Hash;
|
||||
use solana_sdk::message::AddressLookupTableAccount;
|
||||
use solana_sdk::signer::Signer;
|
||||
use solana_sdk::{pubkey::Pubkey, signature::Keypair, signature::Signature};
|
||||
use std::sync::Arc;
|
||||
@@ -93,7 +94,7 @@ pub struct TradeBuyParams {
|
||||
pub extension_params: Box<dyn ProtocolParams>,
|
||||
// Extended configuration
|
||||
/// Optional address lookup table for transaction size optimization
|
||||
pub lookup_table_key: Option<Pubkey>,
|
||||
pub address_lookup_table_account: Option<AddressLookupTableAccount>,
|
||||
/// Whether to wait for transaction confirmation before returning
|
||||
pub wait_transaction_confirmed: bool,
|
||||
/// Whether to create input token associated token account
|
||||
@@ -135,7 +136,7 @@ pub struct TradeSellParams {
|
||||
pub extension_params: Box<dyn ProtocolParams>,
|
||||
// Extended configuration
|
||||
/// Optional address lookup table for transaction size optimization
|
||||
pub lookup_table_key: Option<Pubkey>,
|
||||
pub address_lookup_table_account: Option<AddressLookupTableAccount>,
|
||||
/// Whether to wait for transaction confirmation before returning
|
||||
pub wait_transaction_confirmed: bool,
|
||||
/// Whether to create output token associated token account
|
||||
@@ -292,7 +293,7 @@ impl SolanaTrade {
|
||||
output_token_program: None,
|
||||
input_amount: Some(params.input_token_amount),
|
||||
slippage_basis_points: params.slippage_basis_points,
|
||||
lookup_table_key: params.lookup_table_key,
|
||||
address_lookup_table_account: params.address_lookup_table_account,
|
||||
recent_blockhash: params.recent_blockhash,
|
||||
data_size_limit: 256 * 1024,
|
||||
wait_transaction_confirmed: params.wait_transaction_confirmed,
|
||||
@@ -385,7 +386,7 @@ impl SolanaTrade {
|
||||
output_token_program: None,
|
||||
input_amount: Some(params.input_token_amount),
|
||||
slippage_basis_points: params.slippage_basis_points,
|
||||
lookup_table_key: params.lookup_table_key,
|
||||
address_lookup_table_account: params.address_lookup_table_account,
|
||||
recent_blockhash: params.recent_blockhash,
|
||||
wait_transaction_confirmed: params.wait_transaction_confirmed,
|
||||
protocol_params: protocol_params.clone(),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+1
-1
@@ -188,7 +188,7 @@ async fn main() -> AnyResult<()> {
|
||||
slippage_basis_points: Some(slippage),
|
||||
recent_blockhash: Some(recent_blockhash),
|
||||
extension_params: Box::new(params),
|
||||
lookup_table_key: None,
|
||||
address_lookup_table_account: None,
|
||||
wait_transaction_confirmed: false, // 不等待确认,测试最快提交速度
|
||||
create_input_token_ata: true,
|
||||
close_input_token_ata: true,
|
||||
|
||||
Reference in New Issue
Block a user