Jeśli moduł Inventory to 'pamięć' robota, to moduł Scout jest jego 'oczami'. W burzliwym przepływie tysięcy zmian stanu na Solana na sekundę, zadaniem Scouta jest błyskawiczne filtrowanie, selekcjonowanie i dekodowanie sygnałów, które mają rzeczywiste znaczenie dla strategii arbitrażu.

W świecie MEV prędkość nie jest wszystkim, ale bez prędkości nie ma nic. Niniejszy artykuł dogłębnie zbada, jak zbudować system nasłuchu i analizy transakcji o niskim opóźnieniu i wysokiej równoległości.

1. Filozofia nasłuchu: nóż chirurgiczny vs. duża sieć rybacka

Na Solana zwykle stajemy przed dwoma całkowicie różnymi wymaganiami nasłuchu, odpowiadającymi różnym ścieżkom technologicznym:

1.1 accountSubscribe: precyzyjny nożyk chirurgiczny (tryb Arb)

W przypadku arbitrażu między protokołami, już zablokowaliśmy konkretne pule za pomocą Inventory. Wtedy nie musimy obserwować całego sieci — wystarczy uważnie śledzić zmiany pola Data w kontach tych pul.

  • Mechanizm: gdy saldo tokenów lub cena w puli się zmieniają, węzeł RPC natychmiast przesyła najnowsze dane konta.

  • Zalety: sygnał jest bardzo bezpośredni, pomija skomplikowane analizowanie transakcji — to najszybsza droga do arbitrażu wysokiej częstotliwości.

1.2 logsSubscribe: wielka sieć do łowienia (tryb Sniper)

W przypadku szybkiego wyłapywania nowych pul (Sniping), nie możemy z góry znać adresu puli — możemy tylko nasłuchiwać określonych protokołów (np. Raydium lub Orca) i reagować na sygnały o „utworzeniu puli” lub „wpłacie początkowej płynności” w dziennikach programu.

  • Mechanizm: skanowanie dzienników pod kątem określonych słów kluczowych (np. initialize2).

  • Wyzwania: duża ilość szumu, a po trafieniu często wymagana jest „długa ścieżka” (np. żądanie getTransaction) do uzupełnienia danych o tokenach puli.

2. Architektura główna: wielokanałowe przesyłanie strumieni (Stream Multiplexing)

W dojrzałym systemie możesz potrzebować jednoczesnego nasłuchiwania aktualizacji setek pul. Jeśli dla każdej subskrypcji otworzysz osobny wątek, koszty systemowe natychmiast się wybuchną.

2.1 Scalanie strumieni asynchronicznych (Select All)

Wykorzystujemy ekosystem asynchroniczny w Rust (Tokio + Futures), używając select_all, aby połączyć setki, a nawet tysiące strumieni subskrypcji WebSocket w jeden jednolity strumień zdarzeń. To jakby zebrać obrazy z setek kamer monitoringu na jednym ekranie, gdzie jedna główna pętla (Event Loop) zarządza rozdzielaniem zadań.

2.2 Model wątków i odłączenie „długiej ścieżki”

Szybkość odpowiedzi głównej pętli nasłuchującej decyduje o maksymalnym opóźnieniu systemu.

  • Szybka ścieżka (Hot Path): odbiór danych → dekodowanie w pamięci → uruchomienie obliczeń.

  • Długa ścieżka (Long Path): jeśli potrzebne są dodatkowe dane RPC (np. w trybie Sniper), muszą być wykonywane jako zadania w tle za pomocą tokio::spawn, bez blokowania głównej pętli nasłuchującej.

3. Najwyższa precyzja analizy: pomijanie niepotrzebnych informacji

Dane konta w Solanie to zwykle ciąg binarny (Buffer). Niska wydajność to deserializacja do pełnych obiektów, a ekstremalna wydajność to „analiza na żądanie”.

3.1 Zero-copy i lokalizacja poprzez przesunięcie

Na przykład podczas nasłuchiwania Orca Whirlpool, potrzebujemy tylko wartości sqrt_price i tick_current_index.

  • Nie musimy analizować całego stanu puli (setki bajtów), wystarczy odczytać bezpośrednio 16 bajtów z określonego przesunięcia (Offset) w strumieniu danych.

  • W Rust, poprzez zastosowanie bytemuck lub prostego przesunięcia wskaźników, można w mikrosekundach wyodrębnić kluczowe parametry ceny.

