Browse Source

ckdb - store shares with unknown usernames

master
kanoi 8 years ago
parent
commit
762f8ffad3
  1. 12
      src/ckdb.h
  2. 7
      src/ckdb_cmd.c
  3. 91
      src/ckdb_dbio.c

12
src/ckdb.h

@ -58,7 +58,7 @@
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "1.0.7" #define DB_VERSION "1.0.7"
#define CKDB_VERSION DB_VERSION"-2.510" #define CKDB_VERSION DB_VERSION"-2.511"
#define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__ #define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -1844,6 +1844,9 @@ typedef struct users {
// Address account, not a username account // Address account, not a username account
#define USER_ADDRESS 0x1 #define USER_ADDRESS 0x1
// Username created due to a share that had an unknown username
#define USER_MISSING 0x2
// 16 x base 32 (5 bits) = 10 bytes (8 bits) // 16 x base 32 (5 bits) = 10 bytes (8 bits)
#define TOTPAUTH_KEYSIZE 10 #define TOTPAUTH_KEYSIZE 10
#define TOTPAUTH_DSP_KEYSIZE 16 #define TOTPAUTH_DSP_KEYSIZE 16
@ -3652,11 +3655,14 @@ extern bool users_update(PGconn *conn, K_ITEM *u_item, char *oldhash,
int *event); int *event);
extern K_ITEM *users_add(PGconn *conn, INTRANSIENT *in_username, extern K_ITEM *users_add(PGconn *conn, INTRANSIENT *in_username,
char *emailaddress, char *passwordhash, char *emailaddress, char *passwordhash,
int64_t userbits, char *by, char *code, char *inet, char *secondaryuserid, int64_t userbits, char *by,
tv_t *cd, K_TREE *trf_root); char *code, char *inet, tv_t *cd, K_TREE *trf_root);
extern bool users_replace(PGconn *conn, K_ITEM *u_item, K_ITEM *old_u_item, extern bool users_replace(PGconn *conn, K_ITEM *u_item, K_ITEM *old_u_item,
char *by, char *code, char *inet, tv_t *cd, char *by, char *code, char *inet, tv_t *cd,
K_TREE *trf_root); K_TREE *trf_root);
extern K_ITEM *create_missing_user(PGconn *conn, char *username,
char *secondaryuserid, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root);
extern bool users_fill(PGconn *conn); extern bool users_fill(PGconn *conn);
extern bool useratts_item_add(PGconn *conn, K_ITEM *ua_item, tv_t *cd, extern bool useratts_item_add(PGconn *conn, K_ITEM *ua_item, tv_t *cd,
bool begun); bool begun);

7
src/ckdb_cmd.c

@ -72,8 +72,9 @@ static char *cmd_adduser(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
if (event == EVENT_OK) { if (event == EVENT_OK) {
u_item = users_add(conn, in_username, u_item = users_add(conn, in_username,
transfer_data(i_emailaddress), transfer_data(i_emailaddress),
transfer_data(i_passwordhash), 0, transfer_data(i_passwordhash),
by, code, inet, now, trf_root); NULL, 0, by, code, inet, now,
trf_root);
} }
} }
@ -3116,7 +3117,7 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
DATA_OPTIONCONTROL(optioncontrol, oc_item); DATA_OPTIONCONTROL(optioncontrol, oc_item);
u_item = users_add(conn, in_username, EMPTY, u_item = users_add(conn, in_username, EMPTY,
optioncontrol->optionvalue, optioncontrol->optionvalue,
0, by, code, inet, cd, NULL, 0, by, code, inet, cd,
trf_root); trf_root);
} else } else
ok = false; ok = false;

91
src/ckdb_dbio.c

