mirror of
https://github.com/xmrig/xmrig.git
synced 2025-01-03 17:40:13 +00:00
Optimize job_decode, support variable length blob and redume mutex lock
time.
This commit is contained in:
parent
361394be21
commit
54cef68aa9
5 changed files with 69 additions and 79 deletions
|
@ -41,6 +41,6 @@ extern void (* const extra_hashes[4])(const void *, size_t, char *);
|
|||
|
||||
bool cryptonight_init(int variant);
|
||||
void cryptonight_hash(void* output, const void* input, size_t input_len);
|
||||
int scanhash_cryptonight(int thr_id, uint32_t *hash, uint32_t *restrict pdata, const uint32_t *restrict ptarget, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx);
|
||||
int scanhash_cryptonight(int thr_id, uint32_t *hash, uint32_t *restrict pdata, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx);
|
||||
|
||||
#endif /* __CRYPTONIGHT_H__ */
|
||||
|
|
|
@ -136,7 +136,7 @@ void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, d
|
|||
|
||||
|
||||
#ifndef BUILD_TEST
|
||||
int scanhash_cryptonight(int thr_id, uint32_t *hash, uint32_t *restrict pdata, const uint32_t *restrict ptarget, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx) {
|
||||
int scanhash_cryptonight(int thr_id, uint32_t *hash, uint32_t *restrict pdata, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx) {
|
||||
uint32_t *nonceptr = (uint32_t*) (((char*)pdata) + 39);
|
||||
uint32_t n = *nonceptr - 1;
|
||||
const uint32_t first_nonce = n + 1;
|
||||
|
@ -145,7 +145,7 @@ int scanhash_cryptonight(int thr_id, uint32_t *hash, uint32_t *restrict pdata, c
|
|||
*nonceptr = ++n;
|
||||
cryptonight_hash_ctx(hash, pdata, ctx);
|
||||
|
||||
if (unlikely(hash[7] < ptarget[7])) {
|
||||
if (unlikely(hash[7] < target)) {
|
||||
*hashes_done = n - first_nonce + 1;
|
||||
return true;
|
||||
}
|
||||
|
|
98
stratum.c
98
stratum.c
|
@ -58,6 +58,9 @@
|
|||
#define unlikely(expr) (__builtin_expect(!!(expr), 0))
|
||||
|
||||
|
||||
static struct work work;
|
||||
|
||||
|
||||
static bool send_line(curl_socket_t sock, char *s);
|
||||
static bool socket_full(curl_socket_t sock, int timeout);
|
||||
static void buffer_append(struct stratum_ctx *sctx, const char *s);
|
||||
|
@ -66,7 +69,7 @@ static int sockopt_keepalive_cb(void *userdata, curl_socket_t fd, curlsocktype p
|
|||
static curl_socket_t opensocket_grab_cb(void *clientp, curlsocktype purpose, struct curl_sockaddr *addr);
|
||||
static int closesocket_cb(void *clientp, curl_socket_t item);
|
||||
static bool login_decode(struct stratum_ctx *sctx, const json_t *val);
|
||||
static bool job_decode(struct stratum_ctx *sctx, const json_t *job);
|
||||
static bool job_decode(const json_t *job);
|
||||
static bool jobj_binary(const json_t *obj, const char *key, void *buf, size_t buflen);
|
||||
|
||||
|
||||
|
@ -327,13 +330,17 @@ bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *p
|
|||
}
|
||||
|
||||
login_decode(sctx, val);
|
||||
json_t *job = json_object_get(result, "job");
|
||||
|
||||
pthread_mutex_lock(&sctx->work_lock);
|
||||
if (job) {
|
||||
job_decode(sctx, job);
|
||||
}
|
||||
pthread_mutex_unlock(&sctx->work_lock);
|
||||
job(sctx, json_object_get(result, "job"));
|
||||
// json_t *job = json_object_get(result, "job");
|
||||
|
||||
|
||||
|
||||
//pthread_mutex_lock(&sctx->work_lock);
|
||||
//if (job) {
|
||||
// job_decode(sctx, job);
|
||||
//}
|
||||
//pthread_mutex_unlock(&sctx->work_lock);
|
||||
|
||||
json_decref(val);
|
||||
return true;
|
||||
|
@ -492,11 +499,20 @@ static void buffer_append(struct stratum_ctx *sctx, const char *s)
|
|||
*/
|
||||
static bool job(struct stratum_ctx *sctx, json_t *params)
|
||||
{
|
||||
bool ret = false;
|
||||
if (!job_decode(params)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&sctx->work_lock);
|
||||
ret = job_decode(sctx, params);
|
||||
|
||||
if (sctx->work.target != work.target) {
|
||||
stats_set_target(work.target);
|
||||
}
|
||||
|
||||
memcpy(&sctx->work, &work, sizeof(struct work));
|
||||
pthread_mutex_unlock(&sctx->work_lock);
|
||||
return ret;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -584,33 +600,22 @@ static bool login_decode(struct stratum_ctx *sctx, const json_t *val) {
|
|||
return false;
|
||||
}
|
||||
|
||||
json_t *tmp = json_object_get(res, "id");
|
||||
if (!tmp) {
|
||||
const char *id = json_string_value(json_object_get(res, "id"));
|
||||
if (!id || strlen(id) >= (sizeof(sctx->id))) {
|
||||
applog(LOG_ERR, "JSON invalid id");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *id = json_string_value(tmp);
|
||||
if (!id) {
|
||||
applog(LOG_ERR, "JSON id is not a string");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&sctx->id, id, 64);
|
||||
memset(&sctx->id, 0, sizeof(sctx->id));
|
||||
memcpy(&sctx->id, id, strlen(id));
|
||||
|
||||
pthread_mutex_lock(&sctx->sock_lock);
|
||||
sctx->ready = true;
|
||||
pthread_mutex_unlock(&sctx->sock_lock);
|
||||
|
||||
tmp = json_object_get(res, "status");
|
||||
if (!tmp) {
|
||||
applog(LOG_ERR, "JSON invalid status");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *s = json_string_value(tmp);
|
||||
const char *s = json_string_value(json_object_get(res, "status"));
|
||||
if (!s) {
|
||||
applog(LOG_ERR, "JSON status is not a string");
|
||||
applog(LOG_ERR, "JSON invalid status");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -630,46 +635,40 @@ static bool login_decode(struct stratum_ctx *sctx, const json_t *val) {
|
|||
* @param work
|
||||
* @return
|
||||
*/
|
||||
static bool job_decode(struct stratum_ctx *sctx, const json_t *job) {
|
||||
json_t *tmp = json_object_get(job, "job_id");
|
||||
if (!tmp) {
|
||||
static bool job_decode(const json_t *job) {
|
||||
const char *job_id = json_string_value(json_object_get(job, "job_id"));
|
||||
if (!job_id || strlen(job_id) >= sizeof(work.job_id)) {
|
||||
applog(LOG_ERR, "JSON invalid job id");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *job_id = json_string_value(tmp);
|
||||
tmp = json_object_get(job, "blob");
|
||||
if (!tmp) {
|
||||
const char *blob = json_string_value(json_object_get(job, "blob"));
|
||||
if (!blob) {
|
||||
applog(LOG_ERR, "JSON invalid blob");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *hexblob = json_string_value(tmp);
|
||||
if (!hexblob || strlen(hexblob) != 152) {
|
||||
work.blob_size = strlen(blob);
|
||||
if (work.blob_size % 2 != 0) {
|
||||
applog(LOG_ERR, "JSON invalid blob length");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hex2bin(sctx->blob, hexblob, 76)) {
|
||||
applog(LOG_ERR, "JSON inval blob");
|
||||
work.blob_size /= 2;
|
||||
if (work.blob_size < 76 || work.blob_size > (sizeof(work.blob))) {
|
||||
applog(LOG_ERR, "JSON invalid blob length");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t target;
|
||||
jobj_binary(job, "target", &target, 4);
|
||||
|
||||
if (sctx->target != target) {
|
||||
stats_set_target(target);
|
||||
sctx->target = target;
|
||||
if (!hex2bin((unsigned char *) work.blob, blob, work.blob_size)) {
|
||||
applog(LOG_ERR, "JSON invalid blob");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(sctx->work.data, sctx->blob, 76);
|
||||
memset(sctx->work.target, 0xff, sizeof(sctx->work.target));
|
||||
jobj_binary(job, "target", &work.target, 4);
|
||||
|
||||
sctx->work.target[7] = sctx->target;
|
||||
|
||||
free(sctx->work.job_id);
|
||||
sctx->work.job_id = strdup(job_id);
|
||||
memset(work.job_id, 0, sizeof(work.job_id));
|
||||
memcpy(work.job_id, job_id, strlen(job_id));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -699,6 +698,7 @@ static bool jobj_binary(const json_t *obj, const char *key, void *buf, size_t bu
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!hex2bin(buf, hexstr, buflen)) {
|
||||
return false;
|
||||
}
|
||||
|
|
20
stratum.h
20
stratum.h
|
@ -29,14 +29,18 @@
|
|||
#include <curl/curl.h>
|
||||
|
||||
|
||||
/**
|
||||
* 128tx exploit.
|
||||
*
|
||||
* Max blob size is 84 (75 fixed + 9 variable), aligned to 96.
|
||||
* https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
|
||||
*/
|
||||
struct work {
|
||||
uint32_t data[19];
|
||||
uint32_t target[8];
|
||||
uint32_t hash[8];
|
||||
|
||||
char *job_id;
|
||||
size_t xnonce2_len;
|
||||
unsigned char *xnonce2;
|
||||
uint32_t blob[21] __attribute__((aligned(16)));
|
||||
size_t blob_size __attribute__((aligned(16)));
|
||||
uint32_t target __attribute__((aligned(16)));
|
||||
uint32_t hash[8] __attribute__((aligned(16)));
|
||||
char job_id[64] __attribute__((aligned(16)));
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,8 +57,6 @@ struct stratum_ctx {
|
|||
bool ready;
|
||||
|
||||
char id[64];
|
||||
char blob[76];
|
||||
uint32_t target;
|
||||
|
||||
struct work work;
|
||||
struct work g_work;
|
||||
|
|
24
xmrig.c
24
xmrig.c
|
@ -75,8 +75,6 @@ static void workio_cmd_free(struct workio_cmd *wc);
|
|||
* @param w
|
||||
*/
|
||||
static inline void work_free(struct work *w) {
|
||||
free(w->job_id);
|
||||
free(w->xnonce2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,14 +85,6 @@ static inline void work_free(struct work *w) {
|
|||
*/
|
||||
static inline void work_copy(struct work *dest, const struct work *src) {
|
||||
memcpy(dest, src, sizeof(struct work));
|
||||
if (src->job_id) {
|
||||
dest->job_id = strdup(src->job_id);
|
||||
}
|
||||
|
||||
if (src->xnonce2) {
|
||||
dest->xnonce2 = malloc(src->xnonce2_len);
|
||||
memcpy(dest->xnonce2, src->xnonce2, src->xnonce2_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,9 +107,7 @@ static inline void gen_workify(struct stratum_ctx *sctx) {
|
|||
pthread_mutex_lock(&stratum_ctx->work_lock);
|
||||
|
||||
if (stratum_ctx->work.job_id && (!stratum_ctx->g_work_time || strcmp(stratum_ctx->work.job_id, stratum_ctx->g_work.job_id))) {
|
||||
free(sctx->g_work.job_id);
|
||||
memcpy(&sctx->g_work, &sctx->work, sizeof(struct work));
|
||||
sctx->work.job_id = strdup(sctx->work.job_id);
|
||||
time(&stratum_ctx->g_work_time);
|
||||
|
||||
pthread_mutex_unlock(&stratum_ctx->work_lock);
|
||||
|
@ -143,11 +131,11 @@ static bool submit_upstream_work(struct work *work) {
|
|||
char s[JSON_BUF_LEN];
|
||||
|
||||
/* pass if the previous hash is not the current previous hash */
|
||||
if (memcmp(work->data + 1, stratum_ctx->g_work.data + 1, 32)) {
|
||||
if (memcmp(work->blob + 1, stratum_ctx->g_work.blob + 1, 32)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char *noncestr = bin2hex(((const unsigned char*) work->data) + 39, 4);
|
||||
char *noncestr = bin2hex(((const unsigned char*) work->blob) + 39, 4);
|
||||
char *hashhex = bin2hex((const unsigned char *) work->hash, 32);
|
||||
|
||||
snprintf(s, JSON_BUF_LEN,
|
||||
|
@ -288,7 +276,7 @@ static void *miner_thread(void *userdata) {
|
|||
affine_to_cpu_mask(thr_id, (unsigned long) opt_affinity);
|
||||
}
|
||||
|
||||
uint32_t *nonceptr = (uint32_t*) (((char*)work.data) + 39);
|
||||
uint32_t *nonceptr = (uint32_t*) (((char*)work.blob) + 39);
|
||||
uint32_t hash[8] __attribute__((aligned(32)));
|
||||
|
||||
while (1) {
|
||||
|
@ -304,10 +292,10 @@ static void *miner_thread(void *userdata) {
|
|||
|
||||
pthread_mutex_lock(&stratum_ctx->work_lock);
|
||||
|
||||
if (memcmp(work.data, stratum_ctx->g_work.data, 39) || memcmp(((uint8_t*) work.data) + 43, ((uint8_t*) stratum_ctx->g_work.data) + 43, 33)) {
|
||||
if (memcmp(work.blob, stratum_ctx->g_work.blob, 39) || memcmp(((uint8_t*) work.blob) + 43, ((uint8_t*) stratum_ctx->g_work.blob) + 43, 33)) {
|
||||
work_free(&work);
|
||||
work_copy(&work, &stratum_ctx->g_work);
|
||||
nonceptr = (uint32_t*) (((char*)work.data) + 39);
|
||||
nonceptr = (uint32_t*) (((char*)work.blob) + 39);
|
||||
*nonceptr = 0xffffffffU / opt_n_threads * thr_id;
|
||||
} else {
|
||||
++(*nonceptr);
|
||||
|
@ -335,7 +323,7 @@ static void *miner_thread(void *userdata) {
|
|||
gettimeofday(&tv_start, NULL );
|
||||
|
||||
/* scan nonces for a proof-of-work hash */
|
||||
rc = scanhash_cryptonight(thr_id, hash, work.data, work.target, max_nonce, &hashes_done, persistentctx);
|
||||
rc = scanhash_cryptonight(thr_id, hash, work.blob, work.target, max_nonce, &hashes_done, persistentctx);
|
||||
stats_add_hashes(thr_id, &tv_start, hashes_done);
|
||||
|
||||
memcpy(work.hash, hash, 32);
|
||||
|
|
Loading…
Reference in a new issue