diff --git a/src/ckdb.h b/src/ckdb.h index eb86cebc..1beaf0eb 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -52,7 +52,7 @@ #define DB_VLOCK "1" #define DB_VERSION "0.9.6" -#define CKDB_VERSION DB_VERSION"-0.743" +#define CKDB_VERSION DB_VERSION"-0.744" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -1562,6 +1562,7 @@ extern void dsp_paymentaddresses(K_ITEM *item, FILE *stream); extern cmp_t cmp_paymentaddresses(K_ITEM *a, K_ITEM *b); extern K_ITEM *find_paymentaddresses(int64_t userid, K_TREE_CTX *ctx); extern K_ITEM *find_one_payaddress(int64_t userid, char *payaddress, K_TREE_CTX *ctx); +extern K_ITEM *find_any_payaddress(char *payaddress); extern cmp_t cmp_payments(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_optioncontrol(K_ITEM *a, K_ITEM *b); extern K_ITEM *find_optioncontrol(char *optionname, tv_t *now); diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index cb02768a..369d7a73 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -162,12 +162,12 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id, __maybe_unused tv_t *notcd, K_TREE *trf_root) { K_ITEM *i_username, *i_passwordhash, *i_rows, *i_address, *i_ratio; - K_ITEM *i_email, *u_item, *pa_item; + K_ITEM *i_email, *u_item, *pa_item, *old_pa_item; char *email, *address; char reply[1024] = ""; size_t siz = sizeof(reply); char tmp[1024]; - PAYMENTADDRESSES *row; + PAYMENTADDRESSES *row, *pa; K_STORE *pa_store = NULL; K_TREE_CTX ctx[1]; USERS *users; @@ -337,7 +337,18 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id, pa_item = pa_store->head; while (pa_item) { DATA_PAYMENTADDRESSES(row, pa_item); - if (!btc_valid_address(row->payaddress)) { + // Only EVER validate addresses once ... for now + old_pa_item = find_any_payaddress(row->payaddress); + if (old_pa_item) { + /* This test effectively means that + * two users can never add the same + * payout address */ + DATA_PAYMENTADDRESSES(pa, old_pa_item); + if (pa->userid != users->userid) { + reason = "Unavailable BTC address"; + goto struckout; + } + } else if (!btc_valid_address(row->payaddress)) { reason = "Invalid BTC address"; goto struckout; } diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 8c17cd35..5730261b 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -1164,6 +1164,28 @@ K_ITEM *find_one_payaddress(int64_t userid, char *payaddress, K_TREE_CTX *ctx) return find_in_ktree(paymentaddresses_root, &look, cmp_paymentaddresses, ctx); } +/* This will match any user that has the payaddress + * This avoids the bitcoind delay of rechecking an address + * that has EVER been seen before + * However, also, cmd_userset() that uses it, effectively ensures + * that 2 standard users, that mine to a username rather than + * a bitcoin address, cannot ever use the same bitcoin address */ +K_ITEM *find_any_payaddress(char *payaddress) +{ + PAYMENTADDRESSES *pa; + K_TREE_CTX ctx[1]; + K_ITEM *item; + + item = first_in_ktree(paymentaddresses_root, ctx); + DATA_PAYMENTADDRESSES_NULL(pa, item); + while (item) { + if (strcmp(pa->payaddress, payaddress) == 0) + return item; + item = next_in_ktree(ctx); + } + return NULL; +} + // order by userid asc,paydate asc,payaddress asc,expirydate desc cmp_t cmp_payments(K_ITEM *a, K_ITEM *b) {