move queue

This commit is contained in:
Ben
2023-06-08 07:42:28 -04:00
committed by johnny9
parent c247e50f54
commit c3301aab30
11 changed files with 67 additions and 77 deletions

2
.gitignore vendored
View File

@ -4,7 +4,7 @@ sdkconfig.old
dependencies.lock
# User specific VSCode
.vscode/*
**/.vscode/*
# Production folder
build/

View File

@ -265,7 +265,7 @@ void BM1397_set_default_baud(void){
int BM1397_set_max_baud(void){
// divider of 0 for 3,125,000
ESP_LOGI(TAG, "Setting max baud");
ESP_LOGI(TAG, "Setting max baud of 3125000");
unsigned char baudrate[9] = { 0x00, MISC_CONTROL, 0x00, 0x00, 0b01100000, 0b00110001 };; //baudrate - misc_control
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, false);
return 3125000;

View File

@ -20,6 +20,7 @@ typedef struct {
uint32_t version;
uint32_t target;
uint32_t ntime;
uint32_t difficulty;
} mining_notify;
typedef enum {
@ -38,13 +39,13 @@ int subscribe_to_stratum(int socket, char ** extranonce, int * extranonce2_len);
stratum_method parse_stratum_method(const char * stratum_json);
mining_notify parse_mining_notify_message(const char * stratum_json);
mining_notify * parse_mining_notify_message(const char * stratum_json, uint32_t difficulty);
uint32_t parse_mining_set_difficulty_message(const char * stratum_json);
uint32_t parse_mining_set_version_mask_message(const char * stratum_json);
void free_mining_notify(mining_notify params);
void free_mining_notify(mining_notify * params);
int parse_stratum_subscribe_result_message(const char * result_json_str,
char ** extranonce,

View File

@ -60,6 +60,7 @@ bm_job construct_bm_job(mining_notify * params, const char * merkle_root) {
new_job.starting_nonce = 0;
new_job.target = params->target;
new_job.ntime = params->ntime;
new_job.pool_diff = params->difficulty;
hex2bin(merkle_root, new_job.merkle_root, 32);
swap_endian_words(params->prev_block_hash, new_job.prev_block_hash);

View File

@ -173,7 +173,7 @@ bool parse_stratum_result_message(const char * stratum_json, int16_t * parsed_id
return result;
}
mining_notify parse_mining_notify_message(const char * stratum_json)
mining_notify * parse_mining_notify_message(const char * stratum_json, uint32_t difficulty)
{
cJSON * json = cJSON_Parse(stratum_json);
cJSON * method = cJSON_GetObjectItem(json, "method");
@ -181,39 +181,41 @@ mining_notify parse_mining_notify_message(const char * stratum_json)
assert(strcmp("mining.notify", method->valuestring) == 0);
}
mining_notify new_work;
mining_notify * new_work = malloc(sizeof(mining_notify));
new_work->difficulty = difficulty;
cJSON * params = cJSON_GetObjectItem(json, "params");
new_work.job_id = strdup(cJSON_GetArrayItem(params, 0)->valuestring);
new_work.prev_block_hash = strdup(cJSON_GetArrayItem(params, 1)->valuestring);
new_work.coinbase_1 = strdup(cJSON_GetArrayItem(params, 2)->valuestring);
new_work.coinbase_2 = strdup(cJSON_GetArrayItem(params, 3)->valuestring);
new_work->job_id = strdup(cJSON_GetArrayItem(params, 0)->valuestring);
new_work->prev_block_hash = strdup(cJSON_GetArrayItem(params, 1)->valuestring);
new_work->coinbase_1 = strdup(cJSON_GetArrayItem(params, 2)->valuestring);
new_work->coinbase_2 = strdup(cJSON_GetArrayItem(params, 3)->valuestring);
cJSON * merkle_branch = cJSON_GetArrayItem(params, 4);
new_work.n_merkle_branches = cJSON_GetArraySize(merkle_branch);
if (new_work.n_merkle_branches > MAX_MERKLE_BRANCHES) {
new_work->n_merkle_branches = cJSON_GetArraySize(merkle_branch);
if (new_work->n_merkle_branches > MAX_MERKLE_BRANCHES) {
printf("Too many Merkle branches.\n");
abort();
}
new_work.merkle_branches = malloc(HASH_SIZE * new_work.n_merkle_branches);
for (size_t i = 0; i < new_work.n_merkle_branches; i++) {
hex2bin(cJSON_GetArrayItem(merkle_branch, i)->valuestring, new_work.merkle_branches + HASH_SIZE * i, HASH_SIZE * 2);
new_work->merkle_branches = malloc(HASH_SIZE * new_work->n_merkle_branches);
for (size_t i = 0; i < new_work->n_merkle_branches; i++) {
hex2bin(cJSON_GetArrayItem(merkle_branch, i)->valuestring, new_work->merkle_branches + HASH_SIZE * i, HASH_SIZE * 2);
}
new_work.version = strtoul(cJSON_GetArrayItem(params, 5)->valuestring, NULL, 16);
new_work.target = strtoul(cJSON_GetArrayItem(params, 6)->valuestring, NULL, 16);
new_work.ntime = strtoul(cJSON_GetArrayItem(params, 7)->valuestring, NULL, 16);
new_work->version = strtoul(cJSON_GetArrayItem(params, 5)->valuestring, NULL, 16);
new_work->target = strtoul(cJSON_GetArrayItem(params, 6)->valuestring, NULL, 16);
new_work->ntime = strtoul(cJSON_GetArrayItem(params, 7)->valuestring, NULL, 16);
cJSON_Delete(json);
return new_work;
}
void free_mining_notify(mining_notify params)
void free_mining_notify(mining_notify * params)
{
free(params.job_id);
free(params.prev_block_hash);
free(params.coinbase_1);
free(params.coinbase_2);
free(params.merkle_branches);
free(params->job_id);
free(params->prev_block_hash);
free(params->coinbase_1);
free(params->coinbase_2);
free(params->merkle_branches);
free(params);
}
int parse_stratum_subscribe_result_message(const char * result_json_str,

View File

@ -82,10 +82,10 @@ TEST_CASE("Validate bm job construction 2", "[mining]")
"\"params\":[\"21554471e8\",\"8bc8707eb169ad3bda101ae60c8d48bd00aff68a00006c8b0000000000000000\",\"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4b03d8130cfabe6d6db0ba74b36edc62c9268c945b53ebf1a7865b88bcdd40235a7a63d0f5ed5b6c400100000000000000\",\"e8714455212f736c7573682f00000000033de04728000000001976a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac00000000000000002c6a4c2952534b424c4f434b3ae8c3686251b5ced65b6a65ea3e0491ac2975cd87c02b0640d3ec3c20005167770000000000000000266a24aa21a9eddffbecb5ef0a46324a3dd902fa84509a38d2c91548768845db5d6c2de0e33f6100000000\","
"[\"8ef6b79382a1fc5152c7e69b2dd4e3795ed758d6fe7748ef4d96e3ad8ac180b8\",\"5b6e1cfecd94050b763c2c6a08d4caabd54daee665aa8e41b53b39ec76b62707\",\"f85b768f83fffbb3927f7f440cb57a5ed386f368aae88ad9b9d92e7bc1cdce15\",\"e51b9391c39019d8a2a27becc048cc770f5d33b49a29779fdc7bed04767ca962\",\"9f5d08316ead260455ec532a58935411a3eecf3c9948a52325de495d7dd7b776\",\"57e10cad23a646ad3a87fcd34eae454567dbd44946e746ee6310a86b98afa4ac\",\"f3b65cc08b25901b657efb22f0a9a23e1a61ce1e268f801d8cfe782b4a0c5e5d\",\"648e00fe2a57dca155c7d4260bc52273b28adb42e1bceb45d5ee03f4a4c5d174\",\"43ad393f7efe4b7a29775dbbc10b3b2737e9457764a7b39bc8ac6b470b968ac8\",\"4964b9b2bf601dfb2bd62067acafe556650412b1e6fe32df48c39310f7dc255d\",\"44d354ac57fcb68b408df7f5396122195384914dd2db13d5766c334fc48c2069\",\"568514a2db82a055772218f52db2f5fa157c37a9ba16c1a239819e57f0d16218\"],"
"\"20000004\",\"1705ae3a\",\"6470e2a1\",true]}";
mining_notify params = parse_mining_notify_message(notify_json_str);
char * coinbase_tx = construct_coinbase_tx(params.coinbase_1, params.coinbase_2, "336508070fca95", "0000000000000000");
char * merkle_root = calculate_merkle_root_hash(coinbase_tx, (uint8_t(*)[32])params.merkle_branches, params.n_merkle_branches);
bm_job job = construct_bm_job(&params, merkle_root);
mining_notify * params = parse_mining_notify_message(notify_json_str, 512);
char * coinbase_tx = construct_coinbase_tx(params->coinbase_1, params->coinbase_2, "336508070fca95", "0000000000000000");
char * merkle_root = calculate_merkle_root_hash(coinbase_tx, (uint8_t(*)[32])params->merkle_branches, params->n_merkle_branches);
bm_job job = construct_bm_job(params, merkle_root);
uint8_t expected_midstate_bin[32];
hex2bin("5FD281AF6A1750EAEE502C04067738BD46C82FC22112FFE797CE7F035D276126", expected_midstate_bin, 32);

View File

@ -34,14 +34,14 @@ TEST_CASE("Parse stratum notify params", "[mining.notify]")
"\"41903d4c1b2f736c7573682f0000000003ca890d27000000001976a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac00000000000000002c6a4c2952534b424c4f434b3a4cb4cb2ddfc37c41baf5ef6b6b4899e3253a8f1dfc7e5dd68a5b5b27005014ef0000000000000000266a24aa21a9ed5caa249f1af9fbf71c986fea8e076ca34ae3514fb2f86400561b28c7b15949bf00000000\","
"[\"ae23055e00f0f697cc3640124812d96d4fe8bdfa03484c1c638ce5a1c0e9aa81\",\"980fb87cb61021dd7afd314fcb0dabd096f3d56a7377f6f320684652e7410a21\",\"a52e9868343c55ce405be8971ff340f562ae9ab6353f07140d01666180e19b52\",\"7435bdfa004e603953b2ed39f118803934d9cf17b06d979ceb682f2251bafac2\",\"2a91f061a22d27cb8f44eea79938fb241ebeb359891aa907f05ffde7ed44e52e\",\"302401f80eb5e958155135e25200bb8ea181ad2d05e804a531c7314d86403cdc\",\"318ecb6161eb9b4cfd802bd730e2d36c167ddf102e70aa7b4158e2870dd47392\",\"1114332a9858e0cf84b2425bb1e59eaabf91dd102d114aa443d57fc1b3beb0c9\",\"f43f38095c810613ed795a44d9fab02ff25269706f454885db9be05cdf9c06e1\",\"3e2fc26b27fddc39668b59099cd9635761bb72ed92404204e12bdff08b16fb75\",\"463c19427286342120039a83218fa87ce45448e246895abac11fff0036076758\",\"03d287f655813e540ddb9c4e7aeb922478662b0f5d8e9d0cbd564b20146bab76\"],"
"\"20000004\",\"1705c739\",\"64495522\",false]}";
mining_notify params = parse_mining_notify_message(json_string);
TEST_ASSERT_EQUAL_STRING("1d2e0c4d3d", params.job_id);
TEST_ASSERT_EQUAL_STRING("ef4b9a48c7986466de4adc002f7337a6e121bc43000376ea0000000000000000", params.prev_block_hash);
TEST_ASSERT_EQUAL_STRING("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4b03a5020cfabe6d6d379ae882651f6469f2ed6b8b40a4f9a4b41fd838a3ad6de8cba775f4e8f1d3080100000000000000", params.coinbase_1);
TEST_ASSERT_EQUAL_STRING("41903d4c1b2f736c7573682f0000000003ca890d27000000001976a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac00000000000000002c6a4c2952534b424c4f434b3a4cb4cb2ddfc37c41baf5ef6b6b4899e3253a8f1dfc7e5dd68a5b5b27005014ef0000000000000000266a24aa21a9ed5caa249f1af9fbf71c986fea8e076ca34ae3514fb2f86400561b28c7b15949bf00000000", params.coinbase_2);
TEST_ASSERT_EQUAL_UINT32(0x20000004, params.version);
TEST_ASSERT_EQUAL_UINT32(0x1705c739, params.target);
TEST_ASSERT_EQUAL_UINT32(0x64495522, params.ntime);
mining_notify * params = parse_mining_notify_message(json_string, 512);
TEST_ASSERT_EQUAL_STRING("1d2e0c4d3d", params->job_id);
TEST_ASSERT_EQUAL_STRING("ef4b9a48c7986466de4adc002f7337a6e121bc43000376ea0000000000000000", params->prev_block_hash);
TEST_ASSERT_EQUAL_STRING("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4b03a5020cfabe6d6d379ae882651f6469f2ed6b8b40a4f9a4b41fd838a3ad6de8cba775f4e8f1d3080100000000000000", params->coinbase_1);
TEST_ASSERT_EQUAL_STRING("41903d4c1b2f736c7573682f0000000003ca890d27000000001976a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac00000000000000002c6a4c2952534b424c4f434b3a4cb4cb2ddfc37c41baf5ef6b6b4899e3253a8f1dfc7e5dd68a5b5b27005014ef0000000000000000266a24aa21a9ed5caa249f1af9fbf71c986fea8e076ca34ae3514fb2f86400561b28c7b15949bf00000000", params->coinbase_2);
TEST_ASSERT_EQUAL_UINT32(0x20000004, params->version);
TEST_ASSERT_EQUAL_UINT32(0x1705c739, params->target);
TEST_ASSERT_EQUAL_UINT32(0x64495522, params->ntime);
}
TEST_CASE("Test mining.subcribe result parsing", "[mining.subscribe]")

View File

@ -49,11 +49,11 @@ void ASIC_task(void * pvParameters)
memcpy(&job.ntime, &next_bm_job->ntime, 4);
memcpy(&job.merkle4, next_bm_job->merkle_root + 28, 4);
memcpy(job.midstate, next_bm_job->midstate, 32);
if (active_jobs[job.job_id] != NULL) {
free(active_jobs[job.job_id]->jobid);
free(active_jobs[job.job_id]->extranonce2);
free(active_jobs[job.job_id]);
free_bm_job(active_jobs[job.job_id]);
}
active_jobs[job.job_id] = next_bm_job;
pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock);

View File

@ -17,30 +17,24 @@ void create_jobs_task(void * pvParameters)
while (1) {
char * next_notify_json_str = (char *) queue_dequeue(&GLOBAL_STATE->stratum_queue);
ESP_LOGI(TAG, "New Work Dequeued");
mining_notify params = parse_mining_notify_message(next_notify_json_str);
mining_notify * params = (mining_notify *) queue_dequeue(&GLOBAL_STATE->stratum_queue);
ESP_LOGI(TAG, "New Work Dequeued %s", params->job_id);
uint32_t extranonce_2 = 0;
while (extranonce_2 < UINT_MAX && GLOBAL_STATE->abandon_work == 0)
{
char * extranonce_2_str = extranonce_2_generate(extranonce_2, GLOBAL_STATE->extranonce_2_len);
char *coinbase_tx = construct_coinbase_tx(params.coinbase_1, params.coinbase_2, GLOBAL_STATE->extranonce_str, extranonce_2_str);
//ESP_LOGI(TAG, "Coinbase tx: %s", coinbase_tx);
char *merkle_root = calculate_merkle_root_hash(coinbase_tx, (uint8_t(*)[32])params.merkle_branches, params.n_merkle_branches);
//ESP_LOGI(TAG, "Merkle root: %s", merkle_root);
char *coinbase_tx = construct_coinbase_tx(params->coinbase_1, params->coinbase_2, GLOBAL_STATE->extranonce_str, extranonce_2_str);
bm_job next_job = construct_bm_job(&params, merkle_root);
next_job.pool_diff = GLOBAL_STATE->stratum_difficulty; //each job is tied to the _current_ difficulty
char *merkle_root = calculate_merkle_root_hash(coinbase_tx, (uint8_t(*)[32])params->merkle_branches, params->n_merkle_branches);
bm_job next_job = construct_bm_job(params, merkle_root);
bm_job * queued_next_job = malloc(sizeof(bm_job));
memcpy(queued_next_job, &next_job, sizeof(bm_job));
queued_next_job->extranonce2 = strdup(extranonce_2_str);
queued_next_job->jobid = strdup(params.job_id);
queued_next_job->jobid = strdup(params->job_id);
queue_enqueue(&GLOBAL_STATE->ASIC_jobs_queue, queued_next_job);
@ -56,7 +50,6 @@ void create_jobs_task(void * pvParameters)
}
free_mining_notify(params);
free(next_notify_json_str);
}
}

View File

@ -6,6 +6,7 @@
#include "bm1397.h"
#include "global_state.h"
#define PORT CONFIG_STRATUM_PORT
#define STRATUM_URL CONFIG_STRATUM_URL
@ -15,7 +16,6 @@
static const char *TAG = "stratum_task";
static ip_addr_t ip_Addr;
static bool bDNSFound = false;
static bool difficulty_changed = false;
void dns_found_cb(const char * name, const ip_addr_t * ipaddr, void * callback_arg)
@ -92,15 +92,11 @@ void stratum_task(void * pvParameters)
stratum_method method = parse_stratum_method(line);
if (method == MINING_NOTIFY) {
if ((difficulty_changed || should_abandon_work(line)) && GLOBAL_STATE->stratum_queue.count > 0) {
if (difficulty_changed) {
ESP_LOGI(TAG, "pool diff changed, clearing queues");
difficulty_changed = false;
} else {
ESP_LOGI(TAG, "clean_jobs is true, clearing queues");
}
if (method == MINING_NOTIFY) {
if (should_abandon_work(line) && GLOBAL_STATE->stratum_queue.count > 0) {
ESP_LOGI(TAG, "pool diff changed, clearing queues");
GLOBAL_STATE->abandon_work = 1;
queue_clear(&GLOBAL_STATE->stratum_queue);
@ -113,26 +109,24 @@ void stratum_task(void * pvParameters)
pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock);
}
if ( GLOBAL_STATE->stratum_queue.count == QUEUE_SIZE) {
char * next_notify_json_str = (char *) queue_dequeue(&GLOBAL_STATE->stratum_queue);
free(next_notify_json_str);
mining_notify * next_notify_json_str = (mining_notify *) queue_dequeue(&GLOBAL_STATE->stratum_queue);
free_mining_notify(next_notify_json_str);
}
queue_enqueue(&GLOBAL_STATE->stratum_queue, line);
mining_notify * params = parse_mining_notify_message(line, GLOBAL_STATE->stratum_difficulty);
queue_enqueue(&GLOBAL_STATE->stratum_queue, params);
} else if (method == MINING_SET_DIFFICULTY) {
uint32_t new_difficulty = parse_mining_set_difficulty_message(line);
if (new_difficulty != GLOBAL_STATE->stratum_difficulty) {
GLOBAL_STATE->stratum_difficulty = new_difficulty;
difficulty_changed = true;
ESP_LOGI(TAG, "Set stratum difficulty: %d", GLOBAL_STATE->stratum_difficulty);
BM1397_set_job_difficulty_mask(GLOBAL_STATE->stratum_difficulty);
}
free(line);
} else if (method == MINING_SET_VERSION_MASK) {
version_mask = parse_mining_set_version_mask_message(line);
//1fffe000
ESP_LOGI(TAG, "Set version mask: %08x", version_mask);
free(line);
} else if (method == STRATUM_RESULT) {
int16_t parsed_id;
@ -143,11 +137,9 @@ void stratum_task(void * pvParameters)
ESP_LOGI(TAG, "message id %d result rejected", parsed_id);
SYSTEM_notify_rejected_share(&GLOBAL_STATE->SYSTEM_MODULE);
}
free(line);
} else {
free(line);
}
free(line);
}

View File

@ -1,4 +1,5 @@
#include "work_queue.h"
#include "esp_log.h"
void queue_init(work_queue * queue) {
queue->head = 0;
@ -47,8 +48,8 @@ void queue_clear(work_queue * queue)
while (queue->count > 0)
{
void * next_work = queue->buffer[queue->head];
free(next_work);
mining_notify * next_work = queue->buffer[queue->head];
free_mining_notify(next_work);
queue->head = (queue->head + 1) % QUEUE_SIZE;
queue->count--;
}