Keep work data in host byte order
This commit is contained in:
parent
3c78575e0f
commit
c96b468d1c
4 changed files with 68 additions and 98 deletions
45
cpu-miner.c
45
cpu-miner.c
|
@ -180,10 +180,8 @@ static struct option const options[] = {
|
|||
};
|
||||
|
||||
struct work {
|
||||
unsigned char data[128];
|
||||
unsigned char target[32];
|
||||
|
||||
unsigned char hash[32];
|
||||
uint32_t data[32];
|
||||
uint32_t target[8];
|
||||
};
|
||||
|
||||
static struct work g_work;
|
||||
|
@ -214,6 +212,8 @@ static bool jobj_binary(const json_t *obj, const char *key,
|
|||
|
||||
static bool work_decode(const json_t *val, struct work *work)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (unlikely(!jobj_binary(val, "data", work->data, sizeof(work->data)))) {
|
||||
applog(LOG_ERR, "JSON inval data");
|
||||
goto err_out;
|
||||
|
@ -223,7 +223,10 @@ static bool work_decode(const json_t *val, struct work *work)
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
memset(work->hash, 0, sizeof(work->hash));
|
||||
for (i = 0; i < ARRAY_SIZE(work->data); i++)
|
||||
work->data[i] = be32dec(work->data + i);
|
||||
for (i = 0; i < ARRAY_SIZE(work->target); i++)
|
||||
work->target[i] = le32dec(work->target + i);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -231,7 +234,7 @@ err_out:
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool submit_upstream_work(CURL *curl, const struct work *work)
|
||||
static bool submit_upstream_work(CURL *curl, struct work *work)
|
||||
{
|
||||
char *hexstr = NULL;
|
||||
json_t *val, *res;
|
||||
|
@ -241,11 +244,16 @@ static bool submit_upstream_work(CURL *curl, const struct work *work)
|
|||
bool rc = false;
|
||||
|
||||
/* pass if the previous hash is not the current previous hash */
|
||||
if (!submit_old && memcmp(work->data + 4, g_work.data + 4, 32))
|
||||
if (!submit_old && memcmp(work->data + 1, g_work.data + 1, 32)) {
|
||||
if (opt_debug)
|
||||
applog(LOG_DEBUG, "DEBUG: stale work detected, discarding");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* build hex string */
|
||||
hexstr = bin2hex(work->data, sizeof(work->data));
|
||||
for (i = 0; i < ARRAY_SIZE(work->data); i++)
|
||||
be32enc(work->data + i, work->data[i]);
|
||||
hexstr = bin2hex((unsigned char *)work->data, sizeof(work->data));
|
||||
if (unlikely(!hexstr)) {
|
||||
applog(LOG_ERR, "submit_upstream_work OOM");
|
||||
goto out;
|
||||
|
@ -483,8 +491,9 @@ static void *miner_thread(void *userdata)
|
|||
{
|
||||
struct thr_info *mythr = userdata;
|
||||
int thr_id = mythr->id;
|
||||
struct work work;
|
||||
uint32_t max_nonce;
|
||||
uint32_t next_nonce;
|
||||
uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - 4;
|
||||
unsigned char *scratchbuf = NULL;
|
||||
|
||||
/* Set worker threads to nice 19 and then preferentially to SCHED_IDLE
|
||||
|
@ -504,7 +513,6 @@ static void *miner_thread(void *userdata)
|
|||
}
|
||||
|
||||
while (1) {
|
||||
struct work work __attribute__((aligned(128)));
|
||||
unsigned long hashes_done;
|
||||
struct timeval tv_start, tv_end, diff;
|
||||
int64_t max64;
|
||||
|
@ -512,7 +520,8 @@ static void *miner_thread(void *userdata)
|
|||
|
||||
/* obtain new work from internal workio thread */
|
||||
pthread_mutex_lock(&g_work_lock);
|
||||
if (!have_longpoll || time(NULL) >= g_work_time + LP_SCANTIME*3/4) {
|
||||
if (!have_longpoll || time(NULL) >= g_work_time + LP_SCANTIME*3/4
|
||||
|| work.data[19] >= end_nonce) {
|
||||
if (unlikely(!get_work(mythr, &g_work))) {
|
||||
applog(LOG_ERR, "work retrieval failed, exiting "
|
||||
"mining thread %d", mythr->id);
|
||||
|
@ -525,8 +534,9 @@ static void *miner_thread(void *userdata)
|
|||
}
|
||||
if (memcmp(work.data, g_work.data, 76)) {
|
||||
memcpy(&work, &g_work, sizeof(struct work));
|
||||
next_nonce = 0xffffffffU / opt_n_threads * thr_id;
|
||||
}
|
||||
work.data[19] = 0xffffffffU / opt_n_threads * thr_id;
|
||||
} else
|
||||
work.data[19]++;
|
||||
pthread_mutex_unlock(&g_work_lock);
|
||||
work_restart[thr_id].restart = 0;
|
||||
|
||||
|
@ -536,10 +546,10 @@ static void *miner_thread(void *userdata)
|
|||
max64 *= thr_hashrates[thr_id];
|
||||
if (max64 <= 0)
|
||||
max64 = 0xfffLL;
|
||||
if (next_nonce + max64 > 0xfffffffeLL)
|
||||
max_nonce = 0xfffffffeU;
|
||||
if (work.data[19] + max64 > end_nonce)
|
||||
max_nonce = end_nonce;
|
||||
else
|
||||
max_nonce = next_nonce + max64;
|
||||
max_nonce = work.data[19] + max64;
|
||||
|
||||
hashes_done = 0;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
|
@ -548,7 +558,7 @@ static void *miner_thread(void *userdata)
|
|||
switch (opt_algo) {
|
||||
case ALGO_SCRYPT:
|
||||
rc = scanhash_scrypt(thr_id, work.data, scratchbuf, work.target,
|
||||
max_nonce, &next_nonce, &hashes_done);
|
||||
max_nonce, &hashes_done);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1000,4 +1010,3 @@ int main(int argc, char *argv[])
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
27
miner.h
27
miner.h
|
@ -104,21 +104,6 @@ static inline uint32_t swab32(uint32_t v)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline void swap256(void *dest_p, const void *src_p)
|
||||
{
|
||||
uint32_t *dest = dest_p;
|
||||
const uint32_t *src = src_p;
|
||||
|
||||
dest[0] = src[7];
|
||||
dest[1] = src[6];
|
||||
dest[2] = src[5];
|
||||
dest[3] = src[4];
|
||||
dest[4] = src[3];
|
||||
dest[5] = src[2];
|
||||
dest[6] = src[1];
|
||||
dest[7] = src[0];
|
||||
}
|
||||
|
||||
static inline uint32_t be32dec(const void *pp)
|
||||
{
|
||||
const uint8_t *p = (uint8_t const *)pp;
|
||||
|
@ -155,19 +140,19 @@ extern bool opt_debug;
|
|||
extern bool opt_protocol;
|
||||
|
||||
extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
|
||||
const char *rpc_req, bool, bool, int *);
|
||||
const char *rpc_req, bool, bool, int *);
|
||||
extern char *bin2hex(const unsigned char *p, size_t len);
|
||||
extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len);
|
||||
|
||||
extern unsigned char *scrypt_buffer_alloc();
|
||||
extern int scanhash_scrypt(int thr_id, unsigned char *pdata,
|
||||
unsigned char *scratchbuf, const unsigned char *ptarget,
|
||||
uint32_t max_nonce, uint32_t *next_nonce, unsigned long *hashes_done);
|
||||
extern int scanhash_scrypt(int thr_id, uint32_t *pdata,
|
||||
unsigned char *scratchbuf, const uint32_t *ptarget,
|
||||
uint32_t max_nonce, unsigned long *hashes_done);
|
||||
|
||||
extern int
|
||||
timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
|
||||
timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y);
|
||||
|
||||
extern bool fulltest(const unsigned char *hash, const unsigned char *target);
|
||||
extern bool fulltest(const uint32_t *hash, const uint32_t *target);
|
||||
|
||||
extern int opt_timeout;
|
||||
extern bool want_longpoll;
|
||||
|
|
47
scrypt.c
47
scrypt.c
|
@ -602,43 +602,26 @@ static void scrypt_1024_1_1_256_sp_3way(const uint32_t *input,
|
|||
}
|
||||
#endif /* SCRYPT_MAX_WAYS >= 3 */
|
||||
|
||||
__attribute__ ((noinline)) static int confirm_hash(const uint32_t *hash,
|
||||
const uint32_t *target)
|
||||
{
|
||||
int i;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
uint32_t t = le32dec(&target[i]);
|
||||
if (hash[i] > t)
|
||||
return 0;
|
||||
if (hash[i] < t)
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int scanhash_scrypt(int thr_id, unsigned char *pdata,
|
||||
unsigned char *scratchbuf, const unsigned char *ptarget,
|
||||
uint32_t max_nonce, uint32_t *next_nonce, unsigned long *hashes_done)
|
||||
int scanhash_scrypt(int thr_id, uint32_t *pdata,
|
||||
unsigned char *scratchbuf, const uint32_t *ptarget,
|
||||
uint32_t max_nonce, unsigned long *hashes_done)
|
||||
{
|
||||
uint32_t data[SCRYPT_MAX_WAYS * 20], hash[SCRYPT_MAX_WAYS * 8];
|
||||
uint32_t midstate[8];
|
||||
const uint32_t first_nonce = *next_nonce;
|
||||
uint32_t n = *next_nonce;
|
||||
const uint32_t Htarg = le32dec(&((const uint32_t *)ptarget)[7]);
|
||||
uint32_t n = pdata[19] - 1;
|
||||
const uint32_t Htarg = ptarget[7];
|
||||
const int throughput = scrypt_best_throughput();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 19; i++)
|
||||
data[i] = be32dec(&((const uint32_t *)pdata)[i]);
|
||||
for (i = 1; i < throughput; i++)
|
||||
memcpy(data + i * 20, data, 80);
|
||||
for (i = 0; i < throughput; i++)
|
||||
memcpy(data + i * 20, pdata, 80);
|
||||
|
||||
SHA256_InitState(midstate);
|
||||
SHA256_Transform(midstate, data, 1);
|
||||
|
||||
do {
|
||||
for (i = 0; i < throughput; i++)
|
||||
data[i * 20 + 19] = n++;
|
||||
data[i * 20 + 19] = ++n;
|
||||
|
||||
#if SCRYPT_MAX_WAYS >= 3
|
||||
if (throughput == 3)
|
||||
|
@ -653,17 +636,15 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata,
|
|||
scrypt_1024_1_1_256_sp(data, hash, midstate, scratchbuf);
|
||||
|
||||
for (i = 0; i < throughput; i++) {
|
||||
if (hash[i * 8 + 7] <= Htarg
|
||||
&& confirm_hash(hash + i * 8, (uint32_t *)ptarget)) {
|
||||
be32enc(&((uint32_t *)pdata)[19], data[i * 20 + 19]);
|
||||
*next_nonce = n;
|
||||
*hashes_done = n - first_nonce;
|
||||
if (hash[i * 8 + 7] <= Htarg && fulltest(hash + i * 8, ptarget)) {
|
||||
*hashes_done = n - pdata[19] + 1;
|
||||
pdata[19] = data[i * 20 + 19];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} while (n <= max_nonce && !work_restart[thr_id].restart);
|
||||
} while (n < max_nonce && !work_restart[thr_id].restart);
|
||||
|
||||
*next_nonce = n;
|
||||
*hashes_done = n - first_nonce;
|
||||
*hashes_done = n - pdata[19] + 1;
|
||||
pdata[19] = n;
|
||||
return 0;
|
||||
}
|
||||
|
|
45
util.c
45
util.c
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* Copyright 2010 Jeff Garzik, 2012 pooler
|
||||
*
|
||||
|
@ -16,6 +15,8 @@
|
|||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <jansson.h>
|
||||
#include <curl/curl.h>
|
||||
|
@ -464,49 +465,44 @@ timeval_subtract (
|
|||
return x->tv_sec < y->tv_sec;
|
||||
}
|
||||
|
||||
bool fulltest(const unsigned char *hash, const unsigned char *target)
|
||||
bool fulltest(const uint32_t *hash, const uint32_t *target)
|
||||
{
|
||||
unsigned char hash_swap[32], target_swap[32];
|
||||
uint32_t *hash32 = (uint32_t *) hash_swap;
|
||||
uint32_t *target32 = (uint32_t *) target_swap;
|
||||
int i;
|
||||
bool rc = true;
|
||||
char *hash_str, *target_str;
|
||||
|
||||
swap256(hash_swap, hash);
|
||||
swap256(target_swap, target);
|
||||
|
||||
for (i = 0; i < 32/4; i++) {
|
||||
uint32_t h32tmp = swab32(hash32[i]);
|
||||
uint32_t t32tmp = target32[i];
|
||||
|
||||
target32[i] = swab32(target32[i]); /* for printing */
|
||||
|
||||
if (h32tmp > t32tmp) {
|
||||
for (i = 7; i >= 0; i--) {
|
||||
if (hash[i] > target[i]) {
|
||||
rc = false;
|
||||
break;
|
||||
}
|
||||
if (h32tmp < t32tmp) {
|
||||
if (hash[i] < target[i]) {
|
||||
rc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_debug) {
|
||||
hash_str = bin2hex(hash_swap, 32);
|
||||
target_str = bin2hex(target_swap, 32);
|
||||
uint32_t hash_be[32], target_be[32];
|
||||
char *hash_str, *target_str;
|
||||
|
||||
applog(LOG_DEBUG, " Proof: %s\nTarget: %s\nTrgVal? %s",
|
||||
for (i = 0; i < 8; i++) {
|
||||
be32enc(hash_be + i, hash[7 - i]);
|
||||
be32enc(target_be + i, target[7 - i]);
|
||||
}
|
||||
hash_str = bin2hex((unsigned char *)hash_be, 32);
|
||||
target_str = bin2hex((unsigned char *)target_be, 32);
|
||||
|
||||
applog(LOG_DEBUG, "DEBUG: %s\nHash: %s\nTarget: %s",
|
||||
rc ? "hash <= target"
|
||||
: "hash > target (false positive)",
|
||||
hash_str,
|
||||
target_str,
|
||||
rc ? "YES (hash < target)" :
|
||||
"no (false positive; hash > target)");
|
||||
target_str);
|
||||
|
||||
free(hash_str);
|
||||
free(target_str);
|
||||
}
|
||||
|
||||
return true; /* FIXME: return rc; */
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct thread_q *tq_new(void)
|
||||
|
@ -621,4 +617,3 @@ out:
|
|||
pthread_mutex_unlock(&tq->mutex);
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue