From 647971cde6637f95e2411cfb7150013ab5468c12 Mon Sep 17 00:00:00 2001 From: Jethro Grassie Date: Sun, 2 Jun 2019 21:14:44 -0400 Subject: [PATCH 1/4] add RandomX support --- Makefile | 3 +- src/pool.c | 102 ++++++++++++++++++++++++++++++++++++++++++++-------- src/xmr.cpp | 16 ++++++++- src/xmr.h | 5 ++- 4 files changed, 108 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 35810f4..76748ac 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,8 @@ MONERO_LIBS = \ ${MONERO_BUILD_ROOT}/src/ringct/libringct_basic.a \ ${MONERO_BUILD_ROOT}/src/device/libdevice.a \ ${MONERO_BUILD_ROOT}/contrib/epee/src/libepee.a \ - ${MONERO_BUILD_ROOT}/external/easylogging++/libeasylogging.a + ${MONERO_BUILD_ROOT}/external/easylogging++/libeasylogging.a \ + ${MONERO_BUILD_ROOT}/external/randomx/librandomx.a DIRS = src data rxi/log/src diff --git a/src/pool.c b/src/pool.c index 037c351..e9bf390 100644 --- a/src/pool.c +++ b/src/pool.c @@ -150,6 +150,8 @@ typedef struct block_template_t uint64_t height; char prev_hash[64]; uint32_t reserved_offset; + char seed_hash[64]; + char next_seed_hash[64]; } block_template_t; typedef struct job_t @@ -246,6 +248,9 @@ static FILE *fd_log; static unsigned char sec_view[32]; static unsigned char pub_spend[32]; +extern void rx_stop_mining(); +extern void rx_slow_hash_free_state(); + #define JSON_GET_OR_ERROR(name, parent, type, client) \ json_object *name = NULL; \ if (!json_object_object_get_ex(parent, #name, &name)) { \ @@ -857,12 +862,14 @@ stratum_get_proxy_job_body(char *body, const client_t *client, "\"difficulty\":%"PRIu64",\"height\":%"PRIu64"," "\"reserved_offset\":%u," "\"client_nonce_offset\":%u,\"client_pool_offset\":%u," - "\"target_diff\":%"PRIu64",\"target_diff_hex\":\"%s\"}," + "\"target_diff\":%"PRIu64",\"target_diff_hex\":\"%s\"," + "\"seed_hash\":\"%.64s\",\"next_seed_hash\":\"%.64s\"}," "\"status\":\"OK\"}}\n", json_id, client_id, block_hex, job_id, bt->difficulty, bt->height, bt->reserved_offset, bt->reserved_offset + 12, - bt->reserved_offset + 8, target, target_hex); + bt->reserved_offset + 8, target, target_hex, + bt->seed_hash, bt->next_seed_hash); } else { @@ -873,11 +880,13 @@ stratum_get_proxy_job_body(char *body, const client_t *client, "\"difficulty\":%"PRIu64",\"height\":%"PRIu64"," "\"reserved_offset\":%u," "\"client_nonce_offset\":%u,\"client_pool_offset\":%u," - "\"target_diff\":%"PRIu64",\"target_diff_hex\":\"%s\"}," + "\"target_diff\":%"PRIu64",\"target_diff_hex\":\"%s\"," + "\"seed_hash\":\"%.64s\",\"next_seed_hash\":\"%.64s\"}," "\"status\":\"OK\"}}\n", client_id, block_hex, job_id, bt->difficulty, bt->height, bt->reserved_offset, bt->reserved_offset + 12, - bt->reserved_offset + 8, target, target_hex); + bt->reserved_offset + 8, target, target_hex, + bt->seed_hash, bt->next_seed_hash); } } @@ -893,6 +902,14 @@ stratum_get_job_body_ss(char *body, const client_t *client, bool response) uint64_t target = job->target; char target_hex[17] = {0}; target_to_hex(target, &target_hex[0]); + char empty[] = ""; + char *seed_hash = empty; + char *next_seed_hash = empty; + if (job->miner_template) + { + seed_hash = job->miner_template->seed_hash; + next_seed_hash = job->miner_template->next_seed_hash; + } unsigned char extra_bin[8]; memcpy(extra_bin, &job->extra_nonce, 4); memcpy(extra_bin+4, &instance_id, 4); @@ -905,10 +922,11 @@ stratum_get_job_body_ss(char *body, const client_t *client, bool response) "\"error\":null,\"result\"" ":{\"id\":\"%.32s\",\"job\":{" "\"job_id\":\"%.32s\",\"target\":\"%s\"," - "\"extra_nonce\":\"%s\", \"pool_wallet\":\"%s\"}," + "\"extra_nonce\":\"%s\", \"pool_wallet\":\"%s\"," + "\"seed_hash\":\"%.64s\",\"next_seed_hash\":\"%.64s\"}," "\"status\":\"OK\"}}\n", json_id, client_id, job_id, target_hex, extra_hex, - config.pool_wallet); + config.pool_wallet, seed_hash, next_seed_hash); } else { @@ -916,8 +934,10 @@ stratum_get_job_body_ss(char *body, const client_t *client, bool response) "\"job\",\"params\"" ":{\"id\":\"%.32s\",\"job_id\":\"%.32s\"," "\"target\":\"%s\"," - "\"extra_nonce\":\"%s\", \"pool_wallet\":\"%s\"}}\n", - client_id, job_id, target_hex, extra_hex, config.pool_wallet); + "\"extra_nonce\":\"%s\", \"pool_wallet\":\"%s\"," + "\"seed_hash\":\"%.64s\",\"next_seed_hash\":\"%.64s\"}}\n", + client_id, job_id, target_hex, extra_hex, config.pool_wallet, + seed_hash, next_seed_hash); } } @@ -934,6 +954,8 @@ stratum_get_job_body(char *body, const client_t *client, bool response) uint64_t height = job->block_template->height; char target_hex[17] = {0}; target_to_hex(target, &target_hex[0]); + char *seed_hash = job->block_template->seed_hash; + char *next_seed_hash = job->block_template->next_seed_hash; if (response) { @@ -941,9 +963,11 @@ stratum_get_job_body(char *body, const client_t *client, bool response) "\"error\":null,\"result\"" ":{\"id\":\"%.32s\",\"job\":{" "\"blob\":\"%s\",\"job_id\":\"%.32s\",\"target\":\"%s\"," - "\"height\":%"PRIu64"}," + "\"height\":%"PRIu64",\"seed_hash\":\"%.64s\"," + "\"next_seed_hash\":\"%.64s\"}," "\"status\":\"OK\"}}\n", - json_id, client_id, blob, job_id, target_hex, height); + json_id, client_id, blob, job_id, target_hex, height, + seed_hash, next_seed_hash); } else { @@ -951,8 +975,10 @@ stratum_get_job_body(char *body, const client_t *client, bool response) "\"job\",\"params\"" ":{\"id\":\"%.32s\",\"blob\":\"%s\",\"job_id\":\"%.32s\"," "\"target\":\"%s\"," - "\"height\":%"PRIu64"}}\n", - client_id, blob, job_id, target_hex, height); + "\"height\":%"PRIu64",\"seed_hash\":\"%.64s\"," + "\"next_seed_hash\":\"%.64s\"}}\n", + client_id, blob, job_id, target_hex, height, + seed_hash, next_seed_hash); } } @@ -1202,6 +1228,23 @@ response_to_block_template(json_object *result, block_template->height = json_object_get_int64(height); memcpy(block_template->prev_hash, json_object_get_string(prev_hash), 64); block_template->reserved_offset = json_object_get_int(reserved_offset); + + unsigned int major_version = 0; + sscanf(block_template->blocktemplate_blob, "%2x", &major_version); + uint8_t pow_variant = major_version >= 7 ? major_version - 6 : 0; + log_trace("Variant: %u", pow_variant); + + if (pow_variant >= 6) + { + JSON_GET_OR_WARN(seed_hash, result, json_type_string); + JSON_GET_OR_WARN(next_seed_hash, result, json_type_string); + assert(seed_hash != NULL); + assert(next_seed_hash != NULL); + memcpy(block_template->seed_hash, + json_object_get_string(seed_hash), 64); + memcpy(block_template->next_seed_hash, + json_object_get_string(next_seed_hash), 64); + } } static void @@ -2087,6 +2130,23 @@ client_on_block_template(json_object *message, client_t *client) memcpy(job->miner_template->prev_hash, json_object_get_string(prev_hash), 64); + unsigned int major_version = 0; + sscanf(btb, "%2x", &major_version); + uint8_t pow_variant = major_version >= 7 ? major_version - 6 : 0; + log_trace("Variant: %u", pow_variant); + + if (pow_variant >= 6) + { + JSON_GET_OR_WARN(seed_hash, params, json_type_string); + JSON_GET_OR_WARN(next_seed_hash, params, json_type_string); + assert(seed_hash != NULL); + assert(next_seed_hash != NULL); + memcpy(job->miner_template->seed_hash, + json_object_get_string(seed_hash), 64); + memcpy(job->miner_template->next_seed_hash, + json_object_get_string(next_seed_hash), 64); + } + log_trace("Client set template: %s", btb); char body[STATUS_BODY_MAX]; stratum_get_status_body(body, client->json_id, "OK"); @@ -2256,9 +2316,19 @@ client_on_submit(json_object *message, client_t *client) unsigned char result_hash[32] = {0}; unsigned char submitted_hash[32] = {0}; uint8_t major_version = (uint8_t)block[0]; - const int cn_variant = major_version >= 7 ? major_version - 6 : 0; - get_hash(hashing_blob, hashing_blob_size, - (unsigned char**)&result_hash, cn_variant, bt->height); + uint8_t pow_variant = major_version >= 7 ? major_version - 6 : 0; + if (pow_variant >= 6) + { + unsigned char seed_hash[32]; + hex_to_bin(bt->seed_hash, 64, seed_hash, 32); + get_rx_hash(hashing_blob, hashing_blob_size, + (unsigned char*)result_hash, seed_hash, bt->height); + } + else + { + get_hash(hashing_blob, hashing_blob_size, + (unsigned char*)result_hash, pow_variant, bt->height); + } hex_to_bin(result_hex, 64, submitted_hash, 32); if (memcmp(submitted_hash, result_hash, 32) != 0) @@ -2768,6 +2838,8 @@ cleanup(void) database_close(); BN_free(base_diff); BN_CTX_free(bn_ctx); + rx_stop_mining(); + rx_slow_hash_free_state(); pthread_mutex_destroy(&mutex_clients); log_info("Pool shutdown successfully"); if (fd_log) diff --git a/src/xmr.cpp b/src/xmr.cpp index 7aed529..44b238b 100644 --- a/src/xmr.cpp +++ b/src/xmr.cpp @@ -48,6 +48,7 @@ developers. #include "serialization/binary_utils.h" #include "ringct/rctSigs.h" #include "common/base58.h" +#include "common/util.h" #include "string_tools.h" #include "xmr.h" @@ -94,12 +95,25 @@ int parse_address(const char *input, uint64_t *prefix, } void get_hash(const unsigned char *input, const size_t in_size, - unsigned char **output, int variant, uint64_t height) + unsigned char *output, int variant, uint64_t height) { cn_slow_hash(input, in_size, reinterpret_cast(*output), variant, height); } +void get_rx_hash(const unsigned char *input, const size_t in_size, + unsigned char *output, const unsigned char *seed_hash, + const uint64_t height) +{ + static unsigned max_concurrency = 1;//tools::get_max_concurrency(); + uint64_t seed_height; + if (rx_needhash(height, &seed_height)) + { + rx_seedhash(seed_height, (const char*)seed_hash, max_concurrency); + } + rx_slow_hash((const char*)input, in_size, (char*)output, max_concurrency); +} + int validate_block_from_blob(const char *blob_hex, const unsigned char *sec_view, const unsigned char *pub_spend) diff --git a/src/xmr.h b/src/xmr.h index b9d76d4..6088c66 100644 --- a/src/xmr.h +++ b/src/xmr.h @@ -55,7 +55,10 @@ int get_hashing_blob(const unsigned char *input, const size_t in_size, int parse_address(const char *input, uint64_t *prefix, unsigned char *pub_spend); void get_hash(const unsigned char *input, const size_t in_size, - unsigned char **output, int variant, uint64_t height); + unsigned char *output, int variant, uint64_t height); +void get_rx_hash(const unsigned char *input, const size_t in_size, + unsigned char *output, const unsigned char *seed_hash, + const uint64_t height); int validate_block_from_blob(const char *blob_hex, const unsigned char *sec_view, const unsigned char *pub_spend); From 4d69befdd14962556ace2ec53aea4890b2346235 Mon Sep 17 00:00:00 2001 From: Jethro Grassie Date: Wed, 21 Aug 2019 09:57:07 -0400 Subject: [PATCH 2/4] tools: show recent shares --- tools/inspect-data | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tools/inspect-data b/tools/inspect-data index 2b63b4a..2670e91 100755 --- a/tools/inspect-data +++ b/tools/inspect-data @@ -115,6 +115,22 @@ def print_mined(path): print('{}\t{}\t{}\t{}'.format(height, status, reward, dt)) env.close() +def print_shares(path): + env = lmdb.open(path, readonly=True, max_dbs=1, create=False) + shares = env.open_db('shares'.encode(), dupsort=True) + with env.begin(db=shares) as txn: + with txn.cursor() as curs: + curs.last() + for i in range(10): + key, value = curs.item() + height = c_longlong.from_buffer_copy(key).value + share = share_t.from_buffer_copy(value) + address = format_address(address_from_key(share.address)) + print('{}\t{}'.format(height, address)) + if not curs.prev(): + break + env.close() + def main(): parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group(required=True) @@ -124,6 +140,8 @@ def main(): help='list payments made') group.add_argument('-m', '--mined', action='store_true', help='list mined blocks') + group.add_argument('-s', '--shares', action='store_true', + help='list recent shares') parser.add_argument('database', help='path to database') args = parser.parse_args() if args.balances: @@ -132,6 +150,8 @@ def main(): print_payements(args.database) elif args.mined: print_mined(args.database) + elif args.shares: + print_shares(args.database) if __name__ == '__main__': main() From 2c636d00e96a3f2e7b82bde0b32d4e97e2f07ab7 Mon Sep 17 00:00:00 2001 From: Jethro Grassie Date: Wed, 21 Aug 2019 18:32:57 -0400 Subject: [PATCH 3/4] fix balance updates --- src/pool.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pool.c b/src/pool.c index e9bf390..1f90da3 100644 --- a/src/pool.c +++ b/src/pool.c @@ -572,7 +572,12 @@ balance_add(const char *address, uint64_t amount, MDB_txn *parent) { log_trace("Adding new balance entry"); MDB_val new_val = { sizeof(amount), (void*)&amount }; - mdb_cursor_put(cursor, &key, &new_val, MDB_APPEND); + rc = mdb_cursor_put(cursor, &key, &new_val, 0); + if (rc != 0) + { + err = mdb_strerror(rc); + log_error("%s", err); + } } else if (rc == 0) { @@ -663,6 +668,8 @@ payout_block(block_t *block, MDB_txn *parent) rc = balance_add(share->address, amount, txn); if (rc != 0) { + err = mdb_strerror(rc); + log_error("%s", err); mdb_cursor_close(cursor); mdb_txn_abort(txn); return rc; From bcc25dee1b1ea5b0c31c36d8c366b591875d5d1c Mon Sep 17 00:00:00 2001 From: Jethro Grassie Date: Wed, 21 Aug 2019 19:35:30 -0400 Subject: [PATCH 4/4] ease building with / without randomx --- Makefile | 14 ++++++++++++-- src/pool.c | 5 +++++ src/xmr.cpp | 4 +++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 76748ac..c48f2f2 100644 --- a/Makefile +++ b/Makefile @@ -56,8 +56,9 @@ MONERO_LIBS = \ ${MONERO_BUILD_ROOT}/src/ringct/libringct_basic.a \ ${MONERO_BUILD_ROOT}/src/device/libdevice.a \ ${MONERO_BUILD_ROOT}/contrib/epee/src/libepee.a \ - ${MONERO_BUILD_ROOT}/external/easylogging++/libeasylogging.a \ - ${MONERO_BUILD_ROOT}/external/randomx/librandomx.a + ${MONERO_BUILD_ROOT}/external/easylogging++/libeasylogging.a + +LIBRX = ${MONERO_BUILD_ROOT}/external/randomx/librandomx.a DIRS = src data rxi/log/src @@ -65,6 +66,15 @@ OS := $(shell uname -s) CPPDEFS = _GNU_SOURCE AUTO_INITIALIZE_EASYLOGGINGPP LOG_USE_COLOR +ifeq ($(wildcard ${LIBRX}),${LIBRX}) + MONERO_LIBS += ${LIBRX} + CPPDEFS += HAVE_RX +else + ifneq ($(MAKECMDGOALS),clean) + $(warning Building without RandomX!) + endif +endif + W = -W -Wall -Wno-unused-parameter -Wuninitialized OPT = -maes -fPIC CFLAGS = $(W) -Wbad-function-cast $(OPT) -std=c99 diff --git a/src/pool.c b/src/pool.c index 1f90da3..4c38ffc 100644 --- a/src/pool.c +++ b/src/pool.c @@ -248,8 +248,13 @@ static FILE *fd_log; static unsigned char sec_view[32]; static unsigned char pub_spend[32]; +#ifdef HAVE_RX extern void rx_stop_mining(); extern void rx_slow_hash_free_state(); +#else +void rx_stop_mining(){} +void rx_slow_hash_free_state(){} +#endif #define JSON_GET_OR_ERROR(name, parent, type, client) \ json_object *name = NULL; \ diff --git a/src/xmr.cpp b/src/xmr.cpp index 44b238b..fa9afe0 100644 --- a/src/xmr.cpp +++ b/src/xmr.cpp @@ -105,13 +105,15 @@ void get_rx_hash(const unsigned char *input, const size_t in_size, unsigned char *output, const unsigned char *seed_hash, const uint64_t height) { - static unsigned max_concurrency = 1;//tools::get_max_concurrency(); +#ifdef HAVE_RX + static unsigned max_concurrency = tools::get_max_concurrency(); uint64_t seed_height; if (rx_needhash(height, &seed_height)) { rx_seedhash(seed_height, (const char*)seed_hash, max_concurrency); } rx_slow_hash((const char*)input, in_size, (char*)output, max_concurrency); +#endif } int validate_block_from_blob(const char *blob_hex,