Pe Solana, unde se generează mii de tranzacții pe secundă, dacă încerci să urmărești toate actualizările conturilor din rețea, robotul tău va fi repede înghițit de zgomotul masiv de date. Limitările de bandă ale nodurilor RPC, presiunea de procesare a CPU-ului și întârzierile de rețea vor distruge instant oportunitățile de arbitraj.

Searcher-ul eficient nu „ascultă pe întuneric“. Ei folosesc o strategie numită „ascultare ghidată de stoc (Inventory-Driven Monitoring)“: construiesc mai întâi offline un index global al lichidității din întreaga rețea, filtrează un „coș de candidați la arbitraj“ de înaltă valoare, apoi se abonează cu precizie.

Acest articol va explica cum să construim acest sistem Inventory de înaltă performanță.

1. Conceptul central: restrângeți câmpul de luptă, concentrați-vă pe punctele decisive

1.1 De ce să construim Inventory?

DEX-urile (burse descentralizate) de pe Solana, cum ar fi Raydium și Orca, au zeci de mii de pool-uri de lichiditate. Dar pentru strategiile de arbitraj, doar perechile de tranzacționare care există simultan în mai multe protocoale (de exemplu, SOL/USDC în Raydium are pool, în Orca de asemenea) au potențial de arbitraj atomic.

Sarcina Inventory este:

  • Pornire rece agregată: obțineți lista completă de pool-uri de la API-urile DEX.

  • Calculul intersecției: găsiți perechile de tranzacționare suprapuse.

  • Filtrul listei albe: eliminați pool-urile zombie, pool-urile cu lichiditate scăzută, generând o „listă albă de observație”.

1.2 Conducere prin inventar vs. conducere completă

  • Conducere completă: abonați-vă la toate jurnalele, găsiți oportunități și verificați tabelele. Avantajul este acoperirea largă, dezavantajul este întârzierea extrem de mare și prelucrarea datelor redundante.

  • Conducere prin inventar: abonați-vă doar la actualizările conturilor din lista albă. Avantajul este un răspuns foarte rapid, economisind resurse RPC, fiind alegerea preferată pentru arbitrajul de înaltă frecvență.

2. Arhitectura tehnică: mașină de stare cu concurență ridicată bazată pe Rust

În motorul de execuție Rust, modulul Inventory este proiectat ca un singleton de înaltă concurență, sigur pentru fire, destinat partajării între mai multe module de strategie.

2.1 Structuri de date cheie: DashMap și Arc

Deoarece procesarea datelor în Solana este paralelă pe fire multiple, Inventory trebuie să gestioneze frecvențe extrem de ridicate de citire și scriere:

  • DashMap: aceasta este o tabelă hash concurentă de înaltă performanță. Spre deosebire de HashMap standard + Mutex, aceasta reduce granularitatea blocării la nivel de fragment (Shard), evitând competiția globală a blocajelor în timpul analizei frecvente.

  • Arc (Contor de Referință Atomic): utilizat pentru a partaja în siguranță adresele de memorie ale Inventory între diferite sarcini Tokio (cum ar fi sarcini de ascultare, sarcini de prețuire, sarcini de execuție), realizând acces la date fără copiere.

2.2 Logica stratificării indexului

Sistemul menține două niveluri de indexare:

  1. Indexul global al pool-urilor: înregistrează maparea adreselor pool-urilor la metadatele token-ului (Mint, Decimale, Vault).

  2. Harta perechilor de arbitraj: înregistrează „perechile de arbitraj candidate”. De exemplu, introducând adresa Mint a SOL, se returnează imediat informațiile despre corelarea sa în pool-ul Raydium A și pool-ul Orca B.

3. Implementarea algoritmului: O(N+M)O(N+M) pentru intersecții rapide

