mirror of
https://github.com/GOSTSec/poolserver
synced 2025-01-15 01:00:10 +00:00
More work
This commit is contained in:
parent
6432acff9d
commit
0fccd298c6
@ -3,8 +3,9 @@
|
|||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
template<>
|
DataMgr* DataMgr::singleton = 0;
|
||||||
void DataMgr<Share>::Upload()
|
|
||||||
|
void DataMgr::Upload()
|
||||||
{
|
{
|
||||||
sLog.Info(LOG_SERVER, "We have %u shares", Size());
|
sLog.Info(LOG_SERVER, "We have %u shares", Size());
|
||||||
|
|
||||||
@ -15,8 +16,6 @@ void DataMgr<Share>::Upload()
|
|||||||
std::string query("INSERT INTO `shares` (`rem_host`, `username`, `our_result`, `upstream_result`, `reason`, `time`, `difficulty`) VALUES ");
|
std::string query("INSERT INTO `shares` (`rem_host`, `username`, `our_result`, `upstream_result`, `reason`, `time`, `difficulty`) VALUES ");
|
||||||
for (int i = 0; i < BULK_COUNT; ++i)
|
for (int i = 0; i < BULK_COUNT; ++i)
|
||||||
{
|
{
|
||||||
sLog.Info(LOG_SERVER, "Query: %s", query.c_str());
|
|
||||||
|
|
||||||
Share share = Pop();
|
Share share = Pop();
|
||||||
|
|
||||||
query += Util::FS("(INET_NTOA(%u), '%s', %u, 0, '%s', FROM_UNIXTIME(%u), %u)", share.host, share.username.c_str(), share.result, share.reason.c_str(), share.time, share.diff);
|
query += Util::FS("(INET_NTOA(%u), '%s', %u, 0, '%s', FROM_UNIXTIME(%u), %u)", share.host, share.username.c_str(), share.result, share.reason.c_str(), share.time, share.diff);
|
||||||
@ -28,9 +27,8 @@ void DataMgr<Share>::Upload()
|
|||||||
query += ',';
|
query += ',';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sLog.Debug(LOG_SERVER, "Query: %s", query.c_str());
|
||||||
|
|
||||||
sDatabase.ExecuteAsync(query.c_str());
|
sDatabase.ExecuteAsync(query.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DataMgr<Share> sDataMgr;
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Share.h"
|
#include "Share.h"
|
||||||
@ -10,19 +11,38 @@
|
|||||||
#define BULK_MIN 1
|
#define BULK_MIN 1
|
||||||
#define BULK_COUNT 50
|
#define BULK_COUNT 50
|
||||||
|
|
||||||
template<class T>
|
using namespace boost;
|
||||||
|
|
||||||
class DataMgr
|
class DataMgr
|
||||||
{
|
{
|
||||||
|
// Singleton
|
||||||
|
private:
|
||||||
|
static DataMgr* singleton;
|
||||||
public:
|
public:
|
||||||
DataMgr() {}
|
|
||||||
|
|
||||||
void Push(T data)
|
static DataMgr* Instance()
|
||||||
|
{
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Initialize(asio::io_service& io_service)
|
||||||
|
{
|
||||||
|
singleton = new DataMgr(io_service);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
DataMgr(asio::io_service& io_service) : _io_service(io_service), _uploadTimer(io_service)
|
||||||
|
{
|
||||||
|
UploadTimerStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Push(Share data)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::mutex> lock(_datamutex);
|
boost::unique_lock<boost::mutex> lock(_datamutex);
|
||||||
_datastore.push_back(data);
|
_datastore.push_back(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
T Pop()
|
Share Pop()
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::mutex> lock(_datamutex);
|
boost::unique_lock<boost::mutex> lock(_datamutex);
|
||||||
Share share = _datastore.front();
|
Share share = _datastore.front();
|
||||||
@ -36,12 +56,28 @@ public:
|
|||||||
return _datastore.size();
|
return _datastore.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UploadTimerStart()
|
||||||
|
{
|
||||||
|
_uploadTimer.expires_from_now(boost::posix_time::seconds(3));
|
||||||
|
_uploadTimer.async_wait(boost::bind(&DataMgr::UploadTimerExpired, this, boost::asio::placeholders::error));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UploadTimerExpired(const boost::system::error_code& /*e*/)
|
||||||
|
{
|
||||||
|
Upload();
|
||||||
|
UploadTimerStart();
|
||||||
|
}
|
||||||
|
|
||||||
void Upload();
|
void Upload();
|
||||||
private:
|
private:
|
||||||
|
// io service
|
||||||
|
asio::io_service& _io_service;
|
||||||
|
|
||||||
|
// timer
|
||||||
|
boost::asio::deadline_timer _uploadTimer;
|
||||||
|
|
||||||
boost::mutex _datamutex;
|
boost::mutex _datamutex;
|
||||||
std::deque<T> _datastore;
|
std::deque<Share> _datastore;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DataMgr<Share> sDataMgr;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -147,7 +147,7 @@ void NetworkMgr::BlockCheck()
|
|||||||
|
|
||||||
void NetworkMgr::BlockCheckTimerStart()
|
void NetworkMgr::BlockCheckTimerStart()
|
||||||
{
|
{
|
||||||
_blockCheckTimer.expires_from_now(boost::posix_time::seconds(3));
|
_blockCheckTimer.expires_from_now(boost::posix_time::seconds(2));
|
||||||
_blockCheckTimer.async_wait(boost::bind(&NetworkMgr::BlockCheckTimerExpired, this, boost::asio::placeholders::error));
|
_blockCheckTimer.async_wait(boost::bind(&NetworkMgr::BlockCheckTimerExpired, this, boost::asio::placeholders::error));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,12 +161,14 @@ void NetworkMgr::BlockCheckTimerExpired(const boost::system::error_code& /*e*/)
|
|||||||
void NetworkMgr::BlockNotifyBind(FBlockNotify f)
|
void NetworkMgr::BlockNotifyBind(FBlockNotify f)
|
||||||
{
|
{
|
||||||
_blockNotifyBinds.push_back(f);
|
_blockNotifyBinds.push_back(f);
|
||||||
|
// Send block template
|
||||||
|
f(_curBlockTmpl, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block notify timer
|
// Block notify timer
|
||||||
void NetworkMgr::BlockNotifyTimerStart()
|
void NetworkMgr::BlockNotifyTimerStart()
|
||||||
{
|
{
|
||||||
_blockNotifyTimer.expires_from_now(boost::posix_time::seconds(3));
|
_blockNotifyTimer.expires_from_now(boost::posix_time::seconds(30));
|
||||||
_blockNotifyTimer.async_wait(boost::bind(&NetworkMgr::BlockNotifyTimerExpired, this, boost::asio::placeholders::error));
|
_blockNotifyTimer.async_wait(boost::bind(&NetworkMgr::BlockNotifyTimerExpired, this, boost::asio::placeholders::error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
Server::Server(asio::io_service& io) : serverLoops(0), io_service(io), uploadtimer(io)
|
Server::Server(asio::io_service& io) : serverLoops(0), io_service(io)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,19 +24,6 @@ Server::~Server()
|
|||||||
//delete stratumServer;
|
//delete stratumServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncQueryCallback(MySQL::QueryResult result)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Server::UploadShares(const boost::system::error_code& /*e*/)
|
|
||||||
{
|
|
||||||
sDataMgr.Upload();
|
|
||||||
uploadtimer.expires_from_now(boost::posix_time::seconds(3)); //repeat rate here
|
|
||||||
uploadtimer.async_wait(boost::bind(&Server::UploadShares, this, boost::asio::placeholders::error));
|
|
||||||
}
|
|
||||||
|
|
||||||
int Server::Run()
|
int Server::Run()
|
||||||
{
|
{
|
||||||
sLog.Info(LOG_SERVER, "Server is starting...");
|
sLog.Info(LOG_SERVER, "Server is starting...");
|
||||||
@ -101,7 +88,7 @@ int Server::Run()
|
|||||||
sLog.Info(LOG_SERVER, "Trans: %s", Util::BinToASCII(buf2.vec).c_str());*/
|
sLog.Info(LOG_SERVER, "Trans: %s", Util::BinToASCII(buf2.vec).c_str());*/
|
||||||
|
|
||||||
|
|
||||||
|
DataMgr::Initialize(io_service);
|
||||||
NetworkMgr::Initialize(io_service);
|
NetworkMgr::Initialize(io_service);
|
||||||
|
|
||||||
std::vector<std::string> btcrpc = sConfig.Get<std::vector<std::string> >("BitcoinRPC");
|
std::vector<std::string> btcrpc = sConfig.Get<std::vector<std::string> >("BitcoinRPC");
|
||||||
@ -126,10 +113,6 @@ int Server::Run()
|
|||||||
tcp::endpoint endpoint(tcp::v4(), sConfig.Get<uint16>("StratumPort"));
|
tcp::endpoint endpoint(tcp::v4(), sConfig.Get<uint16>("StratumPort"));
|
||||||
srv.Start(endpoint);
|
srv.Start(endpoint);
|
||||||
|
|
||||||
// Start timer
|
|
||||||
uploadtimer.expires_from_now(boost::posix_time::seconds(3)); //repeat rate here
|
|
||||||
uploadtimer.async_wait(boost::bind(&Server::UploadShares, this, boost::asio::placeholders::error));
|
|
||||||
|
|
||||||
io_service.run();
|
io_service.run();
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ public:
|
|||||||
|
|
||||||
bool InitDatabase();
|
bool InitDatabase();
|
||||||
|
|
||||||
boost::asio::deadline_timer uploadtimer;
|
|
||||||
asio::io_service& io_service;
|
asio::io_service& io_service;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "DataMgr.h"
|
#include "DataMgr.h"
|
||||||
#include "ShareLimiter.h"
|
#include "ShareLimiter.h"
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
|
#include "ServerDatabaseEnv.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace Stratum
|
namespace Stratum
|
||||||
@ -70,12 +71,28 @@ namespace Stratum
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check username
|
||||||
|
std::string username = params[0].GetString();
|
||||||
|
if (!_workers.count(username)) {
|
||||||
|
sLog.Error(LOG_SERVER, "Worker not authenticated");
|
||||||
|
JSON response;
|
||||||
|
response["id"] = msg["id"];
|
||||||
|
response["result"];
|
||||||
|
response["error"].Add(int64(24));
|
||||||
|
response["error"].Add("Unauthorized worker");
|
||||||
|
response["error"].Add(JSON());
|
||||||
|
SendMessage(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 jobid;
|
uint32 jobid;
|
||||||
ByteBuffer jobbuf(Util::ASCIIToBin(params[1].GetString()));
|
ByteBuffer jobbuf(Util::ASCIIToBin(params[1].GetString()));
|
||||||
jobbuf >> jobid;
|
jobbuf >> jobid;
|
||||||
|
|
||||||
// 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));
|
||||||
|
|
||||||
JSON response;
|
JSON response;
|
||||||
response["id"] = msg["id"];
|
response["id"] = msg["id"];
|
||||||
response["result"];
|
response["result"];
|
||||||
@ -86,9 +103,6 @@ namespace Stratum
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check username
|
|
||||||
std::string username = params[0].GetString();
|
|
||||||
|
|
||||||
BinaryData extranonce2 = Util::ASCIIToBin(params[2].GetString());
|
BinaryData extranonce2 = Util::ASCIIToBin(params[2].GetString());
|
||||||
if (extranonce2.size() != 4) {
|
if (extranonce2.size() != 4) {
|
||||||
sLog.Error(LOG_SERVER, "Wrong extranonce size");
|
sLog.Error(LOG_SERVER, "Wrong extranonce size");
|
||||||
@ -135,6 +149,8 @@ namespace Stratum
|
|||||||
share << extranonce2 << timebuf << noncebuf;
|
share << extranonce2 << timebuf << noncebuf;
|
||||||
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));
|
||||||
|
|
||||||
JSON response;
|
JSON response;
|
||||||
response["id"] = msg["id"];
|
response["id"] = msg["id"];
|
||||||
response["result"];
|
response["result"];
|
||||||
@ -161,18 +177,12 @@ namespace Stratum
|
|||||||
// Set coinbase tx
|
// Set coinbase tx
|
||||||
block.tx[0] = coinbasetx;
|
block.tx[0] = coinbasetx;
|
||||||
|
|
||||||
sLog.Info(LOG_SERVER, "Coinbase hash1: %s", Util::BinToASCII(Crypto::SHA256D(coinbasebuf.Binary())).c_str());
|
|
||||||
sLog.Info(LOG_SERVER, "Coinbase hash2: %s", Util::BinToASCII(coinbasetx.GetHash()).c_str());
|
|
||||||
|
|
||||||
// Rebuilds only left side of merkle tree
|
// Rebuilds only left side of merkle tree
|
||||||
block.RebuildMerkleTree();
|
block.RebuildMerkleTree();
|
||||||
sLog.Info(LOG_SERVER, "Merklehash: %s", Util::BinToASCII(block.merkleRootHash).c_str());
|
|
||||||
|
|
||||||
// Get block hash
|
// Get block hash
|
||||||
BinaryData hash = block.GetHash();
|
BinaryData hash = block.GetHash();
|
||||||
|
|
||||||
sLog.Info(LOG_SERVER, "Block hash: %s", Util::BinToASCII(hash).c_str());
|
|
||||||
|
|
||||||
// Get block target
|
// Get block target
|
||||||
BigInt target(Util::BinToASCII(Util::Reverse(hash)), 16);
|
BigInt target(Util::BinToASCII(Util::Reverse(hash)), 16);
|
||||||
|
|
||||||
@ -187,6 +197,8 @@ namespace Stratum
|
|||||||
// Check if difficulty meets job diff
|
// Check if difficulty meets job diff
|
||||||
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));
|
||||||
|
|
||||||
JSON response;
|
JSON response;
|
||||||
response["id"] = msg["id"];
|
response["id"] = msg["id"];
|
||||||
response["result"];
|
response["result"];
|
||||||
@ -203,7 +215,7 @@ namespace Stratum
|
|||||||
|
|
||||||
_server->SubmitBlock(block);
|
_server->SubmitBlock(block);
|
||||||
} else {
|
} else {
|
||||||
sDataMgr.Push(Share(_ip, username, true, "", Util::Date(), job.diff));
|
DataMgr::Instance()->Push(Share(_ip, username, true, "", Util::Date(), job.diff));
|
||||||
|
|
||||||
JSON response;
|
JSON response;
|
||||||
response["id"] = msg["id"];
|
response["id"] = msg["id"];
|
||||||
@ -247,11 +259,25 @@ namespace Stratum
|
|||||||
std::string username = msg["params"][0].GetString();
|
std::string username = msg["params"][0].GetString();
|
||||||
std::string password = msg["params"][1].GetString();
|
std::string password = msg["params"][1].GetString();
|
||||||
|
|
||||||
JSON response;
|
MySQL::QueryResult result = sDatabase.Query(Util::FS("SELECT * FROM `pool_worker` WHERE `username` = '%s' and `password` = '%s'", sDatabase.Escape(username).c_str(), sDatabase.Escape(password).c_str()).c_str());
|
||||||
response["id"] = msg["id"].GetInt();
|
|
||||||
response["error"];
|
if (result) {
|
||||||
response["result"] = true;
|
_workers.insert(username);
|
||||||
SendMessage(response);
|
|
||||||
|
JSON response;
|
||||||
|
response["id"] = msg["id"].GetInt();
|
||||||
|
response["error"];
|
||||||
|
response["result"] = true;
|
||||||
|
SendMessage(response);
|
||||||
|
} else {
|
||||||
|
JSON response;
|
||||||
|
response["id"] = msg["id"].GetInt();
|
||||||
|
response["error"].Add(int64(20));
|
||||||
|
response["error"].Add("Authentication failed");
|
||||||
|
response["error"].Add(JSON());
|
||||||
|
response["result"] = true;
|
||||||
|
SendMessage(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Job Client::GetJob()
|
Job Client::GetJob()
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/enable_shared_from_this.hpp>
|
#include <boost/enable_shared_from_this.hpp>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#define MAX_PACKET 2048
|
#define MAX_PACKET 2048
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ namespace Stratum
|
|||||||
Stratum::Server* _server;
|
Stratum::Server* _server;
|
||||||
|
|
||||||
// Authorization
|
// Authorization
|
||||||
std::vector<std::string> _workers;
|
std::set<std::string> _workers;
|
||||||
|
|
||||||
// Jobs
|
// Jobs
|
||||||
bool _subscribed;
|
bool _subscribed;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "ShareLimiter.h"
|
#include "ShareLimiter.h"
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
#include "Client.h"
|
#include "Client.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
namespace Stratum
|
namespace Stratum
|
||||||
{
|
{
|
||||||
@ -15,23 +16,33 @@ namespace Stratum
|
|||||||
if (sinceLast < RETARGET_INTERVAL)
|
if (sinceLast < RETARGET_INTERVAL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
_lastRetarget = curTime;
|
||||||
|
|
||||||
while (_shares.size() && (_shares.front() < curTime - RETARGET_TIME_BUFFER))
|
while (_shares.size() && (_shares.front() < curTime - RETARGET_TIME_BUFFER))
|
||||||
_shares.pop_front();
|
_shares.pop_front();
|
||||||
|
|
||||||
uint32 interval = std::min(curTime - _startTime, uint64(RETARGET_TIME_BUFFER));
|
uint32 interval = std::min(curTime - _startTime, uint64(RETARGET_TIME_BUFFER));
|
||||||
|
|
||||||
// Calculate shares/min
|
// Calculate shares/min
|
||||||
double speed = (_shares.size()*60) / interval;
|
double speed = double(_shares.size()*60) / double(interval);
|
||||||
|
|
||||||
// Calculate difference from pool target in %
|
// Calculate difference from pool target in %
|
||||||
double variance = (speed - RETARGET_SHARES_PER_MIN) / RETARGET_SHARES_PER_MIN;
|
double variance = speed / double(RETARGET_SHARES_PER_MIN);
|
||||||
|
|
||||||
|
sLog.Info(LOG_SERVER, "Miner variance: %f speed: %f", variance, speed);
|
||||||
|
|
||||||
// Check if we need to retarget
|
// Check if we need to retarget
|
||||||
if (std::abs(variance)*100 < RETARGET_VARIANCE)
|
if (variance*100 < RETARGET_VARIANCE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
uint64 newDiff = double(_client->GetDifficulty()) * variance;
|
uint64 newDiff = double(_client->GetDifficulty()) * variance;
|
||||||
|
|
||||||
|
if (newDiff < 1)
|
||||||
|
newDiff = 1;
|
||||||
|
|
||||||
|
if (newDiff > RETARGET_MAXDIFF)
|
||||||
|
newDiff = RETARGET_MAXDIFF;
|
||||||
|
|
||||||
_client->SetDifficulty(newDiff, true);
|
_client->SetDifficulty(newDiff, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -6,29 +6,23 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
#define RETARGET_INTERVAL 60
|
#define RETARGET_INTERVAL 20
|
||||||
#define RETARGET_TIME_BUFFER 60*5
|
#define RETARGET_TIME_BUFFER 60*5
|
||||||
#define RETARGET_SHARES_PER_MIN 15
|
#define RETARGET_SHARES_PER_MIN 15
|
||||||
#define RETARGET_VARIANCE 40
|
#define RETARGET_VARIANCE 40
|
||||||
|
#define RETARGET_MAXDIFF 1000000
|
||||||
|
|
||||||
namespace Stratum
|
namespace Stratum
|
||||||
{
|
{
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
class ShareLimiterRecord
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShareLimiterRecord(uint64 atime, uint64 adiff) : time(atime), diff(adiff) {}
|
|
||||||
uint64 time;
|
|
||||||
uint64 diff;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShareLimiter
|
class ShareLimiter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShareLimiter(Client* client) : _client(client), _lastRetarget(0)
|
ShareLimiter(Client* client) : _client(client)
|
||||||
{
|
{
|
||||||
_startTime = Util::Date();
|
_startTime = Util::Date();
|
||||||
|
_lastRetarget = _startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Submit();
|
bool Submit();
|
||||||
|
@ -82,6 +82,15 @@ namespace MySQL
|
|||||||
return _stmts[index];
|
return _stmts[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Escape(std::string text)
|
||||||
|
{
|
||||||
|
char* buf = new char[text.length()*2 + 1];
|
||||||
|
mysql_real_escape_string(_mysql, buf, text.c_str(), text.length());
|
||||||
|
std::string result(buf);
|
||||||
|
delete buf;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _Query(const char *sql, MYSQL_RES** result, MYSQL_FIELD** fields, uint64& rowCount, uint32& fieldCount);
|
bool _Query(const char *sql, MYSQL_RES** result, MYSQL_FIELD** fields, uint64& rowCount, uint32& fieldCount);
|
||||||
bool _Query(PreparedStatement* stmt, MYSQL_RES** result, MYSQL_STMT** resultSTMT, uint32& fieldCount);
|
bool _Query(PreparedStatement* stmt, MYSQL_RES** result, MYSQL_STMT** resultSTMT, uint32& fieldCount);
|
||||||
|
@ -40,13 +40,22 @@ namespace MySQL
|
|||||||
class DatabaseQueryOperation : public DatabaseOperation
|
class DatabaseQueryOperation : public DatabaseOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DatabaseQueryOperation(const char* query, DatabaseCallback callback = NULL): DatabaseOperation(), _query(query), _callback(callback) {};
|
DatabaseQueryOperation(const char* query, DatabaseCallback callback = NULL): DatabaseOperation(), _callback(callback)
|
||||||
|
{
|
||||||
|
_query = new char[strlen(query)];
|
||||||
|
strcpy(_query, const_cast<char *>(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
~DatabaseQueryOperation()
|
||||||
|
{
|
||||||
|
delete[] _query;
|
||||||
|
}
|
||||||
|
|
||||||
void Execute();
|
void Execute();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DatabaseCallback _callback;
|
DatabaseCallback _callback;
|
||||||
const char* _query;
|
char* _query;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Util::SynchronisedQueue<DatabaseOperation*> DatabaseWorkQueue;
|
typedef Util::SynchronisedQueue<DatabaseOperation*> DatabaseWorkQueue;
|
||||||
|
@ -93,6 +93,14 @@ namespace MySQL
|
|||||||
return new PreparedStatement(stmtid);
|
return new PreparedStatement(stmtid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Escape(std::string text)
|
||||||
|
{
|
||||||
|
DatabaseConnection* conn = GetSyncConnection();
|
||||||
|
std::string result = conn->Escape(text);
|
||||||
|
conn->Unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DatabaseConnection* GetSyncConnection()
|
DatabaseConnection* GetSyncConnection()
|
||||||
{
|
{
|
||||||
|
@ -18,14 +18,9 @@ std::string Util::Date(const char* format, bool utc)
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Util::Date(bool utc)
|
uint32 Util::Date()
|
||||||
{
|
{
|
||||||
boost::posix_time::ptime now;
|
boost::posix_time::ptime now = boost::posix_time::second_clock::universal_time();
|
||||||
if (utc)
|
|
||||||
now = boost::posix_time::second_clock::universal_time();
|
|
||||||
else
|
|
||||||
now = boost::posix_time::second_clock::local_time();
|
|
||||||
|
|
||||||
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
|
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
|
||||||
boost::posix_time::time_duration diff = now - epoch;
|
boost::posix_time::time_duration diff = now - epoch;
|
||||||
return diff.total_seconds();
|
return diff.total_seconds();
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
namespace Util
|
namespace Util
|
||||||
{
|
{
|
||||||
std::string Date(const char* format, bool utc = false);
|
std::string Date(const char* format, bool utc = false);
|
||||||
uint32 Date(bool utc = true);
|
uint32 Date();
|
||||||
std::string FS(const char *str, ...);
|
std::string FS(const char *str, ...);
|
||||||
std::vector<std::string> Explode(std::string input, std::string delim);
|
std::vector<std::string> Explode(std::string input, std::string delim);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user