@ -706,8 +706,9 @@ unparam:
} }
K_ITEM *users_add(PGconn *conn, INTRANSIENT *in_username, char *emailaddress, K_ITEM *users_add(PGconn *conn, INTRANSIENT *in_username, char *emailaddress,
char *passwordhash, int64_t userbits, char *by, char *passwordhash, char *secondaryuserid,
char *code, char *inet, tv_t *cd, K_TREE *trf_root) int64_t userbits, char *by, char *code, char *inet,
tv_t *cd, K_TREE *trf_root)
{ {
ExecStatusType rescode; ExecStatusType rescode;
bool conned = false; bool conned = false;
@ -771,9 +772,14 @@ K_ITEM *users_add(PGconn *conn, INTRANSIENT *in_username, char *emailaddress,
row->status[0] = '\0'; row->status[0] = '\0';
STRNCPY(row->emailaddress, emailaddress); STRNCPY(row->emailaddress, emailaddress);
snprintf(tohash, sizeof(tohash), "%s&#%s", in_username->str, emailaddress); if (secondaryuserid == NULL) {
HASH_BER(tohash, strlen(tohash), 1, hash, tmp); snprintf(tohash, sizeof(tohash), "%s&#%s",
__bin2hex(row->secondaryuserid, (void *)(&hash), sizeof(hash)); in_username->str,
emailaddress);
HASH_BER(tohash, strlen(tohash), 1, hash, tmp);
__bin2hex(row->secondaryuserid, (void *)(&hash), sizeof(hash));
} else
STRNCPY(row->secondaryuserid, secondaryuserid);
make_salt(row); make_salt(row);
if (passwordhash == EMPTY) { if (passwordhash == EMPTY) {
@ -969,6 +975,27 @@ unparam:
return ok; return ok;
} }
/* If a share contains an unknown username then it will most likely be from
* reloading a data file when the users table is incomplete or corrupt
* Since the share is valid, it should be counted against the pool stats and
* creating a user also means the payout rewards are calculated correctly
* This also gives 2 options to resolve it later:
* 1) Correct the database/redistribute the rewards to the correct user
* 2) Rollback the database and reload it with a corrected users table
* Option 1) gives a simpler solution vs option 2) if 2) is too far in
* the past to easily do a reload */
K_ITEM *create_missing_user(PGconn *conn, char *username, char *secondaryuserid,
char *by, char *code, char *inet, tv_t *cd,
K_TREE *trf_root)
{
INTRANSIENT *in_username;
in_username = get_intransient("username", username);
return users_add(conn, in_username, EMPTY, EMPTY, secondaryuserid,
USER_MISSING, by, code, inet, cd, trf_root);
}
bool users_fill(PGconn *conn) bool users_fill(PGconn *conn)
{ {
ExecStatusType rescode; ExecStatusType rescode;
@ -3656,10 +3683,11 @@ static bool shares_process(PGconn *conn, SHARES *shares, K_ITEM *wi_item,
shares->createcode, shares->createinet, shares->createcode, shares->createinet,
&(shares->createdate), trf_root); &(shares->createdate), trf_root);
if (!w_item) { if (!w_item) {
LOGDEBUG("%s(): new_default_worker failed %"PRId64"/%s/%ld,%ld", LOGERR("%s(): ERR new_default_worker failed"
__func__, shares->userid, " %"PRId64"/%s/%ld,%ld",
st = safe_text_nonull(shares->in_workername), __func__, shares->userid,
shares->createdate.tv_sec, shares->createdate.tv_usec); st = safe_text_nonull(shares->in_workername),
shares->createdate.tv_sec, shares->createdate.tv_usec);
FREENULL(st); FREENULL(st);
return false; return false;
} }
@ -3671,12 +3699,12 @@ static bool shares_process(PGconn *conn, SHARES *shares, K_ITEM *wi_item,
MARKER_PROCESSED, NULL); MARKER_PROCESSED, NULL);
K_RUNLOCK(workmarkers_free); K_RUNLOCK(workmarkers_free);
if (wm_item) { if (wm_item) {
LOGDEBUG("%s(): workmarker exists for wid %"PRId64 LOGERR("%s(): ERR workmarker exists for wid %"PRId64
" %"PRId64"/%s/%ld,%ld", " %"PRId64"/%s/%ld,%ld",
__func__, shares->workinfoid, shares->userid, __func__, shares->workinfoid, shares->userid,
st = safe_text_nonull(shares->in_workername), st = safe_text_nonull(shares->in_workername),
shares->createdate.tv_sec, shares->createdate.tv_sec,
shares->createdate.tv_usec); shares->createdate.tv_usec);
FREENULL(st); FREENULL(st);
return false; return false;
} }
@ -3875,18 +3903,31 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username,
K_RLOCK(users_free); K_RLOCK(users_free);
u_item = find_users(username); u_item = find_users(username);
K_RUNLOCK(users_free); K_RUNLOCK(users_free);
/* Can't change outside lock since we don't delete users /* Won't change outside lock since we don't delete users
* or change their *userid */ * or change their *userid */
if (!u_item) { if (!u_item) {
btv_to_buf(cd, cd_buf, sizeof(cd_buf));
/* This should never happen unless there's a bug in ckpool /* This should never happen unless there's a bug in ckpool
or the authentication information got to ckdb after or the authentication information got to ckdb after
the shares ... which shouldn't ever happen */ the shares or the users table is missing data ...
LOGERR("%s() %s/%ld,%ld %s no user! Share discarded!", which shouldn't ever happen
__func__, st = safe_text_nonull(username), However, since it's a valid share, store it */
cd->tv_sec, cd->tv_usec, cd_buf); u_item = create_missing_user(conn, username, secondaryuserid,
FREENULL(st); by, code, inet, cd, trf_root);
goto tisbad; btv_to_buf(cd, cd_buf, sizeof(cd_buf));
if (!u_item) {
LOGERR("%s() ERR %s/%ld,%ld %s no/failed user! Share"
" discarded!",
__func__, st = safe_text_nonull(username),
cd->tv_sec, cd->tv_usec, cd_buf);
FREENULL(st);
goto tisbad;
} else {
DATA_USERS(users, u_item);
LOGERR("%s() MISSING %s/%ld,%ld %s created",
__func__, st = safe_text_nonull(username),
cd->tv_sec, cd->tv_usec, cd_buf);
FREENULL(st);
}
} }
DATA_USERS(users, u_item); DATA_USERS(users, u_item);
shares->userid = users->userid; shares->userid = users->userid;
@ -7818,8 +7859,8 @@ bool auths_add(PGconn *conn, INTRANSIENT *in_poolinstance,
if (!u_item) { if (!u_item) {
if (addressuser) { if (addressuser) {
u_item = users_add(conn, in_username, EMPTY, EMPTY, u_item = users_add(conn, in_username, EMPTY, EMPTY,
USER_ADDRESS, by, code, inet, cd, NULL, USER_ADDRESS, by, code, inet,
trf_root); cd, trf_root);
} else { } else {
LOGDEBUG("%s(): unknown user '%s'", LOGDEBUG("%s(): unknown user '%s'",
__func__, __func__,

Loading…
Cancel
Save