Почему TON-лайтсервер отвечает «not ready» и как это убрать
TON-лайтсервер отвечает «not ready» или ADNL-таймаутом? Разбираем причину на публичном конфиге и убираем ошибку ретраями и hosted-ключом TONNode.
Лайтсервер not ready: вы отправили простой запрос — а в ответ прилетело «not ready»
Вы пишете агента, который должен проверить баланс кошелька или вызвать get-метод контракта. Код правильный, адрес правильный, конфиг лайтсервера взят из официального global-config.json. Но вместо ответа вы регулярно ловите то not ready, то вообще ничего — соединение просто висит и отваливается по ADNL-таймауту. Причём воспроизводится не всегда: утром работает, под нагрузкой — нет. Знакомо? Это не баг в вашем коде и не «TON лежит». Это предсказуемое поведение публичных лайтсерверов из глобального конфига. Разберёмся, почему возникает TON liteserver not ready, что реально помогает на стороне клиента, а что нет.
Что значит «not ready» и ADNL-таймаут у TON-лайтсервера
not ready — это прямой ответ лайтсервера: «я ещё не синхронизирован, не могу тебе ответить». В TON два уровня блокчейна: мастерчейн (masterchain) и basechain (воркчейн 0), который делится на шардчейны/шарды (shardchains). Мастерчейн — как оглавление книги, а шарды — сами главы с транзакциями и состоянием аккаунтов. Нода часто получает голову мастерчейна раньше, чем догоняет соответствующие shard-блоки. В этот момент мастерчейн опережает basechain, а состояние аккаунта живёт в последнем shard-блоке — и проверить его пока нельзя. Нода честно отвечает not ready, вместо того чтобы отдать вам устаревшие или неполные данные.
ADNL-таймаут — это соседний симптом той же болезни. ADNL — нативный транспортный протокол TON, по которому лайтсервер общается с клиентом (никакого HTTP там нет). Когда нода перегружена, она просто не отвечает на ADNL-запрос в отведённое окно, и клиент отваливается по таймауту, даже не дойдя до бизнес-логики.
Здесь важно не путать слои. not ready и ADNL-таймаут живут на уровне нативного ADNL-протокола лайтсервера. Это не то же самое, что HTTP 429 Too Many Requests, который отдают HTTP-шлюзы вроде toncenter и tonapi.io при превышении лимита. Разные слои, разные коды, разные причины. Если вы боретесь именно с 429 — это отдельная история: разбор про фикс 429 у toncenter. А мем про «ошибку 228» из TON-чатов — это шутка сообщества, а не реальный код; лайтсервер таким не отвечает.
Почему публичные лайтсерверы из глобального конфига отваливаются под нагрузкой
Корень проблемы прозаичен. Лайтсерверы из ton.org/global-config.json — общие и лимитированные. Это публичный ресурс, на который одновременно ходят тысячи разработчиков, ботов, индексаторов и агентов со всего мира. У такого ресурса три системных ограничения:
- Общая нагрузка. Вы делите пул со всей экосистемой. Под пиком нода либо не успевает догнать голову сети (отсюда
not ready), либо просто не отвечает вовремя (ADNL-таймаут). - Нет глубокой истории. Публичные ноды не хранят глубокий архив. Если вам нужна старая транзакция по паре
lt/hash, её там может уже не быть — про работу с историей есть отдельный материал про lt и hash. - Никаких гарантий. Это ресурс «как есть». Приоритета у вас нет, пропускную способность вам никто не обещает: сегодня повезло, завтра нет.
То есть not ready — не случайность, которую можно «переждать», а закономерное поведение общего ресурса под нагрузкой. И никакой ваш код не заставит чужую перегруженную ноду синхронизироваться быстрее.
Клиентские фиксы: ретраи, ротация эндпоинтов и таймауты
Прежде чем менять инфраструктуру, выжмите максимум из клиента. Эти приёмы честно работают, но у них есть потолок — ноды всё равно остаются общими.
1. Ретраи с экспоненциальным бэкоффом
not ready часто транзиентен: через 200–800 мс тот же лайтсервер уже применил нужный shard-блок. Простой повтор с нарастающей задержкой снимает заметную долю ошибок.
async function withRetry<T>(fn: () => Promise<T>, tries = 4): Promise<T> {
let lastErr: unknown;
for (let i = 0; i < tries; i++) {
try {
return await fn();
} catch (e) {
lastErr = e;
// ретраим 'not ready' и ADNL-таймауты, но не бизнес-ошибки
await new Promise((r) => setTimeout(r, 200 * 2 ** i));
}
}
throw lastErr;
}
2. Ротация эндпоинтов
Держите в пуле несколько лайтсерверов из конфига и переключайтесь на следующий, если текущий отдал not ready или ушёл в таймаут. Одна нода отстаёт — соседняя может быть уже догнавшей.
3. Поднятый таймаут
Дефолтный ADNL-таймаут иногда слишком жёсткий для перегруженной публичной ноды. Небольшой запас (несколько секунд) снижает ложные обрывы. Но если задирать таймаут до бесконечности — просто копите зависшие запросы; это не лечение, а анестезия.
Отдельный полезный приём — лёгкий healthcheck перед реальным запросом. Идеально подходит get_masterchain_info (голова мастерчейна): именно эта операция первой отдаёт свежий seqno, когда нода догнала голову сети, и возвращает not ready, только когда нода ещё не догнала саму голову мастерчейна. Отдала свежий seqno — нода в строю, можно делать get_account_state, get_balance, run_get_method.
Честный вывод: ретраи + ротация + таймауты сдвигают частоту ошибок вниз, но не убирают причину. Публичные ноды перегружены by design — вы просто аккуратнее стучитесь в дверь, за которой всё та же очередь. Другие подходы к доступу к TON собраны в обзоре альтернатив toncenter на 2026.
Решение без своей ноды: hosted-ключ TONNode на нашем лайтсервере
Радикально not ready убирается одним способом — перестать ходить на общие ноды. Поднимать и обслуживать собственную ноду TON дорого и муторно: синхронизация, диск, апдейты, мониторинг. Промежуточный вариант — ходить не в общий пул, а получить через ключ гарантированную пропускную способность и приоритетный доступ.
TONNode — это hosted MCP-сервер для TON. MCP (Model Context Protocol) — стандарт, по которому ИИ-агенты (Claude, Cursor, ChatGPT/Codex, любой MCP-клиент) вызывают инструменты. Вместо того чтобы ваш код парсил глобальный конфиг и танцевал вокруг not ready, агент вызывает готовый инструмент, а за ним — hosted-эндпоинт https://mcp.tonnode.io/mcp с вашим Bearer-ключом. Это гарантированная пропускная способность вместо общей очереди.
Пакет @tonnode/mcp — open source (MIT, есть на npm и GitHub tonnode/mcp) — работает по нативному ADNL-протоколу TON, без HTTP-прослоек. То есть вы не меняете транспорт на медленный HTTP-шлюз, а остаётесь на том же честном ADNL — но с приоритетным доступом под ваш ключ.
Для диагностики и повседневного чтения пригодятся:
get_masterchain_info— голова мастерчейна, естественный healthcheck.get_account_state— статус, флаги и последняя транзакция аккаунта.get_balance— баланс в GRAM.run_get_method— любой read-only get-метод контракта.
Если вы только начинаете с MCP на TON, разберитесь по гайду по MCP для TON.
Как подключить: npx локально или hosted-эндпоинт с ключом
Бесплатно локально
Полный набор инструментов чтения работает локально из коробки, по публичному конфигу, без карты и без ключа:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
Это отлично для разработки и локальных экспериментов. Но помните: локальный npx под капотом всё ещё ходит на те же общие лайтсерверы, поэтому от not ready под нагрузкой он не спасает — он спасает от возни с зависимостями и даёт единый интерфейс инструментов.
Hosted с ключом
Чтобы уйти от общих нод, переключите транспорт на HTTP-MCP со своим Bearer-ключом (сам вызов инструментов уходит на нашу ноду по ADNL):
{
"mcpServers": {
"ton": {
"type": "http",
"url": "https://mcp.tonnode.io/mcp",
"headers": { "Authorization": "Bearer tn_live_…" }
}
}
}
Как это выглядит в работе с агентом
После подключения агенту достаточно обычного промпта — инструменты он выберет сам:
Сначала
get_masterchain_infoдля healthcheck. Затемget_account_stateдляEQC…— покажи статус и последнюю транзакцию. Потомget_balanceпо тому же адресу.
Под капотом это цепочка: get_masterchain_info (нода жива и догнала голову) → get_account_state (статус, флаги, последняя транзакция) → get_balance (баланс GRAM). Никаких ретраев вокруг чужой очереди — запрос уходит на гарантированную пропускную способность. Кстати, GRAM — это переименованный Toncoin (переименование прошло в июне 2026); сеть по-прежнему называется TON.
Бесплатный ключ Hobby (60 запросов/мин) выдаётся сразу после входа, без карты. Дальше по мере роста: Pro — $29/мес, 300 запросов/мин; Scale — $199/мес, 1200 запросов/мин. Важная деталь: на всех тарифах доступны все 16 инструментов TONNode — платите вы только за пропускную способность, а не за функциональность.
Свой выделенный лайтсервер — по запросу, а не self-serve
Иногда hosted-тарифа мало и нужен выделенный (single-tenant) лайтсервер — только под ваш трафик, без соседей вообще. Такой вариант есть, но честно: это не самообслуживание. Кнопки «включить single-tenant» в дашборде нет — это оформляется вручную: напишите нам, обсудим нагрузку и конфигурацию.
И ещё одна честная оговорка про глубину истории. Архивная нода TONNode сейчас синхронизируется и пока не обслуживает запросы. «Архивная глубина» — это пункт роадмапа, а не готовая функция. Если вам критична глубокая история за всё время прямо сегодня, планируйте это отдельно. Что уже готово, а что в планах — на роадмапе.
Коротко
not ready= нода не синхронизирована: мастерчейн опережает shard, состояние аккаунта в последнем shard-блоке ещё нельзя проверить.- Публичные лайтсерверы из глобального конфига — общие и лимитированные:
not ready, ADNL-таймауты, нет глубокой истории. Это не путать с HTTP 429 у toncenter/tonapi — другой слой. - Клиентские фиксы (ретраи с бэкоффом, ротация эндпоинтов, таймауты) снижают частоту ошибок, но не убирают причину.
get_masterchain_info— ваш healthcheck: краснеетnot ready, только когда нода вообще не догнала голову мастерчейна.- Реальное лечение — уйти с общего ресурса на гарантированную пропускную способность.
Возьмите бесплатный hosted-ключ Hobby и перестаньте ловить «not ready» на общих нодах → tonnode.io/dashboard?plan=hobby
Дайте вашему агенту доступ к TON
16 MCP-инструментов: чтение, некастодиальные свапы, кроссчейн и кошельки. Бесплатный тариф — 60 запр/мин, карта не нужна.