mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-06-21 07:30:59 +02:00
Stratum message ordering fix (#192)
* rough strategy for this fix. needs testing * seems to be working with OCEAN. need to make sure nothing else is broken * add version mask debug * removed stratum setup response results from A/R shares tally
This commit is contained in:
parent
00d5a7386f
commit
11c1d087a8
@ -17,9 +17,14 @@ typedef enum
|
|||||||
MINING_SET_DIFFICULTY,
|
MINING_SET_DIFFICULTY,
|
||||||
MINING_SET_VERSION_MASK,
|
MINING_SET_VERSION_MASK,
|
||||||
STRATUM_RESULT,
|
STRATUM_RESULT,
|
||||||
STRATUM_RESULT_VERSION_MASK
|
STRATUM_RESULT_SETUP,
|
||||||
|
STRATUM_RESULT_VERSION_MASK,
|
||||||
|
STRATUM_RESULT_SUBSCRIBE
|
||||||
} stratum_method;
|
} stratum_method;
|
||||||
|
|
||||||
|
static const int STRATUM_ID_SUBSCRIBE = 1;
|
||||||
|
static const int STRATUM_ID_CONFIGURE = 2;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *job_id;
|
char *job_id;
|
||||||
@ -37,6 +42,8 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
char * extranonce_str;
|
||||||
|
int extranonce_2_len;
|
||||||
|
|
||||||
int16_t message_id;
|
int16_t message_id;
|
||||||
// Indicates the type of request the message represents.
|
// Indicates the type of request the message represents.
|
||||||
@ -57,7 +64,7 @@ void STRATUM_V1_initialize_buffer();
|
|||||||
|
|
||||||
char *STRATUM_V1_receive_jsonrpc_line(int sockfd);
|
char *STRATUM_V1_receive_jsonrpc_line(int sockfd);
|
||||||
|
|
||||||
int STRATUM_V1_subscribe(int socket, char ** extranonce, int * extranonce2_len, char * model);
|
int STRATUM_V1_subscribe(int socket, char * model);
|
||||||
|
|
||||||
void STRATUM_V1_parse(StratumApiV1Message *message, const char *stratum_json);
|
void STRATUM_V1_parse(StratumApiV1Message *message, const char *stratum_json);
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ static size_t json_rpc_buffer_size = 0;
|
|||||||
static int send_uid = 1;
|
static int send_uid = 1;
|
||||||
|
|
||||||
static void debug_stratum_tx(const char *);
|
static void debug_stratum_tx(const char *);
|
||||||
|
int _parse_stratum_subscribe_result_message(const char * result_json_str, char ** extranonce, int * extranonce2_len);
|
||||||
|
|
||||||
void STRATUM_V1_initialize_buffer()
|
void STRATUM_V1_initialize_buffer()
|
||||||
{
|
{
|
||||||
@ -116,6 +117,8 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json)
|
|||||||
|
|
||||||
cJSON * method_json = cJSON_GetObjectItem(json, "method");
|
cJSON * method_json = cJSON_GetObjectItem(json, "method");
|
||||||
stratum_method result = STRATUM_UNKNOWN;
|
stratum_method result = STRATUM_UNKNOWN;
|
||||||
|
|
||||||
|
//if there is a method, then use that to decide what to do
|
||||||
if (method_json != NULL && cJSON_IsString(method_json)) {
|
if (method_json != NULL && cJSON_IsString(method_json)) {
|
||||||
if (strcmp("mining.notify", method_json->valuestring) == 0) {
|
if (strcmp("mining.notify", method_json->valuestring) == 0) {
|
||||||
result = MINING_NOTIFY;
|
result = MINING_NOTIFY;
|
||||||
@ -126,30 +129,78 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json)
|
|||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "unhandled method in stratum message: %s", stratum_json);
|
ESP_LOGI(TAG, "unhandled method in stratum message: %s", stratum_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if there is no method, then it is a result
|
||||||
} else {
|
} else {
|
||||||
// parse results
|
// parse results
|
||||||
cJSON * result_json = cJSON_GetObjectItem(json, "result");
|
cJSON * result_json = cJSON_GetObjectItem(json, "result");
|
||||||
cJSON * error_json = cJSON_GetObjectItem(json, "error");
|
cJSON * error_json = cJSON_GetObjectItem(json, "error");
|
||||||
|
|
||||||
|
//if the result is null, then it's a fail
|
||||||
if (result_json == NULL) {
|
if (result_json == NULL) {
|
||||||
message->response_success = false;
|
message->response_success = false;
|
||||||
} else {
|
|
||||||
|
//if it's an error, then it's a fail
|
||||||
|
} else if (!cJSON_IsNull(error_json)) {
|
||||||
|
if (parsed_id < 5) {
|
||||||
|
result = STRATUM_RESULT_SETUP;
|
||||||
|
} else {
|
||||||
|
result = STRATUM_RESULT;
|
||||||
|
}
|
||||||
|
message->response_success = false;
|
||||||
|
|
||||||
|
//if the result is a boolean, then parse it
|
||||||
|
} else if (cJSON_IsBool(result_json)) {
|
||||||
|
if (parsed_id < 5) {
|
||||||
|
result = STRATUM_RESULT_SETUP;
|
||||||
|
} else {
|
||||||
|
result = STRATUM_RESULT;
|
||||||
|
}
|
||||||
|
if (cJSON_IsTrue(result_json)) {
|
||||||
|
message->response_success = true;
|
||||||
|
} else {
|
||||||
|
message->response_success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the id is STRATUM_ID_SUBSCRIBE parse it
|
||||||
|
} else if (parsed_id == STRATUM_ID_SUBSCRIBE) {
|
||||||
|
result = STRATUM_RESULT_SUBSCRIBE;
|
||||||
|
|
||||||
|
cJSON * extranonce2_len_json = cJSON_GetArrayItem(result_json, 2);
|
||||||
|
if (extranonce2_len_json == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Unable to parse extranonce2_len: %s", result_json->valuestring);
|
||||||
|
message->response_success = false;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
message->extranonce_2_len = extranonce2_len_json->valueint;
|
||||||
|
|
||||||
|
cJSON * extranonce_json = cJSON_GetArrayItem(result_json, 1);
|
||||||
|
if (extranonce_json == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Unable parse extranonce: %s", result_json->valuestring);
|
||||||
|
message->response_success = false;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
message->extranonce_str = malloc(strlen(extranonce_json->valuestring) + 1);
|
||||||
|
strcpy(message->extranonce_str, extranonce_json->valuestring);
|
||||||
|
message->response_success = true;
|
||||||
|
|
||||||
|
//print the extranonce_str
|
||||||
|
ESP_LOGI(TAG, "extranonce_str: %s", message->extranonce_str);
|
||||||
|
ESP_LOGI(TAG, "extranonce_2_len: %d", message->extranonce_2_len);
|
||||||
|
|
||||||
|
//if the id is STRATUM_ID_CONFIGURE parse it
|
||||||
|
} else if (parsed_id == STRATUM_ID_CONFIGURE) {
|
||||||
cJSON * mask = cJSON_GetObjectItem(result_json, "version-rolling.mask");
|
cJSON * mask = cJSON_GetObjectItem(result_json, "version-rolling.mask");
|
||||||
if (mask != NULL) {
|
if (mask != NULL) {
|
||||||
result = STRATUM_RESULT_VERSION_MASK;
|
result = STRATUM_RESULT_VERSION_MASK;
|
||||||
message->version_mask = strtoul(mask->valuestring, NULL, 16);
|
message->version_mask = strtoul(mask->valuestring, NULL, 16);
|
||||||
} else if (cJSON_IsBool(result_json)) {
|
ESP_LOGI(TAG, "Set version mask: %08lx", message->version_mask);
|
||||||
result = STRATUM_RESULT;
|
|
||||||
if (cJSON_IsTrue(result_json)) {
|
|
||||||
message->response_success = true;
|
|
||||||
} else {
|
|
||||||
message->response_success = false;
|
|
||||||
}
|
|
||||||
} else if (!cJSON_IsNull(error_json)) {
|
|
||||||
result = STRATUM_RESULT;
|
|
||||||
message->response_success = false;
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "unhandled result in stratum message: %s", stratum_json);
|
ESP_LOGI(TAG, "error setting version mask: %s", stratum_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "unhandled result in stratum message: %s", stratum_json);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +248,7 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json)
|
|||||||
uint32_t version_mask = strtoul(cJSON_GetArrayItem(params, 0)->valuestring, NULL, 16);
|
uint32_t version_mask = strtoul(cJSON_GetArrayItem(params, 0)->valuestring, NULL, 16);
|
||||||
message->version_mask = version_mask;
|
message->version_mask = version_mask;
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
cJSON_Delete(json);
|
cJSON_Delete(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,20 +295,13 @@ int _parse_stratum_subscribe_result_message(const char * result_json_str, char *
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int STRATUM_V1_subscribe(int socket, char ** extranonce, int * extranonce2_len, char * model)
|
int STRATUM_V1_subscribe(int socket, char * model)
|
||||||
{
|
{
|
||||||
// Subscribe
|
// Subscribe
|
||||||
char subscribe_msg[BUFFER_SIZE];
|
char subscribe_msg[BUFFER_SIZE];
|
||||||
sprintf(subscribe_msg, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": [\"bitaxe/%s\"]}\n", send_uid++, model);
|
sprintf(subscribe_msg, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": [\"bitaxe/%s\"]}\n", send_uid++, model);
|
||||||
debug_stratum_tx(subscribe_msg);
|
debug_stratum_tx(subscribe_msg);
|
||||||
write(socket, subscribe_msg, strlen(subscribe_msg));
|
write(socket, subscribe_msg, strlen(subscribe_msg));
|
||||||
char * line;
|
|
||||||
line = STRATUM_V1_receive_jsonrpc_line(socket);
|
|
||||||
ESP_LOGI(TAG, "Received result %s", line);
|
|
||||||
|
|
||||||
_parse_stratum_subscribe_result_message(line, extranonce, extranonce2_len);
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -269,15 +313,6 @@ int STRATUM_V1_suggest_difficulty(int socket, uint32_t difficulty)
|
|||||||
debug_stratum_tx(difficulty_msg);
|
debug_stratum_tx(difficulty_msg);
|
||||||
write(socket, difficulty_msg, strlen(difficulty_msg));
|
write(socket, difficulty_msg, strlen(difficulty_msg));
|
||||||
|
|
||||||
/* TODO: fix race condition with first mining.notify message
|
|
||||||
char * line;
|
|
||||||
line = STRATUM_V1_receive_jsonrpc_line(socket);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Received result %s", line);
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,26 +355,6 @@ void STRATUM_V1_configure_version_rolling(int socket, uint32_t * version_mask)
|
|||||||
ESP_LOGI(TAG, "tx: %s", configure_msg);
|
ESP_LOGI(TAG, "tx: %s", configure_msg);
|
||||||
write(socket, configure_msg, strlen(configure_msg));
|
write(socket, configure_msg, strlen(configure_msg));
|
||||||
|
|
||||||
char * line = STRATUM_V1_receive_jsonrpc_line(socket);
|
|
||||||
cJSON * json = cJSON_Parse(line);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Received result %s", line);
|
|
||||||
|
|
||||||
cJSON * result = cJSON_GetObjectItem(json, "result");
|
|
||||||
if (result != NULL) {
|
|
||||||
cJSON * version_rolling_enabled = cJSON_GetObjectItem(result, "version-rolling");
|
|
||||||
if (cJSON_IsBool(version_rolling_enabled) && cJSON_IsTrue(version_rolling_enabled)) {
|
|
||||||
cJSON * mask = cJSON_GetObjectItem(result, "version-rolling.mask");
|
|
||||||
*version_mask = strtoul(mask->valuestring, NULL, 16);
|
|
||||||
ESP_LOGI(TAG, "Set version mask: %08lx", *version_mask);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
printf("configure_version result null\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
cJSON_Delete(json);
|
|
||||||
free(line);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t (*init_fn)(u_int64_t);
|
uint8_t (*init_fn)(uint64_t);
|
||||||
task_result * (*receive_result_fn)(void * GLOBAL_STATE);
|
task_result * (*receive_result_fn)(void * GLOBAL_STATE);
|
||||||
int (*set_max_baud_fn)(void);
|
int (*set_max_baud_fn)(void);
|
||||||
void (*set_difficulty_mask_fn)(int);
|
void (*set_difficulty_mask_fn)(int);
|
||||||
|
@ -101,30 +101,24 @@ void stratum_task(void * pvParameters)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mining.subscribe
|
///// Start Stratum Action
|
||||||
STRATUM_V1_subscribe(GLOBAL_STATE->sock, &GLOBAL_STATE->extranonce_str, &GLOBAL_STATE->extranonce_2_len,
|
// mining.subscribe - ID: 1
|
||||||
GLOBAL_STATE->asic_model);
|
STRATUM_V1_subscribe(GLOBAL_STATE->sock, GLOBAL_STATE->asic_model);
|
||||||
|
|
||||||
|
// mining.configure - ID: 2
|
||||||
// mining.configure
|
|
||||||
STRATUM_V1_configure_version_rolling(GLOBAL_STATE->sock, &GLOBAL_STATE->version_mask);
|
STRATUM_V1_configure_version_rolling(GLOBAL_STATE->sock, &GLOBAL_STATE->version_mask);
|
||||||
|
|
||||||
|
//mining.suggest_difficulty - ID: 3
|
||||||
// This should come before the final step of authenticate so the first job is sent with the proper difficulty set
|
|
||||||
//mining.suggest_difficulty
|
|
||||||
STRATUM_V1_suggest_difficulty(GLOBAL_STATE->sock, STRATUM_DIFFICULTY);
|
STRATUM_V1_suggest_difficulty(GLOBAL_STATE->sock, STRATUM_DIFFICULTY);
|
||||||
|
|
||||||
char * username = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, STRATUM_USER);
|
char * username = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, STRATUM_USER);
|
||||||
char * password = nvs_config_get_string(NVS_CONFIG_STRATUM_PASS, STRATUM_PW);
|
char * password = nvs_config_get_string(NVS_CONFIG_STRATUM_PASS, STRATUM_PW);
|
||||||
|
|
||||||
|
//mining.authorize - ID: 4
|
||||||
STRATUM_V1_authenticate(GLOBAL_STATE->sock, username, password);
|
STRATUM_V1_authenticate(GLOBAL_STATE->sock, username, password);
|
||||||
free(password);
|
free(password);
|
||||||
free(username);
|
free(username);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//ESP_LOGI(TAG, "Extranonce: %s", GLOBAL_STATE->extranonce_str);
|
|
||||||
//ESP_LOGI(TAG, "Extranonce 2 length: %d", GLOBAL_STATE->extranonce_2_len);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
char * line = STRATUM_V1_receive_jsonrpc_line(GLOBAL_STATE->sock);
|
char * line = STRATUM_V1_receive_jsonrpc_line(GLOBAL_STATE->sock);
|
||||||
ESP_LOGI(TAG, "rx: %s", line); // debug incoming stratum messages
|
ESP_LOGI(TAG, "rx: %s", line); // debug incoming stratum messages
|
||||||
@ -160,10 +154,13 @@ void stratum_task(void * pvParameters)
|
|||||||
ESP_LOGI(TAG, "Set stratum difficulty: %ld", SYSTEM_TASK_MODULE.stratum_difficulty);
|
ESP_LOGI(TAG, "Set stratum difficulty: %ld", SYSTEM_TASK_MODULE.stratum_difficulty);
|
||||||
}
|
}
|
||||||
} else if (stratum_api_v1_message.method == MINING_SET_VERSION_MASK ||
|
} else if (stratum_api_v1_message.method == MINING_SET_VERSION_MASK ||
|
||||||
stratum_api_v1_message.method == STRATUM_RESULT_VERSION_MASK) {
|
stratum_api_v1_message.method == .0) {
|
||||||
// 1fffe000
|
// 1fffe000
|
||||||
ESP_LOGI(TAG, "Set version mask: %08lx", stratum_api_v1_message.version_mask);
|
ESP_LOGI(TAG, "Set version mask: %08lx", stratum_api_v1_message.version_mask);
|
||||||
GLOBAL_STATE->version_mask = stratum_api_v1_message.version_mask;
|
GLOBAL_STATE->version_mask = stratum_api_v1_message.version_mask;
|
||||||
|
} else if (stratum_api_v1_message.method == STRATUM_RESULT_SUBSCRIBE) {
|
||||||
|
GLOBAL_STATE->extranonce_str = stratum_api_v1_message.extranonce_str;
|
||||||
|
GLOBAL_STATE->extranonce_2_len = stratum_api_v1_message.extranonce_2_len;
|
||||||
} else if (stratum_api_v1_message.method == STRATUM_RESULT) {
|
} else if (stratum_api_v1_message.method == STRATUM_RESULT) {
|
||||||
if (stratum_api_v1_message.response_success) {
|
if (stratum_api_v1_message.response_success) {
|
||||||
ESP_LOGI(TAG, "message result accepted");
|
ESP_LOGI(TAG, "message result accepted");
|
||||||
@ -172,6 +169,12 @@ void stratum_task(void * pvParameters)
|
|||||||
ESP_LOGE(TAG, "message result rejected");
|
ESP_LOGE(TAG, "message result rejected");
|
||||||
SYSTEM_notify_rejected_share(&GLOBAL_STATE->SYSTEM_MODULE);
|
SYSTEM_notify_rejected_share(&GLOBAL_STATE->SYSTEM_MODULE);
|
||||||
}
|
}
|
||||||
|
} else if (stratum_api_v1_message.method == STRATUM_RESULT_SETUP) {
|
||||||
|
if (stratum_api_v1_message.response_success) {
|
||||||
|
ESP_LOGI(TAG, "setup message accepted");
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "setup message rejected");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user