Release 1.3

- Midstates implemented
- Known bug on lilygo TDisplayS3 5V external power
- Better stability current hashrate 22kHs
- Bug delete current config Release v1.2
This commit is contained in:
BitMaker 2023-05-01 22:26:01 +02:00
parent 360fb29df8
commit 638407a3e8
7 changed files with 184 additions and 128 deletions

Binary file not shown.

View File

@ -31,8 +31,8 @@ board_build.partitions = huge_app.csv
build_flags = build_flags =
-D LV_LVGL_H_INCLUDE_SIMPLE -D LV_LVGL_H_INCLUDE_SIMPLE
-D BOARD_HAS_PSRAM -D BOARD_HAS_PSRAM
;-D ARDUINO_USB_MODE=1 -D ARDUINO_USB_MODE=1
;-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_CDC_ON_BOOT=1
;-D DEBUG_MINING=1 ;-D DEBUG_MINING=1
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender

View File

@ -40,6 +40,7 @@ void setup()
// 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();
/******** INIT NERDMINER ************/ /******** INIT NERDMINER ************/
Serial.println("NerdMiner v2 starting......"); Serial.println("NerdMiner v2 starting......");
@ -117,6 +118,9 @@ void loop() {
oldStatus = newStatus; oldStatus = newStatus;
} }
checkRemoveConfiguration(); checkResetConfigButton();
//Run miner on main core when there is time --Currently on test
runMiner();
} }

View File

