Жизненный цикл соединения: от TCP-рукопожатия до стабильного майнинга
Общая картина
Заголовок раздела «Общая картина»Когда ASIC-майнер включается и подключается к майнинг-пулу, он проходит через точную последовательность шагов, прежде чем начнёт зарабатывать вам деньги. Представьте это как первый день на новой работе: сначала вы приходите в здание (TCP-подключение), затем отмечаетесь на ресепшене (subscribe), показываете пропуск (authorize), получаете информацию о сложности заданий (set_difficulty), получаете первое задание (notify), и затем приступаете к работе (хеширование и отправка).
Эта статья проведёт вас через каждый шаг этой последовательности с реальными JSON-RPC сообщениями, которые вы увидите на проводе.
Полная последовательность подключения
Заголовок раздела «Полная последовательность подключения»Вот полный жизненный цикл — от холодного старта до стабильного майнинга:
МАЙНЕР ПУЛ | | | Шаг 1: TCP-подключение | |-------- SYN --------------------------------->| |<------- SYN-ACK -----------------------------| |-------- ACK --------------------------------->| | | | Шаг 2 (опционально): mining.configure | | (согласование version rolling) | |-------- mining.configure -------------------->| |<------- результат configure ------------------| | | | Шаг 3: mining.subscribe | | (регистрация, получение extraNonce) | |-------- mining.subscribe -------------------->| |<------- результат subscribe ------------------| | | | Шаг 4: mining.authorize | | (аутентификация воркера) | |-------- mining.authorize -------------------->| |<------- результат authorize ------------------| | | | Шаг 5: Пул отправляет начальные параметры | |<------- mining.set_difficulty ----------------| |<------- mining.notify (первое задание) -------| | | | Шаг 6: Стабильный цикл майнинга | | [майнер хеширует... находит шару] | |-------- mining.submit ----------------------->| |<------- результат submit ---------------------| | | | [пул нашёл новый блок или меняет сложность] | |<------- mining.notify (новое задание) --------| |<------- mining.set_difficulty (коррекция) ----| | | | [цикл продолжается бесконечно] | | |Давайте разберём каждый шаг подробно.
Шаг 1: TCP-соединение
Заголовок раздела «Шаг 1: TCP-соединение»Прежде чем начнётся обмен сообщениями Stratum, майнер должен установить TCP-соединение с пулом. Это стандартная сетевая процедура — трёхстороннее рукопожатие (SYN, SYN-ACK, ACK), которое создаёт надёжный двунаправленный канал связи.
Майнер подключается к определённому хосту и порту, указанному пулом. Например:
stratum+tcp://pool.example.com:3333— стандартное нешифрованное соединениеstratum+ssl://pool.example.com:3334— шифрование TLS (некоторые пулы поддерживают)
Номер порта важен. Многие пулы используют разные порты для разных уровней сложности или функций:
| Порт | Типичное использование |
|---|---|
| 3333 | Стандартная сложность (ASIC) |
| 3334 | Высокая сложность |
| 3335 | NiceHash или прокси-соединения |
| 25 | Низкая сложность (старые/маломощные устройства) |
После установки TCP-соединения майнер и пул могут начать обмен JSON-RPC сообщениями. Каждое сообщение — это одна строка JSON, завершающаяся символом \n.
Шаг 2 (опционально): mining.configure
Заголовок раздела «Шаг 2 (опционально): mining.configure»Современные ASIC, поддерживающие version rolling (техника, связанная с AsicBoost), отправляют сообщение mining.configure перед подпиской. Оно согласовывает, какие расширения протокола поддерживают и майнер, и пул.
Майнер отправляет:
{ "id": 1, "method": "mining.configure", "params": [ ["version-rolling"], {"version-rolling.mask": "1fffe000", "version-rolling.min-bit-count": 2} ]}Пул отвечает:
{ "id": 1, "result": { "version-rolling": true, "version-rolling.mask": "1fffe000" }, "error": null}version-rolling.mask указывает майнеру, какие биты поля версии блока ему разрешено изменять. Это даёт ASIC дополнительное пространство для перебора без необходимости изменять сам nonce или extraNonce. Мы рассмотрим это подробнее в статье о mining.subscribe.
Шаг 3: mining.subscribe
Заголовок раздела «Шаг 3: mining.subscribe»Здесь майнер регистрируется на пуле. Представьте это как заселение в гостиницу — вам дают номер комнаты (идентификатор сессии) и ключ (extraNonce1).
Майнер отправляет:
{ "id": 2, "method": "mining.subscribe", "params": ["bmminer/2.0.0", null]}Параметры:
- Строка пользовательского агента — идентифицирует ПО для майнинга и его версию
- ID предыдущей подписки —
nullдля нового соединения, или ID сессии при попытке возобновления
Пул отвечает:
{ "id": 2, "result": [ [ ["mining.set_difficulty", "deadbeef00000000"], ["mining.notify", "deadbeef00000001"] ], "a1f1c230", 4 ], "error": null}Ответ содержит три критически важных элемента:
- Пары подписок — сообщают майнеру, на какие уведомления он подписан (set_difficulty и notify), каждое со своим ID подписки
- extraNonce1 — hex-строка (
"a1f1c230"), которая уникально идентифицирует сессию этого майнера. Каждая шара, отправленная этим майнером, будет содержать это значение. - Размер extraNonce2 — количество байтов (4 в этом примере), которые майнер может использовать для собственного перебора
extraNonce1 назначается пулом и не должен изменяться майнером. Пул использует его для различения шар от разных майнеров.
Шаг 4: mining.authorize
Заголовок раздела «Шаг 4: mining.authorize»Теперь майнер представляется — кто этот воркер и на какой аккаунт начислять награду за майнинг?
Майнер отправляет:
{ "id": 3, "method": "mining.authorize", "params": ["username.worker1", "x"]}Параметры:
- Имя воркера — обычно в формате
аккаунт.воркерилиадрес_кошелька.воркер - Пароль — обычно игнорируется большинством пулов (часто просто
"x"или""), хотя некоторые пулы используют его для настройки
Пул отвечает (успех):
{ "id": 3, "result": true, "error": null}Пул отвечает (неудача):
{ "id": 3, "result": null, "error": [24, "Unauthorized worker", null]}Если авторизация не пройдена, майнер не сможет отправлять шары. Большинство реализаций закроют соединение и попробуют снова с правильными учётными данными.
Шаг 5: Пул отправляет начальные параметры
Заголовок раздела «Шаг 5: Пул отправляет начальные параметры»Как только майнер подписан и авторизован, пул немедленно отправляет два критически важных элемента:
Назначение сложности
Заголовок раздела «Назначение сложности»{ "id": null, "method": "mining.set_difficulty", "params": [512]}Это сообщает майнеру текущую сложность шары. Майнер должен находить хеши, которые ниже таргета, соответствующего этому значению сложности. Обратите внимание: id равен null — это уведомление, а не запрос.
Первое задание
Заголовок раздела «Первое задание»{ "id": null, "method": "mining.notify", "params": [ "bf", "0000000000000000000354da8e026f48a0467f9d5290a7e30b86e1a80213e5fe", "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4b03a8960cfabe6d6d", "0100000001000000001976a914cb72e7463c3544121c5f37a8f3296c16c6a1289388ac00000000", [ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35" ], "20000000", "1705ae3a", "64a5f8c2", true ]}Это собственно работа, которую должен выполнить майнер. Мы детально разберём каждое поле mining.notify в следующей статье, а пока главное: это сообщение содержит всё, что нужно майнеру для построения заголовков блоков и начала хеширования.
Последний параметр (true) — это флаг clean_jobs. Когда он true, это означает: “Бросай всю предыдущую работу и переключайся на это немедленно.” Для первого задания он всегда true.
Шаг 6: Стабильный цикл майнинга
Заголовок раздела «Шаг 6: Стабильный цикл майнинга»Теперь майнер полностью работоспособен. Он входит в цикл, который продолжается, пока соединение живо:
-
Хеширование — Майнер строит заголовки блоков, используя данные из
mining.notify, и перебирает пространство nonce, ища хеши, удовлетворяющие целевой сложности. -
Отправка шар — Когда майнер находит хеш ниже таргета, он отправляет
mining.submit:
{ "id": 4, "method": "mining.submit", "params": [ "username.worker1", "bf", "00000001", "64a5f8c2", "1a2b3c4d" ]}Пул отвечает успехом или ошибкой:
{"id": 4, "result": true, "error": null}-
Получение новых заданий — Пул периодически отправляет новые сообщения
mining.notify. Это может происходить по нескольким причинам:- В сети найден новый блок (clean_jobs = true)
- Пул хочет обновить набор транзакций в шаблоне блока (clean_jobs = false)
- Прошло достаточно времени, и метку времени пора обновить
-
Корректировка сложности — Пул отслеживает частоту отправки шар и корректирует сложность через
mining.set_difficulty. Если вы отправляете шары слишком часто, сложность растёт. Слишком редко — снижается.
Этот цикл продолжается бесконечно — часами, днями, неделями — пока что-нибудь не разорвёт соединение.
Что происходит при разрыве соединения
Заголовок раздела «Что происходит при разрыве соединения»Соединения рвутся. Это факт жизни. Скачки напряжения, перезагрузки роутера, техобслуживание пула, сбои провайдера — существует множество причин, по которым TCP-соединение может оборваться. Вот что делает правильно работающий майнер:
Обнаружение
Заголовок раздела «Обнаружение»Майнер обнаруживает разрыв одним из нескольких способов:
- Получен TCP reset или FIN от пула
- Запись в сокет не удалась (broken pipe)
- Данные не получены слишком долго (собственный таймаут keepalive майнера)
Некоторые майнеры периодически отправляют сообщения mining.ping (или любой фиктивный запрос) для обнаружения мёртвых соединений. Если пул не отвечает в течение таймаута, соединение считается разорванным.
Стратегия переподключения
Заголовок раздела «Стратегия переподключения»Соединение разорвано | v Ожидание (период отсрочки) | v Попытка основного пула ---> Успех? ---> Повторная подписка + авторизация | | | Неудача v v Возобновление майнинга Попытка резервного пула с новым extraNonce1 и заданиями | | Неудача v Увеличение отсрочки (экспоненциально: 1с, 2с, 4с, 8с... до 60с) | v Повторная попытка основного пула [цикл]Ключевые моменты переподключения:
-
Повторная подписка обязательна. После переподключения майнер должен снова пройти
mining.subscribeиmining.authorize. Пул может назначить другойextraNonce1. -
Старая работа недействительна. Любые шары, над которыми майнер работал в предыдущей сессии, бесполезны. Майнер должен дождаться новых сообщений
mining.notify. -
Экспоненциальная отсрочка. Хороший майнер не забрасывает пул попытками переподключения. Он ждёт 1 секунду, затем 2, затем 4, затем 8 и так далее, с ограничением около 60 секунд. Это предотвращает перегрузку пула при сбое.
-
Резервные пулы. Большинство прошивок позволяют настроить несколько адресов пулов. Если основной пул недоступен, майнер переключается на вторичный, затем на третичный. Он периодически проверяет, не вернулся ли основной пул.
Пример возобновления сессии
Заголовок раздела «Пример возобновления сессии»Майнер пытается возобновить:
{ "id": 1, "method": "mining.subscribe", "params": ["bmminer/2.0.0", "previous_subscription_id_here"]}Если пул ещё хранит сессию в памяти, он может вернуть тот же extraNonce1, позволяя майнеру продолжить без потерь. Если сессия истекла или пул не поддерживает возобновление, он просто назначает новую сессию.
Хронометраж: как быстро всё это происходит?
Заголовок раздела «Хронометраж: как быстро всё это происходит?»При типичном соединении всё рукопожатие — от TCP-подключения до получения первого задания — занимает значительно менее одной секунды. Вот реалистичная хронология:
| Шаг | Время от начала |
|---|---|
| TCP-рукопожатие (SYN/SYN-ACK/ACK) | ~20-50 мс |
| mining.configure (если используется) | ~50-100 мс |
| mining.subscribe + ответ | ~80-150 мс |
| mining.authorize + ответ | ~100-200 мс |
| Получение mining.set_difficulty | ~120-220 мс |
| Получение mining.notify | ~130-230 мс |
| Майнер начинает хеширование | ~150-250 мс |
Эти числа предполагают стабильное интернет-соединение с задержкой ~20 мс до пула. На практике большинство ASIC начинают хешировать в течение 200-300 миллисекунд после подключения. Для машины, работающей 24/7, эти затраты на запуск пренебрежимо малы.
Реальный захват пакетов
Заголовок раздела «Реальный захват пакетов»Чтобы свести всё воедино, вот как могут выглядеть реальные байты на проводе при полной настройке соединения. Каждая строка — одно JSON-RPC сообщение (разделённое символами новой строки):
Майнер —> Пул:
{"id":1,"method":"mining.configure","params":[["version-rolling"],{"version-rolling.mask":"1fffe000","version-rolling.min-bit-count":2}]}Пул —> Майнер:
{"id":1,"result":{"version-rolling":true,"version-rolling.mask":"1fffe000"},"error":null}Майнер —> Пул:
{"id":2,"method":"mining.subscribe","params":["bmminer/2.0.0",null]}Пул —> Майнер:
{"id":2,"result":[[["mining.set_difficulty","1"],["mining.notify","1"]],"abcd1234",4],"error":null}Майнер —> Пул:
{"id":3,"method":"mining.authorize","params":["myaccount.worker1","x"]}Пул —> Майнер:
{"id":3,"result":true,"error":null}Пул —> Майнер:
{"id":null,"method":"mining.set_difficulty","params":[512]}Пул —> Майнер:
{"id":null,"method":"mining.notify","params":["job1","prevhash...","cb1...","cb2...","merkle...","20000000","1a0ffff0","64b1c3a5",true]}В этот момент майнер имеет всё необходимое и начинает хеширование. Первая отправка шары может произойти через секунды или минуты, в зависимости от хешрейта майнера и сложности шары.
Несколько воркеров на одном соединении
Заголовок раздела «Несколько воркеров на одном соединении»Интересная особенность Stratum — одно TCP-соединение может обслуживать нескольких воркеров. Это часто используется майнинг-прокси — программным обеспечением, которое стоит между фермой ASIC и пулом. Прокси поддерживает одно соединение с пулом, но управляет десятками или сотнями ASIC локально.
Процесс выглядит так:
{"id":3,"method":"mining.authorize","params":["account.worker1","x"]}{"id":4,"method":"mining.authorize","params":["account.worker2","x"]}{"id":5,"method":"mining.authorize","params":["account.worker3","x"]}Каждый воркер авторизуется независимо, и шары, отправленные через mining.submit, указывают, какой воркер их нашёл. Пул отслеживает хешрейт и заработок по каждому воркеру.
Типичные проблемы при подключении
Заголовок раздела «Типичные проблемы при подключении»Вот проблемы, с которыми вы можете столкнуться, и что они означают:
“Connection refused” — Сервер пула не слушает на этом порту. Проверьте имя хоста, порт и то, что пул действительно работает.
“Connection timeout” — Ваша сеть не может добраться до пула. Может быть файрвол, проблема провайдера или перегрузка пула. Попробуйте другой адрес или порт.
Ошибка авторизации — Вы подключаетесь нормально, но пул отклоняет имя воркера. Перепроверьте имя аккаунта, адрес кошелька или формат воркера. Некоторые пулы требуют предварительного создания воркеров в веб-панели.
Немедленное отключение после subscribe — Это иногда происходит при подключении к неправильному порту (например, SSL-порт без TLS или наоборот).
Устаревшие шары после переподключения — Если вы переподключитесь и немедленно отправите шары из старой сессии, пул их отклонит. Всегда дожидайтесь свежих сообщений mining.notify после переподключения.
Жизненный цикл соединения Stratum — это чётко определённая последовательность:
- TCP-подключение к хосту и порту пула
- mining.configure (опционально) для согласования расширений протокола, таких как version rolling
- mining.subscribe для регистрации и получения extraNonce1 и размера extraNonce2
- mining.authorize для аутентификации воркера
- mining.set_difficulty и mining.notify от пула для настройки начальной работы
- Стабильный цикл: получение заданий, хеширование, отправка шар, корректировка сложности
При разрыве соединения майнер переподключается с экспоненциальной отсрочкой и проходит всё рукопожатие заново. Некоторые пулы поддерживают возобновление сессии для более быстрого восстановления.
В следующей статье мы детально разберём mining.subscribe и mining.authorize — рассмотрим каждое поле, каждый крайний случай и то, как на самом деле работает назначение extraNonce.