MYSTERRIA3.0

Пишем LongPoll сервер для bitcoin pool-сервера

Сам по себе LongPoll (далее ЛП) - простая как барабан технология, появившаяся в результате того, что http соединение рвется после получения клиентом ответа на запрос и не дает возможности серверу оповещать клиента о новых событиях. Чтобы обойти это ограничение клиент посылает запрос на сервер и ждет от сервера ответа. Сервер в свою очередь отдает ответ только тогда, когда ему есть, что сообщить. Если соединение порвалось из-за таймаута, проблем с сетью или в результате полученного от сервера ответа, клиент соединение переподнимает. Со стороны сервера все это выглядит, как пулл соединений, которые он асинхронно обрабатывает. Такой подход еще называют мультиплексным сервером. Для работы с пулом коннектов хорошо подходят такие технологии как select или epoll.

В рамках bitcon протокола getwork ЛП используется для оповещения майнера о смене блока, дабы майнер срочно бросил считать хэши по текущим воркам и обратился к серверу за новыми. Getwork - это JSON протокол, использующий HTTP в роли транспорта или протокола более низкого уровня, ЛП так же использует в роли транспорта HTTP. И вот именно тут зарыты все проблемы работы с майнерами. Надо сказать, что мало кто из разработчиков копателей озаботился изучением HTTP протокола и еще меньше пытались следовать его спецификации, программируя сетевое поведение майнера.

Итак, совет 1. Не надейтесь, что кто-то поймет заголовок Connection: close.

Не надейтесь, что кому-то вообще есть дело до заголовков. Из-за бага в коде GUIminer он не может корректно работать, если вы будете честно объявлять о намерении закрыть коннект и этот коннект добропорядочно закроете. При таком раскладе бедный зверек плюется в консоль питоновским null-pointer эксепшеном и переоткрывает соединение с ЛП, чтобы при следующем оповещении о блоке опять свалиться. Самое обидное в этой истории, что смену блока он так и не отработает, вместо этого, пока не получит новый ворк, будет плодить стэйлы или анноун-ворки.

Багрепорт в GUIminer я, конечно, отошлю, но надо понимать, что находясь на месте пулл-оператора, вы кровно заинтересованы в максимально низком количестве стейлов и анноунов, поэтому придется научиться поддерживать старые бажные клиенты. Процесс обновления народом софта - вещь во времени весьма растянутая, а банить майнеров из-за кривого ЛП - бизнесс-невыгодно.

Совет 2. Не найдейтесь, что майнеры умеют работать с Connection: keep-alive.

Ну вот, приехали, скажите вы. А я предупреждал, школокодеры не обучены HTTP. И тут как пример я возьму уважаемый CGminer, от которого я, право, не ожидал такого тупняка. Cам майнер ничего не говорит на тему того, как бы он хотел работать с соединением, впрочем ладно, пол беды. Вторая половина беды происходит тогда, когда получая keep-alive майнер, не закрывая исходного соединения, открывает еще одно. Как вы понимаете, таким образом количество соединений будет расти вплоть до окончания ресурсов на сервере.

Решение тут следующее, работать надо изначально в режиме keep-alive, это к тому же снижает нагрузку на порождение и инициализацию новых коннектов, авторизацию и тому подобное. Если майнер поддерживает этот режим - все в шоколаде. Если же майнер keep-alive не умеет, мы должны предусмотреть закрытие им сокета и относиться к этому с пониманием. Кроме того, будем трекить послал ли майнер в сокет следующий запрос после получения данных о блоке (ответа) и, если какое-то время после получения ответа заголовков запроса не последовало - коннект будем закрывать. Я закрываю такие неиспользуемые keep-alive-ы по событию прихода нового блока, когда по-любому надо обойти все соединения для рассылки ответов.

Рубрики: Криптовалюты

↑ Наверх


blog comments powered by Disqus

Контакты

Igor Zinkovsky aka TLoD,Snake. Писать на электропочту, стучаться в аську 302380533, искать в Санкт-Петербурге.

© 2002-2019