mirror of https://github.com/GOSTSec/poolserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.5 KiB
135 lines
3.5 KiB
#ifndef STRATUM_SERVER_H_ |
|
#define STRATUM_SERVER_H_ |
|
|
|
#include "Common.h" |
|
#include "Client.h" |
|
#include "Config.h" |
|
#include "Log.h" |
|
#include "JSON.h" |
|
#include "JSONRPC.h" |
|
#include "Bitcoin.h" |
|
#include "Util.h" |
|
#include "ByteBuffer.h" |
|
#include "NetworkMgr.h" |
|
|
|
#include <boost/asio.hpp> |
|
#include <boost/bind.hpp> |
|
#include <boost/thread/mutex.hpp> |
|
#include <set> |
|
|
|
using namespace boost; |
|
using namespace boost::asio::ip; |
|
|
|
namespace Stratum |
|
{ |
|
struct ListenInfo |
|
{ |
|
std::string Host; |
|
uint16 Port; |
|
}; |
|
|
|
// Used for sorting std::set |
|
struct ClientPtrCMP |
|
{ |
|
bool operator() (const ClientPtr& a, const ClientPtr& b) |
|
{ |
|
return a->GetID() < b->GetID(); |
|
} |
|
}; |
|
|
|
class Server |
|
{ |
|
public: |
|
Server(asio::io_service& io_service) : _io_service(io_service), _acceptor(io_service), _extranonce(0), _clientId(0) |
|
{ |
|
// Subscribe for block updates |
|
NetworkMgr::Instance()->BlockNotifyBind(boost::bind(&Server::BlockNotify, this, _1, _2)); |
|
} |
|
|
|
~Server() |
|
{ |
|
std::set<ClientPtr>::iterator it; |
|
for (it = _clients.begin(); it != _clients.end(); ++it) |
|
(*it)->Disconnect(); |
|
} |
|
|
|
// Starts accepting connections |
|
void Start(tcp::endpoint endpoint); |
|
|
|
// Sends message to all clients |
|
void SendToAll(JSON msg); |
|
|
|
// Returns new extranonce |
|
uint32 GetExtranonce() |
|
{ |
|
return _extranonce++; |
|
} |
|
|
|
// Returns current work |
|
Bitcoin::BlockPtr GetWork() |
|
{ |
|
boost::lock_guard<boost::mutex> guard(_mtxCurrentWork); |
|
return _currentWork; |
|
} |
|
|
|
// Block template update event |
|
void BlockNotify(Bitcoin::BlockPtr block, bool newBlock) |
|
{ |
|
sLog.Debug(LOG_SERVER, "Received block template update"); |
|
_mtxCurrentWork.lock(); |
|
_currentWork = block; |
|
_mtxCurrentWork.unlock(); |
|
SendBlockTmpl(newBlock); |
|
} |
|
|
|
// Resets work for all clients |
|
void SendBlockTmpl(bool resetWork); |
|
|
|
// Submits block to bitcoind |
|
bool SubmitBlock(Bitcoin::Block block); |
|
|
|
// Disconnects client |
|
void Disconnect(ClientPtr client) |
|
{ |
|
client->Disconnect(); |
|
_clients.erase(client); |
|
} |
|
|
|
private: |
|
void _StartAccept() |
|
{ |
|
ClientPtr client = ClientPtr(new Client(this, _io_service, _clientId++)); |
|
|
|
_acceptor.async_accept(client->GetSocket(), boost::bind(&Server::_OnAccept, this, client, asio::placeholders::error)); |
|
} |
|
|
|
void _OnAccept(ClientPtr client, const boost::system::error_code& error) |
|
{ |
|
if (!error) { |
|
sLog.Debug(LOG_STRATUM, "New stratum client accepted. Total clients: %u", _clients.size()); |
|
client->Start(); |
|
_clients.insert(client); |
|
} else { |
|
sLog.Debug(LOG_STRATUM, "Failed to accept stratum client"); |
|
} |
|
|
|
_StartAccept(); |
|
} |
|
|
|
private: |
|
// Network |
|
asio::io_service& _io_service; |
|
tcp::acceptor _acceptor; |
|
|
|
// Clients |
|
std::set<ClientPtr, ClientPtrCMP> _clients; |
|
uint64 _clientId; |
|
|
|
// Work |
|
Bitcoin::BlockPtr _currentWork; |
|
boost::mutex _mtxCurrentWork; |
|
uint32 _extranonce; |
|
}; |
|
} |
|
|
|
#endif
|
|
|