Merge branch 'master' of https://github.com/alcar21/NerdMiner_v2 into feature/add_platformio_support_and_improvements
# Conflicts: # .gitignore # Lib/Free_Fonts.h # Lib/images.h # Lib/myFonts.h # NerdMinerV2.ino # README.md # TFT_setup/User_Setup.h # lib/TFT_eSPI/User_Setup.h # platformio.ini # src/Lib/Free_Fonts.h # src/Lib/images.h # src/Lib/myFonts.h # src/NerdMinerV2.ino # src/NerdMinerV2.ino.cpp # src/TFT_setup/User_Setup.h # src/media/Free_Fonts.h # src/media/images.h # src/media/myFonts.h # src/mining.cpp # src/mining.h # src/wManager.h
This commit is contained in:
commit
cf0e667668
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,6 +1,2 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
.vscode/*
|
||||
.vscode
|
70
README.md
70
README.md
@ -1,33 +1,83 @@
|
||||
# NerdSoloMiner
|
||||
The NerdSoloMiner v2
|
||||
**The NerdSoloMiner v2**
|
||||
|
||||
This is a **free and open source project** that let you try to reach a bitcoin block with a small piece of hardware.
|
||||
|
||||
The main aim of this project is to let you **learn more about minery** and to have a beautiful piece of hardware in your desktop.
|
||||
|
||||
|
||||
Original project https://github.com/valerio-vaccaro/HAN
|
||||
|
||||
![image](https://raw.githubusercontent.com/BitMaker-hub/NerdMiner_v2/master/images/NerdMinerv2.jpg)
|
||||
![image](images/NerdMinerv2.jpg)
|
||||
|
||||
## Requirements
|
||||
- TTGO T-Display S3
|
||||
- 3D BOX [here](3d_files/)
|
||||
|
||||
## Description
|
||||
ESP32 implementing Stratum protocol to mine on solo pool. Pool can be changed but originally works with ckpool.
|
||||
### Project description
|
||||
**ESP32 implementing Stratum protocol** to mine on solo pool. Pool can be changed but originally works with ckpool.
|
||||
|
||||
This project is using ESP32-S3, uses WifiManager to modify miner settings and save them to SPIFF.
|
||||
|
||||
This miner is multicore and multithreads, each thread mine a different block template. After 1,000,000 trials the block in refreshed in order to avoid mining on old template.
|
||||
|
||||
## TUTORIAL
|
||||
Create your own miner using the online tool ESPtool and the binary files that you will find in the bin folder.
|
||||
***Current project is still in developement and more features will be added***
|
||||
|
||||
## Build Tutorial
|
||||
### Hardware requirements
|
||||
- TTGO T-Display S3 > Buy it on aliexpress or amazon
|
||||
- 3D BOX
|
||||
|
||||
### Flash firmware
|
||||
Create your own miner using the online tool **ESPtool** and the **binary files** that you will find in the src/bin folder.
|
||||
If you want you can compile the entire project using Arduino, PlatformIO or Expressif IDF.
|
||||
|
||||
1. Get a TTGO T-display S3
|
||||
1. Download this repository
|
||||
1. Go to ESPtool online: https://espressif.github.io/esptool-js/
|
||||
1. Load the firmware with the binaries from the bin folder.
|
||||
1. Load the firmware with the binaries from the src/bin folder.
|
||||
1. Plug your board and select each file from src/bin with its address
|
||||
|
||||
Complete tutorial on YouTube:
|
||||
#### Build troubleshooting
|
||||
1. Online ESPtool works with chrome, chromium, brave
|
||||
1. ESPtool recommendations: use 115200bps
|
||||
1. Build errors > If during firmware download upload stops, it's recommended to enter the board in boot mode. Unplug cable, hold right bottom button and then plug cable. Try programming
|
||||
|
||||
### NerdMiner configuration
|
||||
After programming, you will only need to setup your Wifi and BTC address.
|
||||
|
||||
1. Connect to NerdMinerAP
|
||||
1. Setup your Wifi Network
|
||||
1. Add your BTCaddress
|
||||
|
||||
Optional you can select other pool:
|
||||
|
||||
| Pool URL | Port | URL |
|
||||
|--- |--- |--- |
|
||||
| solo.ckpool.org | 3333 | https://solo.ckpool.org/ |
|
||||
| btc.zsolo.bid | 6057 | https://zsolo.bid/en/btc-solo-mining-pool |
|
||||
| eu.stratum.slushpool.com | 3333 | https://braiins.com/pool |
|
||||
|
||||
**If you need to reboot your currentConfig**, hold right top button during 5 seconds and config will be deleted.
|
||||
|
||||
#### Build video
|
||||
[![Ver video aquí](https://img.youtube.com/vi/POUT2R_opDs/0.jpg)](https://youtu.be/POUT2R_opDs)
|
||||
|
||||
## DEVELOPMENT
|
||||
You can use platformio pltaform to develop this project.
|
||||
## Developers
|
||||
### Project guidelines
|
||||
- Current project was addapted to work with PlatformIO
|
||||
- Current project works with ESP32-S3 but any ESP32 can be used.
|
||||
- Partition squeme should be build as huge app
|
||||
- All libraries needed shown on platform.ini
|
||||
|
||||
### On process
|
||||
- [x] Move project to platformIO
|
||||
- [x] Bug rectangle on screen when 1milion shares
|
||||
- [x] Bug memory leaks
|
||||
- [x] Bug Reboots when received JSON contains some null values
|
||||
- [ ] Improve hashrate using Blockstream Jade miner code
|
||||
- [ ] Add blockHeight to screen
|
||||
- [ ] Add new screen with global mining stats
|
||||
- [ ] Add support to control BM1397
|
||||
|
||||
Enjoy
|
@ -1,2 +0,0 @@
|
||||
Navegar al directorio mis documentos, arduino y allí cambiar la configuración del fichero user_setup.h por este.
|
||||
Verigicar que el user_setup_select.h está indicado que es user_setup.h
|
Binary file not shown.
BIN
bin/0x0000_bootloader.bin
Normal file
BIN
bin/0x0000_bootloader.bin
Normal file
Binary file not shown.
Binary file not shown.
BIN
bin/0x10000_firmware.bin
Normal file
BIN
bin/0x10000_firmware.bin
Normal file
Binary file not shown.
39
include/README
Normal file
39
include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
@ -7,6 +7,7 @@
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
globallib_dir = lib
|
||||
|
||||
@ -29,7 +30,8 @@ build_flags =
|
||||
-D BOARD_HAS_PSRAM
|
||||
-D ARDUINO_USB_MODE=1
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-D DEBUG_MINING=1
|
||||
lib_deps =
|
||||
https://github.com/takkaO/OpenFontRender
|
||||
bblanchon/ArduinoJson@^6.21.1
|
||||
bblanchon/ArduinoJson@^6.21.2
|
||||
https://github.com/tzapu/WiFiManager.git
|
@ -14,6 +14,7 @@
|
||||
unsigned long templates = 0;
|
||||
unsigned long hashes= 0;
|
||||
unsigned long Mhashes = 0;
|
||||
|
||||
int halfshares; // increase if blockhash has 16 bits of zeroes
|
||||
int shares; // increase if blockhash has 32 bits of zeroes
|
||||
int valids; // increased if blockhash <= target
|
||||
@ -34,6 +35,14 @@ bool checkHalfShare(unsigned char* hash) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#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 valid;
|
||||
}
|
||||
|
||||
@ -45,6 +54,14 @@ bool checkShare(unsigned char* hash) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -59,12 +76,14 @@ bool checkValid(unsigned char* hash, unsigned char* target) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MINING
|
||||
if (valid) {
|
||||
Serial.print("\tvalid : ");
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
Serial.printf("%02x ", hash[i]);
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
return valid;
|
||||
}
|
||||
|
||||
@ -141,12 +160,14 @@ void runWorker(void *name) {
|
||||
Serial.print(" extranonce2_size: "); Serial.println(extranonce2_size);
|
||||
Serial.print(" error: "); Serial.println(error);
|
||||
if((extranonce1.length() == 0) || line.length() == 0 || (error != 0)) {
|
||||
Serial.printf("[WORKER] %s >>>>>>>>> Worker aborted\n", (char *)name);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -160,6 +181,7 @@ void runWorker(void *name) {
|
||||
Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n'));
|
||||
Serial.print(" Receiving: "); Serial.println(client.readStringUntil('\n'));
|
||||
client.stop();
|
||||
|
||||
deserializeJson(doc, line);
|
||||
String job_id = String((const char*) doc["params"][0]);
|
||||
String prevhash = String((const char*) doc["params"][1]);
|
||||
@ -170,6 +192,8 @@ void runWorker(void *name) {
|
||||
String nbits = String((const char*) doc["params"][6]);
|
||||
String ntime = String((const char*) doc["params"][7]);
|
||||
bool clean_jobs = doc["params"][8]; //bool
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" job_id: "); Serial.println(job_id);
|
||||
Serial.print(" prevhash: "); Serial.println(prevhash);
|
||||
Serial.print(" coinb1: "); Serial.println(coinb1);
|
||||
@ -179,6 +203,7 @@ void runWorker(void *name) {
|
||||
Serial.print(" nbits: "); Serial.println(nbits);
|
||||
Serial.print(" ntime: "); Serial.println(ntime);
|
||||
Serial.print(" clean_jobs: "); Serial.println(clean_jobs);
|
||||
#endif
|
||||
doc.clear();
|
||||
templates++;
|
||||
|
||||
@ -223,24 +248,26 @@ void runWorker(void *name) {
|
||||
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));
|
||||
Serial.print(" extranonce2: "); Serial.println(extranonce2);
|
||||
|
||||
//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];
|
||||
|
||||
size_t res = to_byte_array(coinbase.c_str(), str_len*2, bytearray);
|
||||
Serial.print(" coinbase bytes - size ");
|
||||
Serial.println(res);
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" extranonce2: "); Serial.println(extranonce2);
|
||||
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.println("---");
|
||||
#endif
|
||||
|
||||
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
|
||||
mbedtls_md_init(&ctx);
|
||||
@ -257,10 +284,12 @@ void runWorker(void *name) {
|
||||
mbedtls_md_update(&ctx, interResult, 32);
|
||||
mbedtls_md_finish(&ctx, shaResult);
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" coinbase double sha: ");
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
Serial.printf("%02x", shaResult[i]);
|
||||
Serial.println("");
|
||||
#endif
|
||||
|
||||
byte merkle_result[32];
|
||||
// copy coinbase hash
|
||||
@ -272,15 +301,21 @@ void runWorker(void *name) {
|
||||
uint8_t bytearray[32];
|
||||
size_t res = to_byte_array(merkle_element, 64, bytearray);
|
||||
|
||||
// Serial.print("\tmerkle element "); Serial.print(k); Serial.print(": "); Serial.println(merkle_element);
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" merkle element "); Serial.print(k); Serial.print(": "); Serial.println(merkle_element);
|
||||
#endif
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
merkle_concatenated[i] = merkle_result[i];
|
||||
merkle_concatenated[32 + i] = bytearray[i];
|
||||
}
|
||||
// Serial.print("\tmerkle concatenated: ");
|
||||
// for (size_t i = 0; i < 64; i++)
|
||||
// Serial.printf("%02x", merkle_concatenated[i]);
|
||||
// Serial.println("");
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" merkle element "); Serial.print(k); Serial.print(": "); Serial.println(merkle_element);
|
||||
Serial.print(" merkle concatenated: ");
|
||||
for (size_t i = 0; i < 64; i++)
|
||||
Serial.printf("%02x", merkle_concatenated[i]);
|
||||
Serial.println("");
|
||||
#endif
|
||||
|
||||
mbedtls_md_starts(&ctx);
|
||||
mbedtls_md_update(&ctx, merkle_concatenated, 64);
|
||||
@ -290,14 +325,16 @@ void runWorker(void *name) {
|
||||
mbedtls_md_update(&ctx, interResult, 32);
|
||||
mbedtls_md_finish(&ctx, merkle_result);
|
||||
|
||||
// Serial.print("\tmerkle sha : ");
|
||||
// for (size_t i = 0; i < 32; i++)
|
||||
// Serial.printf("%02x", merkle_result[i]);
|
||||
// Serial.println("");
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" merkle sha : ");
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
Serial.printf("%02x", merkle_result[i]);
|
||||
Serial.println("");
|
||||
#endif
|
||||
}
|
||||
// merkle root from merkle_result
|
||||
|
||||
Serial.print("\tmerkle sha : ");
|
||||
Serial.print(" merkle sha : ");
|
||||
char merkle_root[65];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
Serial.printf("%02x", merkle_result[i]);
|
||||
@ -310,9 +347,11 @@ void runWorker(void *name) {
|
||||
String blockheader = version + prevhash + String(merkle_root) + nbits + ntime + "00000000";
|
||||
str_len = blockheader.length()/2;
|
||||
uint8_t bytearray_blockheader[str_len];
|
||||
Serial.println(" blockheader bytes "); Serial.print(str_len); Serial.print(" -> ");
|
||||
res = to_byte_array(blockheader.c_str(), str_len*2, bytearray_blockheader);
|
||||
Serial.println(res);
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.println(" blockheader bytes "); Serial.print(str_len); Serial.print(" -> ");
|
||||
#endif
|
||||
|
||||
// reverse version
|
||||
uint8_t buff;
|
||||
@ -342,6 +381,8 @@ void runWorker(void *name) {
|
||||
bytearray_blockheader[2 * boffset + bsize - 1 - j] = buff;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" >>> bytearray_blockheader : ");
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
Serial.printf("%02x", bytearray_blockheader[i]);
|
||||
@ -370,10 +411,12 @@ void runWorker(void *name) {
|
||||
for (size_t i = 76; i < 76+4; i++)
|
||||
Serial.printf("%02x", bytearray_blockheader[i]);
|
||||
Serial.println("");
|
||||
#endif
|
||||
|
||||
// search a valid nonce
|
||||
uint32_t nonce = 0;
|
||||
uint32_t startT = micros();
|
||||
Serial.println(">>> STARTING TO HASH NONCES");
|
||||
while(true) {
|
||||
bytearray_blockheader[76] = (nonce >> 0) & 0xFF;
|
||||
bytearray_blockheader[77] = (nonce >> 8) & 0xFF;
|
||||
@ -395,9 +438,6 @@ void runWorker(void *name) {
|
||||
// check if share
|
||||
if(checkShare(shaResult)) {
|
||||
shares++;
|
||||
}
|
||||
}
|
||||
|
||||
// check if valid header
|
||||
if(checkValid(shaResult, bytearray_target)) {
|
||||
//Serial.printf("%s on core %d: ", (char *)name, xPortGetCoreID());
|
||||
@ -419,9 +459,12 @@ void runWorker(void *name) {
|
||||
nonce = MAX_NONCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonce++;
|
||||
hashes++;
|
||||
|
||||
if(hashes++>1000000) { Mhashes++; hashes=0;}
|
||||
// exit
|
||||
if (nonce >= MAX_NONCE) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
//Botón configuración
|
||||
#define PIN_BUTTON_1 0
|
||||
#define PIN_BUTTON_2 14
|
||||
@ -8,3 +6,4 @@ void init_WifiManager();
|
||||
void wifiManagerProcess();
|
||||
void checkResetConfigButton();
|
||||
void checkRemoveConfiguration();
|
||||
|
||||
|
11
test/README
Normal file
11
test/README
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
Loading…
Reference in New Issue
Block a user