From 4cf368864e8a01aff57581549086b6163499f6ba Mon Sep 17 00:00:00 2001 From: Skot Croshere Date: Fri, 19 May 2023 22:21:24 -0400 Subject: [PATCH] added a midstate sha256 function --- components/stratum/include/utils.h | 1 + components/stratum/mining.c | 28 +++++++++-- components/stratum/stratum_api.c | 2 +- components/stratum/utils.c | 29 ++++++++++- main/Kconfig.projbuild | 23 ++++++++- main/miner.c | 77 ++++++++++++++++++++---------- main/serial.c | 8 ++-- 7 files changed, 131 insertions(+), 37 deletions(-) diff --git a/components/stratum/include/utils.h b/components/stratum/include/utils.h index 31a76580..8f3d609f 100644 --- a/components/stratum/include/utils.h +++ b/components/stratum/include/utils.h @@ -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); diff --git a/components/stratum/mining.c b/components/stratum/mining.c index 38025441..3ab5449a 100644 --- a/components/stratum/mining.c +++ b/components/stratum/mining.c @@ -1,6 +1,8 @@ #include +#include #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; diff --git a/components/stratum/stratum_api.c b/components/stratum/stratum_api.c index 456a8fc7..c73362be 100644 --- a/components/stratum/stratum_api.c +++ b/components/stratum/stratum_api.c @@ -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; diff --git a/components/stratum/utils.c b/components/stratum/utils.c index 107ccb00..2fd8e0ad 100644 --- a/components/stratum/utils.c +++ b/components/stratum/utils.c @@ -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) { diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 59513e0c..afdf6d33 100755 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -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 diff --git a/main/miner.c b/main/miner.c index 5d47c282..d6e9ce5c 100755 --- a/main/miner.c +++ b/main/miner.c @@ -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); diff --git a/main/serial.c b/main/serial.c index 615141ac..a1443838 100644 --- a/main/serial.c +++ b/main/serial.c @@ -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();