From 0aabedcbd1ab5f3aa8d81a09ec16c423d31520dc Mon Sep 17 00:00:00 2001 From: "Alfonso C. Alvarez" Date: Wed, 3 May 2023 21:11:59 +0200 Subject: [PATCH] Revert "Merge branch 'master' of https://github.com/alcar21/NerdMiner_v2 into feature/add_platformio_support_and_improvements" This reverts commit 8884bb58d70f6120b8843e5dccf8704c1d047e6f. --- .gitignore | 1 - platformio.ini | 8 +- src/NerdMinerV2.ino.cpp | 6 +- src/mining.cpp | 257 ++++++++++++++++------------------------ src/mining.h | 11 +- 5 files changed, 116 insertions(+), 167 deletions(-) diff --git a/.gitignore b/.gitignore index 6396bf6..5ca6960 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ .pio .vscode NerdMinerLog.txt -platformio-device-monitor*.log diff --git a/platformio.ini b/platformio.ini index 910b64c..0b0cec5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,20 +18,22 @@ framework = arduino monitor_filters = esp32_exception_decoder time - log2file board_build.arduino.memory_type = qio_opi monitor_speed = 115200 upload_speed = 115200 +# 2 x 4.5MB app, 6.875MB SPIFFS +;board_build.partitions = large_spiffs_16MB.csv +;board_build.partitions = default_8MB.csv board_build.partitions = huge_app.csv +;board_build.partitions = default.csv build_flags = -D LV_LVGL_H_INCLUDE_SIMPLE -D BOARD_HAS_PSRAM -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_CDC_ON_BOOT=1 - -D DEBUG_MINING=1 - ;-D DEBUG_MINING_SHARE + ;-D DEBUG_MINING=1 lib_deps = https://github.com/takkaO/OpenFontRender bblanchon/ArduinoJson@^6.21.2 diff --git a/src/NerdMinerV2.ino.cpp b/src/NerdMinerV2.ino.cpp index b921a25..f6c2750 100644 --- a/src/NerdMinerV2.ino.cpp +++ b/src/NerdMinerV2.ino.cpp @@ -79,6 +79,7 @@ void setup() // Higher prio monitor task Serial.println(""); Serial.println("Initiating tasks..."); + xTaskCreate(runMonitor, "Monitor", 5000, NULL, 4, NULL); /******** CREATE MINER TASKS *****/ for (size_t i = 0; i < THREADS; i++) { @@ -87,10 +88,8 @@ void setup() // Start mining tasks BaseType_t res = xTaskCreate(runWorker, name, 30000, (void*)name, 1, NULL); - Serial.printf("Starting miner %s %s!\n", name, res == pdPASS? "successful":"failed"); + Serial.printf("Starting %s %s!\n", name, res == pdPASS? "successful":"failed"); } - - Serial.println("NerdMiner v2 started......"); } void app_error_fault_handler(void *arg) { @@ -124,5 +123,4 @@ void loop() { //Run miner on main core when there is time --Currently on test runMiner(); - runMonitor(); } \ No newline at end of file diff --git a/src/mining.cpp b/src/mining.cpp index 581ec22..1fa30ac 100644 --- a/src/mining.cpp +++ b/src/mining.cpp @@ -3,7 +3,6 @@ #include #include #include // Graphics and font library for ILI9341 driver chip -#include #include "media/Free_Fonts.h" #include "media/images.h" #include "mbedtls/md.h" @@ -12,7 +11,6 @@ #include "mining.h" #define TARGET_BUFFER_SIZE 64 -#define BUFFER_JSON_DOC 1024 unsigned long templates = 0; unsigned long hashes= 0; @@ -31,6 +29,8 @@ extern char btcString[80]; extern OpenFontRender render; extern TFT_eSprite background; + + bool checkValid(unsigned char* hash, unsigned char* target) { bool valid = true; for(uint8_t i=31; i>=0; i--) { @@ -42,7 +42,7 @@ bool checkValid(unsigned char* hash, unsigned char* target) { break; } } - #ifdef DEBUG_MINING_SHARE + #ifdef DEBUG_MINING if (valid) { Serial.print("\tvalid : "); for (size_t i = 0; i < 32; i++) @@ -87,55 +87,21 @@ bool verifyPayload (String line){ return true; } -unsigned long getNextId(unsigned long id) { - if (id == ULONG_MAX) { - id = 1; - return id; - } - return ++id; -} - -void getNextExtranonce2(int extranonce2_size, char *extranonce2) { - - unsigned long extranonce2_number = strtoul(extranonce2, NULL, 10); - extranonce2_number++; - - memset(extranonce2, '0', 2 * extranonce2_size); - if (extranonce2_number > long(pow(10, 2 * extranonce2_size))) { - return; - } - - char next_extranounce2[2 * extranonce2_size + 1]; - memset(extranonce2, '0', 2 * extranonce2_size); - ultoa(extranonce2_number, next_extranounce2, 10); - memcpy(extranonce2 + (2 * extranonce2_size) - long(log10(extranonce2_number)) - 1 , next_extranounce2, strlen(next_extranounce2)); - extranonce2[2 * extranonce2_size] = 0; -} - -bool checkError(const StaticJsonDocument doc) { - if (doc["error"].size() == 0) { - return false; - } - Serial.printf("ERROR: %d | reason: %s \n", (const int) doc["error"][0], (const char*) doc["error"][1]); - return true; -} - void runWorker(void *name) { // TEST: https://bitcoin.stackexchange.com/questions/22929/full-example-data-for-scrypt-stratum-client Serial.println(""); Serial.printf("\n[WORKER] Started. Running %s on core %d\n", (char *)name, xPortGetCoreID()); - - #ifdef DEBUG_MEMORY Serial.printf("### [Total Heap / Free heap]: %d / %d \n", ESP.getHeapSize(), ESP.getFreeHeap()); - #endif + + String ADDRESS = String(btcString); // connect to pool WiFiClient client; bool continueSecuence = false; - String line, extranonce1, extranonce2 = String("0"); - unsigned long id = 0, extranonce_number = 0; + String line, extranonce1; + unsigned long id = 1; unsigned int extranonce2_size; while(true) { @@ -143,47 +109,54 @@ void runWorker(void *name) { if(WiFi.status() != WL_CONNECTED) continue; // get template - StaticJsonDocument doc; - - char payload[BUFFER_JSON_DOC] = {0}; + DynamicJsonDocument doc(4 * 1024); + String payload; if (!client.connect(poolString, portNumber)) { continue; } - // STEP 1: Pool server connection (SUBSCRIBE) - // Docs: - // - https://cs.braiins.com/stratum-v1/docs - // - https://github.com/aeternity/protocol/blob/master/STRATUM.md#mining-subscribe - id = getNextId(id); - sprintf(payload, "{\"id\": %u, \"method\": \"mining.subscribe\", \"params\": [\"NerdMinerV2\"]}\n", id); + // STEP 1: Pool server connection + payload = "{\"id\": "+ String(id++) +", \"method\": \"mining.subscribe\", \"params\": [\"" + ADDRESS + "\", \"password\"]}\n"; Serial.printf("[WORKER] %s ==> Mining subscribe\n", (char *)name); Serial.print(" Sending : "); Serial.println(payload); - client.print(payload); + client.print(payload.c_str()); line = client.readStringUntil('\n'); if(!verifyPayload(line)) return; Serial.print(" Receiving: "); Serial.println(line); deserializeJson(doc, line); - if (checkError(doc)) { - Serial.printf("[WORKER] %s >>>>>>>>> Work aborted\n", (char *)name); - continue; - } + int error = doc["error"]; String sub_details = String((const char*) doc["result"][0][0][1]); extranonce1 = String((const char*) doc["result"][1]); int extranonce2_size = doc["result"][2]; // DIFFICULTY line = client.readStringUntil('\n'); - Serial.print(" Receiving: "); Serial.println(line); Serial.print(" sub_details: "); Serial.println(sub_details); Serial.print(" extranonce1: "); Serial.println(extranonce1); Serial.print(" extranonce2_size: "); Serial.println(extranonce2_size); - - // Recibe Work - //line = "{\"params\": [\"b3ba\", \"7dcf1304b04e79024066cd9481aa464e2fe17966e19edf6f33970e1fe0b60277\", \"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff270362f401062f503253482f049b8f175308\", \"0d2f7374726174756d506f6f6c2f000000000100868591052100001976a91431482118f1d7504daf1c001cbfaf91ad580d176d88ac00000000\", [\"57351e8569cb9d036187a79fd1844fd930c1309efcd16c46af9bb9713b6ee734\", \"936ab9c33420f187acae660fcdb07ffdffa081273674f0f41e6ecc1347451d23\"], \"00000002\", \"1b44dfdb\", \"53178f9b\", true], \"id\": null, \"method\": \"mining.notify\"}"; + Serial.print(" error: "); Serial.println(error); + if((extranonce1.length() == 0) || line.length() == 0 || (error != 0)) { + Serial.printf("[WORKER] %s >>>>>>>>> Work aborted\n", (char *)name); + Serial.printf("extranonce1 length: %u | line2 length: %u | error code: %u \n", extranonce1.length(), line.length(), error); + client.stop(); + doc.clear(); + doc.garbageCollect(); + continue; + } + + // STEP 2: Pool authorize work + payload = "{\"params\": [\"" + ADDRESS + "\", \"password\"], \"id\": "+ String(id++) +", \"method\": \"mining.authorize\"}\n"; + Serial.printf("[WORKER] %s ==> Autorize work\n", (char *)name); + Serial.print(" Sending : "); Serial.println(payload); + client.print(payload.c_str()); line = client.readStringUntil('\n'); - doc.clear(); + if(!verifyPayload(line)) return; + Serial.print(" Receiving: "); Serial.println(line); + Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n')); + Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n')); + client.stop(); + deserializeJson(doc, line); - Serial.print("doc size: "); Serial.println(doc.size()); String job_id = String((const char*) doc["params"][0]); String prevhash = String((const char*) doc["params"][1]); String coinb1 = String((const char*) doc["params"][2]); @@ -194,28 +167,6 @@ void runWorker(void *name) { String ntime = String((const char*) doc["params"][7]); bool clean_jobs = doc["params"][8]; //bool - if((extranonce1.length() == 0) || line.length() == 0) { - Serial.printf("[WORKER] %s >>>>>>>>> Work aborted\n", (char *)name); - Serial.printf("extranonce1 length: %u | line2 length: %u \n", extranonce1.length(), line.length()); - client.stop(); - doc.clear(); - doc.garbageCollect(); - continue; - } - - // STEP 2: Pool authorize work (Block Info) - id = getNextId(id); - sprintf(payload, "{\"params\": [\"%s\", \"x\"], \"id\": %u, \"method\": \"mining.authorize\"}\n", - btcString, - id); - Serial.printf("[WORKER] %s ==> Autorize work\n", (char *)name); - Serial.print(" Sending : "); Serial.println(payload); - client.print(payload); - line = client.readStringUntil('\n'); - if(!verifyPayload(line)) return; - Serial.print(" Receiving: "); Serial.println(line); - client.stop(); - #ifdef DEBUG_MINING Serial.print(" job_id: "); Serial.println(job_id); Serial.print(" prevhash: "); Serial.println(prevhash); @@ -232,6 +183,7 @@ void runWorker(void *name) { Serial.println(">>>>>>>>> Worker aborted"); client.stop(); doc.clear(); + doc.garbageCollect(); continue; } @@ -244,7 +196,7 @@ void runWorker(void *name) { memset(target, '0', TARGET_BUFFER_SIZE); int zeros = (int) strtol(nbits.substring(0, 2).c_str(), 0, 16) - 3; memcpy(target + zeros - 2, nbits.substring(2).c_str(), nbits.length() - 2); - target[TARGET_BUFFER_SIZE] = 0; + target[TARGET_BUFFER_SIZE+1] = 0; Serial.print(" target: "); Serial.println(target); // bytearray target uint8_t bytearray_target[32]; @@ -262,15 +214,30 @@ void runWorker(void *name) { } // get extranonce2 - extranonce2 = hex(random.randint(0,2**32-1))[2:].zfill(2*extranonce2_size) - char extranonce2_char[2 * extranonce2_size+1]; - extranonce2.toCharArray(extranonce2_char, 2 * extranonce2_size + 1); - getNextExtranonce2(extranonce2_size, extranonce2_char); - //extranonce2 = String(extranonce2_char); - extranonce2 = "00000002"; - + uint32_t extranonce2_a_bin = esp_random(); + uint32_t extranonce2_b_bin = esp_random(); + String extranonce2_a = String(extranonce2_a_bin, HEX); + String extranonce2_b = String(extranonce2_b_bin, HEX); + uint8_t pad = 8 - extranonce2_a.length(); + char extranonce2_a_char[pad+1]; + for (int k = 0; k < pad; k++) { + extranonce2_a_char[k] = '0'; + } + extranonce2_a_char[pad+1] = 0; + extranonce2_a = String(extranonce2_a_char) + extranonce2_a; + + pad = 8 - extranonce2_b.length(); + char extranonce2_b_char[pad+1]; + for (int k = 0; k < pad; k++) { + extranonce2_b_char[k] = '0'; + } + + extranonce2_b_char[pad+1] = 0; + extranonce2_b = String(extranonce2_b_char) + extranonce2_b; + + String extranonce2 = String(extranonce2_a + extranonce2_b).substring(0, 17 - (2 * extranonce2_size)); //get coinbase - coinbase_hash_bin = hashlib.sha256(hashlib.sha256(binascii.unhexlify(coinbase)).digest()).digest() String coinbase = coinb1 + extranonce1 + extranonce2 + coinb2; - Serial.print(" coinbase: "); Serial.println(coinbase); size_t str_len = coinbase.length()/2; uint8_t bytearray[str_len]; @@ -281,7 +248,7 @@ void runWorker(void *name) { Serial.print(" coinbase: "); Serial.println(coinbase); Serial.print(" coinbase bytes - size: "); Serial.println(res); for (size_t i = 0; i < res; i++) - Serial.printf("%02x", bytearray[i]); + Serial.printf("%02x ", bytearray[i]); Serial.println("---"); #endif @@ -312,7 +279,7 @@ void runWorker(void *name) { memcpy(merkle_result, shaResult, sizeof(shaResult)); byte merkle_concatenated[32 * 2]; - for (size_t k=0; k < merkle_branch.size(); k++) { + for (size_t k=0; k>> STARTING TO HASH NONCES"); @@ -484,7 +444,7 @@ void runWorker(void *name) { Serial.println(""); */ hashes++; - if (nonce++> TARGET_NONCE) break; //exit + if (nonce++> MAX_NONCE) break; //exit // check if 16bit share if(hash[31]!=0) continue; @@ -497,30 +457,24 @@ void runWorker(void *name) { // check if valid header if(checkValid(hash, bytearray_target)){ - Serial.printf("[WORKER] %s CONGRATULATIONS! Valid completed with nonce: %d | 0x%x\n", (char *)name, nonce, nonce); - valids++; - Serial.printf("[WORKER] %s Submiting work valid!\n", (char *)name); - while (!client.connected()) { - client.connect(poolString, portNumber); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - // STEP 3: Submit mining job - id = getNextId(id); - sprintf(payload, "{\"params\": [\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"], \"id\": %u, \"method\": \"mining.submit\"}", - btcString, - job_id, - extranonce2, - ntime, - String(nonce, HEX), - id - ); - Serial.print(" Sending : "); Serial.println(payload); - client.print(payload); - Serial.print(" Receiving: "); Serial.println(client.readString()); - client.stop(); - // exit - nonce = MAX_NONCE; - break; + //Serial.printf("%s on core %d: ", (char *)name, xPortGetCoreID()); + Serial.printf("[WORKER] %s CONGRATULATIONS! Valid completed with nonce: %d | 0x%x\n", (char *)name, nonce, nonce); + valids++; + Serial.printf("[WORKER] %s Submiting work valid!\n", (char *)name); + while (!client.connected()) { + client.connect(poolString, portNumber); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + // STEP 3: Submit mining job + payload = "{\"params\": [\"" + ADDRESS + "\", \"" + job_id + "\", \"" + extranonce2 + "\", \"" + ntime + "\", \"" + String(nonce, HEX) + "\"], \"id\": "+ String(id++) +", \"method\": \"mining.submit\"}"; + Serial.print(" Sending : "); Serial.println(payload); + client.print(payload.c_str()); + line = client.readStringUntil('\n'); + Serial.print(" Receiving: "); Serial.println(line); + client.stop(); + // exit + nonce = MAX_NONCE; + break; } } // exit if found a valid result or nonce > MAX_NONCE @@ -528,31 +482,22 @@ void runWorker(void *name) { mbedtls_sha256_free(midstate); enableGlobalHash = false; - // TODO Pending doub if(hashes>=MAX_NONCE) { Mhashes=Mhashes+MAX_NONCE/1000000; hashes=hashes-MAX_NONCE;} - if (nonce == TARGET_NONCE) { + if (nonce == MAX_NONCE) { Serial.printf("[WORKER] %s SUBMITING WORK... MAX Nonce reached > MAX_NONCE\n", (char *)name); // STEP 3: Submit mining job - id = getNextId(id); if (client.connect(poolString, portNumber)) { - sprintf(payload, "{\"params\": [\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"], \"id\": %u, \"method\": \"mining.submit\"}", - btcString, - job_id, - extranonce2, - ntime, - String(nonce, HEX), - id - ); + payload = "{\"params\": [\"" + ADDRESS + "\", \"" + job_id + "\", \"" + extranonce2 + "\", \"" + ntime + "\", \"" + String(nonce, HEX) + "\"], \"id\": "+ String(id++) +", \"method\": \"mining.submit\"}"; Serial.print(" Sending : "); Serial.println(payload); - client.print(payload); - unsigned long timeout = millis(); - Serial.print(" Receiving: "); Serial.println(client.readString()); - Serial.printf("[WORKER] %s SUBMITED WORK\n", (char *)name); + client.print(payload.c_str()); + Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n')); + while (client.available()) { + Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n')); + } client.stop(); } } - uint32_t duration = micros() - startT; } @@ -560,10 +505,11 @@ void runWorker(void *name) { //////////////////THREAD CALLS/////////////////// + //Testeamos hashrate final usando hilo principal //this is currently on test -void runMiner(void) { +void runMiner(void){ uint32_t nonce=0; unsigned char bytearray_blockheader[80]; @@ -580,7 +526,7 @@ void runMiner(void) { //Iteraciones unsigned char *header64 = bytearray_blockheader + 64; - for(nonce = 0; nonce < 10000; nonce++) { + for(nonce = 0; nonce < 10000; nonce++){ memcpy(bytearray_blockheader + 77, &nonce, 3); mbedtls_sha256_clone(&ctx, midstate); //Clonamos el contexto anterior para continuar el SHA desde allĂ­ mbedtls_sha256_update_ret(&ctx, header64, 16); @@ -599,7 +545,7 @@ void runMiner(void) { } -void runMonitor() { +void runMonitor(void *name){ Serial.println("[MONITOR] started"); @@ -610,9 +556,8 @@ void runMonitor() { unsigned long mElapsed = millis()-mStart; unsigned long totalKHashes = (Mhashes*1000) + hashes/1000; //Serial.println("[runMonitor Task] -> Printing results on screen "); - - //Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %.3f KH/s\n", - // shares, totalKHashes, (1.0*(totalKHashes*1000))/mElapsed); + Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %.3f KH/s\n", + shares, totalKHashes, (1.0*(totalKHashes*1000))/mElapsed); //Hashrate render.setFontSize(70); @@ -654,6 +599,6 @@ void runMonitor() { background.pushSprite(0,0); // Pause the task for 5000ms - // vTaskDelay(5000 / portTICK_PERIOD_MS); + vTaskDelay(5000 / portTICK_PERIOD_MS); } } diff --git a/src/mining.h b/src/mining.h index ffc5093..eadc0b6 100644 --- a/src/mining.h +++ b/src/mining.h @@ -1,9 +1,14 @@ // Mining #define THREADS 1 -#define MAX_NONCE 5000000U -#define TARGET_NONCE 471136297U +#define MAX_NONCE 3000000 +// #define MAX_NONCE 1.215.752.192 -void runMonitor(); +// Pool +//#define POOL_URL "solo.ckpool.org" //"btc.zsolo.bid" "eu.stratum.slushpool.com" +//#define POOL_PORT 3333 //6057 //3333 + + +void runMonitor(void *name); void runWorker(void *name); void runMiner(void); \ No newline at end of file