added a midstate sha256 function

This commit is contained in:
Skot Croshere 2023-05-19 22:21:24 -04:00 committed by johnny9
parent 27b24d3c3e
commit 4cf368864e
7 changed files with 131 additions and 37 deletions

View File

@ -20,6 +20,7 @@ char * double_sha256(const char * hex_string);
uint8_t * double_sha256_bin(const uint8_t * data, const size_t data_len);
void single_sha256_bin(const uint8_t * data, const size_t data_len, uint8_t * dest);
void midstate_sha256_bin( const uint8_t * data, const size_t data_len, uint8_t * dest);
void swap_endian_words(const char * hex, uint8_t * output);

View File

@ -1,6 +1,8 @@
#include <string.h>
#include <stdio.h>
#include "mining.h"
#include "utils.h"
#include "../../main/pretty.h"
char * construct_coinbase_tx(const char * coinbase_1, const char * coinbase_2,
const char * extranonce, const char * extranonce_2)
@ -51,14 +53,30 @@ bm_job construct_bm_job(uint32_t version, const char * prev_block_hash, const ch
new_job.ntime = ntime;
uint8_t merkle_root_bin[32];
uint8_t prev_block_bin[32];
hex2bin(merkle_root, merkle_root_bin, 32);
hex2bin(prev_block_hash, prev_block_bin, 32);
uint8_t midstate_data[64];
memcpy(midstate_data, &version, 4);
//swap_endian_words(prev_block_hash, midstate_data + 4);
memcpy(midstate_data + 36, merkle_root_bin, 28);
single_sha256_bin(midstate_data, 64, new_job.midstate);
//reverse_bytes(new_job.midstate, 32);
//print the header
printf("header: %08x%s%s%08x%08x000000000000008000000000000000000000000000000000000000000000000000000000\n", version, prev_block_hash, merkle_root, ntime, target);
memcpy(midstate_data, &version, 4); //copy version
// midstate_data[3] = version & 0xff;
// midstate_data[2] = (version >> 8) & 0xff;
// midstate_data[1] = (version >> 16) & 0xff;
// midstate_data[0] = (version >> 24) & 0xff;
swap_endian_words(prev_block_hash, midstate_data + 4);
//memcpy(midstate_data + 4, prev_block_bin, 32);
swap_endian_words(merkle_root, midstate_data + 36);
//memcpy(midstate_data + 36, merkle_root_bin, 28);
printf("midstate_data: ");
prettyHex(midstate_data, 64);
printf("\n");
//single_sha256_bin(midstate_data, 64, new_job.midstate);
midstate_sha256_bin(midstate_data, 64, new_job.midstate);
reverse_bytes(new_job.midstate, 32);
memcpy(&new_job.merkle_root_end, merkle_root_bin + 28, 4);
return new_job;

View File

@ -196,7 +196,7 @@ int subscribe_to_stratum(int socket, char ** extranonce, int * extranonce2_len)
{
// Subscribe
char subscribe_msg[BUFFER_SIZE];
sprintf(subscribe_msg, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": []}\n", send_uid++);
sprintf(subscribe_msg, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": [\"bitaxe v2.2\"]}\n", send_uid++);
ESP_LOGI(TAG, "Subscribe: %s", subscribe_msg);
write(socket, subscribe_msg, strlen(subscribe_msg));
char * line;

View File

@ -125,7 +125,34 @@ uint8_t * double_sha256_bin(const uint8_t * data, const size_t data_len)
void single_sha256_bin( const uint8_t * data, const size_t data_len, uint8_t * dest)
{
mbedtls_sha256(data, data_len, dest, 0);
//mbedtls_sha256(data, data_len, dest, 0);
// Initialize SHA256 context
mbedtls_sha256_context sha256_ctx;
mbedtls_sha256_init(&sha256_ctx);
mbedtls_sha256_starts(&sha256_ctx, 0);
// Compute first SHA256 hash of header
mbedtls_sha256_update(&sha256_ctx, data, 64);
unsigned char hash[32];
mbedtls_sha256_finish(&sha256_ctx, hash);
// Compute midstate from hash
memcpy(dest, hash, 32);
}
void midstate_sha256_bin( const uint8_t * data, const size_t data_len, uint8_t * dest)
{
mbedtls_sha256_context midstate;
//Calculate midstate
mbedtls_sha256_init(&midstate);
mbedtls_sha256_starts_ret(&midstate, 0);
mbedtls_sha256_update_ret(&midstate, data, 64);
memcpy(dest, midstate.state, 32);
}
void swap_endian_words(const char * hex_words, uint8_t * output) {

View File

@ -3,14 +3,14 @@ menu "Example Configuration"
config I2C_MASTER_SCL
int "SCL GPIO Num"
default 6 if IDF_TARGET_ESP32C3
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 48 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
GPIO number for I2C Master clock line.
config I2C_MASTER_SDA
int "SDA GPIO Num"
default 5 if IDF_TARGET_ESP32C3
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 47 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
GPIO number for I2C Master data line.
@ -35,6 +35,13 @@ menu "Example Configuration"
help
The example will connect to this IPV4 address.
config EXAMPLE_STRATUM_URL
string "Stratum Address"
default "solo.ckpool.org"
depends on EXAMPLE_IPV4
help
The example will connect to this Stratum pool address.
config EXAMPLE_IPV6_ADDR
string "IPV6 Address"
default "FE80::30AD:E57B:C212:68AD"
@ -49,6 +56,18 @@ menu "Example Configuration"
help
The remote port to which the client example will connect to.
config EXAMPLE_STRATUM_USER
string "Stratum username"
default ""
help
Stratum user to use with pool
config EXAMPLE_STRATUM_PW
string "Stratum password"
default "x"
help
Stratum password to use with pool
choice EXAMPLE_SOCKET_IP_INPUT
prompt "Socket example source"
default EXAMPLE_SOCKET_IP_INPUT_STRING

View File

@ -13,6 +13,9 @@
#include "addr_from_stdin.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "lwip/ip4_addr.h"
#include "lwip/dns.h"
#include "stratum_api.h"
#include "mining.h"
#include "work_queue.h"
@ -31,8 +34,10 @@
#endif
#define PORT CONFIG_EXAMPLE_PORT
#define STRATUM_URL CONFIG_EXAMPLE_STRATUM_URL
#define STRATUM_USER CONFIG_EXAMPLE_STRATUM_USER
#define STRATUM_PW CONFIG_EXAMPLE_STRATUM_PW
#define STRATUM_USERNAME "johnny9.esp"
static const char *TAG = "stratum client";
@ -91,7 +96,13 @@ static void AsicTask(void * pvParameters)
//reverse_bytes((uint8_t *) &nonce.nonce, 4);
print_hex((uint8_t *) &nonce.nonce, 4, 4, "nonce: ");
memset(buf, 0, 1024);
submit_share(sock, STRATUM_USERNAME, next_bm_job->jobid,
//check the nonce difficulty
if (nonce.nonce < next_bm_job->target) {
ESP_LOGI(TAG, "Nonce is valid");
} else {
ESP_LOGI(TAG, "Nonce is invalid");
}
submit_share(sock, STRATUM_USER, next_bm_job->jobid,
next_bm_job->ntime, next_bm_job->extranonce2, nonce.nonce);
}
}
@ -126,9 +137,9 @@ static void mining_task(void * pvParameters)
params.ntime, params.target);
ESP_LOGI(TAG, "bm_job: ");
print_hex((uint8_t *) &next_job.target, 4, 4, "target: ");
print_hex((uint8_t *) &next_job.ntime, 4, 4, "ntime: ");
print_hex((uint8_t *) &next_job.merkle_root_end, 4, 4, "merkle root end: ");
// print_hex((uint8_t *) &next_job.target, 4, 4, "nbits: ");
// print_hex((uint8_t *) &next_job.ntime, 4, 4, "ntime: ");
// print_hex((uint8_t *) &next_job.merkle_root_end, 4, 4, "merkle root end: ");
print_hex(next_job.midstate, 32, 32, "midstate: ");
bm_job * queued_next_job = malloc(sizeof(bm_job));
@ -144,34 +155,52 @@ static void mining_task(void * pvParameters)
}
}
ip_addr_t ip_Addr;
bool bDNSFound = false;
void dns_found_cb(const char *name, const ip_addr_t *ipaddr, void *callback_arg)
{
ip_Addr = *ipaddr;
bDNSFound = true;
}
static void admin_task(void *pvParameters)
{
initialize_stratum_buffer();
char host_ip[] = HOST_IP_ADDR;
char host_ip[20];
int addr_family = 0;
int ip_protocol = 0;
while (1)
{
#if defined(CONFIG_EXAMPLE_IPV4)
//get ip address from hostname
IP_ADDR4( &ip_Addr, 0,0,0,0 );
printf("Get IP for URL: %s\n", STRATUM_URL);
dns_gethostbyname(STRATUM_URL, &ip_Addr, dns_found_cb, NULL );
while( !bDNSFound );
//make IP address string from ip_Addr
snprintf( host_ip, sizeof(host_ip), "%d.%d.%d.%d",
ip4_addr1(&ip_Addr.u_addr.ip4),
ip4_addr2(&ip_Addr.u_addr.ip4),
ip4_addr3(&ip_Addr.u_addr.ip4),
ip4_addr4(&ip_Addr.u_addr.ip4) );
printf( "Connecting to: stratum+tcp://%s:%d (%s)\n", STRATUM_URL, PORT, host_ip);
// printf( "DNS found: %i.%i.%i.%i\n",
// ip4_addr1(&ip_Addr.u_addr.ip4),
// ip4_addr2(&ip_Addr.u_addr.ip4),
// ip4_addr3(&ip_Addr.u_addr.ip4),
// ip4_addr4(&ip_Addr.u_addr.ip4) );
while (1) {
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(host_ip);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
#elif defined(CONFIG_EXAMPLE_IPV6)
struct sockaddr_in6 dest_addr = {0};
inet6_aton(host_ip, &dest_addr.sin6_addr);
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(PORT);
dest_addr.sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE);
addr_family = AF_INET6;
ip_protocol = IPPROTO_IPV6;
#elif defined(CONFIG_EXAMPLE_SOCKET_IP_INPUT_STDIN)
struct sockaddr_storage dest_addr = {0};
ESP_ERROR_CHECK(get_addr_from_stdin(PORT, SOCK_STREAM, &ip_protocol, &addr_family, &dest_addr));
#endif
sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (sock < 0)
{
@ -186,10 +215,10 @@ static void admin_task(void *pvParameters)
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
break;
}
auth_to_stratum(sock, STRATUM_USERNAME);
subscribe_to_stratum(sock, &extranonce_str, &extranonce_2_len);
auth_to_stratum(sock, STRATUM_USER);
ESP_LOGI(TAG, "Extranonce: %s", extranonce_str);
ESP_LOGI(TAG, "Extranonce 2 length: %d", extranonce_2_len);

View File

@ -99,11 +99,11 @@ void SerialTask(void *arg) {
//setup a nice test job
//this should find nonce 258a8b34 @ 50
//uint8_t work1[146] = {0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xE0, 0x05, 0x17, 0x24, 0x27, 0x36, 0x64, 0xF5, 0x63, 0x54, 0xDA, 0x33, 0xE2, 0xDE, 0x8F, 0xFC, 0xDD, 0x48, 0x96, 0xE1, 0x36, 0xD7, 0x03, 0x5C, 0xBB, 0x5F, 0xA3, 0xFD, 0x5F, 0x68, 0x39, 0xAA, 0xA4, 0xBE, 0x10, 0x9C, 0x7E, 0x00, 0x78, 0x4E, 0x69, 0x34, 0xAC, 0x84, 0x05, 0x65, 0xAE, 0x32, 0x58, 0x09, 0xBB, 0xEA, 0x44, 0x6D, 0x61, 0x57, 0xF2, 0x61, 0xBE, 0x58, 0x33, 0xFA, 0xA8, 0x1D, 0x9A, 0x16, 0xBF, 0xE0, 0x82, 0x64, 0x37, 0x91, 0x15, 0xB6, 0x32, 0x93, 0xC4, 0x83, 0x42, 0xB2, 0xE6, 0x63, 0x96, 0xE0, 0x25, 0x02, 0x9E, 0x01, 0x76, 0xD9, 0x24, 0x0F, 0xD3, 0x57, 0x27, 0x38, 0xE2, 0x65, 0xDD, 0xCD, 0xBD, 0x01, 0xE0, 0x61, 0xFB, 0x57, 0x5D, 0xD6, 0xAB, 0xAE, 0xFD, 0x6B, 0x5F, 0x77, 0x74, 0x5C, 0x64, 0x2C, 0xF3, 0x34, 0x2F, 0x82, 0xB3, 0xCC, 0xC1, 0x2D, 0x84, 0xDD, 0xCB, 0x10, 0xDE, 0x5E, 0xE0, 0xCD, 0x9C, 0x5B, 0x65, 0x92, 0xBB};
//struct job_packet test_job;
//memcpy((uint8_t *)&test_job, work1, 146);
// uint8_t work1[146] = {0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xE0, 0x05, 0x17, 0x24, 0x27, 0x36, 0x64, 0xF5, 0x63, 0x54, 0xDA, 0x33, 0xE2, 0xDE, 0x8F, 0xFC, 0xDD, 0x48, 0x96, 0xE1, 0x36, 0xD7, 0x03, 0x5C, 0xBB, 0x5F, 0xA3, 0xFD, 0x5F, 0x68, 0x39, 0xAA, 0xA4, 0xBE, 0x10, 0x9C, 0x7E, 0x00, 0x78, 0x4E, 0x69, 0x34, 0xAC, 0x84, 0x05, 0x65, 0xAE, 0x32, 0x58, 0x09, 0xBB, 0xEA, 0x44, 0x6D, 0x61, 0x57, 0xF2, 0x61, 0xBE, 0x58, 0x33, 0xFA, 0xA8, 0x1D, 0x9A, 0x16, 0xBF, 0xE0, 0x82, 0x64, 0x37, 0x91, 0x15, 0xB6, 0x32, 0x93, 0xC4, 0x83, 0x42, 0xB2, 0xE6, 0x63, 0x96, 0xE0, 0x25, 0x02, 0x9E, 0x01, 0x76, 0xD9, 0x24, 0x0F, 0xD3, 0x57, 0x27, 0x38, 0xE2, 0x65, 0xDD, 0xCD, 0xBD, 0x01, 0xE0, 0x61, 0xFB, 0x57, 0x5D, 0xD6, 0xAB, 0xAE, 0xFD, 0x6B, 0x5F, 0x77, 0x74, 0x5C, 0x64, 0x2C, 0xF3, 0x34, 0x2F, 0x82, 0xB3, 0xCC, 0xC1, 0x2D, 0x84, 0xDD, 0xCB, 0x10, 0xDE, 0x5E, 0xE0, 0xCD, 0x9C, 0x5B, 0x65, 0x92, 0xBB};
// struct job_packet test_job;
// memcpy((uint8_t *)&test_job, work1, 146);
send_work(&test_job);
// send_work(&test_job);
while (1) {
debug_serial_rx();