mirror of
https://github.com/LBRYFoundation/pool.git
synced 2025-08-23 17:37:25 +00:00
331 lines
6.9 KiB
C++
331 lines
6.9 KiB
C++
|
|
#include "stratum.h"
|
|
|
|
static int g_extraonce1_counter = 0;
|
|
|
|
void get_next_extraonce1(char *extraonce1)
|
|
{
|
|
CommonLock(&g_nonce1_mutex);
|
|
|
|
g_extraonce1_counter++;
|
|
sprintf(extraonce1, "%08x", g_extraonce1_counter|0x81000000);
|
|
|
|
CommonUnlock(&g_nonce1_mutex);
|
|
}
|
|
|
|
void get_random_key(char *key)
|
|
{
|
|
int i1 = rand();
|
|
int i2 = rand();
|
|
int i3 = rand();
|
|
int i4 = rand();
|
|
sprintf(key, "%08x%08x%08x%08x", i1, i2, i3, i4);
|
|
}
|
|
|
|
YAAMP_CLIENT *client_find_notify_id(const char *notify_id, bool reconnecting)
|
|
{
|
|
g_list_client.Enter();
|
|
for(CLI li = g_list_client.first; li; li = li->next)
|
|
{
|
|
YAAMP_CLIENT *client = (YAAMP_CLIENT *)li->data;
|
|
if(client->reconnecting == reconnecting && !strcmp(client->notify_id, notify_id))
|
|
{
|
|
g_list_client.Leave();
|
|
return client;
|
|
}
|
|
}
|
|
|
|
g_list_client.Leave();
|
|
return NULL;
|
|
}
|
|
|
|
void client_sort()
|
|
{
|
|
for(CLI li = g_list_client.first; li && li->next; li = li->next)
|
|
{
|
|
YAAMP_CLIENT *client1 = (YAAMP_CLIENT *)li->data;
|
|
YAAMP_CLIENT *client2 = (YAAMP_CLIENT *)li->next->data;
|
|
|
|
// if(client2->difficulty_actual > client1->difficulty_actual)
|
|
if(client2->speed > client1->speed*1.5)
|
|
{
|
|
g_list_client.Swap(li, li->next);
|
|
client_sort();
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
int client_send_error(YAAMP_CLIENT *client, int error, const char *string)
|
|
{
|
|
char buffer3[1024];
|
|
|
|
if(client->id_str)
|
|
sprintf(buffer3, "\"%s\"", client->id_str);
|
|
else
|
|
sprintf(buffer3, "%d", client->id_int);
|
|
|
|
return socket_send(client->sock, "{\"id\":%s,\"result\":false,\"error\":[%d,\"%s\",null]}\n", buffer3, error, string);
|
|
}
|
|
|
|
int client_send_result(YAAMP_CLIENT *client, const char *format, ...)
|
|
{
|
|
char buffer[YAAMP_SMALLBUFSIZE];
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
vsprintf(buffer, format, args);
|
|
va_end(args);
|
|
|
|
char buffer3[1024];
|
|
|
|
if(client->id_str)
|
|
sprintf(buffer3, "\"%s\"", client->id_str);
|
|
else
|
|
sprintf(buffer3, "%d", client->id_int);
|
|
|
|
return socket_send(client->sock, "{\"id\":%s,\"result\":%s,\"error\":null}\n", buffer3, buffer);
|
|
}
|
|
|
|
int client_call(YAAMP_CLIENT *client, const char *method, const char *format, ...)
|
|
{
|
|
char buffer[YAAMP_SMALLBUFSIZE];
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
vsprintf(buffer, format, args);
|
|
va_end(args);
|
|
|
|
return socket_send(client->sock, "{\"id\":null,\"method\":\"%s\",\"params\":%s}\n", method, buffer);
|
|
}
|
|
|
|
int client_ask(YAAMP_CLIENT *client, const char *method, const char *format, ...)
|
|
{
|
|
char buffer[YAAMP_SMALLBUFSIZE];
|
|
va_list args;
|
|
int64_t id = client->shares;
|
|
|
|
va_start(args, format);
|
|
vsprintf(buffer, format, args);
|
|
va_end(args);
|
|
|
|
int ret = socket_send(client->sock, "{\"id\":%d,\"method\":\"%s\",\"params\":%s}\n", id, method, buffer);
|
|
if (ret == -1) {
|
|
debuglog("unable to ask %s\n", method);
|
|
return 0; // -errno
|
|
}
|
|
client->reqid = id;
|
|
return id;
|
|
}
|
|
|
|
void client_block_ip(YAAMP_CLIENT *client, const char *reason)
|
|
{
|
|
char buffer[1024];
|
|
|
|
sprintf(buffer, "iptables -A INPUT -s %s -p tcp --dport %d -j REJECT", client->sock->ip, g_tcp_port);
|
|
int s = system(buffer);
|
|
|
|
stratumlog("%s %s blocked (%s)\n", client->sock->ip, client->username, reason);
|
|
}
|
|
|
|
bool client_reset_multialgo(YAAMP_CLIENT *client, bool first)
|
|
{
|
|
// return false;
|
|
if(!client->algos_subscribed[0].algo) return false;
|
|
// debuglog("client_reset_multialgo\n");
|
|
|
|
YAAMP_CLIENT_ALGO *best = NULL;
|
|
YAAMP_CLIENT_ALGO *current = NULL;
|
|
|
|
for(int i=0; g_algos[i].name[0]; i++)
|
|
{
|
|
YAAMP_ALGO *algo = &g_algos[i];
|
|
for(int j=0; client->algos_subscribed[j].algo; j++)
|
|
{
|
|
YAAMP_CLIENT_ALGO *candidate = &client->algos_subscribed[j];
|
|
if(candidate->algo == algo)
|
|
{
|
|
if(!best || algo->profit*candidate->factor > best->algo->profit*best->factor)
|
|
best = candidate;
|
|
}
|
|
|
|
if(!current && candidate->algo == g_current_algo)
|
|
current = candidate;
|
|
}
|
|
}
|
|
|
|
if(!best || !current || best == current)
|
|
{
|
|
client->last_best = time(NULL);
|
|
return false;
|
|
}
|
|
|
|
if(!first)
|
|
{
|
|
int e = time(NULL) - client->last_best;
|
|
double d = best->algo->profit*best->factor - current->algo->profit*current->factor;
|
|
double p = d/best->algo->profit/best->factor;
|
|
#ifdef DEBUG_BEST_MULTI
|
|
debuglog("current %s %f\n", current->algo->name, current->algo->profit*current->factor);
|
|
debuglog("best %s %f\n", best->algo->name, best->algo->profit*best->factor);
|
|
debuglog(" %d * %f = %f --- percent %f %f\n", e, d, e*d, p, e*p);
|
|
#endif
|
|
if(p < 0.02) return false;
|
|
if(e*p < 100) return false;
|
|
}
|
|
|
|
shutdown(client->sock->sock, SHUT_RDWR);
|
|
return true;
|
|
}
|
|
|
|
bool client_initialize_multialgo(YAAMP_CLIENT *client)
|
|
{
|
|
char *p = strstr(client->password, "p=");
|
|
if(p)
|
|
{
|
|
double profit = atof(p+2);
|
|
if(profit > g_current_algo->profit)
|
|
return true;
|
|
}
|
|
|
|
char tmp[1024];
|
|
memset(tmp, 0, 1024);
|
|
strncpy(tmp, client->password, 1023);
|
|
|
|
p = tmp;
|
|
while(p)
|
|
{
|
|
double value = 0;
|
|
|
|
char *p1 = strchr(p, ',');
|
|
if(p1) *p1 = 0;
|
|
|
|
char *p2 = strchr(p, '=');
|
|
if(p2)
|
|
{
|
|
*p2 = 0;
|
|
value = atof(p2+1);
|
|
}
|
|
|
|
for(int i=0; g_algos[i].name[0]; i++)
|
|
{
|
|
YAAMP_ALGO *algo = &g_algos[i];
|
|
if(!strcmp(algo->name, p))
|
|
{
|
|
int i=0;
|
|
for(; i<YAAMP_MAXALGOS-1 && client->algos_subscribed[i].algo; i++);
|
|
|
|
client->algos_subscribed[i].algo = algo;
|
|
client->algos_subscribed[i].factor = value? value: algo->factor;
|
|
}
|
|
}
|
|
|
|
p = p1? p1+1: p1;
|
|
}
|
|
|
|
bool reset = client_reset_multialgo(client, true);
|
|
return reset;
|
|
}
|
|
|
|
void client_add_job_history(YAAMP_CLIENT *client, int jobid)
|
|
{
|
|
if(!jobid)
|
|
{
|
|
debuglog("trying to add jobid 0\n");
|
|
return;
|
|
}
|
|
|
|
bool b = client_find_job_history(client, jobid, 0);
|
|
if(b)
|
|
{
|
|
// debuglog("ERROR history already added job %x\n", jobid);
|
|
return;
|
|
}
|
|
|
|
for(int i=YAAMP_JOB_MAXHISTORY-1; i>0; i--)
|
|
client->job_history[i] = client->job_history[i-1];
|
|
|
|
client->job_history[0] = jobid;
|
|
}
|
|
|
|
bool client_find_job_history(YAAMP_CLIENT *client, int jobid, int startat)
|
|
{
|
|
for(int i=startat; i<YAAMP_JOB_MAXHISTORY; i++)
|
|
{
|
|
if(client->job_history[i] == jobid)
|
|
{
|
|
// if(!startat)
|
|
// debuglog("job %x already sent, index %d\n", jobid, i);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int hostname_to_ip(const char *hostname , char* ip)
|
|
{
|
|
struct hostent *he;
|
|
struct in_addr **addr_list;
|
|
int i;
|
|
|
|
if(hostname[0]>='0' && hostname[0]<='9')
|
|
{
|
|
strcpy(ip, hostname);
|
|
return 0;
|
|
}
|
|
|
|
if ( (he = gethostbyname( hostname ) ) == NULL)
|
|
{
|
|
// get the host info
|
|
herror("gethostbyname");
|
|
return 1;
|
|
}
|
|
|
|
addr_list = (struct in_addr **) he->h_addr_list;
|
|
|
|
for(i = 0; addr_list[i] != NULL; i++)
|
|
{
|
|
//Return the first one;
|
|
strcpy(ip, inet_ntoa(*addr_list[i]));
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
bool client_find_my_ip(const char *name)
|
|
{
|
|
// return false;
|
|
char ip[1024] = "";
|
|
|
|
hostname_to_ip(name, ip);
|
|
if(!ip[0]) return false;
|
|
|
|
char host[NI_MAXHOST];
|
|
for(struct ifaddrs *ifa = g_ifaddr; ifa != NULL; ifa = ifa->ifa_next)
|
|
{
|
|
if(ifa->ifa_addr == NULL) continue;
|
|
host[0] = 0;
|
|
|
|
getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
|
|
if(!host[0]) continue;
|
|
|
|
if(!strcmp(host, ip))
|
|
{
|
|
debuglog("found my ip %s\n", ip);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|