bool coind_validate_address(YAAMP_COIND *coind) { if(!coind->wallet[0]) return false; char params[YAAMP_SMALLBUFSIZE]; sprintf(params, "[\"%s\"]", coind->wallet); 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 wallet %s is not valid.\n", coind->name, coind->wallet); bool ismine = json_get_bool(json_result, "ismine"); if(!ismine) stratumlog("%s wallet %s is not mine.\n", coind->name, coind->wallet); const char *p = json_get_string(json_result, "pubkey"); if(p) strcpy(coind->pubkey, p); json_value_free(json); base58_decode(coind->wallet, coind->script_pubkey); return isvalid && ismine; }
void db_query(YAAMP_DB *db, const char *format, ...) { va_list arglist; va_start(arglist, format); char *buffer = (char *)malloc(YAAMP_SMALLBUFSIZE+strlen(format)); if(!buffer) return; int len = vsprintf(buffer, format, arglist); va_end(arglist); while(1) { int res = mysql_query(&db->mysql, buffer); if(!res) break; res = mysql_errno(&db->mysql); stratumlog("SQL ERROR: %d, %s\n", res, mysql_error(&db->mysql)); if(res != CR_SERVER_GONE_ERROR && res != CR_SERVER_LOST) exit(1); db_reconnect(db); } free(buffer); }
bool coind_submitgetauxblock(YAAMP_COIND *coind, const char *hash, const char *block) { int paramlen = strlen(block); char *params = (char *)malloc(paramlen+1024); if(!params) return false; sprintf(params, "[\"%s\",\"%s\"]", hash, block); json_value *json = rpc_call(&coind->rpc, "getauxblock", params); free(params); if(!json) return false; json_value *json_error = json_get_object(json, "error"); if(json_error && json_error->type != json_null) { const char *p = json_get_string(json_error, "message"); if(p) stratumlog("ERROR %s %s\n", coind->name, p); // job_reset(); json_value_free(json); return false; } json_value *json_result = json_get_object(json, "result"); bool b = json_result && json_result->type == json_boolean && json_result->u.boolean; json_value_free(json); return b; }
void db_reconnect(YAAMP_DB *db) { mysql_init(&db->mysql); for(int i=0; i<6; i++) { MYSQL *p = mysql_real_connect(&db->mysql, g_sql_host, g_sql_username, g_sql_password, g_sql_database, 0, 0, 0); if(p) break; stratumlog("%d, %s\n", i, mysql_error(&db->mysql)); sleep(10); mysql_init(&db->mysql); } }
void coind_init(YAAMP_COIND *coind) { yaamp_create_mutex(&coind->mutex); bool valid = coind_validate_address(coind); if(valid) return; json_value *json = rpc_call(&coind->rpc, "getaccountaddress", "[\"\"]"); if(!json) { stratumlog("ERROR getaccountaddress %s\n", coind->name); return; } strcpy(coind->wallet, json->u.object.values[0].value->u.string.ptr); json_value_free(json); debuglog(">>>>>>>>>>>>>>>>>>>> using wallet %s\n", coind->wallet); coind_validate_address(coind); }
void coind_create_job(YAAMP_COIND *coind, bool force) { // debuglog("create job %s\n", coind->symbol); bool b = rpc_connected(&coind->rpc); if(!b) return; CommonLock(&coind->mutex); YAAMP_JOB_TEMPLATE *templ = coind_create_template(coind); if(!templ) { CommonUnlock(&coind->mutex); return; } YAAMP_JOB *job_last = coind->job; if( !force && job_last && job_last->templ && job_last->templ->created + 45 > time(NULL) && templ->height == job_last->templ->height && templ->txcount == job_last->templ->txcount && strcmp(templ->coinb2, job_last->templ->coinb2) == 0) { // debuglog("coind_create_job %s %d same template %x \n", coind->name, coind->height, coind->job->id); delete templ; CommonUnlock(&coind->mutex); return; } //////////////////////////////////////////////////////////////////////////////////////// int height = coind->height; coind->height = templ->height-1; if(height > coind->height) { stratumlog("%s went from %d to %d\n", coind->name, height, coind->height); // coind->auto_ready = false; } if(height < coind->height && !coind->newblock) { if(coind->auto_ready && coind->notreportingcounter++ > 5) stratumlog("%s %d not reporting\n", coind->name, coind->height); } uint64_t coin_target = decode_compact(templ->nbits); coind->difficulty = target_to_diff(coin_target); coind->newblock = false; //////////////////////////////////////////////////////////////////////////////////////// object_delete(coind->job); coind->job = new YAAMP_JOB; memset(coind->job, 0, sizeof(YAAMP_JOB)); sprintf(coind->job->name, "%s", coind->symbol); coind->job->id = job_get_jobid(); coind->job->templ = templ; coind->job->profit = coind_profitability(coind); coind->job->maxspeed = coind_nethash(coind) * (g_current_algo->profit? min(1.0, coind_profitability(coind)/g_current_algo->profit): 1); coind->job->coind = coind; coind->job->remote = NULL; g_list_job.AddTail(coind->job); CommonUnlock(&coind->mutex); // debuglog("coind_create_job %s %d new job %x\n", coind->name, coind->height, coind->job->id); }
json_value *socket_nextjson(YAAMP_SOCKET *s, YAAMP_CLIENT *client) { while(!strchr(s->buffer, '}') && s->buflen<YAAMP_SOCKET_BUFSIZE-1) { // pthread_mutex_unlock(&s->mutex); int len = recv(s->sock, s->buffer+s->buflen, YAAMP_SOCKET_BUFSIZE-s->buflen-1, 0); if(len <= 0) return NULL; s->last_read = time(NULL); s->total_read += len; s->buflen += len; s->buffer[s->buflen] = 0; // if(client && client->logtraffic) // stratumlog("recv: %s\n", s->buffer); // pthread_mutex_lock(&s->mutex); } char *p = strchr(s->buffer, '}'); if(!p) { if(client) clientlog(client, "bad json"); debuglog("%s\n", s->buffer); return NULL; } p++; char saved = *p; *p = 0; if(client && client->logtraffic) stratumlog("%s, %s, %s, %s, recv: %s\n", client->sock->ip, client->username, client->password, g_current_algo->name, s->buffer); int bytes = strlen(s->buffer); json_value *json = json_parse(s->buffer, bytes); if(!json) { if(client) clientlog(client, "bad json parse"); debuglog("%s\n", s->buffer); return NULL; } *p = saved; while(*p && *p != '{') p++; if(*p == '{') { memmove(s->buffer, p, s->buflen - (p - s->buffer)); s->buflen = s->buflen - (p - s->buffer); s->buffer[s->buflen] = 0; // if(client && client->logtraffic) // stratumlog("still: %s\n", s->buffer); } else { memset(s->buffer, 0, YAAMP_SOCKET_BUFSIZE); s->buflen = 0; } return json; }