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:
Skot
2024-05-31 17:43:10 -04:00
committed by GitHub
parent 00d5a7386f
commit 11c1d087a8
4 changed files with 92 additions and 67 deletions

View File

@ -23,6 +23,7 @@ static size_t json_rpc_buffer_size = 0;
static int send_uid = 1;
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()
{
@ -116,6 +117,8 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json)
cJSON * method_json = cJSON_GetObjectItem(json, "method");
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 (strcmp("mining.notify", method_json->valuestring) == 0) {
result = MINING_NOTIFY;
@ -126,30 +129,78 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json)
} else {
ESP_LOGI(TAG, "unhandled method in stratum message: %s", stratum_json);
}
//if there is no method, then it is a result
} else {
// parse results
cJSON * result_json = cJSON_GetObjectItem(json, "result");
cJSON * error_json = cJSON_GetObjectItem(json, "error");
//if the result is null, then it's a fail
if (result_json == NULL) {
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");
if (mask != NULL) {
result = STRATUM_RESULT_VERSION_MASK;
message->version_mask = strtoul(mask->valuestring, NULL, 16);
} else if (cJSON_IsBool(result_json)) {
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;
ESP_LOGI(TAG, "Set version mask: %08lx", message->version_mask);
} 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);
message->version_mask = version_mask;
}
done:
cJSON_Delete(json);
}
@ -244,20 +295,13 @@ int _parse_stratum_subscribe_result_message(const char * result_json_str, char *
return 0;
}
int STRATUM_V1_subscribe(int socket, char ** extranonce, int * extranonce2_len, char * model)
int STRATUM_V1_subscribe(int socket, char * model)
{
// Subscribe
char subscribe_msg[BUFFER_SIZE];
sprintf(subscribe_msg, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": [\"bitaxe/%s\"]}\n", send_uid++, model);
debug_stratum_tx(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;
}
@ -269,15 +313,6 @@ int STRATUM_V1_suggest_difficulty(int socket, uint32_t difficulty)
debug_stratum_tx(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;
}
@ -320,26 +355,6 @@ void STRATUM_V1_configure_version_rolling(int socket, uint32_t * version_mask)
ESP_LOGI(TAG, "tx: %s", 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;
}