← Все статьи
5 мин чтенияru

Скоростной трейдинг на TON: где живут миллисекунды и как их отыграть

трейдинг на TONарбитраж TONmempool TONзадержка RPC TONliteserverSTON.fiDeDustADNL

Арбитражное окно на TON живёт примерно один блок — около 400 мс. За это время нужно увидеть расхождение цен между STON.fi и DeDust, собрать транзакцию, доставить её валидаторам и попасть в ближайший блок раньше конкурента. Поэтому скоростной трейдинг на TON — это прежде всего инженерия задержек, а не хитрые контракты. Разберём путь транзакции по миллисекундам и посмотрим, какие из них реально отыграть.

Анатомия задержки: путь одного свопа

Полный цикл «сигнал → исполнение» складывается из четырёх отрезков.

  1. Наблюдение. Вы опрашиваете состояние пулов. Если через HTTP API вроде toncenter — каждый запрос проходит лишний hop: прокси сам ходит в лайтсервер по ADNL и переупаковывает ответ в JSON. Это плюс 30–150 мс к каждому чтению. Та самая задержка RPC TON, о которой не думают, пока не начнут считать.
  2. Решение. Ваш код. Единицы миллисекунд, здесь всё под вашим контролем.
  3. Доставка. External-сообщение должно долететь до валидаторов (их в сети 382). Один перегруженный публичный узел — и вы стоите в чужой очереди.
  4. Включение в блок. Блок в TON выходит каждые ~400 мс, финальность — около 800 мс. Это нижняя граница: быстрее физики сети не стать.

Пункты 2 и 4 почти не оптимизируются. Вся борьба идёт за пункты 1 и 3.

Общий шлюз: почему burst-стратегии умирают на окне в 10 секунд

Анонимный toncenter отдаёт 1 запрос в секунду — для трейдинга это ни о чём. Платные общие лайтсерверы (Tonkeeper / tonapi.io) продают 10 RPS за $50 и 50 RPS за $200 в месяц, но лимит считается по скользящему окну в 10 секунд. Превысили — получаете фирменную ошибку 228.

Для арбитража на TON это архитектурная проблема, а не тарифная. Рыночное событие — листинг, крупный своп, сдвиг курса — требует всплеска: 150–200 запросов за полсекунды (состояние двух пулов, балансы, seqno, отправка, ретраи). На тарифе «50 RPS» окно даёт бюджет 500 запросов на 10 секунд, и один всплеск съедает половину. Второй сигнал в те же десять секунд — и вы ловите 228 ровно тогда, когда счёт идёт на миллисекунды.

Добавьте типовые болезни публичных лайтсерверов: «failed to send query to server: not ready», таймаут ADNL с кодом 652, отставшие узлы, отвечающие «Cannot get server version and time». Каждый ретрай — минус один-два блока.

Мемпул TON: где он живёт и как его читать

Мемпул в TON устроен иначе, чем в Ethereum: pending-сообщения не лежат в одной общей очереди, которую любой желающий читает целиком. Они живут на уровне узлов — external-сообщение сначала попадает на ноду, и лишь потом валидаторы включают его в блок.

Практический вывод: узел, через который идёт трафик, знает о входящих сообщениях на сотни миллисекунд раньше, чем они окажутся в блоке. Чем больше у провайдера нод и чем ближе они к валидаторам, тем полнее картина. Мы оформляем этот слой как WebSocket-стрим — это и есть мемпул TON в рабочем смысле слова.

Что это даёт на практике:

  • сигнал о крупном свопе в пул примерно на блок раньше, чем его увидят те, кто читает только блоки;
  • контроль доставки собственных транзакций: видно, что сеть приняла сообщение, ещё до блока;
  • быстрые ретраи: нет сообщения в стриме через N мс — шлёте повторно.

Чего это не даёт: полной картины всех pending-сообщений сети. Видимость ограничена узлами, к которым у вас есть доступ. Это преимущество в один блок, а не телепатия. Подписка выглядит примерно так:

{
  "op": "subscribe",
  "stream": "pending_external",
  "filter": { "dst": ["EQ...stonfi_pool", "EQ...dedust_vault"] }
}

Выделенный ADNL-эндпоинт: убрать очередь и лишний hop

Лайтсерверы говорят на ADNL — бинарном протоколе, в котором клиент сам проверяет ответы Merkle-пруфами и не обязан доверять узлу. HTTP API поверх него — удобство ценой задержки. Документация TON прямо рекомендует выделенный лайтсервер для продакшена.

Приватный эндпоинт меняет три вещи:

  • нет разделяемой очереди — ваши запросы не конкурируют с чужими ботами;
  • нет скользящего окна — burst на 200 запросов за 300 мс проходит штатно;
  • прямой ADNL — минус прокси-hop на каждом чтении.
from pytoniq import LiteClient

# свой узел вместо публичных из ton.org/global.config.json
client = LiteClient.from_config(my_private_config, trust_level=0)
await client.connect()  # каждый ответ проверяется Merkle-пруфом

Отдельный слой — приоритетный broadcast: транзакция уходит одновременно через несколько узлов в разных точках сети. Для снайпинга и арбитража это страховка от единственного медленного маршрута до валидаторов.

Свой узел: считаем честно

Можно поднять узел самостоятельно. Официальные требования к архивному узлу: 16 ядер, 128 ГБ RAM, NVMe с 64k+ IOPS, 16 ТБ под ZFS с lz4 (около 20 ТБ без сжатия), канал 1 Гбит/с и порядка 16 ТБ трафика в месяц. Дамп с archival-dump.ton.org разворачивается через curl | zstd -d | zfs recv, а реалистичный срок запуска — одна-две недели: дни на скачивание, дни на импорт, затем догоняющая синхронизация.

Для команды со своим DevOps это разумная инвестиция. Для стратегии, которую хочется проверить на этой неделе, — нет.

Что в итоге

Миллисекунды в трейдинге на TON живут в двух местах: в лишнем HTTP-hop на чтении и в очередях общих шлюзов на записи. Время блока и финальность одинаковы для всех; выигрывает тот, у кого короче путь до узла и нет лимитера между сигналом и отправкой.

Если считать деньгами: приватный лайтсервер TONNode стоит от $20 в месяц (10 RPS, lite) до $999 (400 RPS, архив), есть pay-per-request ($0,01 за lite-запрос, $0,02 за archive, с бёрстами до 500 RPS) — удобно прогнать стратегию на выходных, не подписываясь на месяц; подписки от недели. Mempool-стрим и приоритетный multi-node broadcast входят в тарифы, узел выдаётся меньше чем за 60 секунд, оплата в GRAM или USDT. Подробности — на странице тарифов, а если ботом управляет AI-агент, посмотрите наш MCP-сервер.