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
#define WDT_TIMEOUT 3
//120 seconds WDT for miner task
#define WDT_MINER_TIMEOUT 120
OneButton button1(PIN_BUTTON_1);
OneButton button2(PIN_BUTTON_2);
@ -56,6 +58,7 @@ void setup()
Serial.setTimeout(0);
delay(100);
esp_task_wdt_init(WDT_MINER_TIMEOUT, true);
// Idle task that would reset WDT never runs, because core 0 gets fully utilized
disableCore0WDT();
//disableCore1WDT();
@ -137,8 +140,11 @@ void setup()
// Start mining tasks
//BaseType_t res = xTaskCreate(runWorker, name, 35000, (void*)name, 1, NULL);
xTaskCreate(runMiner, "Miner0", 15000, NULL, 1, NULL);
xTaskCreate(runMiner, "Miner1", 15000, NULL, 1, NULL);
TaskHandle_t minerTask1, minerTask2 = 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 *****/
setup_monitor();
@ -164,4 +170,4 @@ void loop() {
wifiManagerProcess(); // avoid delays() in loop when non-blocking and other long running code
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}

View File

@ -1,6 +1,7 @@
#include <Arduino.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include <esp_task_wdt.h>
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include <wolfssl/wolfcrypt/sha256.h>
#include "media/Free_Fonts.h"
@ -110,12 +111,14 @@ void runStratumWorker(void *name) {
// connect to pool
float currentPoolDifficulty = atof(DEFAULT_DIFFICULTY);
double currentPoolDifficulty = DEFAULT_DIFFICULTY;
while(true) {
if(WiFi.status() != WL_CONNECTED){
vTaskDelay(1000 / portTICK_PERIOD_MS);
// WiFi is disconnected, so reconnect now
WiFi.reconnect();
vTaskDelay(5000 / portTICK_PERIOD_MS);
continue;
}
@ -210,12 +213,12 @@ void runStratumWorker(void *name) {
//This works only with one thread, TODO -> Class or miner_data for each thread
#include "shaTests/jadeSHA256.h"
#include "shaTests/customSHA256.h"
#include "mbedtls/sha256.h"
void runMiner(void * name){
unsigned long nonce;
unsigned long max_nonce;
//#include "shaTests/jadeSHA256.h"
//#include "shaTests/customSHA256.h"
//#include "mbedtls/sha256.h"
void runMiner(void * task_id) {
unsigned int miner_id = (uint32_t)task_id;
while(1){
@ -226,16 +229,10 @@ void runMiner(void * name){
}
vTaskDelay(10 / portTICK_PERIOD_MS); //Small delay to join both mining threads
if(mMiner.newJob) {
if(mMiner.newJob)
mMiner.newJob = false; //Clear newJob flag
nonce = 0;
max_nonce = MAX_NONCE;
}
else if(mMiner.newJob2){
else if(mMiner.newJob2)
mMiner.newJob2 = false; //Clear newJob flag
nonce = TARGET_NONCE - MAX_NONCE;
max_nonce = TARGET_NONCE;
}
mMiner.inRun = true; //Set inRun flag
//Prepare Premining data
@ -258,11 +255,23 @@ void runMiner(void * name){
Serial.println("");
*/
// 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();
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");
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
// Primer SHA-256
@ -283,11 +292,15 @@ void runMiner(void * name){
Serial.println(""); */
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;}
// 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++;
//Check target to submit
@ -304,26 +317,40 @@ void runMiner(void * name){
Serial.print(" - TX SHARE: ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash[i]);
Serial.println("");
#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("");
mLastTXtoPool = millis();
}
// 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++;
// check if valid header
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++;
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
tx_mining_submit(client, mWorker, mJob, nonce);
client.stop();
// exit
nonce = MAX_NONCE;
break;
}
}
// increment nonce
nonce += 2;
} // exit if found a valid result or nonce > MAX_NONCE
wc_Sha256Free(&sha256);
@ -338,6 +365,8 @@ void runMiner(void * name){
}
uint32_t duration = micros() - startT;
if (esp_task_wdt_reset() == ESP_OK)
Serial.print(">>> Resetting watchdog timer");
}
}

View File

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

View File

@ -176,15 +176,15 @@ bool parse_mining_notify(String line, mining_job& mJob)
mJob.clean_jobs = doc["params"][8]; //bool
#ifdef DEBUG_MINING
Serial.print(" job_id: "); Serial.println(job_id);
Serial.print(" prevhash: "); Serial.println(prev_block_hash);
Serial.print(" coinb1: "); Serial.println(coinb1);
Serial.print(" coinb2: "); Serial.println(coinb2);
Serial.print(" merkle_branch size: "); Serial.println(merkle_branches.size());
Serial.print(" version: "); Serial.println(version);
Serial.print(" nbits: "); Serial.println(nbits);
Serial.print(" ntime: "); Serial.println(ntime);
Serial.print(" clean_jobs: "); Serial.println(clean_jobs);
Serial.print(" job_id: "); Serial.println(mJob.job_id);
Serial.print(" prevhash: "); Serial.println(mJob.prev_block_hash);
Serial.print(" coinb1: "); Serial.println(mJob.coinb1);
Serial.print(" coinb2: "); Serial.println(mJob.coinb2);
Serial.print(" merkle_branch size: "); Serial.println(mJob.merkle_branch.size());
Serial.print(" version: "); Serial.println(mJob.version);
Serial.print(" nbits: "); Serial.println(mJob.nbits);
Serial.print(" ntime: "); Serial.println(mJob.ntime);
Serial.print(" clean_jobs: "); Serial.println(mJob.clean_jobs);
#endif
//Check if parameters where correctly received
if (checkError(doc)) {
@ -216,7 +216,7 @@ bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job m
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]");
if(!verifyPayload(&line)) return false;
@ -226,22 +226,18 @@ bool parse_mining_set_difficulty(String line, float& difficulty)
if (error) return false;
if (!doc.containsKey("params")) return false;
Serial.print(" difficulty: "); Serial.println((float)doc["params"][0],12);
difficulty = (float)doc["params"][0];
#ifdef DEBUG_MINING
Serial.print(" job_id: "); Serial.println(job_id);
#endif
Serial.print(" difficulty: "); Serial.println((double)doc["params"][0],12);
difficulty = (double)doc["params"][0];
return true;
}
bool tx_suggest_difficulty(WiFiClient& client, const char * difficulty)
bool tx_suggest_difficulty(WiFiClient& client, double difficulty)
{
char payload[BUFFER] = {0};
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);
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);
//Difficulty Methods
bool tx_suggest_difficulty(WiFiClient& client, const char * difficulty);
bool parse_mining_set_difficulty(String line, float& difficulty);
bool tx_suggest_difficulty(WiFiClient& client, double difficulty);
bool parse_mining_set_difficulty(String line, double& difficulty);
#endif // STRATUM_API_H

View File

@ -83,16 +83,16 @@ double le256todouble(const void *target)
double dcut64;
data64 = (uint64_t *)(target + 24);
dcut64 = bswap64(*data64) * 6277101735386680763835789423207666416102355444464034512896.0;
dcut64 = *data64 * 6277101735386680763835789423207666416102355444464034512896.0;
data64 = (uint64_t *)(target + 16);
dcut64 += bswap64(*data64) * 340282366920938463463374607431768211456.0;
dcut64 += *data64 * 340282366920938463463374607431768211456.0;
data64 = (uint64_t *)(target + 8);
dcut64 += bswap64(*data64) * 18446744073709551616.0;
dcut64 += *data64 * 18446744073709551616.0;
data64 = (uint64_t *)(target);
dcut64 += bswap64(*data64);
dcut64 += *data64;
return dcut64;
}
@ -100,7 +100,6 @@ double le256todouble(const void *target)
double diff_from_target(void *target)
{
double d64, dcut64;
//reverse_bytes((uint8_t *) target, 32);
d64 = truediffone;
dcut64 = le256todouble(target);
@ -155,7 +154,7 @@ miner_data init_miner_data(void){
miner_data newMinerData;
newMinerData.poolDifficulty = atof(DEFAULT_DIFFICULTY);
newMinerData.poolDifficulty = DEFAULT_DIFFICULTY;
newMinerData.inRun = 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);
#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 bytes - size: "); Serial.println(res);
for (size_t i = 0; i < res; i++)
@ -271,7 +270,7 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
#ifdef DEBUG_MINING
Serial.print(" merkle sha : ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", merkle_result[i]);
Serial.printf("%02x", mMiner.merkle_result[i]);
Serial.println("");
#endif
}
@ -285,22 +284,23 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
}
merkle_root[65] = 0;
Serial.println("");
// calculate blockheader
// 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";
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);
#ifdef DEBUG_MINING
Serial.println(" blockheader: "); Serial.print(blockheader);
Serial.println(" blockheader bytes "); Serial.print(str_len); Serial.print(" -> ");
#endif
// reverse version
uint8_t buff;
size_t bsize, boffset;
size_t bword, bsize, boffset;
boffset = 0;
bsize = 4;
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;
}
// reverse merkle
boffset = 36;
// reverse prev hash (4-byte word swap)
boffset = 4;
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 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++) {
buff = mMiner.bytearray_blockheader[j];
mMiner.bytearray_blockheader[j] = mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j];
mMiner.bytearray_blockheader[2 * boffset + bsize - 1 - j] = buff;
}
// reverse difficulty
boffset = 72;
bsize = 4;
@ -330,35 +358,35 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
#ifdef DEBUG_MINING
Serial.print(" >>> bytearray_blockheader : ");
for (size_t i = 0; i < 4; i++)
Serial.printf("%02x", bytearray_blockheader[i]);
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println("");
Serial.print("version ");
for (size_t i = 0; i < 4; i++)
Serial.printf("%02x", bytearray_blockheader[i]);
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println("");
Serial.print("prev hash ");
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.print("merkle root ");
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.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++)
Serial.printf("%02x", bytearray_blockheader[i]);
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println("");
Serial.print("nonce ");
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("bytearray_blockheader: ");
for (size_t i = 0; i < str_len; i++) {
Serial.printf("%02x", bytearray_blockheader[i]);
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
}
Serial.println("");
#endif