Browse Source

Merge branch 'master' into peercoin

peercoin
Intel 11 years ago
parent
commit
ac66ae677a
  1. 38
      src/server/poolserver/Stratum/Client.cpp
  2. 17
      src/server/poolserver/Stratum/Client.h
  3. 28
      src/server/poolserver/Stratum/Server.h
  4. 6
      src/server/poolserver/Stratum/ShareLimiter.cpp
  5. 10
      src/server/poolserver/Stratum/ShareLimiter.h

38
src/server/poolserver/Stratum/Client.cpp

@ -9,6 +9,22 @@
namespace Stratum namespace Stratum
{ {
void Client::Start()
{
// Get IP
tcp::endpoint remote_ep = _socket.remote_endpoint();
address remote_ad = remote_ep.address();
_ip = remote_ad.to_v4().to_ulong();
if (_server->IsBanned(_ip)) {
Disconnect();
return;
}
// Start reading socket
StartRead();
}
void Client::SendJob(bool clean) void Client::SendJob(bool clean)
{ {
if (clean) if (clean)
@ -92,6 +108,7 @@ namespace Stratum
// Check if such job exists // Check if such job exists
if (!_jobs.count(jobid)) { if (!_jobs.count(jobid)) {
DataMgr::Instance()->Push(Share(_ip, username, false, "Job not found", Util::Date(), 1)); DataMgr::Instance()->Push(Share(_ip, username, false, "Job not found", Util::Date(), 1));
_shareLimiter.LogBad();
JSON response; JSON response;
response["id"] = msg["id"]; response["id"] = msg["id"];
@ -150,6 +167,7 @@ namespace Stratum
if (!job.SubmitShare(share.Binary())) { if (!job.SubmitShare(share.Binary())) {
sLog.Error(LOG_SERVER, "Duplicate share"); sLog.Error(LOG_SERVER, "Duplicate share");
DataMgr::Instance()->Push(Share(_ip, username, false, "Duplicate share", Util::Date(), job.diff)); DataMgr::Instance()->Push(Share(_ip, username, false, "Duplicate share", Util::Date(), job.diff));
_shareLimiter.LogBad();
JSON response; JSON response;
response["id"] = msg["id"]; response["id"] = msg["id"];
@ -198,6 +216,7 @@ namespace Stratum
if (target > Bitcoin::DiffToTarget(job.diff)) { if (target > Bitcoin::DiffToTarget(job.diff)) {
sLog.Error(LOG_SERVER, "Share above target"); sLog.Error(LOG_SERVER, "Share above target");
DataMgr::Instance()->Push(Share(_ip, username, false, "Share above target", Util::Date(), job.diff)); DataMgr::Instance()->Push(Share(_ip, username, false, "Share above target", Util::Date(), job.diff));
_shareLimiter.LogBad();
JSON response; JSON response;
response["id"] = msg["id"]; response["id"] = msg["id"];
@ -213,7 +232,11 @@ namespace Stratum
if (target <= criteria) { if (target <= criteria) {
sLog.Info(LOG_SERVER, "We have found a block candidate!"); sLog.Info(LOG_SERVER, "We have found a block candidate!");
_server->SubmitBlock(block); if (_server->SubmitBlock(block)) {
std::string query("INSERT INTO `shares` (`rem_host`, `username`, `our_result`, `upstream_result`, `reason`, `solution`, `time`, `difficulty`) VALUES ");
query += Util::FS("(INET_NTOA(%u), '%s', 1, 1, '', '%s', FROM_UNIXTIME(%u), %u)", _ip, username.c_str(), Util::BinToASCII(hash).c_str(), Util::Date(), job.diff);
sDatabase.ExecuteAsync(query.c_str());
}
} else { } else {
DataMgr::Instance()->Push(Share(_ip, username, true, "", Util::Date(), job.diff)); DataMgr::Instance()->Push(Share(_ip, username, true, "", Util::Date(), job.diff));
@ -304,6 +327,17 @@ namespace Stratum
return job; return job;
} }
void Client::Ban(uint32 time)
{
_server->Ban(_ip, time);
Disconnect();
}
void Client::Disconnect()
{
_server->Disconnect(shared_from_this());
}
void Client::_OnReceive(const boost::system::error_code& error, size_t bytes_transferred) void Client::_OnReceive(const boost::system::error_code& error, size_t bytes_transferred)
{ {
if (!error) { if (!error) {
@ -334,7 +368,7 @@ namespace Stratum
} else { } else {
// Client disconnected // Client disconnected
if ((error == asio::error::eof) || (error == asio::error::connection_reset)) { if ((error == asio::error::eof) || (error == asio::error::connection_reset)) {
_server->Disconnect(shared_from_this()); Disconnect();
} }
} }
} }

17
src/server/poolserver/Stratum/Client.h

@ -38,16 +38,8 @@ namespace Stratum
return _socket; return _socket;
} }
void Start() // Start client up!
{ void Start();
// Get IP
tcp::endpoint remote_ep = _socket.remote_endpoint();
address remote_ad = remote_ep.address();
_ip = remote_ad.to_v4().to_ulong();
// Start reading socket
StartRead();
}
void StartRead() void StartRead()
{ {
@ -124,7 +116,10 @@ namespace Stratum
return _id; return _id;
} }
void Disconnect() void Ban(uint32 time);
void Disconnect();
void CloseSocket()
{ {
_socket.close(); _socket.close();
} }

28
src/server/poolserver/Stratum/Server.h

@ -16,6 +16,7 @@
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <set> #include <set>
#include <vector>
using namespace boost; using namespace boost;
using namespace boost::asio::ip; using namespace boost::asio::ip;
@ -28,6 +29,12 @@ namespace Stratum
uint16 Port; uint16 Port;
}; };
struct BanInfo
{
uint32 ip;
uint64 timestamp;
};
// Used for sorting std::set // Used for sorting std::set
struct ClientPtrCMP struct ClientPtrCMP
{ {
@ -95,6 +102,26 @@ namespace Stratum
_clients.erase(client); _clients.erase(client);
} }
void Ban(uint32 ip, uint64 time)
{
BanInfo ban;
ban.ip = ip;
ban.timestamp = Util::Date() + time;
_bans.push_back(ban);
}
bool IsBanned(uint32 ip)
{
for (int i = 0; i < _bans.size(); ++i) {
if (_bans[i].ip == ip) {
if (_bans[i].timestamp > Util::Date())
return true;
}
}
return false;
}
private: private:
void _StartAccept() void _StartAccept()
{ {
@ -123,6 +150,7 @@ namespace Stratum
// Clients // Clients
std::set<ClientPtr, ClientPtrCMP> _clients; std::set<ClientPtr, ClientPtrCMP> _clients;
std::vector<BanInfo> _bans;
uint64 _clientId; uint64 _clientId;
// Work // Work

6
src/server/poolserver/Stratum/ShareLimiter.cpp

@ -8,6 +8,8 @@ namespace Stratum
// Returning false will stop any further share verifications (DoS prevention, etc) // Returning false will stop any further share verifications (DoS prevention, etc)
bool ShareLimiter::Submit() bool ShareLimiter::Submit()
{ {
++_totalShares;
uint64 curTime = Util::Date(); uint64 curTime = Util::Date();
uint64 sinceLast = curTime - _lastRetarget; uint64 sinceLast = curTime - _lastRetarget;
@ -18,6 +20,10 @@ namespace Stratum
_lastRetarget = curTime; _lastRetarget = curTime;
// Check if miner is ok
if (_totalShares > 20 && (double(_totalBadShares)/double(_totalShares)) > 0.8)
_client->Ban(60);
while (_shares.size() && (_shares.front() < curTime - RETARGET_TIME_BUFFER)) while (_shares.size() && (_shares.front() < curTime - RETARGET_TIME_BUFFER))
_shares.pop_front(); _shares.pop_front();

10
src/server/poolserver/Stratum/ShareLimiter.h

@ -19,7 +19,7 @@ namespace Stratum
class ShareLimiter class ShareLimiter
{ {
public: public:
ShareLimiter(Client* client) : _client(client) ShareLimiter(Client* client) : _client(client), _totalShares(0), _totalBadShares(0)
{ {
_startTime = Util::Date(); _startTime = Util::Date();
_lastRetarget = _startTime; _lastRetarget = _startTime;
@ -27,11 +27,19 @@ namespace Stratum
bool Submit(); bool Submit();
void LogBad()
{
++_totalBadShares;
}
private: private:
std::deque<uint64> _shares; std::deque<uint64> _shares;
Client* _client; Client* _client;
uint64 _lastRetarget; uint64 _lastRetarget;
uint64 _startTime; uint64 _startTime;
uint64 _totalShares;
uint64 _totalBadShares;
}; };
} }

Loading…
Cancel
Save