void db_update_renters(YAAMP_DB *db) { db_query(db, "select id, balance, updated from renters"); MYSQL_RES *result = mysql_store_result(&db->mysql); if(!result) yaamp_error("Cant query database"); MYSQL_ROW row; g_list_renter.Enter(); while((row = mysql_fetch_row(result)) != NULL) { if(!row[0] || !row[1]) continue; YAAMP_RENTER *renter = (YAAMP_RENTER *)object_find(&g_list_renter, atoi(row[0])); if(!renter) { renter = new YAAMP_RENTER; memset(renter, 0, sizeof(YAAMP_RENTER)); renter->id = atoi(row[0]); g_list_renter.AddTail(renter); } if(row[1]) renter->balance = atof(row[1]); if(row[2]) renter->updated = atoi(row[2]); } mysql_free_result(result); g_list_renter.Leave(); }
// Check whether or not we have enough space for another object. // If we have enough space, allocate backing memory, add object to namespace. // allocates space for an object, points *object at it int object_new(uint8_t id, objtype_t type, uint32_t number, char *string) { int ret = SUCCESS; object_t *object = NULL; if (SUCCESS != (ret = allocate(SZ_PAGE, FALSE, (void **)&object))) { #ifdef DEBUG fprintf(stderr, "[E] object_new | allocate() failed\n"); #endif goto bail; } // Reject duplicate IDs // This appears to be in agreement with machine.py design. if (NULL != object_find(id)) { #ifdef DEBUG fprintf(stderr, "[D] object_new | dupe ID; silently rejecting\n", id); #endif goto bail; } // Initialize the object object->id = id; object->type = TYPE_UNKNOWN; object->number = NULL; object->string = NULL; // If the object type is known (specified as part of construction), // then fill in appropriate values. Type is trusted here; we check type // and NUMBER -> STRING promotion in calling functions. if (TYPE_NUMBER == type) { object->type = TYPE_NUMBER; object->number = (uint32_t *)(object + OFF_NUMBER); *(object->number) = number; } else if (TYPE_STRING == type) { object->type = TYPE_STRING; object->string = (char *)(object + OFF_STRING); // If a VAL isn't specified, don't try to copy from NULL. if (NULL != string) { strncpy(object->string, string, MAX_SZ_STRING); } } else { #ifdef DEBUG fprintf(stderr, "[E] object_new | TYPE INVALID (shouldn't happen)\n", id); #endif ret = ERRNO_MALFORMED_JSON; goto bail; } // Add the object to the namespace. ns.obj[id] = object; bail: return ret; }
/** * Blit face from inventory located by tag. * @param tag Item tag to locate * @param x X position to blit the item * @param y Y position to blit the item */ void blt_inventory_face_from_tag(int tag, int x, int y) { object *tmp; /* Check item is in inventory and faces are loaded, etc */ tmp = object_find(tag); if (!tmp) return; blt_inv_item_centered(tmp, x, y); }
OBJECT *object_initialize(char *name, char *classIn, int size) { OBJECT *object_short, *object_long; object_long = (OBJECT*) malloc(size); object_short = object_find(name, classIn); object_long->name = object_short->name; object_long->_class = object_short->_class; object_long->value = object_short->value; object_long->valueptr = &object_short->value; object_short->valueptr = &object_long->value; if (miobject <= niobject) { miobject += 100; object_list = (OBJECT**) realloc(object_list, miobject*sizeof(OBJECT *)); } object_list[niobject] = object_long; niobject++; return object_long; }
bool client_submit(YAAMP_CLIENT *client, json_value *json_params) { // submit(worker_name, jobid, extranonce2, ntime, nonce): if(json_params->u.array.length<5) { debuglog("%s - %s bad message\n", client->username, client->sock->ip); client->submit_bad++; return false; } // char name[1024]; char extranonce2[32]; char ntime[32]; char nonce[32]; memset(extranonce2, 0, 32); memset(ntime, 0, 32); memset(nonce, 0, 32); int jobid = htoi(json_params->u.array.values[1]->u.string.ptr); strncpy(extranonce2, json_params->u.array.values[2]->u.string.ptr, 31); strncpy(ntime, json_params->u.array.values[3]->u.string.ptr, 31); strncpy(nonce, json_params->u.array.values[4]->u.string.ptr, 31); // debuglog("submit %s %d, %s, %s, %s\n", client->sock->ip, jobid, extranonce2, ntime, nonce); string_lower(extranonce2); string_lower(ntime); string_lower(nonce); YAAMP_JOB *job = (YAAMP_JOB *)object_find(&g_list_job, jobid, true); if(!job) { client_submit_error(client, NULL, 21, "Invalid job id", extranonce2, ntime, nonce); return true; } if(job->deleted) { client_send_result(client, "true"); object_unlock(job); return true; } YAAMP_JOB_TEMPLATE *templ = job->templ; // dump_submit_debug(client, job, extranonce2, ntime, nonce); if(strlen(nonce) != YAAMP_NONCE_SIZE*2) { client_submit_error(client, job, 20, "Invalid nonce size", extranonce2, ntime, nonce); return true; } // if(strcmp(ntime, templ->ntime)) // { // client_submit_error(client, job, 23, "Invalid time rolling", extranonce2, ntime, nonce); // return true; // } YAAMP_SHARE *share = share_find(job->id, extranonce2, ntime, nonce, client->extranonce1); if(share) { client_submit_error(client, job, 22, "Duplicate share", extranonce2, ntime, nonce); return true; } if(strlen(extranonce2) != client->extranonce2size*2) { client_submit_error(client, job, 24, "Invalid extranonce2 size", extranonce2, ntime, nonce); return true; } /////////////////////////////////////////////////////////////////////////////////////////// YAAMP_JOB_VALUES submitvalues; memset(&submitvalues, 0, sizeof(submitvalues)); build_submit_values(&submitvalues, templ, client->extranonce1, extranonce2, ntime, nonce); if(submitvalues.hash_bin[30] || submitvalues.hash_bin[31]) { client_submit_error(client, job, 25, "Invalid share", extranonce2, ntime, nonce); return true; } uint64_t hash_int = get_hash_difficulty(submitvalues.hash_bin); uint64_t user_target = diff_to_target(client->difficulty_actual); uint64_t coin_target = decode_compact(templ->nbits); // debuglog("%016llx actual\n", hash_int); // debuglog("%016llx target\n", user_target); // debuglog("%016llx coin\n", coin_target); if(hash_int > user_target && hash_int > coin_target) { client_submit_error(client, job, 26, "Low difficulty share", extranonce2, ntime, nonce); return true; } if(job->coind) client_do_submit(client, job, &submitvalues, extranonce2, ntime, nonce); else remote_submit(client, job, &submitvalues, extranonce2, ntime, nonce); client_send_result(client, "true"); client_record_difficulty(client); client->submit_bad = 0; share_add(client, job, true, extranonce2, ntime, nonce, 0); object_unlock(job); return true; }
void db_update_remotes(YAAMP_DB *db) { db_query(db, "select id, speed/1000000, host, port, username, password, time, price, renterid from jobs where active and ready and algo='%s' order by time", g_stratum_algo); MYSQL_RES *result = mysql_store_result(&db->mysql); if(!result) yaamp_error("Cant query database"); MYSQL_ROW row; g_list_remote.Enter(); while((row = mysql_fetch_row(result)) != NULL) { if(!row[0] || !row[1] || !row[2] || !row[3] || !row[4] || !row[5] || !row[6] || !row[7]) continue; bool newremote = false; YAAMP_REMOTE *remote = (YAAMP_REMOTE *)object_find(&g_list_remote, atoi(row[0])); if(!remote) { remote = new YAAMP_REMOTE; memset(remote, 0, sizeof(YAAMP_REMOTE)); remote->id = atoi(row[0]); newremote = true; } // else if(remote->reset_balance) // continue; else if(row[6] && atoi(row[6]) > remote->updated) remote->status = YAAMP_REMOTE_RESET; remote->speed = atof(row[1]); strcpy(remote->host, row[2]); remote->port = atoi(row[3]); strcpy(remote->username, row[4]); strcpy(remote->password, row[5]); remote->updated = atoi(row[6]); remote->price = atof(row[7]); remote->touch = true; remote->submit_last = NULL; int renterid = row[8]? atoi(row[8]): 0; if(renterid && !remote->renter) remote->renter = (YAAMP_RENTER *)object_find(&g_list_renter, renterid); if(newremote) { if(remote->renter && remote->renter->balance <= 0.00001000) { debuglog("dont load that job %d\n", remote->id); delete remote; continue; } pthread_t thread; pthread_create(&thread, NULL, remote_thread, remote); pthread_detach(thread); g_list_remote.AddTail(remote); usleep(100*YAAMP_MS); } if(remote->renter) { if(!strcmp(g_current_algo->name, "sha256")) remote->speed = min(remote->speed, max(remote->renter->balance/g_current_algo->rent*100000000, 1)); else remote->speed = min(remote->speed, max(remote->renter->balance/g_current_algo->rent*100000, 1)); } } mysql_free_result(result); /////////////////////////////////////////////////////////////////////////////////////////// for(CLI li = g_list_remote.first; li; li = li->next) { YAAMP_REMOTE *remote = (YAAMP_REMOTE *)li->data; // if(remote->reset_balance && remote->renter) // { // db_query(db, "update renters set balance=0 where id=%d", remote->renter->id); // db_query(db, "update jobs set ready=false, active=false where renterid=%d", remote->renter->id); // // remote->reset_balance = false; // } if(remote->deleted) continue; if(remote->kill) { debuglog("******* kill that sucka %s\n", remote->host); pthread_cancel(remote->thread); object_delete(remote); continue; } if(remote->sock && remote->sock->last_read && remote->sock->last_read+120<time(NULL)) { debuglog("****** timeout %s\n", remote->host); remote->status = YAAMP_REMOTE_TERMINATE; remote->kill = true; remote_close(remote); continue; } if(!remote->touch) { remote->status = YAAMP_REMOTE_TERMINATE; continue; } remote->touch = false; if(remote->difficulty_written != remote->difficulty_actual) { remote->difficulty_written = remote->difficulty_actual; db_query(db, "update jobs set difficulty=%f where id=%d", remote->difficulty_actual, remote->id); } } // remote_sort(); g_list_remote.Leave(); }
void db_update_coinds(YAAMP_DB *db) { for(CLI li = g_list_coind.first; li; li = li->next) { YAAMP_COIND *coind = (YAAMP_COIND *)li->data; if(coind->deleted) continue; if(coind->auto_ready) continue; debuglog("disabling %s\n", coind->symbol); db_query(db, "update coins set auto_ready=%d where id=%d", coind->auto_ready, coind->id); } //////////////////////////////////////////////////////////////////////////////////////// db_query(db, "select id, name, rpchost, rpcport, rpcuser, rpcpasswd, rpcencoding, master_wallet, reward, price, "\ "hassubmitblock, txmessage, enable, auto_ready, algo, pool_ttf, charity_address, charity_amount, charity_percent, "\ "reward_mul, symbol, auxpow, actual_ttf, network_ttf, usememorypool "\ "from coins where enable and auto_ready and algo='%s' order by index_avg", g_stratum_algo); MYSQL_RES *result = mysql_store_result(&db->mysql); if(!result) yaamp_error("Cant query database"); MYSQL_ROW row; g_list_coind.Enter(); while((row = mysql_fetch_row(result)) != NULL) { YAAMP_COIND *coind = (YAAMP_COIND *)object_find(&g_list_coind, atoi(row[0])); if(!coind) { coind = new YAAMP_COIND; memset(coind, 0, sizeof(YAAMP_COIND)); coind->newcoind = true; coind->newblock = true; coind->id = atoi(row[0]); coind->aux.coind = coind; } else coind->newcoind = false; strcpy(coind->name, row[1]); if(row[7]) strcpy(coind->wallet, row[7]); if(row[6]) coind->pos = strcmp(row[6], "POS")? false: true; if(row[10]) coind->hassubmitblock = atoi(row[10]); if(row[2]) strcpy(coind->rpc.host, row[2]); if(row[3]) coind->rpc.port = atoi(row[3]); if(row[4] && row[5]) { char buffer[1024]; sprintf(buffer, "%s:%s", row[4], row[5]); base64_encode(coind->rpc.credential, buffer); coind->rpc.coind = coind; } if(row[8]) coind->reward = atof(row[8]); if(row[9]) coind->price = atof(row[9]); if(row[11]) coind->txmessage = atoi(row[11]); if(row[12]) coind->enable = atoi(row[12]); if(row[13]) coind->auto_ready = atoi(row[13]); if(row[15]) coind->pool_ttf = atoi(row[15]); if(row[16]) strcpy(coind->charity_address, row[16]); if(row[17]) coind->charity_amount = atof(row[17]); if(row[18]) coind->charity_percent = atof(row[18]); if(row[19]) coind->reward_mul = atof(row[19]); strcpy(coind->symbol, row[20]); if(row[21]) coind->isaux = atoi(row[21]); if(row[22] && row[23]) coind->actual_ttf = min(atoi(row[22]), atoi(row[23])); else if(row[22]) coind->actual_ttf = atoi(row[22]); coind->actual_ttf = min(coind->actual_ttf, 120); coind->actual_ttf = max(coind->actual_ttf, 20); if(row[24]) coind->usememorypool = atoi(row[24]); //////////////////////////////////////////////////////////////////////////////////////////////////// coind->touch = true; if(coind->newcoind) { debuglog("connecting to coind %s\n", coind->symbol); bool b = rpc_connect(&coind->rpc); coind_init(coind); g_list_coind.AddTail(coind); usleep(100*YAAMP_MS); } coind_create_job(coind); } mysql_free_result(result); for(CLI li = g_list_coind.first; li; li = li->next) { YAAMP_COIND *coind = (YAAMP_COIND *)li->data; if(coind->deleted) continue; if(!coind->touch) { debuglog("remove coind %s\n", coind->name); rpc_close(&coind->rpc); object_delete(coind); continue; } coind->touch = false; } coind_sort(); g_list_coind.Leave(); }
// Format: // SET <id> [<val>] int op_set(char **cursor, uint16_t *line_remaining) { int ret = SUCCESS; uint8_t id = 0; object_t *object = NULL; char *bak_cursor = NULL; uint16_t bak_line_remaining = 0; //// // Get ID //// if (SUCCESS != (ret = parse_id(cursor, line_remaining, &id))) { #ifdef DEBUG fprintf(stderr, "[E] op_set | non-SUCCESS from parse_id()\n"); #endif goto bail; } // If ID doesn't exist, bail. if (NULL == (object = object_find(id))) { #ifdef DEBUG fprintf(stderr, "[D] op_set | could not find object; skipping assignment\n"); #endif #ifdef DEBUG fprintf(stderr, "[D] op_set | DEBUG: prior to advancement: *cursor: '%s', *line_remaining: %d\n", *cursor, *line_remaining); #endif // NOTE: minus one because we don't want to skip the \n *cursor += (*line_remaining - 1); *line_remaining = 0; #ifdef DEBUG fprintf(stderr, "[D] op_set | DEBUG: after advancement: *cursor: '%s', *line_remaining: %d\n", *cursor, *line_remaining); #endif goto bail; } //// // Get VAL (based on TYPE) //// if (TYPE_NUMBER == object->type) { // If promotion happens, we will attempt to parse bytes as NUMBER, // which we'll need to re-parse as a STRING. So we store the // before-parse values here and restore them should we need to re-parse. bak_cursor = *cursor; bak_line_remaining = *line_remaining; ret = parse_number(cursor, line_remaining, object->number); if (SUCCESS == ret) { #ifdef DEBUG fprintf(stderr, "[D] op_set | number update: %03d = %d\n", object->id, object->number); #endif } else if (ERRNO_NUMBER_TOO_LARGE == ret) { // Supress the "error" & conduct promotion. ret = SUCCESS; // Vulnerable promotion does not result in updating of type. #ifdef PATCHED object->type = TYPE_STRING; object->string = (char *)(object + OFF_STRING); #endif // We're now a string; set the number ptr to NULL. object->number = NULL; // The string pointer is set to the promoted string value. // Reset cursor and line_remaining and re-parse. *cursor = bak_cursor; *line_remaining = bak_line_remaining; if (SUCCESS != (ret = parse_string(cursor, line_remaining, object->string))) { #ifdef DEBUG fprintf(stderr, "[E] op_set | something bad happened in parse_string()\n", object->id, object->string); #endif goto bail; } #ifdef DEBUG fprintf(stderr, "[D] op_set | number->string promotion: %03d = %s\n", object->id, object->string); #endif } else { #ifdef DEBUG fprintf(stderr, "[E] op_set | parse_number returned error\n"); #endif goto bail; } } else if (TYPE_STRING == object->type) { if (SUCCESS != (ret = parse_string(cursor, line_remaining, object->string))) { #ifdef DEBUG fprintf(stderr, "[E] op_set | something bad happened in parse_string()\n", object->id, object->string); #endif goto bail; } } else { #ifdef DEBUG fprintf(stderr, "[E] op_new | INVALID TYPE (SHOULDN'T HAPPEN)\n"); #endif } bail: return ret; }
// // Iterate the list of objects, and send them to the user. // void command_who(object_t *node) { object_find(command_who_sub, (void *)node, NULL); }