Merge pull request #100 from golden-guy/bitmaker-dev

Essential Nerdminer code rework
This commit is contained in:
BitMaker 2023-07-24 16:43:12 +02:00 committed by GitHub
commit 2d23e6a9d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 74 deletions

View File

@ -20,6 +20,8 @@
//3 seconds WDT //3 seconds WDT
#define WDT_TIMEOUT 3 #define WDT_TIMEOUT 3
//120 seconds WDT for miner task
#define WDT_MINER_TIMEOUT 120
OneButton button1(PIN_BUTTON_1); OneButton button1(PIN_BUTTON_1);
OneButton button2(PIN_BUTTON_2); OneButton button2(PIN_BUTTON_2);
@ -56,6 +58,7 @@ void setup()
Serial.setTimeout(0); Serial.setTimeout(0);
delay(100); delay(100);
esp_task_wdt_init(WDT_MINER_TIMEOUT, true);
// Idle task that would reset WDT never runs, because core 0 gets fully utilized // Idle task that would reset WDT never runs, because core 0 gets fully utilized
disableCore0WDT(); disableCore0WDT();
//disableCore1WDT(); //disableCore1WDT();
@ -137,8 +140,11 @@ void setup()
// Start mining tasks // Start mining tasks
//BaseType_t res = xTaskCreate(runWorker, name, 35000, (void*)name, 1, NULL); //BaseType_t res = xTaskCreate(runWorker, name, 35000, (void*)name, 1, NULL);
xTaskCreate(runMiner, "Miner0", 15000, NULL, 1, NULL); TaskHandle_t minerTask1, minerTask2 = NULL;
xTaskCreate(runMiner, "Miner1", 15000, NULL, 1, NULL); xTaskCreate(runMiner, "Miner0", 15000, (void*)0, 1, &minerTask1);
xTaskCreate(runMiner, "Miner1", 15000, (void*)1, 1, &minerTask2);
esp_task_wdt_add(minerTask1);
esp_task_wdt_add(minerTask2);
/******** MONITOR SETUP *****/ /******** MONITOR SETUP *****/
setup_monitor(); setup_monitor();

View File