@ -6,6 +6,7 @@
#include "media/Free_Fonts.h" #include "media/Free_Fonts.h"
#include "media/images.h" #include "media/images.h"
#include "mbedtls/md.h" #include "mbedtls/md.h"
#include "mbedtls/sha256.h"
#include "OpenFontRender.h" #include "OpenFontRender.h"
#include "mining.h" #include "mining.h"
@ -18,6 +19,7 @@ unsigned long Mhashes = 0;
int halfshares; // increase if blockhash has 16 bits of zeroes int halfshares; // increase if blockhash has 16 bits of zeroes
int shares; // increase if blockhash has 32 bits of zeroes int shares; // increase if blockhash has 32 bits of zeroes
int valids; // increased if blockhash <= target int valids; // increased if blockhash <= target
bool enableGlobalHash = false;
// Variables to hold data from custom textboxes // Variables to hold data from custom textboxes
extern char poolString[80]; extern char poolString[80];
@ -27,42 +29,7 @@ extern char btcString[80];
extern OpenFontRender render; extern OpenFontRender render;
extern TFT_eSprite background; extern TFT_eSprite background;
bool checkHalfShare(unsigned char* hash) {
//bool valid = true;
for(uint8_t i=31; i>31-2; i--) {
if(hash[i] != 0) {
return false;
}
}
#ifdef DEBUG_MINING
if (valid) {
Serial.print("\thalf share : ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x ", hash[i]);
Serial.println();
}
#endif
return true;
}
bool checkShare(unsigned char* hash) {
bool valid = true;
for(uint8_t i=31; i>31-4; i--) {
if(hash[i] != 0) {
valid = false;
break;
}
}
#ifdef DEBUG_MINING
if (valid) {
Serial.print("\tshare : ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x ", hash[i]);
Serial.println();
}
#endif
return valid;
}
bool checkValid(unsigned char* hash, unsigned char* target) { bool checkValid(unsigned char* hash, unsigned char* target) {
bool valid = true; bool valid = true;
@ -111,17 +78,25 @@ int to_byte_array(const char *in, size_t in_size, uint8_t *out) {
return count; return count;
} }
} }
bool verifyPayload (String line){
String inData=line;
if(inData.length() == 0) return false;
inData.trim();
if(inData.isEmpty()) return false;
return true;
}
void runWorker(void *name) { void runWorker(void *name) {
// TEST: https://bitcoin.stackexchange.com/questions/22929/full-example-data-for-scrypt-stratum-client // TEST: https://bitcoin.stackexchange.com/questions/22929/full-example-data-for-scrypt-stratum-client
Serial.println(""); Serial.println("");
Serial.printf("\n[WORKER] Started. Running %s on core %d\n", (char *)name, xPortGetCoreID()); Serial.printf("\n[WORKER] Started. Running %s on core %d\n", (char *)name, xPortGetCoreID());
;Serial.printf("### [Total Heap / Free heap]: %d / %d \n", ESP.getHeapSize(), ESP.getFreeHeap()); Serial.printf("### [Total Heap / Free heap]: %d / %d \n", ESP.getHeapSize(), ESP.getFreeHeap());
String ADDRESS = String(btcString); String ADDRESS = String(btcString);
mbedtls_md_context_t ctx;
// connect to pool // connect to pool
WiFiClient client; WiFiClient client;
bool continueSecuence = false; bool continueSecuence = false;
@ -146,6 +121,7 @@ void runWorker(void *name) {
Serial.print(" Sending : "); Serial.println(payload); Serial.print(" Sending : "); Serial.println(payload);
client.print(payload.c_str()); client.print(payload.c_str());
line = client.readStringUntil('\n'); line = client.readStringUntil('\n');
if(!verifyPayload(line)) return;
Serial.print(" Receiving: "); Serial.println(line); Serial.print(" Receiving: "); Serial.println(line);
deserializeJson(doc, line); deserializeJson(doc, line);
int error = doc["error"]; int error = doc["error"];
@ -174,6 +150,7 @@ void runWorker(void *name) {
Serial.print(" Sending : "); Serial.println(payload); Serial.print(" Sending : "); Serial.println(payload);
client.print(payload.c_str()); client.print(payload.c_str());
line = client.readStringUntil('\n'); line = client.readStringUntil('\n');
if(!verifyPayload(line)) return;
Serial.print(" Receiving: "); Serial.println(line); Serial.print(" Receiving: "); Serial.println(line);
Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n')); Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n'));
Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n')); Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n'));
@ -275,20 +252,20 @@ void runWorker(void *name) {
Serial.println("---"); Serial.println("---");
#endif #endif
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; mbedtls_sha256_context ctx;
mbedtls_md_init(&ctx); mbedtls_sha256_init(&ctx);
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0);
byte interResult[32]; // 256 bit byte interResult[32]; // 256 bit
byte shaResult[32]; // 256 bit byte shaResult[32]; // 256 bit
mbedtls_md_starts(&ctx); mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_md_update(&ctx, bytearray, str_len); mbedtls_sha256_update_ret(&ctx, bytearray, str_len);
mbedtls_md_finish(&ctx, interResult); mbedtls_sha256_finish_ret(&ctx, interResult);
mbedtls_md_starts(&ctx); mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_md_update(&ctx, interResult, 32); mbedtls_sha256_update_ret(&ctx, interResult, 32);
mbedtls_md_finish(&ctx, shaResult); mbedtls_sha256_finish_ret(&ctx, shaResult);
mbedtls_sha256_free(&ctx);
#ifdef DEBUG_MINING #ifdef DEBUG_MINING
Serial.print(" coinbase double sha: "); Serial.print(" coinbase double sha: ");
@ -323,13 +300,16 @@ void runWorker(void *name) {
Serial.println(""); Serial.println("");
#endif #endif
mbedtls_md_starts(&ctx); mbedtls_sha256_context ctx;
mbedtls_md_update(&ctx, merkle_concatenated, 64); mbedtls_sha256_init(&ctx);
mbedtls_md_finish(&ctx, interResult); mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_sha256_update_ret(&ctx, merkle_concatenated, 64);
mbedtls_sha256_finish_ret(&ctx, interResult);
mbedtls_md_starts(&ctx); mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_md_update(&ctx, interResult, 32); mbedtls_sha256_update_ret(&ctx, interResult, 32);
mbedtls_md_finish(&ctx, merkle_result); mbedtls_sha256_finish_ret(&ctx, merkle_result);
mbedtls_sha256_free(&ctx);
#ifdef DEBUG_MINING #ifdef DEBUG_MINING
Serial.print(" merkle sha : "); Serial.print(" merkle sha : ");
@ -419,66 +399,91 @@ void runWorker(void *name) {
Serial.println(""); Serial.println("");
#endif #endif
mbedtls_sha256_context midstate[32];
unsigned char hash[32];
//Calcular midstate
mbedtls_sha256_init(midstate);
mbedtls_sha256_starts_ret(midstate, 0);
mbedtls_sha256_update_ret(midstate, bytearray_blockheader, 64);
// search a valid nonce // search a valid nonce
enableGlobalHash = true;
uint32_t nonce = 0; uint32_t nonce = 0;
uint32_t startT = micros(); uint32_t startT = micros();
bytearray_blockheader[79] = 0; //We only mine until 1MHashes this will allways be zero unsigned char *header64 = bytearray_blockheader + 64;
Serial.println(">>> STARTING TO HASH NONCES"); Serial.println(">>> STARTING TO HASH NONCES");
while(true) { while(true) {
bytearray_blockheader[76] = (nonce >> 0) & 0xFF; memcpy(bytearray_blockheader + 77, &nonce, 3);
bytearray_blockheader[77] = (nonce >> 8) & 0xFF;
bytearray_blockheader[78] = (nonce >> 16) & 0xFF;
bytearray_blockheader[79] = (nonce >> 24) & 0xFF;
// double sha // double sha
mbedtls_md_starts(&ctx); // Sin midstate
mbedtls_md_update(&ctx, bytearray_blockheader, 80); /*mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_md_finish(&ctx, interResult); mbedtls_sha256_update_ret(&ctx, bytearray_blockheader, 80);
mbedtls_sha256_finish_ret(&ctx, interResult);
mbedtls_md_starts(&ctx); mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_md_update(&ctx, interResult, 32); mbedtls_sha256_update_ret(&ctx, interResult, 32);
mbedtls_md_finish(&ctx, shaResult); mbedtls_sha256_finish_ret(&ctx, shaResult);
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", shaResult[i]);
Serial.println("");*/
// check if half share //Con midstate
if(checkHalfShare(shaResult)) { // Primer SHA-256
halfshares++; mbedtls_sha256_clone(&ctx, midstate); //Clonamos el contexto anterior para continuar el SHA desde allí
// check if share mbedtls_sha256_update_ret(&ctx, header64, 16);
if(checkShare(shaResult)) { mbedtls_sha256_finish_ret(&ctx, hash);
shares++;
// check if valid header
if(checkValid(shaResult, bytearray_target)) {
//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;
}
}
}
nonce++; // Segundo SHA-256
hashes++; mbedtls_sha256_starts_ret(&ctx, 0);
mbedtls_sha256_update_ret(&ctx, hash, 32);
mbedtls_sha256_finish_ret(&ctx, hash);
/*for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash[i]);
Serial.println(""); */
if(hashes++>1000000) { Mhashes++; hashes=0;} hashes++;
// exit if (nonce++> MAX_NONCE) break; //exit
if (nonce >= MAX_NONCE) {
break; // check if 16bit share
} if(hash[31]!=0) continue;
if(hash[30]!=0) continue;
halfshares++;
// check if 32bit share
if(hash[29]!=0) continue;
if(hash[28]!=0) continue;
shares++;
// check if valid header
if(checkValid(hash, bytearray_target)){
//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 } // exit if found a valid result or nonce > MAX_NONCE
mbedtls_sha256_free(&ctx);
mbedtls_sha256_free(midstate);
enableGlobalHash = false;
if(hashes>=MAX_NONCE) { Mhashes=Mhashes+MAX_NONCE/1000000; hashes=hashes-MAX_NONCE;}
if (nonce == MAX_NONCE) { if (nonce == MAX_NONCE) {
Serial.printf("[WORKER] %s SUBMITING WORK... MAX Nonce reached > MAX_NONCE\n", (char *)name); Serial.printf("[WORKER] %s SUBMITING WORK... MAX Nonce reached > MAX_NONCE\n", (char *)name);
// STEP 3: Submit mining job // STEP 3: Submit mining job
@ -495,12 +500,51 @@ void runWorker(void *name) {
} }
uint32_t duration = micros() - startT; uint32_t duration = micros() - startT;
} }
mbedtls_md_free(&ctx);
} }
//////////////////THREAD CALLS/////////////////// //////////////////THREAD CALLS///////////////////
//Testeamos hashrate final usando hilo principal
//this is currently on test
void runMiner(void){
uint32_t nonce=0;
unsigned char bytearray_blockheader[80];
if(!enableGlobalHash) return;
mbedtls_sha256_context midstate[32], ctx;
unsigned char hash[32];
//Calcular midstate
mbedtls_sha256_init(midstate);
mbedtls_sha256_starts_ret(midstate, 0);
mbedtls_sha256_update_ret(midstate, bytearray_blockheader, 64);
//Iteraciones
unsigned char *header64 = bytearray_blockheader + 64;
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);
mbedtls_sha256_finish_ret(&ctx, hash);
// Segundo SHA-256
mbedtls_sha256_starts_ret(&ctx, 0);
mbedtls_sha256_update_ret(&ctx, hash, 32);
mbedtls_sha256_finish_ret(&ctx, hash);
hashes++;
}
mbedtls_sha256_free(&ctx);
mbedtls_sha256_free(midstate);
}
void runMonitor(void *name){ void runMonitor(void *name){
Serial.println("[MONITOR] started"); Serial.println("[MONITOR] started");

View File

@ -1,7 +1,7 @@
// Mining // Mining
#define THREADS 1 #define THREADS 1
#define MAX_NONCE 1000000 #define MAX_NONCE 3000000
// #define MAX_NONCE 1.215.752.192 // #define MAX_NONCE 1.215.752.192
// Pool // Pool
@ -11,3 +11,4 @@
void runMonitor(void *name); void runMonitor(void *name);
void runWorker(void *name); void runWorker(void *name);
void runMiner(void);

View File

@ -141,8 +141,12 @@ void init_WifiManager()
Serial.begin(115200); Serial.begin(115200);
//Serial.setTxTimeoutMs(10); //Serial.setTxTimeoutMs(10);
//Init config pin //Init config pin
// pinMode(TRIGGER_PIN, INPUT); pinMode(PIN_BUTTON_2, INPUT);
//Init pin 15 to eneble 5V external power (LilyGo bug)
pinMode(PIN_ENABLE5V, OUTPUT);
digitalWrite(PIN_ENABLE5V, HIGH);
// Change to true when testing to force configuration every time we run // Change to true when testing to force configuration every time we run
bool forceConfig = false; bool forceConfig = false;
@ -170,7 +174,7 @@ void init_WifiManager()
//Advanced settings //Advanced settings
wm.setConfigPortalBlocking(false); //Hacemos que el portal no bloquee el firmware wm.setConfigPortalBlocking(false); //Hacemos que el portal no bloquee el firmware
wm.setConnectTimeout(30); // how long to try to connect for before continuing wm.setConnectTimeout(50); // how long to try to connect for before continuing
//wm.setConfigPortalTimeout(30); // auto close configportal after n seconds //wm.setConfigPortalTimeout(30); // auto close configportal after n seconds
// wm.setCaptivePortalEnable(false); // disable captive portal redirection // wm.setCaptivePortalEnable(false); // disable captive portal redirection
// wm.setAPClientCheck(true); // avoid timeout if client connected to softap // wm.setAPClientCheck(true); // avoid timeout if client connected to softap
@ -267,10 +271,10 @@ void init_WifiManager()
} }
} }
void checkResetConfigButton(){ /*void checkResetConfigButton(){
// Leer el estado del botón // Leer el estado del botón
int buttonState = digitalRead(PIN_BUTTON_1); int buttonState = digitalRead(PIN_BUTTON_0);
unsigned int last_time = (millis() - lastButtonPress); unsigned int last_time = (millis() - lastButtonPress);
Serial.printf("button pressed %i - %u\n", buttonReset, last_time); Serial.printf("button pressed %i - %u\n", buttonReset, last_time);
@ -286,24 +290,26 @@ void checkResetConfigButton(){
buttonPressed = true; buttonPressed = true;
} }
} }*/
void checkRemoveConfiguration() { void checkResetConfigButton() {
if(!buttonPressed){
return;
}
buttonPressed = false;
// check for button press // check for button press
Serial.printf("[CONFIG] Button reset pressed %i\n", buttonReset); if ( digitalRead(PIN_BUTTON_2) == LOW ) {
Serial.println("[CONFIG] Erasing pool config"); // poor mans debounce/press-hold, code not ideal for production
Serial.println("[CONFIG] Deleting existing configuration"); delay(50);
SPIFFS.remove(JSON_CONFIG_FILE); //Borramos fichero if( digitalRead(PIN_BUTTON_2) == LOW ){
Serial.println("[CONFIG] Erasing wifi config"); Serial.println("Button Pressed");
wm.resetSettings(); // still holding button for 3000 ms, reset settings, code not ideaa for production
Serial.println("[CONFIG] Restarting"); delay(3000); // reset delay hold
delay(1000); if( digitalRead(PIN_BUTTON_2) == LOW ){
ESP.restart(); Serial.println("Button Held");
Serial.println("Erasing Config, restarting");
wm.resetSettings();
SPIFFS.remove(JSON_CONFIG_FILE); //Borramos fichero
ESP.restart();
}
}
}
} }

View File

@ -1,6 +1,7 @@
//Botón configuración //Botón configuración
#define PIN_BUTTON_1 0 #define PIN_BUTTON_1 0
#define PIN_BUTTON_2 14 #define PIN_BUTTON_2 14
#define PIN_ENABLE5V 15
void init_WifiManager(); void init_WifiManager();
void wifiManagerProcess(); void wifiManagerProcess();