Merge pull request #100 from golden-guy/bitmaker-dev
Essential Nerdminer code rework
This commit is contained in:
commit
2d23e6a9d8
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user