Construirea listei albe pentru arbitraj se concentrează pe „găsirea intersecției”.

  1. Scanează protocolul A (Raydium): salvează toate pool-urile în funcție de Token_A -> Pool_Address într-un tabel hash temporar.

  2. Scanează protocolul B (Orca): parcurge lista de pool-uri, iar dacă găsește același Token_A în tabelul hash al protocolului A, se identifică o oportunitate potențială de arbitraj.

  3. Generați lista de observație: adăugați simultan adresele celor două pool-uri găsite în „lista de observație (Watchlist)”.

Complexitatea temporală: doar două scanări liniare sunt necesare, chiar și în fața a zeci de mii de pool-uri, pornirea rece poate fi finalizată în milisecunde.

4. Puncte de optimizare a performanței: Viteză din detaliile ingineriei

4.1 Cache API și toleranță la erori

API-urile oficiale pentru protocoale precum Raydium sunt adesea instabile. Am adăugat o memorie cache locală persistentă în implementarea ingineriei.

  • La pornirea rece, se prioritizează citirea din pools_cache.json local.

  • Cereri asincrone în fundal pentru actualizarea cache-ului API.

  • Aceasta garantează că, chiar și în condiții de rețea extreme, robotul poate reveni imediat la lucru.

4.2 Limitele de abonare și fragmentarea

Cele mai multe noduri RPC au restricții asupra numărului de conexiuni accountSubscribe (50-100).
Inventory va sorta automat lista de observație în funcție de „căldura pool-ului (volumul de tranzacții/TVL)”, abonându-se prioritar la cele mai profitabile N pool-uri, sau distribuind abonații pe mai multe noduri RPC prin echilibrarea sarcinii.

5. Demonstrarea prototipului algoritmului (implementarea logicii Python)

Deși în mediul de producție folosim Rust, logica sa de bază poate fi exprimată clar prin următorul exemplu Python:

from dataclasses import dataclass
from typing import Dict, List, Set

@dataclass(frozen=True)
class PoolMetadata:
address: str
token_mint: str

def build_arbitrage_radar(ray_pools: List[PoolMetadata], orca_pools: List[PoolMetadata]):
# 1. Construiește indexul Raydium (Token -> Pool)
ray_index = {p.token_mint: p.address for p in ray_pools}

arbitrage_watchlist = []

# 2. Scanează Orca pentru a căuta intersecții
for o_pool in orca_pools:
if o_pool.token_mint in ray_index:
# Găsește suprapunerea: acest token are lichiditate în ambele DEX-uri
arbitrage_watchlist.append({
"token": o_pool.token_mint,
"raydium_pool": ray_index[o_pool.token_mint],
"orca_pool": o_pool.address
})

return arbitrage_watchlist

# Mock date pentru demonstrație
ray_list = [PoolMetadata("RAY_SOL_POOL", "SOL_MINT"), PoolMetadata("RAY_BONK_POOL", "BONK_MINT")]
orca_list = [PoolMetadata("ORCA_SOL_POOL", "SOL_MINT"), PoolMetadata("ORCA_WIF_POOL", "WIF_MINT")]

watchlist = build_arbitrage_radar(ray_list, orca_list)
print(f"[*] Găsite {len(watchlist)} posibile căi de arbitraj")
# Ieșirea va include calea SOL, deoarece ambele DEX-uri au pool-uri SOL

6. Concluzie: radarul a fost activat

Modulul Inventory este „filtrul” întregului sistem MEV, eliminând zgomotul din întreaga rețea și lăsând doar obiectivele care strălucesc cu profit.

  • Fără Inventory: robotul tău procesează fără scop mii de informații invalide.

  • Cu Inventory: robotul tău se concentrează doar pe acele câteva pool-uri cu variații frecvente, pregătit să acționeze oricând.

Previziune pentru următorul pas

Cu lista albă, următorul pas este cum să capturăm în timp real aceste modificări ale conturilor. În următorul articol, vom explora modul în care modulul Scout poate realiza ascultarea tranzacțiilor și analiza datelor la nivel de sub-milisecunde prin protocolul gRPC/WebSocket.

Acest articol a fost scris de Levi.eth, concentrându-se pe practicile de inginerie de înaltă performanță în ecosistemul Solana.