From c772ac4a9121f8bf7c4c67311be145b6666db380 Mon Sep 17 00:00:00 2001 From: shufps Date: Fri, 13 Sep 2024 15:50:34 +0200 Subject: [PATCH 1/6] debug output on malformed merkle tree branch --- src/drivers/nerd-nos/bm1397.cpp | 19 ++++++++++--------- src/drivers/nerd-nos/mining.cpp | 22 +++++++++++++++++++++- src/drivers/nerd-nos/utils.cpp | 18 ++++++++++++++++++ src/drivers/nerd-nos/utils.h | 4 ++++ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/drivers/nerd-nos/bm1397.cpp b/src/drivers/nerd-nos/bm1397.cpp index 4f2fffa..a45a826 100644 --- a/src/drivers/nerd-nos/bm1397.cpp +++ b/src/drivers/nerd-nos/bm1397.cpp @@ -195,7 +195,7 @@ void BM1397_send_hash_frequency(float frequency) vTaskDelay(10 / portTICK_PERIOD_MS); - ESP_LOGI(TAG, "Setting Frequency to %.2fMHz (%.2f)", frequency, newf); + Serial.printf("Setting Frequency to %.2fMHz (%.2f)\n", frequency, newf); } @@ -208,13 +208,13 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count) while (true) { int received = SERIAL_rx(asic_response_buffer, 11, 1000); if (received > 0) { - ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received); + //ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received); chip_counter++; } else { break; } } - ESP_LOGI(TAG, "%i chip(s) detected on the chain, expected %i", chip_counter, asic_count); + Serial.printf("%i chip(s) detected on the chain, expected %i\n", chip_counter, asic_count); // send serial data vTaskDelay(SLEEP_TIME / portTICK_PERIOD_MS); @@ -269,7 +269,7 @@ static void _reset(void) uint8_t BM1397_init(uint64_t frequency, uint16_t asic_count) { - ESP_LOGI(TAG, "Initializing BM1397"); + Serial.println("Initializing BM1397"); memset(asic_response_buffer, 0, sizeof(asic_response_buffer)); @@ -299,7 +299,7 @@ int BM1397_set_default_baud(void) int BM1397_set_max_baud(void) { // divider of 0 for 3,125,000 - ESP_LOGI(TAG, "Setting max baud of 3125000"); + Serial.println("Setting max baud of 3125000"); unsigned char baudrate[9] = {0x00, MISC_CONTROL, 0x00, 0x00, 0b01100000, 0b00110001}; ; // baudrate - misc_control _send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, BM1397_SERIALTX_DEBUG); @@ -330,7 +330,7 @@ void BM1397_set_job_difficulty_mask(int difficulty) job_difficulty_mask[5 - i] = reverse_bits(value); } - ESP_LOGI(TAG, "Setting job ASIC mask to %d", difficulty); + Serial.printf("Setting job ASIC mask to %d\n", difficulty); _send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), job_difficulty_mask, 6, BM1397_SERIALTX_DEBUG); } @@ -369,7 +369,7 @@ asic_result *BM1397_receive_work(uint16_t timeout) if (received < 0) { - ESP_LOGI(TAG, "Error in serial RX"); + Serial.println("Error in serial RX"); return NULL; } else if (received == 0) @@ -380,8 +380,9 @@ asic_result *BM1397_receive_work(uint16_t timeout) if (received != 9 || asic_response_buffer[0] != 0xAA || asic_response_buffer[1] != 0x55) { - ESP_LOGI(TAG, "Serial RX invalid %i", received); - ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received); + Serial.println("Serial RX invalid. Resetting receive buffer ..."); + //ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received); + SERIAL_clear_buffer(); return NULL; } diff --git a/src/drivers/nerd-nos/mining.cpp b/src/drivers/nerd-nos/mining.cpp index 929b072..f8cda28 100644 --- a/src/drivers/nerd-nos/mining.cpp +++ b/src/drivers/nerd-nos/mining.cpp @@ -51,6 +51,21 @@ double nerdnos_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const return ds; } +static void dump(mining_job *job) { + Serial.printf("job_id: %s\n", job->job_id.c_str()); + Serial.printf("prev_block_hash: %s\n", job->prev_block_hash.c_str()); + Serial.printf("coinb1: %s\n", job->coinb1.c_str()); + Serial.printf("coinb2: %s\n", job->coinb2.c_str()); + Serial.printf("nbits: %s\n", job->nbits.c_str()); + Serial.printf("version: %s\n", job->version.c_str()); + Serial.printf("ntime: %s\n", job->ntime.c_str()); + Serial.printf("taget: %lu\n", job->target); + Serial.printf("clean_jobs: %s\n", job->clean_jobs ? "true" : "false"); + for (size_t i = 0; i < job->merkle_branch.size(); i++) { + const char* m = job->merkle_branch[i]; + Serial.printf("merkle_branch[%d]: %s\n", i, m); + } +} static void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, char merkle_root_hash[65]) { size_t coinbase_tx_bin_len = strlen(coinbase_tx) / 2; @@ -63,7 +78,12 @@ static void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, memcpy(both_merkles, new_root, 32); for (size_t i = 0; i < job->merkle_branch.size(); i++) { - hex2bin((const char*) job->merkle_branch[i], &both_merkles[32], 32); + const char* m = job->merkle_branch[i]; + // if merkle branch is not what we expect, dump the job + if (!is_hex_string(m)) { + dump(job); + } + hex2bin(m, &both_merkles[32], 32); double_sha256_bin(both_merkles, 64, new_root); memcpy(both_merkles, new_root, 32); } diff --git a/src/drivers/nerd-nos/utils.cpp b/src/drivers/nerd-nos/utils.cpp index 01a47e1..ce409d3 100644 --- a/src/drivers/nerd-nos/utils.cpp +++ b/src/drivers/nerd-nos/utils.cpp @@ -127,6 +127,24 @@ uint8_t hex2val(char c) } } +bool is_hex_digit(char c) { + return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); +} + +bool is_hex_string(const char* str) { + // Check if the string is exactly 64 characters long + if (strlen(str) != 64) { + return false; + } + // Check if each character is a valid hexadecimal digit + for (size_t i = 0; i < 64; i++) { + if (!is_hex_digit(str[i])) { + return false; + } + } + return true; +} + size_t hex2bin(const char *hex, uint8_t *bin, size_t bin_len) { size_t len = 0; diff --git a/src/drivers/nerd-nos/utils.h b/src/drivers/nerd-nos/utils.h index 78b6852..273a965 100644 --- a/src/drivers/nerd-nos/utils.h +++ b/src/drivers/nerd-nos/utils.h @@ -2,6 +2,7 @@ #include #include +#include int hex2char(uint8_t x, char *c); @@ -38,3 +39,6 @@ unsigned char reverse_bits(unsigned char num); int largest_power_of_two(int num); uint32_t increment_bitmask(const uint32_t value, const uint32_t mask); + +bool is_hex_digit(char c); +bool is_hex_string(const char* str); \ No newline at end of file From def93a857950ccb097a4fbb86f634f0dd6e5ffd5 Mon Sep 17 00:00:00 2001 From: shufps Date: Fri, 13 Sep 2024 18:22:41 +0200 Subject: [PATCH 2/6] copied merkle tree for nerdnos --- src/drivers/nerd-nos/mining.cpp | 8 ++++---- src/stratum.cpp | 15 ++++++++++++++- src/stratum.h | 3 ++- src/utils.cpp | 30 +++++++++++++++--------------- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/drivers/nerd-nos/mining.cpp b/src/drivers/nerd-nos/mining.cpp index f8cda28..c6c291d 100644 --- a/src/drivers/nerd-nos/mining.cpp +++ b/src/drivers/nerd-nos/mining.cpp @@ -61,8 +61,8 @@ static void dump(mining_job *job) { Serial.printf("ntime: %s\n", job->ntime.c_str()); Serial.printf("taget: %lu\n", job->target); Serial.printf("clean_jobs: %s\n", job->clean_jobs ? "true" : "false"); - for (size_t i = 0; i < job->merkle_branch.size(); i++) { - const char* m = job->merkle_branch[i]; + for (size_t i = 0; i < job->merkle_branch_size; i++) { + const char* m = job->merkle_branch[i].c_str(); Serial.printf("merkle_branch[%d]: %s\n", i, m); } } @@ -77,8 +77,8 @@ static void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, double_sha256_bin(coinbase_tx_bin, coinbase_tx_bin_len, new_root); memcpy(both_merkles, new_root, 32); - for (size_t i = 0; i < job->merkle_branch.size(); i++) { - const char* m = job->merkle_branch[i]; + for (size_t i = 0; i < job->merkle_branch_size; i++) { + const char* m = job->merkle_branch[i].c_str(); // if merkle branch is not what we expect, dump the job if (!is_hex_string(m)) { dump(job); diff --git a/src/stratum.cpp b/src/stratum.cpp index a5ec3ac..3b0fd33 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -188,7 +188,20 @@ bool parse_mining_notify(String line, mining_job& mJob) mJob.prev_block_hash = String((const char*) doc["params"][1]); mJob.coinb1 = String((const char*) doc["params"][2]); mJob.coinb2 = String((const char*) doc["params"][3]); - mJob.merkle_branch = doc["params"][4]; + + // this only copies references to the static json buffer + // and can lead to crashes when there is a new stratum response + // and the content of the array is still needed like on NerdNOS + // that computes the merkle tree new each 30ms^^ + //mJob.merkle_branch = doc["params"][4]; + + // This copies the merkle branch + JsonArray merkle_tree = doc["params"][4]; + mJob.merkle_branch_size = merkle_tree.size(); + for (size_t i = 0; i < mJob.merkle_branch_size; i++) { + mJob.merkle_branch[i] = String((const char*) merkle_tree[i]); + } + mJob.version = String((const char*) doc["params"][5]); mJob.nbits = String((const char*) doc["params"][6]); mJob.ntime = String((const char*) doc["params"][7]); diff --git a/src/stratum.h b/src/stratum.h index c0c2ff9..8d5abca 100644 --- a/src/stratum.h +++ b/src/stratum.h @@ -31,7 +31,8 @@ typedef struct mining_job { String coinb1; String coinb2; String nbits; - JsonArray merkle_branch; + String merkle_branch[MAX_MERKLE_BRANCHES]; + size_t merkle_branch_size; String version; uint32_t target; String ntime; diff --git a/src/utils.cpp b/src/utils.cpp index 20120be..1a6a95a 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -170,13 +170,13 @@ void getNextExtranonce2(int extranonce2_size, char *extranonce2) { } miner_data init_miner_data(void){ - + miner_data newMinerData; newMinerData.poolDifficulty = DEFAULT_DIFFICULTY; newMinerData.inRun = false; newMinerData.newJob = false; - + return newMinerData; } @@ -185,14 +185,14 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){ miner_data mMiner = init_miner_data(); // calculate target - target = (nbits[2:]+'00'*(int(nbits[:2],16) - 3)).zfill(64) - + char target[TARGET_BUFFER_SIZE+1]; memset(target, '0', TARGET_BUFFER_SIZE); int zeros = (int) strtol(mJob.nbits.substring(0, 2).c_str(), 0, 16) - 3; memcpy(target + zeros - 2, mJob.nbits.substring(2).c_str(), mJob.nbits.length() - 2); target[TARGET_BUFFER_SIZE] = 0; Serial.print(" target: "); Serial.println(target); - + // bytearray target size_t size_target = to_byte_array(target, 32, mMiner.bytearray_target); @@ -204,12 +204,12 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){ // get extranonce2 - extranonce2 = hex(random.randint(0,2**32-1))[2:].zfill(2*extranonce2_size) //To review - char extranonce2_char[2 * mWorker.extranonce2_size+1]; + char extranonce2_char[2 * mWorker.extranonce2_size+1]; mWorker.extranonce2.toCharArray(extranonce2_char, 2 * mWorker.extranonce2_size + 1); getNextExtranonce2(mWorker.extranonce2_size, extranonce2_char); mWorker.extranonce2 = String(extranonce2_char); //mWorker.extranonce2 = "00000002"; - + //get coinbase - coinbase_hash_bin = hashlib.sha256(hashlib.sha256(binascii.unhexlify(coinbase)).digest()).digest() String coinbase = mJob.coinb1 + mWorker.extranonce1 + mWorker.extranonce2 + mJob.coinb2; Serial.print(" coinbase: "); Serial.println(coinbase); @@ -229,10 +229,10 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){ mbedtls_sha256_context ctx; mbedtls_sha256_init(&ctx); - + byte interResult[32]; // 256 bit byte shaResult[32]; // 256 bit - + mbedtls_sha256_starts_ret(&ctx,0); mbedtls_sha256_update_ret(&ctx, bytearray, str_len); mbedtls_sha256_finish_ret(&ctx, interResult); @@ -249,13 +249,13 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){ Serial.println(""); #endif - + // copy coinbase hash memcpy(mMiner.merkle_result, shaResult, sizeof(shaResult)); - + byte merkle_concatenated[32 * 2]; - for (size_t k=0; k < mJob.merkle_branch.size(); k++) { - const char* merkle_element = (const char*) mJob.merkle_branch[k]; + for (size_t k=0; k < mJob.merkle_branch_size; k++) { + const char* merkle_element = (const char*) mJob.merkle_branch[k].c_str(); uint8_t bytearray[32]; size_t res = to_byte_array(merkle_element, 64, bytearray); @@ -294,7 +294,7 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){ #endif } // merkle root from merkle_result - + Serial.print(" merkle sha : "); char merkle_root[65]; for (int i = 0; i < 32; i++) { @@ -308,7 +308,7 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){ // j.block_header = ''.join([j.version, j.prevhash, merkle_root, j.ntime, j.nbits]) String blockheader = mJob.version + mJob.prev_block_hash + String(merkle_root) + mJob.ntime + mJob.nbits + "00000000"; str_len = blockheader.length()/2; - + //uint8_t bytearray_blockheader[str_len]; res = to_byte_array(blockheader.c_str(), str_len*2, mMiner.bytearray_blockheader); @@ -375,7 +375,7 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){ #ifdef DEBUG_MINING - Serial.print(" >>> bytearray_blockheader : "); + Serial.print(" >>> bytearray_blockheader : "); for (size_t i = 0; i < 4; i++) Serial.printf("%02x", mMiner.bytearray_blockheader[i]); Serial.println(""); From 087253656f23ae19989604dc978d084b9f16ea37 Mon Sep 17 00:00:00 2001 From: shufps Date: Fri, 13 Sep 2024 19:09:52 +0200 Subject: [PATCH 3/6] removed global receive buffer to not loose nonces --- src/drivers/nerd-nos/bm1397.cpp | 43 +++++++++++++++------------------ src/drivers/nerd-nos/bm1397.h | 2 +- src/drivers/nerd-nos/mining.cpp | 4 +-- src/drivers/nerd-nos/mining.h | 2 +- src/drivers/nerd-nos/serial.cpp | 8 +++--- src/mining_nerdnos.cpp | 24 ++++++++---------- 6 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/drivers/nerd-nos/bm1397.cpp b/src/drivers/nerd-nos/bm1397.cpp index a45a826..5c2c45a 100644 --- a/src/drivers/nerd-nos/bm1397.cpp +++ b/src/drivers/nerd-nos/bm1397.cpp @@ -48,9 +48,6 @@ typedef struct __attribute__((__packed__)) static const char *TAG = "bm1397Module"; -static uint8_t asic_response_buffer[CHUNK_SIZE]; -static task_result result; - uint32_t increment_bitmask(const uint32_t value, const uint32_t mask); /// @brief @@ -203,10 +200,11 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count) { // send the init command _send_read_address(); + uint8_t buf[11] = {0}; int chip_counter = 0; while (true) { - int received = SERIAL_rx(asic_response_buffer, 11, 1000); + int received = SERIAL_rx(buf, 11, 1000); if (received > 0) { //ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received); chip_counter++; @@ -271,8 +269,6 @@ uint8_t BM1397_init(uint64_t frequency, uint16_t asic_count) { Serial.println("Initializing BM1397"); - memset(asic_response_buffer, 0, sizeof(asic_response_buffer)); - gpio_set_direction(NERD_NOS_GPIO_PEN, GPIO_MODE_OUTPUT); gpio_set_level(NERD_NOS_GPIO_PEN, 1); @@ -361,46 +357,47 @@ void BM1397_send_work(bm_job_t *next_bm_job, uint8_t job_id) _send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t*) &job, sizeof(job_packet_t), BM1397_DEBUG_WORK); } -asic_result *BM1397_receive_work(uint16_t timeout) +bool BM1397_receive_work(uint16_t timeout, asic_result *result) { + uint8_t *rcv_buf = (uint8_t*) result; // wait for a response, wait time is pretty arbitrary - int received = SERIAL_rx(asic_response_buffer, 9, timeout); + int received = SERIAL_rx(rcv_buf, 9, timeout); if (received < 0) { Serial.println("Error in serial RX"); - return NULL; + return false; } else if (received == 0) { // Didn't find a solution, restart and try again - return NULL; + return false; } - if (received != 9 || asic_response_buffer[0] != 0xAA || asic_response_buffer[1] != 0x55) + if (received != 9 || rcv_buf[0] != 0xAA || rcv_buf[1] != 0x55) { Serial.println("Serial RX invalid. Resetting receive buffer ..."); //ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received); SERIAL_clear_buffer(); - return NULL; + return false; } + return true; - return (asic_result *)asic_response_buffer; } -task_result *BM1397_proccess_work(uint32_t version, uint16_t timeout) +bool BM1397_proccess_work(uint32_t version, uint16_t timeout, task_result *result) { - asic_result *asic_result = BM1397_receive_work(timeout); + asic_result asic_result; - if (asic_result == NULL) + if (!BM1397_receive_work(timeout, &asic_result)) { ESP_LOGI(TAG, "return null"); - return NULL; + return false; } - uint8_t rx_job_id = (asic_result->job_id & 0xfc) >> 2; - uint8_t rx_midstate_index = asic_result->job_id & 0x03; + uint8_t rx_job_id = (asic_result.job_id & 0xfc) >> 2; + uint8_t rx_midstate_index = asic_result.job_id & 0x03; uint32_t rolled_version = version; for (int i = 0; i < rx_midstate_index; i++) @@ -408,10 +405,10 @@ task_result *BM1397_proccess_work(uint32_t version, uint16_t timeout) rolled_version = increment_bitmask(rolled_version, 0x1fffe000); } - result.job_id = rx_job_id; - result.nonce = asic_result->nonce; - result.rolled_version = rolled_version; + result->job_id = rx_job_id; + result->nonce = asic_result.nonce; + result->rolled_version = rolled_version; - return &result; + return true; } diff --git a/src/drivers/nerd-nos/bm1397.h b/src/drivers/nerd-nos/bm1397.h index 743d140..02213e6 100644 --- a/src/drivers/nerd-nos/bm1397.h +++ b/src/drivers/nerd-nos/bm1397.h @@ -17,5 +17,5 @@ void BM1397_set_job_difficulty_mask(int); int BM1397_set_max_baud(void); int BM1397_set_default_baud(void); void BM1397_send_hash_frequency(float frequency); -task_result *BM1397_proccess_work(uint32_t version, uint16_t timeout); +bool BM1397_proccess_work(uint32_t version, uint16_t timeout, task_result *result); diff --git a/src/drivers/nerd-nos/mining.cpp b/src/drivers/nerd-nos/mining.cpp index c6c291d..9a1f5cb 100644 --- a/src/drivers/nerd-nos/mining.cpp +++ b/src/drivers/nerd-nos/mining.cpp @@ -160,8 +160,8 @@ void nerdnos_send_work(bm_job_t *next_bm_job, uint8_t job_id) { BM1397_send_work(next_bm_job, job_id); } -task_result *nerdnos_proccess_work(uint32_t version, uint16_t timeout) { - return BM1397_proccess_work(version, timeout); +bool nerdnos_proccess_work(uint32_t version, uint16_t timeout, task_result *result) { + return BM1397_proccess_work(version, timeout, result); } void nerdnos_free_bm_job(bm_job_t *job) { diff --git a/src/drivers/nerd-nos/mining.h b/src/drivers/nerd-nos/mining.h index 63098c9..fff9eaf 100644 --- a/src/drivers/nerd-nos/mining.h +++ b/src/drivers/nerd-nos/mining.h @@ -16,7 +16,7 @@ void nerdnos_create_job(mining_subscribe *mWorker, mining_job *job, bm_job_t *ne void nerdnos_send_work(bm_job_t *next_bm_job, uint8_t job_id); // receive and process responses -task_result *nerdnos_proccess_work(uint32_t version, uint16_t timeout); +bool nerdnos_proccess_work(uint32_t version, uint16_t timeout, task_result *result); // test difficulty double nerdnos_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const uint32_t rolled_version, uint8_t hash_result[32]); diff --git a/src/drivers/nerd-nos/serial.cpp b/src/drivers/nerd-nos/serial.cpp index 7a88b2c..bbb56ff 100644 --- a/src/drivers/nerd-nos/serial.cpp +++ b/src/drivers/nerd-nos/serial.cpp @@ -51,8 +51,8 @@ int SERIAL_send(uint8_t *data, int len, bool debug) return uart_write_bytes(UART_NUM_1, (const char *)data, len); } -int SERIAL_check_for_data() { - int length; +size_t SERIAL_check_for_data() { + size_t length; uart_get_buffered_data_len(UART_NUM_1, (size_t*)&length); return length; } @@ -65,7 +65,9 @@ int SERIAL_check_for_data() { int16_t SERIAL_rx(uint8_t *buf, uint16_t size, uint16_t timeout_ms) { // don't return incomplete data - if (SERIAL_check_for_data() < size) { + size_t available = SERIAL_check_for_data(); + if (available && available < size) { + Serial.printf("not returning parts of data ... %d vs %d\n", (int) available, (int) size); return 0; } diff --git a/src/mining_nerdnos.cpp b/src/mining_nerdnos.cpp index 181dfaa..290e4b8 100644 --- a/src/mining_nerdnos.cpp +++ b/src/mining_nerdnos.cpp @@ -172,15 +172,11 @@ void runASIC(void * task_id) { // send the job and nerdnos_send_work(&asic_jobs[asic_job_id], asic_job_id); - // the pointer returned is the RS232 receive buffer :shushing-face: - // but we only have a single thread so it should be okay - // process all results if we have more than one - // this is okay because serial uses a buffer and (most likely^^) DMA - task_result *result = NULL; - while ((result = nerdnos_proccess_work(version, 1)) != NULL) { + task_result result = {0}; + while (nerdnos_proccess_work(version, 1, &result)) { // check if the ID is in the valid range and the slot is not empty - if (result->job_id >= ASIC_JOB_COUNT || !asic_jobs[result->job_id].ntime) { - Serial.printf("Invalid job ID or no job found for ID %02x\n", result->job_id); + if (result.job_id >= ASIC_JOB_COUNT || !asic_jobs[result.job_id].ntime) { + Serial.printf("Invalid job ID or no job found for ID %02x\n", result.job_id); continue; } @@ -188,9 +184,9 @@ void runASIC(void * task_id) { // check the nonce difficulty double diff_hash = nerdnos_test_nonce_value( - &asic_jobs[result->job_id], - result->nonce, - result->rolled_version, + &asic_jobs[result.job_id], + result.nonce, + result.rolled_version, hash); // update best diff @@ -199,14 +195,14 @@ void runASIC(void * task_id) { } // calculate the hashrate - if (diff_hash >= asic_jobs[result->job_id].pool_diff) { - calculate_hashrate(&history, asic_jobs[result->job_id].pool_diff); + if (diff_hash >= asic_jobs[result.job_id].pool_diff) { + calculate_hashrate(&history, asic_jobs[result.job_id].pool_diff); Serial.printf("avg hashrate: %.2fGH/s (history spans %.2fs, %d shares)\n", history.avg_gh, history.duration, history.shares); } if(diff_hash > mMiner.poolDifficulty) { - tx_mining_submit_asic(client, mWorker, &asic_jobs[result->job_id], result); + tx_mining_submit_asic(client, mWorker, &asic_jobs[result.job_id], &result); Serial.println("valid share!"); Serial.printf(" - Current diff share: %.3f\n", diff_hash); Serial.printf(" - Current pool diff : %.3f\n", mMiner.poolDifficulty); From 8efa73b1ca878f6373fbecbec50137bbe708a3d7 Mon Sep 17 00:00:00 2001 From: shufps Date: Fri, 13 Sep 2024 20:37:46 +0200 Subject: [PATCH 4/6] fixed history timestamps (uint64_t instead of uint32_t) --- src/mining_nerdnos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mining_nerdnos.cpp b/src/mining_nerdnos.cpp index 290e4b8..38f815f 100644 --- a/src/mining_nerdnos.cpp +++ b/src/mining_nerdnos.cpp @@ -40,7 +40,7 @@ static bm_job_t asic_jobs[ASIC_JOB_COUNT] = {0}; typedef struct { uint32_t diffs[ASIC_HISTORY_SIZE]; - uint32_t timestamps[ASIC_HISTORY_SIZE]; + uint64_t timestamps[ASIC_HISTORY_SIZE]; uint32_t newest; uint32_t oldest; uint64_t sum; @@ -78,7 +78,7 @@ static void calculate_hashrate(history_t *history, uint32_t diff) { history->diffs[history->newest % ASIC_HISTORY_SIZE] = diff; // micros() wraps around after about 71.58min because it's 32bit casted from 64bit timer :facepalm: - history->timestamps[history->newest % ASIC_HISTORY_SIZE] = esp_timer_get_time(); + history->timestamps[history->newest % ASIC_HISTORY_SIZE] = (uint64_t) esp_timer_get_time(); uint64_t oldest_timestamp = history->timestamps[history->oldest % ASIC_HISTORY_SIZE]; uint64_t newest_timestamp = history->timestamps[history->newest % ASIC_HISTORY_SIZE]; From 745a9716845b75d3b2bb0effecfa481ff83cf655 Mon Sep 17 00:00:00 2001 From: shufps Date: Fri, 13 Sep 2024 20:38:40 +0200 Subject: [PATCH 5/6] show mV without decimal places --- src/monitor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/monitor.cpp b/src/monitor.cpp index 3c1afbd..b0a613c 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -250,7 +250,7 @@ String getCurrentTemperature() { } String getCurrentVCore() { - return String(nerdnos_get_vcore(), 2); + return String(nerdnos_get_vcore(), 0); } #else String getCurrentHashRate(unsigned long mElapsed) @@ -263,7 +263,7 @@ String getCurrentTemperature() { } String getCurrentVCore() { - return String(0.0, 2); + return String(0.0, 0); } #endif From 2f288edbe6e12850febe0f9a56468ec11c670a19 Mon Sep 17 00:00:00 2001 From: shufps Date: Fri, 13 Sep 2024 20:43:08 +0200 Subject: [PATCH 6/6] removed additional debugging again --- src/drivers/nerd-nos/mining.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/drivers/nerd-nos/mining.cpp b/src/drivers/nerd-nos/mining.cpp index 9a1f5cb..f24dc13 100644 --- a/src/drivers/nerd-nos/mining.cpp +++ b/src/drivers/nerd-nos/mining.cpp @@ -51,21 +51,6 @@ double nerdnos_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const return ds; } -static void dump(mining_job *job) { - Serial.printf("job_id: %s\n", job->job_id.c_str()); - Serial.printf("prev_block_hash: %s\n", job->prev_block_hash.c_str()); - Serial.printf("coinb1: %s\n", job->coinb1.c_str()); - Serial.printf("coinb2: %s\n", job->coinb2.c_str()); - Serial.printf("nbits: %s\n", job->nbits.c_str()); - Serial.printf("version: %s\n", job->version.c_str()); - Serial.printf("ntime: %s\n", job->ntime.c_str()); - Serial.printf("taget: %lu\n", job->target); - Serial.printf("clean_jobs: %s\n", job->clean_jobs ? "true" : "false"); - for (size_t i = 0; i < job->merkle_branch_size; i++) { - const char* m = job->merkle_branch[i].c_str(); - Serial.printf("merkle_branch[%d]: %s\n", i, m); - } -} static void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, char merkle_root_hash[65]) { size_t coinbase_tx_bin_len = strlen(coinbase_tx) / 2; @@ -79,10 +64,6 @@ static void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, for (size_t i = 0; i < job->merkle_branch_size; i++) { const char* m = job->merkle_branch[i].c_str(); - // if merkle branch is not what we expect, dump the job - if (!is_hex_string(m)) { - dump(job); - } hex2bin(m, &both_merkles[32], 32); double_sha256_bin(both_merkles, 64, new_root); memcpy(both_merkles, new_root, 32);