mirror of
https://github.com/GOSTSec/poolserver
synced 2025-01-14 08:47:53 +00:00
Various fixes
This commit is contained in:
parent
f6f3fca5d6
commit
4df0c537a3
@ -9,12 +9,14 @@ void DataMgr::Upload()
|
||||
{
|
||||
sLog.Info(LOG_SERVER, "We have %u shares", Size());
|
||||
|
||||
while (Size() > BULK_MIN)
|
||||
uint32 bulkCount = sConfig.Get<uint32>("ShareUploadBulkCount");
|
||||
|
||||
while (Size() > sConfig.Get<uint32>("ShareUploadMinCount"))
|
||||
{
|
||||
sLog.Info(LOG_SERVER, "Uploading %u shares to database", Size());
|
||||
|
||||
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 < bulkCount; ++i)
|
||||
{
|
||||
Share share = Pop();
|
||||
|
||||
@ -23,7 +25,7 @@ void DataMgr::Upload()
|
||||
if (!Size())
|
||||
break;
|
||||
|
||||
if (i != BULK_COUNT-1)
|
||||
if (i != bulkCount-1)
|
||||
query += ',';
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,7 @@
|
||||
|
||||
#include "Util.h"
|
||||
#include "Share.h"
|
||||
|
||||
#define BULK_MIN 1
|
||||
#define BULK_COUNT 50
|
||||
#include "Config.h"
|
||||
|
||||
using namespace boost;
|
||||
|
||||
@ -58,7 +56,7 @@ public:
|
||||
|
||||
void UploadTimerStart()
|
||||
{
|
||||
_uploadTimer.expires_from_now(boost::posix_time::seconds(3));
|
||||
_uploadTimer.expires_from_now(boost::posix_time::seconds(sConfig.Get<uint32>("ShareUploadInterval")));
|
||||
_uploadTimer.async_wait(boost::bind(&DataMgr::UploadTimerExpired, this, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,11 @@ bool InitConfig(int argc, char *argv[])
|
||||
// Server
|
||||
descServer.add_options()
|
||||
("ServerThreads", boost::program_options::value<uint32_t>()->default_value(2), "How many threads to use")
|
||||
("MiningAddress", boost::program_options::value<std::string>()->default_value("n1w8gkPXdNGb6edm4vujBn71A72eQFCNCw"), "Address to send coins to")
|
||||
("MiningAddress", boost::program_options::value<std::string>(), "Address to send coins to")
|
||||
("BitcoinRPC", boost::program_options::value<std::vector<std::string> >()->multitoken(), "Bitcoin RPC login credentials")
|
||||
("ShareUploadMinCount", boost::program_options::value<uint32>()->default_value(2), "Minimum share count to upload to database")
|
||||
("ShareUploadBulkCount", boost::program_options::value<uint32>()->default_value(50), "How many shares to upload in one query")
|
||||
("ShareUploadInterval", boost::program_options::value<uint32>()->default_value(3), "How often to upload shares")
|
||||
;
|
||||
|
||||
// Stratum
|
||||
@ -43,7 +46,12 @@ bool InitConfig(int argc, char *argv[])
|
||||
("StratumHost,sh", boost::program_options::value<std::string>()->default_value("0.0.0.0"), "Stratum server host")
|
||||
("StratumPort,sp", boost::program_options::value<uint16_t>()->default_value(3333), "Stratum server port")
|
||||
("StratumBlockCheckTime", boost::program_options::value<uint32>()->default_value(2000), "Time between block checks in ms")
|
||||
("StratumMinDifficulty", boost::program_options::value<uint32>()->default_value(1), "The difficulty on which a new miner starts")
|
||||
("RetargetInterval", boost::program_options::value<uint32>()->default_value(20), "Time between difficulty checks in seconds")
|
||||
("RetargetTimeBuffer", boost::program_options::value<uint32>()->default_value(60*5), "Buffer of shares to keep (in seconds)")
|
||||
("RetargetSharesPerMin", boost::program_options::value<uint32>()->default_value(15), "How many shares per min to target for")
|
||||
("RetargetVariance", boost::program_options::value<uint32>()->default_value(40), "Maximum allowed variance in percent before difficulty change")
|
||||
("RetargetMinDiff", boost::program_options::value<uint32>()->default_value(1), "Minimum difficulty (also starting difficulty)")
|
||||
("RetargetMaxDiff", boost::program_options::value<uint32>()->default_value(1000000), "Maximum difficulty we can reach")
|
||||
;
|
||||
|
||||
// Logging
|
||||
|
@ -93,7 +93,7 @@ namespace Stratum
|
||||
// check username
|
||||
std::string username = params[0].GetString();
|
||||
if (!_workers.count(username)) {
|
||||
sLog.Error(LOG_SERVER, "Worker not authenticated");
|
||||
sLog.Error(LOG_STRATUM, "%s: Worker not authenticated", username.c_str());
|
||||
JSON response;
|
||||
response["id"] = msg["id"];
|
||||
response["result"];
|
||||
@ -125,7 +125,7 @@ namespace Stratum
|
||||
|
||||
BinaryData extranonce2 = Util::ASCIIToBin(params[2].GetString());
|
||||
if (extranonce2.size() != 4) {
|
||||
sLog.Error(LOG_SERVER, "Wrong extranonce size");
|
||||
sLog.Error(LOG_STRATUM, "Wrong extranonce size");
|
||||
JSON response;
|
||||
response["id"] = msg["id"];
|
||||
response["result"];
|
||||
@ -138,7 +138,7 @@ namespace Stratum
|
||||
|
||||
ByteBuffer timebuf(Util::Reverse(Util::ASCIIToBin(params[3].GetString())));
|
||||
if (timebuf.Size() != 4) {
|
||||
sLog.Error(LOG_SERVER, "Wrong ntime size");
|
||||
sLog.Error(LOG_STRATUM, "Wrong ntime size");
|
||||
JSON response;
|
||||
response["id"] = msg["id"];
|
||||
response["result"];
|
||||
@ -151,7 +151,7 @@ namespace Stratum
|
||||
|
||||
ByteBuffer noncebuf(Util::Reverse(Util::ASCIIToBin(params[4].GetString())));
|
||||
if (noncebuf.Size() != 4) {
|
||||
sLog.Error(LOG_SERVER, "Wrong nonce size");
|
||||
sLog.Error(LOG_STRATUM, "Wrong nonce size");
|
||||
JSON response;
|
||||
response["id"] = msg["id"];
|
||||
response["result"];
|
||||
@ -168,7 +168,7 @@ namespace Stratum
|
||||
ByteBuffer share;
|
||||
share << extranonce2 << timebuf << noncebuf;
|
||||
if (!job.SubmitShare(share.Binary())) {
|
||||
sLog.Error(LOG_SERVER, "Duplicate share");
|
||||
sLog.Error(LOG_STRATUM, "%s: Duplicate share", username.c_str());
|
||||
DataMgr::Instance()->Push(Share(_ip, username, false, "Duplicate share", Util::Date(), job.diff));
|
||||
_shareLimiter.LogBad();
|
||||
|
||||
@ -207,17 +207,9 @@ namespace Stratum
|
||||
// Get block target
|
||||
BigInt target(Util::BinToASCII(Util::Reverse(hash)), 16);
|
||||
|
||||
// Network target criteria
|
||||
BigInt criteria(Bitcoin::TargetFromBits(block.bits));
|
||||
|
||||
BigInt diff = Bitcoin::TargetToDiff(criteria);
|
||||
std::cout << "Target: " << target << std::endl;
|
||||
std::cout << "Criteria: " << criteria << std::endl;
|
||||
std::cout << "Diff: " << diff << std::endl;
|
||||
|
||||
// Check if difficulty meets job diff
|
||||
if (target > Bitcoin::DiffToTarget(job.diff)) {
|
||||
sLog.Error(LOG_SERVER, "Share above target");
|
||||
if (target > job.target) {
|
||||
sLog.Error(LOG_STRATUM, "%s: Share above target", username.c_str());
|
||||
DataMgr::Instance()->Push(Share(_ip, username, false, "Share above target", Util::Date(), job.diff));
|
||||
_shareLimiter.LogBad();
|
||||
|
||||
@ -232,7 +224,7 @@ namespace Stratum
|
||||
}
|
||||
|
||||
// Check if block meets criteria
|
||||
if (target <= criteria) {
|
||||
if (target <= job.blockCriteria) {
|
||||
sLog.Info(LOG_SERVER, "We have found a block candidate!");
|
||||
|
||||
if (_server->SubmitBlock(block)) {
|
||||
@ -292,11 +284,17 @@ namespace Stratum
|
||||
std::string username = msg["params"][0].GetString();
|
||||
std::string password = msg["params"][1].GetString();
|
||||
|
||||
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());
|
||||
MySQL::QueryResult result = sDatabase.Query(Util::FS("SELECT `id`, `mindiff` FROM `pool_worker` WHERE `username` = '%s' and `password` = '%s'", sDatabase.Escape(username).c_str(), sDatabase.Escape(password).c_str()).c_str());
|
||||
|
||||
if (result) {
|
||||
_workers.insert(username);
|
||||
|
||||
MySQL::Field* fields = result->FetchRow();
|
||||
_minDiff = fields[1].Get<uint32>();
|
||||
|
||||
if (_diff < _minDiff)
|
||||
SetDifficulty(_minDiff);
|
||||
|
||||
JSON response;
|
||||
response["id"] = msg["id"].GetInt();
|
||||
response["error"];
|
||||
@ -317,7 +315,8 @@ namespace Stratum
|
||||
{
|
||||
Job job;
|
||||
job.block = _server->GetWork();
|
||||
job.diff = 1;
|
||||
job.diff = _diff;
|
||||
job.target = Bitcoin::DiffToTarget(job.diff);
|
||||
|
||||
// Serialize transaction
|
||||
ByteBuffer coinbasebuf;
|
||||
@ -334,6 +333,8 @@ namespace Stratum
|
||||
job.coinbase1 = BinaryData(coinbase.begin(), coinbase.begin() + cbsplit);
|
||||
job.coinbase2 = BinaryData(coinbase.begin() + cbsplit + 8, coinbase.end()); // plus extranonce size
|
||||
|
||||
job.blockCriteria = Bitcoin::TargetFromBits(job.block->bits);
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,8 @@ namespace Stratum
|
||||
public:
|
||||
Client(Server* server, asio::io_service& io_service, uint64 id) : _io_service(io_service), _server(server), _socket(io_service), _ioStrand(io_service), _id(id), _subscribed(false), _jobid(0), _shareLimiter(this)
|
||||
{
|
||||
_diff = sConfig.Get<uint32>("StratumMinDifficulty");
|
||||
_minDiff = _diff;
|
||||
_diff = sConfig.Get<uint32>("RetargetMinDiff");
|
||||
_minDiff = sConfig.Get<uint32>("RetargetMinDiff");
|
||||
}
|
||||
|
||||
~Client()
|
||||
@ -98,6 +98,12 @@ namespace Stratum
|
||||
}
|
||||
void SetDifficulty(uint64 diff, bool resendJob = false)
|
||||
{
|
||||
if (diff < _minDiff)
|
||||
diff = _minDiff;
|
||||
|
||||
if (diff == _diff)
|
||||
return;
|
||||
|
||||
_diff = diff;
|
||||
|
||||
// Send difficulty update
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "Bitcoin.h"
|
||||
#include "Crypto.h"
|
||||
#include "Util.h"
|
||||
#include "BigNum.h"
|
||||
#include <set>
|
||||
|
||||
namespace Stratum
|
||||
@ -16,6 +17,8 @@ namespace Stratum
|
||||
BinaryData coinbase1;
|
||||
BinaryData coinbase2;
|
||||
std::set<std::string> shares;
|
||||
BigInt blockCriteria;
|
||||
BigInt target;
|
||||
|
||||
// Submits share to a job
|
||||
// Returns false if the same share already exists
|
||||
|
@ -82,7 +82,7 @@ namespace Stratum
|
||||
// Block template update event
|
||||
void BlockNotify(Bitcoin::BlockPtr block, bool newBlock)
|
||||
{
|
||||
sLog.Debug(LOG_SERVER, "Received block template update");
|
||||
sLog.Debug(LOG_STRATUM, "Received block template update");
|
||||
_mtxCurrentWork.lock();
|
||||
_currentWork = block;
|
||||
_mtxCurrentWork.unlock();
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "ShareLimiter.h"
|
||||
#include "Server.h"
|
||||
#include "Client.h"
|
||||
#include "Config.h"
|
||||
#include "Log.h"
|
||||
|
||||
namespace Stratum
|
||||
@ -15,42 +16,44 @@ namespace Stratum
|
||||
|
||||
_shares.push_back(curTime);
|
||||
|
||||
if (sinceLast < RETARGET_INTERVAL)
|
||||
if (sinceLast < sConfig.Get<uint32>("RetargetInterval"))
|
||||
return true;
|
||||
|
||||
_lastRetarget = curTime;
|
||||
|
||||
// Check if miner is ok
|
||||
if (_totalShares > 50 && (double(_totalBadShares)/double(_totalShares)) > 0.8)
|
||||
_client->Ban(60);
|
||||
if (_totalShares > 50 && (double(_totalBadShares)/double(_totalShares)) > 0.8) {
|
||||
_client->Ban(600);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (_shares.size()) {
|
||||
if (_shares.front() > curTime - RETARGET_TIME_BUFFER)
|
||||
if (_shares.front() > curTime - sConfig.Get<uint32>("RetargetTimeBuffer"))
|
||||
break;
|
||||
_shares.pop_front();
|
||||
}
|
||||
|
||||
uint32 interval = std::min(curTime - _startTime, uint64(RETARGET_TIME_BUFFER));
|
||||
uint32 interval = std::min(curTime - _startTime, uint64(sConfig.Get<uint32>("RetargetTimeBuffer")));
|
||||
|
||||
// Calculate shares/min
|
||||
double speed = double(_shares.size()*60) / double(interval);
|
||||
|
||||
// Calculate difference from pool target in %
|
||||
double variance = speed / double(RETARGET_SHARES_PER_MIN);
|
||||
double variance = speed / double(sConfig.Get<uint32>("RetargetSharesPerMin"));
|
||||
|
||||
sLog.Info(LOG_SERVER, "Miner variance: %f speed: %f", variance, speed);
|
||||
sLog.Debug(LOG_STRATUM, "Miner variance: %f speed: %f", variance, speed);
|
||||
|
||||
// Check if we need to retarget
|
||||
if (variance*100 < RETARGET_VARIANCE)
|
||||
if (variance*100 < sConfig.Get<uint32>("RetargetVariance"))
|
||||
return true;
|
||||
|
||||
uint64 newDiff = double(_client->GetDifficulty()) * variance;
|
||||
|
||||
if (newDiff < 1)
|
||||
newDiff = 1;
|
||||
if (newDiff < sConfig.Get<uint32>("RetargetMinDiff"))
|
||||
newDiff = sConfig.Get<uint32>("RetargetMinDiff");
|
||||
|
||||
if (newDiff > RETARGET_MAXDIFF)
|
||||
newDiff = RETARGET_MAXDIFF;
|
||||
if (newDiff > sConfig.Get<uint32>("RetargetMaxDiff"))
|
||||
newDiff = sConfig.Get<uint32>("RetargetMaxDiff");
|
||||
|
||||
_client->SetDifficulty(newDiff, true);
|
||||
|
||||
|
@ -6,12 +6,6 @@
|
||||
|
||||
#include <deque>
|
||||
|
||||
#define RETARGET_INTERVAL 20
|
||||
#define RETARGET_TIME_BUFFER 60*5
|
||||
#define RETARGET_SHARES_PER_MIN 15
|
||||
#define RETARGET_VARIANCE 40
|
||||
#define RETARGET_MAXDIFF 1000000
|
||||
|
||||
namespace Stratum
|
||||
{
|
||||
class Client;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <cstring>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "Log.h"
|
||||
|
||||
class Config
|
||||
{
|
||||
@ -16,7 +17,15 @@ public:
|
||||
template<class T>
|
||||
T Get(std::string key)
|
||||
{
|
||||
return vm[key].as<T>();
|
||||
T tmp;
|
||||
|
||||
try {
|
||||
tmp = vm[key].as<T>();
|
||||
} catch(std::exception& e) {
|
||||
sLog.Error(LOG_GENERAL, "Failed to get config value for key '%s'", key.c_str());
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Containers
|
||||
|
Loading…
Reference in New Issue
Block a user