3.2 Sztuka filtrów

W fazie logsSubscribe, wykorzystując filtr mentions oferowany przez RPC, można na poziomie węzła odfiltrować 90% niepotrzebnych dzienników, co znacznie zmniejsza obciążenie sieciowe na stronie Searcher.

4. Punkty optymalizacji wydajności: od implementacji inżynieryjnej do milisekund

  1. Podział subskrypcji (Sharding): ze względu na ograniczenia połączeń z publicznymi węzłami RPC, Scout automatycznie dzieli pulę białych list na fragmenty i odbiera dane równolegle przez kilka połączeń WebSocket, unikając ciśnienia (Backpressure) na pojedynczym połączeniu.

  2. Mechanizm tłumienia szumu: dla pul o częstym zmienianiu stanu, implementuje się proste zasady odrzucania lub scalania (Coalescing) pakietów. Jeśli w ciągu 1 ms ta sama pula wygeneruje wiele aktualizacji, przetwarzana jest tylko ostatnia, co oszczędza zasoby obliczeniowe poziomu strategii.

  3. Wstępne wczytywanie indeksów: podczas analizy dzienników, wstępnie ładuje się informacje o liczbie miejsc po przecinku (Decimals) najczęściej używanych tokenów, aby uniknąć dodatkowych żądań podczas obliczania różnic cen.

5. Demonstracja techniczna: logika scalania wielu strumieni zdarzeń (symulacja w Pythonie)

Choć wydajny rdzeń działa w Rust, to logika scalania i dystrybucji „wiele do jednego” może być idealnie wyrażona za pomocą asyncio:

import asyncio
import random

async def pool_monitor(pool_id: str):
"""Symulacja strumienia subskrypcji dla pojedynczego konta"""
while True:
await asyncio.sleep(random.uniform(0.01, 0.1)) # symulacja losowego przesyłania
yield {"pool": pool_id, "data": random.random()}

async def main_scout_loop():
# symulacja pobrania listy do nasłuchiwania z Inventory
watchlist = ["Pool_A", "Pool_B", "Pool_C"]

# scal wszystkie strumienie do jednej kolejki
queue = asyncio.Queue()

async def producer(pool_id):
asynchroniczny dla aktualizacji w pool_monitor(pool_id):
await queue.put(update)

# Uruchom wszystkie zadania producentów
for p in watchlist:
asyncio.create_task(producer(p))

print("[*] Silnik Scout został uruchomiony, nasłuchuje wielokanałowych sygnałów...")

# Główna pętla konsumenta: dystrybucja strategii
while True:
event = await queue.get()
# W tym momencie natychmiast uruchamiamy asynchroniczne obliczenia na poziomie strategii
asyncio.create_task(execute_strategy(event))

async def execute_strategy(event):
print(f"⚡️ Złapano sygnał: {event['pool']} -> uruchomiono obliczenia modelu cenowego")

if name == "__main__":
asyncio.run(main_scout_loop())

6. Podsumowanie: najbardziej wrażliwy radar

Poziom projektowania modułu Scout bezpośrednio decyduje o „szybkości startu” robota. Dobry Scout powinien:

  • być wystarczająco szeroki: potrafił wyłapywać nowe możliwości dzięki analizie dzienników.

  • być wystarczająco dokładny: potrafił precyzyjnie zlokalizować zmiany cen dzięki subskrypcji kont.

  • być wystarczająco szybki: stosując architekturę asynchroniczną i analizę binarną, ograniczać opóźnienie do poziomu mikrosekund.

Następny krok — zapowiedź

Złapano sygnał, uzyskano dane surowe — co dalej? Musimy przekształcić dane binarne w rzeczywiste ceny aktywów. W kolejnym artykule wejdziemy do modułu AMM i odkryjemy, jak wzór stałego iloczynu Raydium oraz matematyczny model skupienia płynności Orca działają w pamięci z ekstremalną szybkością.

Ten artykuł został napisany przez Levi.eth i poświęcony jest dzieleniu się sztuką inżynieryjną w dziedzinie Solana MEV.

$SOL $JTO

JTO
JTOUSDT
0.3548
-9.85%

SOL
SOL
133.73
-5.87%