From db2efc310d112617b2595c76df7263ca6c89ff4a Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Tue, 21 Jul 2015 12:41:11 +0200 Subject: [PATCH] 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 --- stratum/Makefile | 7 ++++- stratum/client.cpp | 47 +++++++++++++++++++++++++++++++ stratum/coind.cpp | 26 +++++++++++++++++ stratum/coind.h | 1 + stratum/db.h | 3 +- stratum/job.cpp | 16 +++++++++-- stratum/user.cpp | 7 +++-- web/yaamp/core/backend/blocks.php | 8 ++++-- 8 files changed, 107 insertions(+), 8 deletions(-) diff --git a/stratum/Makefile b/stratum/Makefile index 9a10bd6..9feadc2 100755 --- a/stratum/Makefile +++ b/stratum/Makefile @@ -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/ diff --git a/stratum/client.cpp b/stratum/client.cpp index 754a67c..ded6b60 100644 --- a/stratum/client.cpp +++ b/stratum/client.cpp @@ -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); diff --git a/stratum/coind.cpp b/stratum/coind.cpp index 09c4a0f..334c5d2 100644 --- a/stratum/coind.cpp +++ b/stratum/coind.cpp @@ -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; diff --git a/stratum/coind.h b/stratum/coind.h index 0a75437..9e3c6ef 100644 --- a/stratum/coind.h +++ b/stratum/coind.h @@ -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); diff --git a/stratum/db.h b/stratum/db.h index 60bbdd8..c64e4be 100644 --- a/stratum/db.h +++ b/stratum/db.h @@ -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); - diff --git a/stratum/job.cpp b/stratum/job.cpp index 264ecc4..05b6e9b 100644 --- a/stratum/job.cpp +++ b/stratum/job.cpp @@ -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; } diff --git a/stratum/user.cpp b/stratum/user.cpp index 9c3deeb..a58e611 100644 --- a/stratum/user.cpp +++ b/stratum/user.cpp @@ -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); +} diff --git a/web/yaamp/core/backend/blocks.php b/web/yaamp/core/backend/blocks.php index e963c7e..5b35c4c 100644 --- a/web/yaamp/core/backend/blocks.php +++ b/web/yaamp/core/backend/blocks.php @@ -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)