@ -1,6 +1,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <WiFi.h> #include <WiFi.h>
#include <esp_task_wdt.h>
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip #include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include <wolfssl/wolfcrypt/sha256.h> #include <wolfssl/wolfcrypt/sha256.h>
#include "media/Free_Fonts.h" #include "media/Free_Fonts.h"
@ -110,12 +111,14 @@ void runStratumWorker(void *name) {
// connect to pool // connect to pool
float currentPoolDifficulty = atof(DEFAULT_DIFFICULTY); double currentPoolDifficulty = DEFAULT_DIFFICULTY;
while(true) { while(true) {
if(WiFi.status() != WL_CONNECTED){ if(WiFi.status() != WL_CONNECTED){
vTaskDelay(1000 / portTICK_PERIOD_MS); // WiFi is disconnected, so reconnect now
WiFi.reconnect();
vTaskDelay(5000 / portTICK_PERIOD_MS);
continue; continue;
} }
@ -210,12 +213,12 @@ void runStratumWorker(void *name) {
//This works only with one thread, TODO -> Class or miner_data for each thread //This works only with one thread, TODO -> Class or miner_data for each thread
#include "shaTests/jadeSHA256.h" //#include "shaTests/jadeSHA256.h"
#include "shaTests/customSHA256.h" //#include "shaTests/customSHA256.h"
#include "mbedtls/sha256.h" //#include "mbedtls/sha256.h"
void runMiner(void * name){ void runMiner(void * task_id) {
unsigned long nonce;
unsigned long max_nonce; unsigned int miner_id = (uint32_t)task_id;
while(1){ while(1){
@ -226,16 +229,10 @@ void runMiner(void * name){
} }
vTaskDelay(10 / portTICK_PERIOD_MS); //Small delay to join both mining threads vTaskDelay(10 / portTICK_PERIOD_MS); //Small delay to join both mining threads
if(mMiner.newJob) { if(mMiner.newJob)
mMiner.newJob = false; //Clear newJob flag mMiner.newJob = false; //Clear newJob flag
nonce = 0; else if(mMiner.newJob2)
max_nonce = MAX_NONCE;
}
else if(mMiner.newJob2){
mMiner.newJob2 = false; //Clear newJob flag mMiner.newJob2 = false; //Clear newJob flag
nonce = TARGET_NONCE - MAX_NONCE;
max_nonce = TARGET_NONCE;
}
mMiner.inRun = true; //Set inRun flag mMiner.inRun = true; //Set inRun flag
//Prepare Premining data //Prepare Premining data
@ -258,11 +255,23 @@ void runMiner(void * name){
Serial.println(""); Serial.println("");
*/ */
// search a valid nonce // search a valid nonce
unsigned long nonce = TARGET_NONCE - MAX_NONCE;
// split up odd/even nonces between miner tasks
nonce += miner_id;
uint32_t startT = micros(); uint32_t startT = micros();
unsigned char *header64 = mMiner.bytearray_blockheader + 64; unsigned char *header64;
// each miner thread needs to track its own blockheader template
memcpy(mMiner.bytearray_blockheader2, &mMiner.bytearray_blockheader, 80);
if (miner_id == 0)
header64 = mMiner.bytearray_blockheader + 64;
else
header64 = mMiner.bytearray_blockheader2 + 64;
Serial.println(">>> STARTING TO HASH NONCES"); Serial.println(">>> STARTING TO HASH NONCES");
while(true) { while(true) {
memcpy(mMiner.bytearray_blockheader + 76, &nonce, 4); if (miner_id == 0)
memcpy(mMiner.bytearray_blockheader + 76, &nonce, 4);
else
memcpy(mMiner.bytearray_blockheader2 + 76, &nonce, 4);
//Con midstate //Con midstate
// Primer SHA-256 // Primer SHA-256
@ -283,11 +292,15 @@ void runMiner(void * name){
Serial.println(""); */ Serial.println(""); */
hashes++; hashes++;
if (nonce++> max_nonce) break; //exit if (nonce > TARGET_NONCE) break; //exit
if(!mMiner.inRun) { Serial.println ("MINER WORK ABORTED >> waiting new job"); break;} if(!mMiner.inRun) { Serial.println ("MINER WORK ABORTED >> waiting new job"); break;}
// check if 16bit share // check if 16bit share
if(hash[31] !=0 || hash[30] !=0) continue; if(hash[31] !=0 || hash[30] !=0) {
// increment nonce
nonce += 2;
continue;
}
halfshares++; halfshares++;
//Check target to submit //Check target to submit
@ -304,19 +317,31 @@ void runMiner(void * name){
Serial.print(" - TX SHARE: "); Serial.print(" - TX SHARE: ");
for (size_t i = 0; i < 32; i++) for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash[i]); Serial.printf("%02x", hash[i]);
#ifdef DEBUG_MINING
Serial.println("");
Serial.print(" - Current nonce: "); Serial.println(nonce);
Serial.print(" - Current block header: ");
for (size_t i = 0; i < 80; i++) {
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
}
#endif
Serial.println(""); Serial.println("");
mLastTXtoPool = millis(); mLastTXtoPool = millis();
} }
// check if 32bit share // check if 32bit share
if(hash[29] !=0 || hash[28] !=0) continue; if(hash[29] !=0 || hash[28] !=0) {
// increment nonce
nonce += 2;
continue;
}
shares++; shares++;
// check if valid header // check if valid header
if(checkValid(hash, mMiner.bytearray_target)){ if(checkValid(hash, mMiner.bytearray_target)){
Serial.printf("[WORKER] %s CONGRATULATIONS! Valid completed with nonce: %d | 0x%x\n", (char *)name, nonce, nonce); Serial.printf("[WORKER] %d CONGRATULATIONS! Valid block found with nonce: %d | 0x%x\n", miner_id, nonce, nonce);
valids++; valids++;
Serial.printf("[WORKER] %s Submiting work valid!\n", (char *)name); Serial.printf("[WORKER] %d Submitted work valid!\n", miner_id);
// STEP 3: Submit mining job // STEP 3: Submit mining job
tx_mining_submit(client, mWorker, mJob, nonce); tx_mining_submit(client, mWorker, mJob, nonce);
client.stop(); client.stop();
@ -324,6 +349,8 @@ void runMiner(void * name){
nonce = MAX_NONCE; nonce = MAX_NONCE;
break; break;
} }
// increment nonce
nonce += 2;
} // exit if found a valid result or nonce > MAX_NONCE } // exit if found a valid result or nonce > MAX_NONCE
wc_Sha256Free(&sha256); wc_Sha256Free(&sha256);
@ -338,6 +365,8 @@ void runMiner(void * name){
} }
uint32_t duration = micros() - startT; uint32_t duration = micros() - startT;
if (esp_task_wdt_reset() == ESP_OK)
Serial.print(">>> Resetting watchdog timer");
} }
} }

View File

@ -5,7 +5,7 @@
// Mining // Mining
#define MAX_NONCE 5000000U #define MAX_NONCE 5000000U
#define TARGET_NONCE 471136297U #define TARGET_NONCE 471136297U
#define DEFAULT_DIFFICULTY "1e-9" #define DEFAULT_DIFFICULTY 1e-4
#define KEEPALIVE_TIME_ms 30000 #define KEEPALIVE_TIME_ms 30000
#define POOLINACTIVITY_TIME_ms 60000 #define POOLINACTIVITY_TIME_ms 60000
@ -21,7 +21,8 @@ typedef struct{
uint8_t bytearray_pooltarget[32]; uint8_t bytearray_pooltarget[32];
uint8_t merkle_result[32]; uint8_t merkle_result[32];
uint8_t bytearray_blockheader[80]; uint8_t bytearray_blockheader[80];
float poolDifficulty; uint8_t bytearray_blockheader2[80];
double poolDifficulty;
bool inRun; bool inRun;
bool newJob; bool newJob;
bool newJob2; bool newJob2;

View File

@ -176,15 +176,15 @@ bool parse_mining_notify(String line, mining_job& mJob)
mJob.clean_jobs = doc["params"][8]; //bool mJob.clean_jobs = doc["params"][8]; //bool
#ifdef DEBUG_MINING #ifdef DEBUG_MINING
Serial.print(" job_id: "); Serial.println(job_id); Serial.print(" job_id: "); Serial.println(mJob.job_id);
Serial.print(" prevhash: "); Serial.println(prev_block_hash); Serial.print(" prevhash: "); Serial.println(mJob.prev_block_hash);
Serial.print(" coinb1: "); Serial.println(coinb1); Serial.print(" coinb1: "); Serial.println(mJob.coinb1);
Serial.print(" coinb2: "); Serial.println(coinb2); Serial.print(" coinb2: "); Serial.println(mJob.coinb2);
Serial.print(" merkle_branch size: "); Serial.println(merkle_branches.size()); Serial.print(" merkle_branch size: "); Serial.println(mJob.merkle_branch.size());
Serial.print(" version: "); Serial.println(version); Serial.print(" version: "); Serial.println(mJob.version);
Serial.print(" nbits: "); Serial.println(nbits); Serial.print(" nbits: "); Serial.println(mJob.nbits);
Serial.print(" ntime: "); Serial.println(ntime); Serial.print(" ntime: "); Serial.println(mJob.ntime);
Serial.print(" clean_jobs: "); Serial.println(clean_jobs); Serial.print(" clean_jobs: "); Serial.println(mJob.clean_jobs);
#endif #endif
//Check if parameters where correctly received //Check if parameters where correctly received
if (checkError(doc)) { if (checkError(doc)) {
@ -216,7 +216,7 @@ bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job m
return true; return true;
} }
bool parse_mining_set_difficulty(String line, float& difficulty) bool parse_mining_set_difficulty(String line, double& difficulty)
{ {
Serial.println(" Parsing Method [SET DIFFICULTY]"); Serial.println(" Parsing Method [SET DIFFICULTY]");
if(!verifyPayload(&line)) return false; if(!verifyPayload(&line)) return false;
@ -226,22 +226,18 @@ bool parse_mining_set_difficulty(String line, float& difficulty)
if (error) return false; if (error) return false;
if (!doc.containsKey("params")) return false; if (!doc.containsKey("params")) return false;
Serial.print(" difficulty: "); Serial.println((float)doc["params"][0],12); Serial.print(" difficulty: "); Serial.println((double)doc["params"][0],12);
difficulty = (float)doc["params"][0]; difficulty = (double)doc["params"][0];
#ifdef DEBUG_MINING
Serial.print(" job_id: "); Serial.println(job_id);
#endif
return true; return true;
} }
bool tx_suggest_difficulty(WiFiClient& client, const char * difficulty) bool tx_suggest_difficulty(WiFiClient& client, double difficulty)
{ {
char payload[BUFFER] = {0}; char payload[BUFFER] = {0};
id = getNextId(id); id = getNextId(id);
sprintf(payload, "{\"id\": %d, \"method\": \"mining.suggest_difficulty\", \"params\": [%s]}\n", id, difficulty); sprintf(payload, "{\"id\": %d, \"method\": \"mining.suggest_difficulty\", \"params\": [%.10g]}\n", id, difficulty);
Serial.print(" Sending : "); Serial.print(payload); Serial.print(" Sending : "); Serial.print(payload);
return client.print(payload); return client.print(payload);

View File

@ -62,8 +62,8 @@ bool parse_mining_notify(String line, mining_job& mJob);
bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job mJob, unsigned long nonce); bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job mJob, unsigned long nonce);
//Difficulty Methods //Difficulty Methods
bool tx_suggest_difficulty(WiFiClient& client, const char * difficulty); bool tx_suggest_difficulty(WiFiClient& client, double difficulty);
bool parse_mining_set_difficulty(String line, float& difficulty); bool parse_mining_set_difficulty(String line, double& difficulty);
#endif // STRATUM_API_H #endif // STRATUM_API_H

View File

@ -83,16 +83,16 @@ double le256todouble(const void *target)
double dcut64; double dcut64;
data64 = (uint64_t *)(target + 24); data64 = (uint64_t *)(target + 24);
dcut64 = bswap64(*data64) * 6277101735386680763835789423207666416102355444464034512896.0; dcut64 = *data64 * 6277101735386680763835789423207666416102355444464034512896.0;
data64 = (uint64_t *)(target + 16); data64 = (uint64_t *)(target + 16);
dcut64 += bswap64(*data64) * 340282366920938463463374607431768211456.0; dcut64 += *data64 * 340282366920938463463374607431768211456.0;
data64 = (uint64_t *)(target + 8); data64 = (uint64_t *)(target + 8);
dcut64 += bswap64(*data64) * 18446744073709551616.0; dcut64 += *data64 * 18446744073709551616.0;
data64 = (uint64_t *)(target); data64 = (uint64_t *)(target);
dcut64 += bswap64(*data64); dcut64 += *data64;
return dcut64; return dcut64;
} }
@ -100,7 +100,6 @@ double le256todouble(const void *target)
double diff_from_target(void *target) double diff_from_target(void *target)
{ {
double d64, dcut64; double d64, dcut64;
//reverse_bytes((uint8_t *) target, 32);
d64 = truediffone; d64 = truediffone;
dcut64 = le256todouble(target); dcut64 = le256todouble(target);
@ -155,7 +154,7 @@ miner_data init_miner_data(void){
miner_data newMinerData; miner_data newMinerData;
newMinerData.poolDifficulty = atof(DEFAULT_DIFFICULTY); newMinerData.poolDifficulty = DEFAULT_DIFFICULTY;
newMinerData.inRun = false; newMinerData.inRun = false;
newMinerData.newJob = false; newMinerData.newJob = false;
@ -201,7 +200,7 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
size_t res = to_byte_array(coinbase.c_str(), str_len*2, bytearray); size_t res = to_byte_array(coinbase.c_str(), str_len*2, bytearray);
#ifdef DEBUG_MINING #ifdef DEBUG_MINING
Serial.print(" extranonce2: "); Serial.println(extranonce2); Serial.print(" extranonce2: "); Serial.println(mWorker.extranonce2);
Serial.print(" coinbase: "); Serial.println(coinbase); Serial.print(" coinbase: "); Serial.println(coinbase);
Serial.print(" coinbase bytes - size: "); Serial.println(res); Serial.print(" coinbase bytes - size: "); Serial.println(res);
for (size_t i = 0; i < res; i++) for (size_t i = 0; i < res; i++)
@ -271,7 +270,7 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
#ifdef DEBUG_MINING #ifdef DEBUG_MINING
Serial.print(" merkle sha : "); Serial.print(" merkle sha : ");
for (size_t i = 0; i < 32; i++) for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", merkle_result[i]); Serial.printf("%02x", mMiner.merkle_result[i]);
Serial.println(""); Serial.println("");
#endif #endif
} }
@ -295,12 +294,13 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
res = to_byte_array(blockheader.c_str(), str_len*2, mMiner.bytearray_blockheader); res = to_byte_array(blockheader.c_str(), str_len*2, mMiner.bytearray_blockheader);
#ifdef DEBUG_MINING #ifdef DEBUG_MINING
Serial.println(" blockheader: "); Serial.print(blockheader);
Serial.println(" blockheader bytes "); Serial.print(str_len); Serial.print(" -> "); Serial.println(" blockheader bytes "); Serial.print(str_len); Serial.print(" -> ");
#endif #endif
// reverse version // reverse version
uint8_t buff; uint8_t buff;
size_t bsize, boffset; size_t bword, bsize, boffset;
boffset = 0; boffset = 0;
bsize = 4; bsize = 4;
for (size_t j = boffset; j < boffset + (bsize/2); j++) { for (size_t j = boffset; j < boffset + (bsize/2); j++) {
@ -309,14 +309,42 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j] = buff; mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j] = buff;
} }
// reverse merkle // reverse prev hash (4-byte word swap)
boffset = 36; boffset = 4;
bword = 4;
bsize = 32; bsize = 32;
for (size_t i = 1; i <= bsize / bword; i++) {
for (size_t j = boffset; j < boffset + bword / 2; j++) {
buff = mMiner.bytearray_blockheader[j];
mMiner.bytearray_blockheader[j] = mMiner.bytearray_blockheader[2 * boffset + bword - 1 - j];
mMiner.bytearray_blockheader[2 * boffset + bword - 1 - j] = buff;
}
boffset += bword;
}
/*
// reverse merkle (4-byte word swap)
boffset = 36;
bword = 4;
bsize = 32;
for (size_t i = 1; i <= bsize / bword; i++) {
for (size_t j = boffset; j < boffset + bword / 2; j++) {
buff = mMiner.bytearray_blockheader[j];
mMiner.bytearray_blockheader[j] = mMiner.bytearray_blockheader[2 * boffset + bword - 1 - j];
mMiner.bytearray_blockheader[2 * boffset + bword - 1 - j] = buff;
}
boffset += bword;
}
*/
// reverse ntime
boffset = 68;
bsize = 4;
for (size_t j = boffset; j < boffset + (bsize/2); j++) { for (size_t j = boffset; j < boffset + (bsize/2); j++) {
buff = mMiner.bytearray_blockheader[j]; buff = mMiner.bytearray_blockheader[j];
mMiner.bytearray_blockheader[j] = mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j]; mMiner.bytearray_blockheader[j] = mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j];
mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j] = buff; mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j] = buff;
} }
// reverse difficulty // reverse difficulty
boffset = 72; boffset = 72;
bsize = 4; bsize = 4;
@ -330,35 +358,35 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
#ifdef DEBUG_MINING #ifdef DEBUG_MINING
Serial.print(" >>> bytearray_blockheader : "); Serial.print(" >>> bytearray_blockheader : ");
for (size_t i = 0; i < 4; i++) for (size_t i = 0; i < 4; i++)
Serial.printf("%02x", bytearray_blockheader[i]); Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println(""); Serial.println("");
Serial.print("version "); Serial.print("version ");
for (size_t i = 0; i < 4; i++) for (size_t i = 0; i < 4; i++)
Serial.printf("%02x", bytearray_blockheader[i]); Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println(""); Serial.println("");
Serial.print("prev hash "); Serial.print("prev hash ");
for (size_t i = 4; i < 4+32; i++) for (size_t i = 4; i < 4+32; i++)
Serial.printf("%02x", bytearray_blockheader[i]); Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println(""); Serial.println("");
Serial.print("merkle root "); Serial.print("merkle root ");
for (size_t i = 36; i < 36+32; i++) for (size_t i = 36; i < 36+32; i++)
Serial.printf("%02x", bytearray_blockheader[i]); Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println("");
Serial.print("ntime ");
for (size_t i = 68; i < 68+4; i++)
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println(""); Serial.println("");
Serial.print("nbits "); Serial.print("nbits ");
for (size_t i = 68; i < 68+4; i++)
Serial.printf("%02x", bytearray_blockheader[i]);
Serial.println("");
Serial.print("difficulty ");
for (size_t i = 72; i < 72+4; i++) for (size_t i = 72; i < 72+4; i++)
Serial.printf("%02x", bytearray_blockheader[i]); Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println(""); Serial.println("");
Serial.print("nonce "); Serial.print("nonce ");
for (size_t i = 76; i < 76+4; i++) for (size_t i = 76; i < 76+4; i++)
Serial.printf("%02x", bytearray_blockheader[i]); Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println(""); Serial.println("");
Serial.println("bytearray_blockheader: "); Serial.println("bytearray_blockheader: ");
for (size_t i = 0; i < str_len; i++) { for (size_t i = 0; i < str_len; i++) {
Serial.printf("%02x", bytearray_blockheader[i]); Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
} }
Serial.println(""); Serial.println("");
#endif #endif