mining: construct a job for bm13xx

This commit is contained in:
johnny9 2023-05-06 11:37:30 -04:00
parent ac9a121a3c
commit ca827ee4b5
6 changed files with 69 additions and 15 deletions

View File

@ -3,9 +3,20 @@
#include "stratum_api.h"
typedef struct {
uint32_t starting_nonce;
uint32_t target; // aka difficulty, aka nbits
uint32_t ntime;
uint32_t merkle_root_end;
uint8_t midstate[32];
} bm_job;
char * construct_coinbase_tx(const char * coinbase_1, const char * coinbase_2,
const char * extranonce, int extranonce_2_len);
char * calculate_merkle_root_hash(const char * coinbase_tx, const uint8_t merkle_branches[][32], const int num_merkle_branches);
bm_job construct_bm_job(const char * version, const char * prev_block_hash, const char * merkle_root,
uint32_t ntime, uint32_t target);
#endif // MINING_H

View File

@ -12,8 +12,13 @@ uint8_t hex2val(char c);
size_t hex2bin(const char *hex, uint8_t *bin, size_t bin_len);
void print_hex(const uint8_t * b, size_t len,
const size_t in_line, const char * prefix);
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);
#endif // STRATUM_UTILS_H

View File

@ -44,4 +44,27 @@ char * calculate_merkle_root_hash(const char * coinbase_tx, const uint8_t merkle
char * merkle_root_hash = malloc(65);
bin2hex(both_merkles, 32, merkle_root_hash, 65);
return merkle_root_hash;
}
bm_job construct_bm_job(const char * version, const char * prev_block_hash, const char * merkle_root,
uint32_t ntime, uint32_t target)
{
bm_job new_job;
new_job.starting_nonce = 0;
new_job.target = target;
new_job.ntime = ntime;
uint8_t merkle_root_bin[32];
hex2bin(merkle_root, merkle_root_bin, 32);
uint8_t midstate_data[64];
hex2bin(version, midstate_data, 4);
hex2bin(prev_block_hash, midstate_data + 4, 32);
memcpy(midstate_data + 36, merkle_root_bin, 28);
print_hex(midstate_data, 64, 64, "midstate data");
single_sha256_bin(midstate_data, 64, &new_job.midstate);
memcpy(&new_job.merkle_root_end, merkle_root_bin + 28, 4);
return new_job;
}

View File

@ -35,4 +35,20 @@ TEST_CASE("Validate merkle root calculation", "[mining]")
char * root_hash = calculate_merkle_root_hash(coinbase_tx, merkles, num_merkles);
TEST_ASSERT_EQUAL_STRING("adbcbc21e20388422198a55957aedfa0e61be0b8f2b87d7c08510bb9f099a893", root_hash);
free(root_hash);
}
TEST_CASE("Validate bm job construction", "[mining]")
{
const char * merkle_root = "adbcbc21e20388422198a55957aedfa0e61be0b8f2b87d7c08510bb9f099a893";
const char * prev_block_hash = "ef4b9a48c7986466de4adc002f7337a6e121bc43000376ea0000000000000000";
char * version = "40000002";
uint32_t target = 0x39c70517;
uint32_t ntime = 0x22554964;
printf("%lu", ntime);
bm_job job = construct_bm_job(version, prev_block_hash, merkle_root, ntime, target);
TEST_ASSERT_EQUAL_UINT32(job.merkle_root_end, 0x93a899f0);
uint8_t expected_midstate_bin[32];
hex2bin("64f147e5e5fbc24e9b3bb8208b300b685fde34fcaea7fd2496981a16916f343f", expected_midstate_bin, 32);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_midstate_bin, job.midstate, 32);
}

View File

@ -69,11 +69,11 @@ size_t hex2bin(const char *hex, uint8_t *bin, size_t bin_len)
return len;
}
static void print_hex( const uint8_t *b, size_t len,
const size_t in_line, const char *prefix )
void print_hex(const uint8_t * b, size_t len,
const size_t in_line, const char * prefix)
{
size_t i = 0;
const uint8_t *end = b + len;
const uint8_t * end = b + len;
if( prefix == NULL )
{
@ -121,3 +121,8 @@ uint8_t * double_sha256_bin(const uint8_t * data, const size_t data_len)
return second_hash_output;
}
void single_sha256_bin( const uint8_t * data, const size_t data_len, uint8_t * dest)
{
mbedtls_sha256(data, data_len, dest, 0);
}

View File

@ -47,11 +47,11 @@ static void mining_task(void *pvParameters)
{
int termination_flag = 0;
while(true) {
uint32_t free_heap_size = esp_get_free_heap_size();
ESP_LOGI(TAG, "miner heap free size: %u bytes", free_heap_size);
char * next_notify_json_str = queue_dequeue(&g_queue, &termination_flag);
ESP_LOGI(TAG, "New Work Dequeued");
ESP_LOGI(TAG, "Notify json: %s", next_notify_json_str);
uint32_t free_heap_size = esp_get_free_heap_size();
ESP_LOGI(TAG, "miner heap free size: %lu bytes", free_heap_size);
mining_notify params = parse_mining_notify_message(next_notify_json_str);
@ -67,11 +67,7 @@ static void mining_task(void *pvParameters)
free_mining_notify(params);
free(coinbase_tx);
free(merkle_root);
vPortFree(next_notify_json_str);
free_heap_size = esp_get_free_heap_size();
ESP_LOGI(TAG, "miner heap free size: %u bytes", free_heap_size);
free(next_notify_json_str);
// TODO: Prepare the block header and start mining
@ -139,17 +135,15 @@ static void admin_task(void *pvParameters)
while (1)
{
uint32_t free_heap_size = esp_get_free_heap_size();
ESP_LOGI(TAG, "before receive heap free size: %u bytes", free_heap_size);
char * line = receive_jsonrpc_line(sock);
free_heap_size = esp_get_free_heap_size();
ESP_LOGI(TAG, "after receive heap free size: %u bytes", free_heap_size);
ESP_LOGI(TAG, "Received line: %s", line);
ESP_LOGI(TAG, "Received line length: %d", strlen(line));
stratum_method method = parse_stratum_method(line);
if (method == MINING_NOTIFY) {
queue_enqueue(&g_queue, line);
} else {
vPortFree(line);
free(line);
}
}