stratum: only accept compatible addresses

add cflag to only allow compatible mining addresses

and set user coinid directly on connect,
Without that, there are wallet conflicts (CHC vs CTO)

assign the right coin job when exchange is disabled

backend: share only the mined coin
This commit is contained in:
Tanguy Pruvot 2015-07-21 12:41:11 +02:00
parent 3684958354
commit db2efc310d
8 changed files with 107 additions and 8 deletions

View file

@ -3,6 +3,10 @@ CC=gcc
CFLAGS=-c -g `mysql_config --cflags --libs` -march=native
# Comment this line to disable address check on login,
# if you use the auto exchange feature...
CFLAGS += -DNO_EXCHANGE
#CFLAGS += -DHASH_DEBUGLOG_
#CFLAGS += -DRPC_DEBUGLOG_
#CFLAGS += -DREMOTE_DEBUGLOG_
@ -54,7 +58,8 @@ clean:
rm -f sha3/*.o
rm -f sha3/*.a
install: all
install: clean all
strip -s stratum
cp stratum /usr/local/bin/
cp stratum ../bin/

View file

@ -113,6 +113,44 @@ bool client_subscribe(YAAMP_CLIENT *client, json_value *json_params)
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
bool client_validate_user_address(YAAMP_CLIENT *client)
{
if (!client->coinid) {
for(CLI li = g_list_coind.first; li; li = li->next) {
YAAMP_COIND *coind = (YAAMP_COIND *)li->data;
// debuglog("user %s testing on coin %s ...\n", client->username, coind->symbol);
if(!coind_can_mine(coind)) continue;
if(coind->pos) continue;
if(coind_validate_user_address(coind, client->username)) {
debuglog("new user %s for coin %s\n", client->username, coind->symbol);
client->coinid = coind->id;
// update the db now to prevent addresses conflicts
CommonLock(&g_db_mutex);
db_init_user_coinid(g_db, client);
CommonUnlock(&g_db_mutex);
return true;
}
}
}
if (!client->coinid) {
return false;
}
YAAMP_COIND *coind = (YAAMP_COIND *)object_find(&g_list_coind, client->coinid);
if(!coind) {
clientlog(client, "unable to find wallet for coinid %d...", client->coinid);
return false;
}
bool isvalid = coind_validate_user_address(coind, client->username);
if (isvalid) {
client->coinid = coind->id;
}
return isvalid;
}
///////////////////////////////////////////////////////////////////////////////////////////
bool client_authorize(YAAMP_CLIENT *client, json_value *json_params)
@ -158,6 +196,15 @@ bool client_authorize(YAAMP_CLIENT *client, json_value *json_params)
debuglog("new client %s, %s, %s\n", client->username, client->password, client->version);
#endif
#ifdef NO_EXCHANGE
// when auto exchange is disabled, only authorize good wallet address...
if (!client_validate_user_address(client)) {
clientlog(client, "bad mining address %s", client->username);
client_send_result(client, "false");
return false;
}
#endif
client_send_result(client, "true");
client_send_difficulty(client, client->difficulty_actual);

View file

@ -82,6 +82,32 @@ bool coind_can_mine(YAAMP_COIND *coind, bool isaux)
///////////////////////////////////////////////////////////////////////////////
bool coind_validate_user_address(YAAMP_COIND *coind, char* const address)
{
if(!address[0]) return false;
char params[YAAMP_SMALLBUFSIZE];
sprintf(params, "[\"%s\"]", address);
json_value *json = rpc_call(&coind->rpc, "validateaddress", params);
if(!json) return false;
json_value *json_result = json_get_object(json, "result");
if(!json_result) {
json_value_free(json);
return false;
}
bool isvalid = json_get_bool(json_result, "isvalid");
if(!isvalid) stratumlog("%s user address %s is not valid.\n", coind->name, address);
json_value_free(json);
return isvalid;
}
///////////////////////////////////////////////////////////////////////////////
bool coind_validate_address(YAAMP_COIND *coind)
{
if(!coind->wallet[0]) return false;

View file

@ -93,6 +93,7 @@ void coind_init(YAAMP_COIND *coind);
void coind_create_job(YAAMP_COIND *coind, bool force=false);
bool coind_validate_user_address(YAAMP_COIND *coind, char* const address);

View file

@ -27,6 +27,7 @@ void db_clear_worker(YAAMP_DB *db, YAAMP_CLIENT *client);
void db_update_worker(YAAMP_DB *db, YAAMP_CLIENT *client);
void db_update_workers(YAAMP_DB *db);
void db_init_user_coinid(YAAMP_DB *db, YAAMP_CLIENT *client);
void db_update_renters(YAAMP_DB *db);

View file

@ -10,7 +10,7 @@
return ret; \
}
bool job_assign_client(YAAMP_JOB *job, YAAMP_CLIENT *client, double maxhash)
static bool job_assign_client(YAAMP_JOB *job, YAAMP_CLIENT *client, double maxhash)
{
RETURN_ON_CONDITION(client->deleted, true);
RETURN_ON_CONDITION(client->jobid_next, true);
@ -18,6 +18,14 @@ bool job_assign_client(YAAMP_JOB *job, YAAMP_CLIENT *client, double maxhash)
RETURN_ON_CONDITION(client_find_job_history(client, job->id), true);
RETURN_ON_CONDITION(maxhash > 0 && job->speed + client->speed > maxhash, true);
#ifdef NO_EXCHANGE
if(maxhash >= 0. && client->coinid != job->coind->id) {
//debuglog("prevent client %c on %s, not the right coin\n",
// client->username[0], job->coind->symbol);
return false;
}
#endif
if(job->remote)
{
YAAMP_REMOTE *remote = job->remote;
@ -190,7 +198,11 @@ void job_assign_clients_left(double factor)
for(CLI li = g_list_client.first; li; li = li->next)
{
YAAMP_CLIENT *client = (YAAMP_CLIENT *)li->data;
#ifdef NO_EXCHANGE
debuglog("%s factor %f=>100 nethash %f\n", coind->symbol, factor, nethash);
if (client->coinid == coind->id)
factor = 100;
#endif
bool b = job_assign_client(coind->job, client, nethash*factor);
if(!b) break;
}

View file

@ -120,6 +120,9 @@ void db_update_workers(YAAMP_DB *db)
g_list_client.Leave();
}
void db_init_user_coinid(YAAMP_DB *db, YAAMP_CLIENT *client)
{
db_query(db, "UPDATE accounts SET coinid=%d WHERE id=%d AND IFNULL(coinid,0) = 0",
client->coinid, client->userid);
}

View file

@ -6,10 +6,14 @@ function BackendBlockNew($coin, $db_block)
$reward = $db_block->amount;
if(!$reward || $db_block->algo == 'PoS' || $db_block->algo == 'MN') return;
$total_hash_power = dboscalar("SELECT SUM(difficulty) FROM shares WHERE valid AND algo=:algo", array(':algo'=>$coin->algo));
$sqlCond = "valid = 1";
if(!YAAMP_ALLOW_EXCHANGE) // only one coin mined
$sqlCond .= " AND coinid = ".intval($coin->id);
$total_hash_power = dboscalar("SELECT SUM(difficulty) FROM shares WHERE $sqlCond AND algo=:algo", array(':algo'=>$coin->algo));
if(!$total_hash_power) return;
$list = dbolist("SELECT userid, SUM(difficulty) AS total FROM shares WHERE valid AND algo=:algo GROUP BY userid",
$list = dbolist("SELECT userid, SUM(difficulty) AS total FROM shares WHERE $sqlCond AND algo=:algo GROUP BY userid",
array(':algo'=>$coin->algo));
foreach($list as $item)