mirror of
https://github.com/JayDDee/cpuminer-opt.git
synced 2025-09-17 23:44:27 +00:00
v3.8.3.3
This commit is contained in:
10
README.md
10
README.md
@@ -142,11 +142,11 @@ Donations
|
|||||||
|
|
||||||
cpuminer-opt has no fees of any kind but donations are accepted.
|
cpuminer-opt has no fees of any kind but donations are accepted.
|
||||||
|
|
||||||
BTC: 12tdvfF7KmAsihBXQXynT6E6th2c2pByTT
|
BTC: 12tdvfF7KmAsihBXQXynT6E6th2c2pByTT
|
||||||
ETH: 0x72122edabcae9d3f57eab0729305a425f6fef6d0
|
ETH: 0x72122edabcae9d3f57eab0729305a425f6fef6d0
|
||||||
LTC: LdUwoHJnux9r9EKqFWNvAi45kQompHk6e8
|
LTC: LdUwoHJnux9r9EKqFWNvAi45kQompHk6e8
|
||||||
BCH: 1QKYkB6atn4P7RFozyziAXLEnurwnUM1cQ
|
BCH: 1QKYkB6atn4P7RFozyziAXLEnurwnUM1cQ
|
||||||
BTG: GVUyECtRHeC5D58z9F3nGGfVQndwnsPnHQ
|
BTG: GVUyECtRHeC5D58z9F3nGGfVQndwnsPnHQ
|
||||||
|
|
||||||
Happy mining!
|
Happy mining!
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ Additional optional compile flags, add the following to CFLAGS to activate:
|
|||||||
|
|
||||||
SPH may give slightly better performance on algos that use sha256 when using
|
SPH may give slightly better performance on algos that use sha256 when using
|
||||||
openssl 1.0.1 or older. Openssl 1.0.2 adds AVX2 and 1.1 adds SHA and perform
|
openssl 1.0.1 or older. Openssl 1.0.2 adds AVX2 and 1.1 adds SHA and perform
|
||||||
better than SPH.
|
better than SPH. This option is ignored when 4-way is used, even for CPUs
|
||||||
|
with SHA.
|
||||||
|
|
||||||
Start mining.
|
Start mining.
|
||||||
|
|
||||||
@@ -159,6 +160,12 @@ Support for even older x86_64 without AES_NI or SSE2 is not availble.
|
|||||||
Change Log
|
Change Log
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
v3.8.3.3
|
||||||
|
|
||||||
|
Integrated getblocktemplate with algo_gate.
|
||||||
|
Added support for hodl gbt (untested).
|
||||||
|
Reworked some recent quick fixes.
|
||||||
|
|
||||||
v3.8.3.2
|
v3.8.3.2
|
||||||
|
|
||||||
Reverted gbt changes from v3.8.0 that broke getwork.
|
Reverted gbt changes from v3.8.0 that broke getwork.
|
||||||
|
|||||||
@@ -119,9 +119,11 @@ void init_algo_gate( algo_gate_t* gate )
|
|||||||
gate->gen_merkle_root = (void*)&sha256d_gen_merkle_root;
|
gate->gen_merkle_root = (void*)&sha256d_gen_merkle_root;
|
||||||
gate->stratum_gen_work = (void*)&std_stratum_gen_work;
|
gate->stratum_gen_work = (void*)&std_stratum_gen_work;
|
||||||
gate->build_stratum_request = (void*)&std_le_build_stratum_request;
|
gate->build_stratum_request = (void*)&std_le_build_stratum_request;
|
||||||
|
gate->malloc_txs_request = (void*)&std_malloc_txs_request;
|
||||||
gate->set_target = (void*)&std_set_target;
|
gate->set_target = (void*)&std_set_target;
|
||||||
gate->work_decode = (void*)&std_le_work_decode;
|
gate->work_decode = (void*)&std_le_work_decode;
|
||||||
gate->submit_getwork_result = (void*)&std_le_submit_getwork_result;
|
gate->submit_getwork_result = (void*)&std_le_submit_getwork_result;
|
||||||
|
gate->build_block_header = (void*)&std_build_block_header;
|
||||||
gate->build_extraheader = (void*)&std_build_extraheader;
|
gate->build_extraheader = (void*)&std_build_extraheader;
|
||||||
gate->set_work_data_endian = (void*)&do_nothing;
|
gate->set_work_data_endian = (void*)&do_nothing;
|
||||||
gate->calc_network_diff = (void*)&std_calc_network_diff;
|
gate->calc_network_diff = (void*)&std_calc_network_diff;
|
||||||
|
|||||||
@@ -127,7 +127,10 @@ void ( *set_target) ( struct work*, double );
|
|||||||
bool ( *submit_getwork_result ) ( CURL*, struct work* );
|
bool ( *submit_getwork_result ) ( CURL*, struct work* );
|
||||||
void ( *gen_merkle_root ) ( char*, struct stratum_ctx* );
|
void ( *gen_merkle_root ) ( char*, struct stratum_ctx* );
|
||||||
void ( *build_extraheader ) ( struct work*, struct stratum_ctx* );
|
void ( *build_extraheader ) ( struct work*, struct stratum_ctx* );
|
||||||
|
void ( *build_block_header ) ( struct work*, uint32_t, uint32_t*,
|
||||||
|
uint32_t*, uint32_t, uint32_t );
|
||||||
void ( *build_stratum_request ) ( char*, struct work*, struct stratum_ctx* );
|
void ( *build_stratum_request ) ( char*, struct work*, struct stratum_ctx* );
|
||||||
|
char* ( *malloc_txs_request ) ( struct work* );
|
||||||
void ( *set_work_data_endian ) ( struct work* );
|
void ( *set_work_data_endian ) ( struct work* );
|
||||||
double ( *calc_network_diff ) ( struct work* );
|
double ( *calc_network_diff ) ( struct work* );
|
||||||
bool ( *ready_to_mine ) ( struct work*, struct stratum_ctx*, int );
|
bool ( *ready_to_mine ) ( struct work*, struct stratum_ctx*, int );
|
||||||
@@ -228,11 +231,17 @@ void std_le_build_stratum_request( char *req, struct work *work );
|
|||||||
void std_be_build_stratum_request( char *req, struct work *work );
|
void std_be_build_stratum_request( char *req, struct work *work );
|
||||||
void jr2_build_stratum_request ( char *req, struct work *work );
|
void jr2_build_stratum_request ( char *req, struct work *work );
|
||||||
|
|
||||||
|
char* std_malloc_txs_request( struct work *work );
|
||||||
|
|
||||||
// Default is do_nothing (assumed LE)
|
// Default is do_nothing (assumed LE)
|
||||||
void set_work_data_big_endian( struct work *work );
|
void set_work_data_big_endian( struct work *work );
|
||||||
|
|
||||||
double std_calc_network_diff( struct work *work );
|
double std_calc_network_diff( struct work *work );
|
||||||
|
|
||||||
|
void std_build_block_header( struct work* g_work, uint32_t version,
|
||||||
|
uint32_t *prevhash, uint32_t *merkle_root,
|
||||||
|
uint32_t ntime, uint32_t nbits );
|
||||||
|
|
||||||
void std_build_extraheader( struct work *work, struct stratum_ctx *sctx );
|
void std_build_extraheader( struct work *work, struct stratum_ctx *sctx );
|
||||||
|
|
||||||
json_t* std_longpoll_rpc_call( CURL *curl, int *err, char *lp_url );
|
json_t* std_longpoll_rpc_call( CURL *curl, int *err, char *lp_url );
|
||||||
|
|||||||
@@ -42,15 +42,83 @@ void hodl_le_build_stratum_request( char* req, struct work* work,
|
|||||||
free( xnonce2str );
|
free( xnonce2str );
|
||||||
}
|
}
|
||||||
|
|
||||||
void hodl_build_extraheader( struct work* g_work, struct stratum_ctx *sctx )
|
char* hodl_malloc_txs_request( struct work *work )
|
||||||
{
|
{
|
||||||
uchar merkle_root[64] = { 0 };
|
char* req;
|
||||||
size_t t;
|
json_t *val;
|
||||||
|
char data_str[2 * sizeof(work->data) + 1];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
algo_gate.gen_merkle_root( merkle_root, sctx );
|
for ( i = 0; i < ARRAY_SIZE(work->data); i++ )
|
||||||
|
be32enc( work->data + i, work->data[i] );
|
||||||
|
|
||||||
|
bin2hex( data_str, (unsigned char *)work->data, 88 );
|
||||||
|
if ( work->workid )
|
||||||
|
{
|
||||||
|
char *params;
|
||||||
|
val = json_object();
|
||||||
|
json_object_set_new( val, "workid", json_string( work->workid ) );
|
||||||
|
params = json_dumps( val, 0 );
|
||||||
|
json_decref( val );
|
||||||
|
req = malloc( 128 + 2*88 + strlen( work->txs ) + strlen( params ) );
|
||||||
|
sprintf( req,
|
||||||
|
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":1}\r\n",
|
||||||
|
data_str, work->txs, params);
|
||||||
|
free( params );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
req = malloc( 128 + 2*88 + strlen(work->txs));
|
||||||
|
sprintf( req,
|
||||||
|
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":1}\r\n",
|
||||||
|
data_str, work->txs);
|
||||||
|
}
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hodl_build_block_header( struct work* g_work, uint32_t version,
|
||||||
|
uint32_t *prevhash, uint32_t *merkle_tree,
|
||||||
|
uint32_t ntime, uint32_t nbits )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset( g_work->data, 0, sizeof(g_work->data) );
|
||||||
|
g_work->data[0] = version;
|
||||||
|
|
||||||
|
if ( have_stratum )
|
||||||
|
for ( i = 0; i < 8; i++ )
|
||||||
|
g_work->data[1 + i] = le32dec( prevhash + i );
|
||||||
|
else
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
g_work->data[ 8-i ] = le32dec( prevhash + i );
|
||||||
|
|
||||||
|
for ( i = 0; i < 8; i++ )
|
||||||
|
g_work->data[9 + i] = be32dec( merkle_tree + i );
|
||||||
|
|
||||||
|
g_work->data[ algo_gate.ntime_index ] = ntime;
|
||||||
|
g_work->data[ algo_gate.nbits_index ] = nbits;
|
||||||
|
g_work->data[22] = 0x80000000;
|
||||||
|
g_work->data[31] = 0x00000280;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hodl build_extra_header is redundant, hodl can use std_build_extra_header
|
||||||
|
// and call hodl_build_block_header.
|
||||||
|
#if 0
|
||||||
|
void hodl_build_extraheader( struct work* g_work, struct stratum_ctx *sctx )
|
||||||
|
{
|
||||||
|
uchar merkle_tree[64] = { 0 };
|
||||||
|
size_t t;
|
||||||
|
// int i;
|
||||||
|
|
||||||
|
algo_gate.gen_merkle_root( merkle_tree, sctx );
|
||||||
// Increment extranonce2
|
// Increment extranonce2
|
||||||
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
|
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
|
||||||
|
|
||||||
|
algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
|
||||||
|
(uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_tree,
|
||||||
|
le32dec( sctx->job.ntime ), le32dec( sctx->job.nbits ) );
|
||||||
|
/*
|
||||||
// Assemble block header
|
// Assemble block header
|
||||||
memset( g_work->data, 0, sizeof(g_work->data) );
|
memset( g_work->data, 0, sizeof(g_work->data) );
|
||||||
g_work->data[0] = le32dec( sctx->job.version );
|
g_work->data[0] = le32dec( sctx->job.version );
|
||||||
@@ -63,7 +131,9 @@ void hodl_build_extraheader( struct work* g_work, struct stratum_ctx *sctx )
|
|||||||
g_work->data[ algo_gate.nbits_index ] = le32dec( sctx->job.nbits );
|
g_work->data[ algo_gate.nbits_index ] = le32dec( sctx->job.nbits );
|
||||||
g_work->data[22] = 0x80000000;
|
g_work->data[22] = 0x80000000;
|
||||||
g_work->data[31] = 0x00000280;
|
g_work->data[31] = 0x00000280;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// called only by thread 0, saves a backup of g_work
|
// called only by thread 0, saves a backup of g_work
|
||||||
void hodl_get_new_work( struct work* work, struct work* g_work)
|
void hodl_get_new_work( struct work* work, struct work* g_work)
|
||||||
@@ -73,6 +143,22 @@ void hodl_get_new_work( struct work* work, struct work* g_work)
|
|||||||
hodl_work.data[ algo_gate.nonce_index ] = ( clock() + rand() ) % 9999;
|
hodl_work.data[ algo_gate.nonce_index ] = ( clock() + rand() ) % 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_t *hodl_longpoll_rpc_call( CURL *curl, int *err, char* lp_url )
|
||||||
|
{
|
||||||
|
json_t *val;
|
||||||
|
char *req = NULL;
|
||||||
|
|
||||||
|
if ( have_gbt )
|
||||||
|
{
|
||||||
|
req = malloc( strlen( gbt_lp_req ) + strlen( lp_id ) + 1 );
|
||||||
|
sprintf( req, gbt_lp_req, lp_id );
|
||||||
|
}
|
||||||
|
val = json_rpc_call( curl, lp_url, rpc_userpass,
|
||||||
|
req ? req : getwork_req, err, JSON_RPC_LONGPOLL );
|
||||||
|
free( req );
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
// called by every thread, copies the backup to each thread's work.
|
// called by every thread, copies the backup to each thread's work.
|
||||||
void hodl_resync_threads( struct work* work )
|
void hodl_resync_threads( struct work* work )
|
||||||
{
|
{
|
||||||
@@ -112,13 +198,17 @@ bool register_hodl_algo( algo_gate_t* gate )
|
|||||||
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT;
|
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT;
|
||||||
gate->scanhash = (void*)&hodl_scanhash;
|
gate->scanhash = (void*)&hodl_scanhash;
|
||||||
gate->get_new_work = (void*)&hodl_get_new_work;
|
gate->get_new_work = (void*)&hodl_get_new_work;
|
||||||
|
gate->longpoll_rpc_call = (void*)&hodl_longpoll_rpc_call;
|
||||||
gate->set_target = (void*)&hodl_set_target;
|
gate->set_target = (void*)&hodl_set_target;
|
||||||
gate->build_stratum_request = (void*)&hodl_le_build_stratum_request;
|
gate->build_stratum_request = (void*)&hodl_le_build_stratum_request;
|
||||||
gate->build_extraheader = (void*)&hodl_build_extraheader;
|
gate->malloc_txs_request = (void*)&hodl_malloc_txs_request;
|
||||||
|
gate->build_block_header = (void*)&hodl_build_block_header;
|
||||||
|
// gate->build_extraheader = (void*)&hodl_build_extraheader;
|
||||||
gate->resync_threads = (void*)&hodl_resync_threads;
|
gate->resync_threads = (void*)&hodl_resync_threads;
|
||||||
gate->do_this_thread = (void*)&hodl_do_this_thread;
|
gate->do_this_thread = (void*)&hodl_do_this_thread;
|
||||||
gate->work_cmp_size = 76;
|
gate->work_cmp_size = 76;
|
||||||
hodl_scratchbuf = (unsigned char*)malloc( 1 << 30 );
|
hodl_scratchbuf = (unsigned char*)malloc( 1 << 30 );
|
||||||
|
allow_getwork = false;
|
||||||
return ( hodl_scratchbuf != NULL );
|
return ( hodl_scratchbuf != NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,35 @@ void lbry_le_build_stratum_request( char *req, struct work *work,
|
|||||||
rpc_user, work->job_id, xnonce2str, ntimestr, noncestr );
|
rpc_user, work->job_id, xnonce2str, ntimestr, noncestr );
|
||||||
free(xnonce2str);
|
free(xnonce2str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't use lbry_build_block_header, it can't handle clasim, do it inline
|
||||||
|
// in lbry_build_extraheader. The side effect is no gbt support for lbry.
|
||||||
|
void lbry_build_block_header( struct work* g_work, uint32_t version,
|
||||||
|
uint32_t *prevhash, uint32_t *merkle_root,
|
||||||
|
uint32_t ntime, uint32_t nbits )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
memset( g_work->data, 0, sizeof(g_work->data) );
|
||||||
|
g_work->data[0] = version;
|
||||||
|
|
||||||
|
if ( have_stratum )
|
||||||
|
for ( i = 0; i < 8; i++ )
|
||||||
|
g_work->data[1 + i] = le32dec( prevhash + i );
|
||||||
|
else
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
g_work->data[ 8-i ] = le32dec( prevhash + i );
|
||||||
|
|
||||||
|
for ( i = 0; i < 8; i++ )
|
||||||
|
g_work->data[9 + i] = be32dec( merkle_root + i );
|
||||||
|
|
||||||
|
// for ( int i = 0; i < 8; i++ )
|
||||||
|
// g_work->data[17 + i] = claim[i];
|
||||||
|
|
||||||
|
g_work->data[ LBRY_NTIME_INDEX ] = ntime;
|
||||||
|
g_work->data[ LBRY_NBITS_INDEX ] = nbits;
|
||||||
|
g_work->data[28] = 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
void lbry_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
|
void lbry_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
|
||||||
{
|
{
|
||||||
unsigned char merkle_root[64] = { 0 };
|
unsigned char merkle_root[64] = { 0 };
|
||||||
@@ -50,14 +79,23 @@ void lbry_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
|
|||||||
// Increment extranonce2
|
// Increment extranonce2
|
||||||
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
|
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
|
||||||
// Assemble block header
|
// Assemble block header
|
||||||
|
|
||||||
|
// algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
|
||||||
|
// (uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_root,
|
||||||
|
// le32dec( sctx->job.ntime ), le32dec( sctx->job.nbits ) );
|
||||||
|
|
||||||
memset( g_work->data, 0, sizeof(g_work->data) );
|
memset( g_work->data, 0, sizeof(g_work->data) );
|
||||||
g_work->data[0] = le32dec( sctx->job.version );
|
g_work->data[0] = le32dec( sctx->job.version );
|
||||||
|
|
||||||
for ( i = 0; i < 8; i++ )
|
for ( i = 0; i < 8; i++ )
|
||||||
g_work->data[1 + i] = le32dec( (uint32_t *) sctx->job.prevhash + i );
|
g_work->data[1 + i] = le32dec( (uint32_t *) sctx->job.prevhash + i );
|
||||||
|
|
||||||
for ( i = 0; i < 8; i++ )
|
for ( i = 0; i < 8; i++ )
|
||||||
g_work->data[9 + i] = be32dec( (uint32_t *) merkle_root + i );
|
g_work->data[9 + i] = be32dec( (uint32_t *) merkle_root + i );
|
||||||
|
|
||||||
for ( int i = 0; i < 8; i++ )
|
for ( int i = 0; i < 8; i++ )
|
||||||
g_work->data[17 + i] = ((uint32_t*)sctx->job.claim)[i];
|
g_work->data[17 + i] = ((uint32_t*)sctx->job.claim)[i];
|
||||||
|
|
||||||
g_work->data[ LBRY_NTIME_INDEX ] = le32dec(sctx->job.ntime);
|
g_work->data[ LBRY_NTIME_INDEX ] = le32dec(sctx->job.ntime);
|
||||||
g_work->data[ LBRY_NBITS_INDEX ] = le32dec(sctx->job.nbits);
|
g_work->data[ LBRY_NBITS_INDEX ] = le32dec(sctx->job.nbits);
|
||||||
g_work->data[28] = 0x80000000;
|
g_work->data[28] = 0x80000000;
|
||||||
@@ -86,6 +124,7 @@ bool register_lbry_algo( algo_gate_t* gate )
|
|||||||
gate->calc_network_diff = (void*)&lbry_calc_network_diff;
|
gate->calc_network_diff = (void*)&lbry_calc_network_diff;
|
||||||
gate->get_max64 = (void*)&lbry_get_max64;
|
gate->get_max64 = (void*)&lbry_get_max64;
|
||||||
gate->build_stratum_request = (void*)&lbry_le_build_stratum_request;
|
gate->build_stratum_request = (void*)&lbry_le_build_stratum_request;
|
||||||
|
// gate->build_block_header = (void*)&build_block_header;
|
||||||
gate->build_extraheader = (void*)&lbry_build_extraheader;
|
gate->build_extraheader = (void*)&lbry_build_extraheader;
|
||||||
gate->set_target = (void*)&lbry_set_target;
|
gate->set_target = (void*)&lbry_set_target;
|
||||||
gate->ntime_index = LBRY_NTIME_INDEX;
|
gate->ntime_index = LBRY_NTIME_INDEX;
|
||||||
|
|||||||
20
configure
vendored
20
configure
vendored
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.8.3.2.
|
# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.8.3.3.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||||
@@ -577,8 +577,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='cpuminer-opt'
|
PACKAGE_NAME='cpuminer-opt'
|
||||||
PACKAGE_TARNAME='cpuminer-opt'
|
PACKAGE_TARNAME='cpuminer-opt'
|
||||||
PACKAGE_VERSION='3.8.3.2'
|
PACKAGE_VERSION='3.8.3.3'
|
||||||
PACKAGE_STRING='cpuminer-opt 3.8.3.2'
|
PACKAGE_STRING='cpuminer-opt 3.8.3.3'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
@@ -1321,7 +1321,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures cpuminer-opt 3.8.3.2 to adapt to many kinds of systems.
|
\`configure' configures cpuminer-opt 3.8.3.3 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -1392,7 +1392,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of cpuminer-opt 3.8.3.2:";;
|
short | recursive ) echo "Configuration of cpuminer-opt 3.8.3.3:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1497,7 +1497,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
cpuminer-opt configure 3.8.3.2
|
cpuminer-opt configure 3.8.3.3
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
@@ -2000,7 +2000,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by cpuminer-opt $as_me 3.8.3.2, which was
|
It was created by cpuminer-opt $as_me 3.8.3.3, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@@ -2981,7 +2981,7 @@ fi
|
|||||||
|
|
||||||
# Define the identity of the package.
|
# Define the identity of the package.
|
||||||
PACKAGE='cpuminer-opt'
|
PACKAGE='cpuminer-opt'
|
||||||
VERSION='3.8.3.2'
|
VERSION='3.8.3.3'
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
@@ -6677,7 +6677,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by cpuminer-opt $as_me 3.8.3.2, which was
|
This file was extended by cpuminer-opt $as_me 3.8.3.3, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -6743,7 +6743,7 @@ _ACEOF
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
cpuminer-opt config.status 3.8.3.2
|
cpuminer-opt config.status 3.8.3.3
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT([cpuminer-opt], [3.8.3.2])
|
AC_INIT([cpuminer-opt], [3.8.3.3])
|
||||||
|
|
||||||
AC_PREREQ([2.59c])
|
AC_PREREQ([2.59c])
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
|
|||||||
563
cpu-miner.c
563
cpu-miner.c
@@ -177,7 +177,7 @@ static struct work g_work = {{ 0 }};
|
|||||||
time_t g_work_time = 0;
|
time_t g_work_time = 0;
|
||||||
static pthread_mutex_t g_work_lock;
|
static pthread_mutex_t g_work_lock;
|
||||||
static bool submit_old = false;
|
static bool submit_old = false;
|
||||||
static char* lp_id;
|
char* lp_id;
|
||||||
|
|
||||||
static void workio_cmd_free(struct workio_cmd *wc);
|
static void workio_cmd_free(struct workio_cmd *wc);
|
||||||
|
|
||||||
@@ -434,9 +434,10 @@ static bool get_mininginfo(CURL *curl, struct work *work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hodl needs 4 but leave it at 3 until gbt better understood
|
// hodl needs 4 but leave it at 3 until gbt better understood
|
||||||
#define BLOCK_VERSION_CURRENT 3
|
//#define BLOCK_VERSION_CURRENT 3
|
||||||
|
#define BLOCK_VERSION_CURRENT 4
|
||||||
|
|
||||||
static bool gbt_work_decode(const json_t *val, struct work *work)
|
static bool gbt_work_decode( const json_t *val, struct work *work )
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
uint32_t version, curtime, bits;
|
uint32_t version, curtime, bits;
|
||||||
@@ -454,47 +455,52 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
|||||||
json_t *tmp, *txa;
|
json_t *tmp, *txa;
|
||||||
bool rc = false;
|
bool rc = false;
|
||||||
|
|
||||||
tmp = json_object_get(val, "mutable");
|
tmp = json_object_get( val, "mutable" );
|
||||||
if (tmp && json_is_array(tmp)) {
|
if ( tmp && json_is_array( tmp ) )
|
||||||
n = (int) json_array_size(tmp);
|
{
|
||||||
for (i = 0; i < n; i++) {
|
n = (int) json_array_size( tmp );
|
||||||
const char *s = json_string_value(json_array_get(tmp, i));
|
for ( i = 0; i < n; i++ )
|
||||||
if (!s)
|
{
|
||||||
|
const char *s = json_string_value( json_array_get( tmp, i ) );
|
||||||
|
if ( !s )
|
||||||
continue;
|
continue;
|
||||||
if (!strcmp(s, "coinbase/append"))
|
if ( !strcmp( s, "coinbase/append" ) ) coinbase_append = true;
|
||||||
coinbase_append = true;
|
else if ( !strcmp( s, "submit/coinbase" ) ) submit_coinbase = true;
|
||||||
else if (!strcmp(s, "submit/coinbase"))
|
else if ( !strcmp( s, "version/force" ) ) version_force = true;
|
||||||
submit_coinbase = true;
|
else if ( !strcmp( s, "version/reduce" ) ) version_reduce = true;
|
||||||
else if (!strcmp(s, "version/force"))
|
|
||||||
version_force = true;
|
|
||||||
else if (!strcmp(s, "version/reduce"))
|
|
||||||
version_reduce = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = json_object_get(val, "height");
|
tmp = json_object_get( val, "height" );
|
||||||
if (!tmp || !json_is_integer(tmp)) {
|
if ( !tmp || !json_is_integer( tmp ) )
|
||||||
applog(LOG_ERR, "JSON invalid height");
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid height" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
work->height = (int) json_integer_value(tmp);
|
work->height = (int) json_integer_value( tmp );
|
||||||
applog(LOG_BLUE, "Current block is %d", work->height);
|
applog( LOG_BLUE, "Current block is %d", work->height );
|
||||||
|
|
||||||
tmp = json_object_get(val, "version");
|
tmp = json_object_get(val, "version");
|
||||||
if (!tmp || !json_is_integer(tmp)) {
|
if ( !tmp || !json_is_integer( tmp ) )
|
||||||
applog(LOG_ERR, "JSON invalid version");
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid version" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
version = (uint32_t) json_integer_value(tmp);
|
version = (uint32_t) json_integer_value( tmp );
|
||||||
if ((version & 0xffU) > BLOCK_VERSION_CURRENT) {
|
if ( (version & 0xffU) > BLOCK_VERSION_CURRENT )
|
||||||
if (version_reduce) {
|
{
|
||||||
version = (version & ~0xffU) | BLOCK_VERSION_CURRENT;
|
if ( version_reduce )
|
||||||
} else if (have_gbt && allow_getwork && !version_force) {
|
{
|
||||||
applog(LOG_DEBUG, "Switching to getwork, gbt version %d",
|
version = ( version & ~0xffU ) | BLOCK_VERSION_CURRENT;
|
||||||
version);
|
}
|
||||||
|
else if ( have_gbt && allow_getwork && !version_force )
|
||||||
|
{
|
||||||
|
applog( LOG_DEBUG, "Switching to getwork, gbt version %d", version );
|
||||||
have_gbt = false;
|
have_gbt = false;
|
||||||
goto out;
|
goto out;
|
||||||
} else if (!version_force) {
|
}
|
||||||
|
else if ( !version_force )
|
||||||
|
{
|
||||||
applog(LOG_ERR, "Unrecognized block version: %u", version);
|
applog(LOG_ERR, "Unrecognized block version: %u", version);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -503,227 +509,243 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
|||||||
if ( unlikely( !jobj_binary(val, "previousblockhash", prevhash,
|
if ( unlikely( !jobj_binary(val, "previousblockhash", prevhash,
|
||||||
sizeof(prevhash)) ) )
|
sizeof(prevhash)) ) )
|
||||||
{
|
{
|
||||||
applog(LOG_ERR, "JSON invalid previousblockhash");
|
applog( LOG_ERR, "JSON invalid previousblockhash" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = json_object_get(val, "curtime");
|
tmp = json_object_get( val, "curtime" );
|
||||||
if (!tmp || !json_is_integer(tmp)) {
|
if ( !tmp || !json_is_integer( tmp ) )
|
||||||
applog(LOG_ERR, "JSON invalid curtime");
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid curtime" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
curtime = (uint32_t) json_integer_value(tmp);
|
curtime = (uint32_t) json_integer_value(tmp);
|
||||||
|
|
||||||
if (unlikely(!jobj_binary(val, "bits", &bits, sizeof(bits)))) {
|
if ( unlikely( !jobj_binary( val, "bits", &bits, sizeof(bits) ) ) )
|
||||||
|
{
|
||||||
applog(LOG_ERR, "JSON invalid bits");
|
applog(LOG_ERR, "JSON invalid bits");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find count and size of transactions */
|
/* find count and size of transactions */
|
||||||
txa = json_object_get(val, "transactions");
|
txa = json_object_get(val, "transactions" );
|
||||||
if (!txa || !json_is_array(txa)) {
|
if ( !txa || !json_is_array( txa ) )
|
||||||
applog(LOG_ERR, "JSON invalid transactions");
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid transactions" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tx_count = (int) json_array_size(txa);
|
tx_count = (int) json_array_size( txa );
|
||||||
tx_size = 0;
|
tx_size = 0;
|
||||||
for (i = 0; i < tx_count; i++) {
|
for ( i = 0; i < tx_count; i++ )
|
||||||
const json_t *tx = json_array_get(txa, i);
|
{
|
||||||
const char *tx_hex = json_string_value(json_object_get(tx, "data"));
|
const json_t *tx = json_array_get( txa, i );
|
||||||
if (!tx_hex) {
|
const char *tx_hex = json_string_value( json_object_get( tx, "data" ) );
|
||||||
applog(LOG_ERR, "JSON invalid transactions");
|
if ( !tx_hex )
|
||||||
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid transactions" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tx_size += (int) (strlen(tx_hex) / 2);
|
tx_size += (int) ( strlen( tx_hex ) / 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build coinbase transaction */
|
/* build coinbase transaction */
|
||||||
tmp = json_object_get(val, "coinbasetxn");
|
tmp = json_object_get( val, "coinbasetxn" );
|
||||||
if (tmp) {
|
if ( tmp )
|
||||||
const char *cbtx_hex = json_string_value(json_object_get(tmp, "data"));
|
{
|
||||||
cbtx_size = cbtx_hex ? (int) strlen(cbtx_hex) / 2 : 0;
|
const char *cbtx_hex = json_string_value( json_object_get( tmp, "data" ));
|
||||||
cbtx = (uchar*) malloc(cbtx_size + 100);
|
cbtx_size = cbtx_hex ? (int) strlen( cbtx_hex ) / 2 : 0;
|
||||||
if (cbtx_size < 60 || !hex2bin(cbtx, cbtx_hex, cbtx_size)) {
|
cbtx = (uchar*) malloc( cbtx_size + 100 );
|
||||||
applog(LOG_ERR, "JSON invalid coinbasetxn");
|
if ( cbtx_size < 60 || !hex2bin( cbtx, cbtx_hex, cbtx_size ) )
|
||||||
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid coinbasetxn" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int64_t cbvalue;
|
int64_t cbvalue;
|
||||||
if (!pk_script_size) {
|
if ( !pk_script_size )
|
||||||
if (allow_getwork) {
|
{
|
||||||
applog(LOG_INFO, "No payout address provided, switching to getwork");
|
if ( allow_getwork )
|
||||||
|
{
|
||||||
|
applog( LOG_INFO, "No payout address provided, switching to getwork");
|
||||||
have_gbt = false;
|
have_gbt = false;
|
||||||
} else
|
}
|
||||||
applog(LOG_ERR, "No payout address provided");
|
else
|
||||||
|
applog( LOG_ERR, "No payout address provided" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tmp = json_object_get(val, "coinbasevalue");
|
tmp = json_object_get( val, "coinbasevalue" );
|
||||||
if (!tmp || !json_is_number(tmp)) {
|
if ( !tmp || !json_is_number( tmp ) )
|
||||||
applog(LOG_ERR, "JSON invalid coinbasevalue");
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid coinbasevalue" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
cbvalue = (int64_t) (json_is_integer(tmp) ? json_integer_value(tmp) : json_number_value(tmp));
|
cbvalue = (int64_t) ( json_is_integer( tmp ) ? json_integer_value( tmp )
|
||||||
|
: json_number_value( tmp ) );
|
||||||
cbtx = (uchar*) malloc(256);
|
cbtx = (uchar*) malloc(256);
|
||||||
le32enc((uint32_t *)cbtx, 1); /* version */
|
le32enc( (uint32_t *)cbtx, 1 ); /* version */
|
||||||
cbtx[4] = 1; /* in-counter */
|
cbtx[4] = 1; /* in-counter */
|
||||||
memset(cbtx+5, 0x00, 32); /* prev txout hash */
|
memset( cbtx+5, 0x00, 32 ); /* prev txout hash */
|
||||||
le32enc((uint32_t *)(cbtx+37), 0xffffffff); /* prev txout index */
|
le32enc( (uint32_t *)(cbtx+37), 0xffffffff ); /* prev txout index */
|
||||||
cbtx_size = 43;
|
cbtx_size = 43;
|
||||||
/* BIP 34: height in coinbase */
|
/* BIP 34: height in coinbase */
|
||||||
for (n = work->height; n; n >>= 8)
|
for ( n = work->height; n; n >>= 8 )
|
||||||
cbtx[cbtx_size++] = n & 0xff;
|
cbtx[cbtx_size++] = n & 0xff;
|
||||||
cbtx[42] = cbtx_size - 43;
|
cbtx[42] = cbtx_size - 43;
|
||||||
cbtx[41] = cbtx_size - 42; /* scriptsig length */
|
cbtx[41] = cbtx_size - 42; /* scriptsig length */
|
||||||
le32enc((uint32_t *)(cbtx+cbtx_size), 0xffffffff); /* sequence */
|
le32enc( (uint32_t *)( cbtx+cbtx_size ), 0xffffffff ); /* sequence */
|
||||||
cbtx_size += 4;
|
cbtx_size += 4;
|
||||||
cbtx[cbtx_size++] = 1; /* out-counter */
|
cbtx[ cbtx_size++ ] = 1; /* out-counter */
|
||||||
le32enc((uint32_t *)(cbtx+cbtx_size), (uint32_t)cbvalue); /* value */
|
le32enc( (uint32_t *)( cbtx+cbtx_size) , (uint32_t)cbvalue ); /* value */
|
||||||
le32enc((uint32_t *)(cbtx+cbtx_size+4), cbvalue >> 32);
|
le32enc( (uint32_t *)( cbtx+cbtx_size+4 ), cbvalue >> 32 );
|
||||||
cbtx_size += 8;
|
cbtx_size += 8;
|
||||||
cbtx[cbtx_size++] = (uint8_t) pk_script_size; /* txout-script length */
|
cbtx[ cbtx_size++ ] = (uint8_t) pk_script_size; /* txout-script length */
|
||||||
memcpy(cbtx+cbtx_size, pk_script, pk_script_size);
|
memcpy( cbtx+cbtx_size, pk_script, pk_script_size );
|
||||||
cbtx_size += (int) pk_script_size;
|
cbtx_size += (int) pk_script_size;
|
||||||
le32enc((uint32_t *)(cbtx+cbtx_size), 0); /* lock time */
|
le32enc( (uint32_t *)( cbtx+cbtx_size ), 0 ); /* lock time */
|
||||||
cbtx_size += 4;
|
cbtx_size += 4;
|
||||||
coinbase_append = true;
|
coinbase_append = true;
|
||||||
}
|
}
|
||||||
if (coinbase_append)
|
if ( coinbase_append )
|
||||||
{
|
{
|
||||||
unsigned char xsig[100];
|
unsigned char xsig[100];
|
||||||
int xsig_len = 0;
|
int xsig_len = 0;
|
||||||
if (*coinbase_sig) {
|
if ( *coinbase_sig )
|
||||||
n = (int) strlen(coinbase_sig);
|
|
||||||
if (cbtx[41] + xsig_len + n <= 100) {
|
|
||||||
memcpy(xsig+xsig_len, coinbase_sig, n);
|
|
||||||
xsig_len += n;
|
|
||||||
} else {
|
|
||||||
applog(LOG_WARNING, "Signature does not fit in coinbase, skipping");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp = json_object_get(val, "coinbaseaux");
|
|
||||||
if (tmp && json_is_object(tmp))
|
|
||||||
{
|
{
|
||||||
void *iter = json_object_iter(tmp);
|
n = (int) strlen( coinbase_sig );
|
||||||
while (iter)
|
if ( cbtx[41] + xsig_len + n <= 100 )
|
||||||
|
{
|
||||||
|
memcpy( xsig+xsig_len, coinbase_sig, n );
|
||||||
|
xsig_len += n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
applog( LOG_WARNING,
|
||||||
|
"Signature does not fit in coinbase, skipping" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp = json_object_get( val, "coinbaseaux" );
|
||||||
|
if ( tmp && json_is_object( tmp ) )
|
||||||
|
{
|
||||||
|
void *iter = json_object_iter( tmp );
|
||||||
|
while ( iter )
|
||||||
{
|
{
|
||||||
unsigned char buf[100];
|
unsigned char buf[100];
|
||||||
const char *s = json_string_value(json_object_iter_value(iter));
|
const char *s = json_string_value( json_object_iter_value( iter ) );
|
||||||
n = s ? (int) (strlen(s) / 2) : 0;
|
n = s ? (int) ( strlen(s) / 2 ) : 0;
|
||||||
if (!s || n > 100 || !hex2bin(buf, s, n)) {
|
if ( !s || n > 100 || !hex2bin( buf, s, n ) )
|
||||||
|
{
|
||||||
applog(LOG_ERR, "JSON invalid coinbaseaux");
|
applog(LOG_ERR, "JSON invalid coinbaseaux");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cbtx[41] + xsig_len + n <= 100) {
|
if ( cbtx[41] + xsig_len + n <= 100 )
|
||||||
memcpy(xsig+xsig_len, buf, n);
|
{
|
||||||
|
memcpy( xsig+xsig_len, buf, n );
|
||||||
xsig_len += n;
|
xsig_len += n;
|
||||||
}
|
}
|
||||||
iter = json_object_iter_next(tmp, iter);
|
iter = json_object_iter_next( tmp, iter );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xsig_len)
|
if ( xsig_len )
|
||||||
{
|
{
|
||||||
unsigned char *ssig_end = cbtx + 42 + cbtx[41];
|
unsigned char *ssig_end = cbtx + 42 + cbtx[41];
|
||||||
int push_len = cbtx[41] + xsig_len < 76 ? 1 :
|
int push_len = cbtx[41] + xsig_len < 76 ? 1 :
|
||||||
cbtx[41] + 2 + xsig_len > 100 ? 0 : 2;
|
cbtx[41] + 2 + xsig_len > 100 ? 0 : 2;
|
||||||
n = xsig_len + push_len;
|
n = xsig_len + push_len;
|
||||||
memmove(ssig_end + n, ssig_end, cbtx_size - 42 - cbtx[41]);
|
memmove( ssig_end + n, ssig_end, cbtx_size - 42 - cbtx[41] );
|
||||||
cbtx[41] += n;
|
cbtx[41] += n;
|
||||||
if (push_len == 2)
|
if ( push_len == 2 )
|
||||||
*(ssig_end++) = 0x4c; /* OP_PUSHDATA1 */
|
*(ssig_end++) = 0x4c; /* OP_PUSHDATA1 */
|
||||||
if (push_len)
|
if ( push_len )
|
||||||
*(ssig_end++) = xsig_len;
|
*(ssig_end++) = xsig_len;
|
||||||
memcpy(ssig_end, xsig, xsig_len);
|
memcpy( ssig_end, xsig, xsig_len );
|
||||||
cbtx_size += n;
|
cbtx_size += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n = varint_encode(txc_vi, 1 + tx_count);
|
n = varint_encode( txc_vi, 1 + tx_count );
|
||||||
work->txs = (char*) malloc(2 * (n + cbtx_size + tx_size) + 1);
|
work->txs = (char*) malloc( 2 * ( n + cbtx_size + tx_size ) + 1 );
|
||||||
bin2hex(work->txs, txc_vi, n);
|
bin2hex( work->txs, txc_vi, n );
|
||||||
bin2hex(work->txs + 2*n, cbtx, cbtx_size);
|
bin2hex( work->txs + 2*n, cbtx, cbtx_size );
|
||||||
|
|
||||||
/* generate merkle root */
|
/* generate merkle root */
|
||||||
merkle_tree = (uchar(*)[32]) calloc(((1 + tx_count + 1) & ~1), 32);
|
merkle_tree = (uchar(*)[32]) calloc(((1 + tx_count + 1) & ~1), 32);
|
||||||
sha256d(merkle_tree[0], cbtx, cbtx_size);
|
sha256d(merkle_tree[0], cbtx, cbtx_size);
|
||||||
for (i = 0; i < tx_count; i++)
|
for ( i = 0; i < tx_count; i++ )
|
||||||
{
|
{
|
||||||
tmp = json_array_get(txa, i);
|
tmp = json_array_get( txa, i );
|
||||||
const char *tx_hex = json_string_value(json_object_get(tmp, "data"));
|
const char *tx_hex = json_string_value( json_object_get( tmp, "data" ) );
|
||||||
const int tx_size = tx_hex ? (int) (strlen(tx_hex) / 2) : 0;
|
const int tx_size = tx_hex ? (int) ( strlen( tx_hex ) / 2 ) : 0;
|
||||||
unsigned char *tx = (uchar*) malloc(tx_size);
|
unsigned char *tx = (uchar*) malloc( tx_size );
|
||||||
if (!tx_hex || !hex2bin(tx, tx_hex, tx_size))
|
if ( !tx_hex || !hex2bin( tx, tx_hex, tx_size ) )
|
||||||
{
|
{
|
||||||
applog(LOG_ERR, "JSON invalid transactions");
|
applog( LOG_ERR, "JSON invalid transactions" );
|
||||||
free(tx);
|
free( tx );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
sha256d(merkle_tree[1 + i], tx, tx_size);
|
sha256d( merkle_tree[1 + i], tx, tx_size );
|
||||||
if (!submit_coinbase)
|
if ( !submit_coinbase )
|
||||||
strcat(work->txs, tx_hex);
|
strcat( work->txs, tx_hex );
|
||||||
}
|
}
|
||||||
n = 1 + tx_count;
|
n = 1 + tx_count;
|
||||||
while (n > 1)
|
while ( n > 1 )
|
||||||
{
|
{
|
||||||
if (n % 2)
|
if ( n % 2 )
|
||||||
{
|
{
|
||||||
memcpy(merkle_tree[n], merkle_tree[n-1], 32);
|
memcpy( merkle_tree[n], merkle_tree[n-1], 32 );
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
n /= 2;
|
n /= 2;
|
||||||
for (i = 0; i < n; i++)
|
for ( i = 0; i < n; i++ )
|
||||||
sha256d(merkle_tree[i], merkle_tree[2*i], 64);
|
sha256d( merkle_tree[i], merkle_tree[2*i], 64 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assemble block header */
|
/* assemble block header */
|
||||||
work->data[0] = swab32(version);
|
algo_gate.build_block_header( work, swab32( version ),
|
||||||
for (i = 0; i < 8; i++)
|
(uint32_t*) prevhash, (uint32_t*) merkle_tree,
|
||||||
work->data[8 - i] = le32dec(prevhash + i);
|
swab32( curtime ), le32dec( &bits ) );
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
work->data[9 + i] = be32dec((uint32_t *)merkle_tree[0] + i);
|
|
||||||
work->data[17] = swab32(curtime);
|
|
||||||
work->data[18] = le32dec(&bits);
|
|
||||||
memset(work->data + 19, 0x00, 52);
|
|
||||||
work->data[20] = 0x80000000;
|
|
||||||
work->data[31] = 0x00000280;
|
|
||||||
|
|
||||||
if ( unlikely( !jobj_binary(val, "target", target, sizeof(target)) ) )
|
if ( unlikely( !jobj_binary(val, "target", target, sizeof(target)) ) )
|
||||||
{
|
{
|
||||||
applog(LOG_ERR, "JSON invalid target");
|
applog( LOG_ERR, "JSON invalid target" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
for (i = 0; i < ARRAY_SIZE(work->target); i++)
|
for ( i = 0; i < ARRAY_SIZE( work->target ); i++ )
|
||||||
work->target[7 - i] = be32dec(target + i);
|
work->target[7 - i] = be32dec( target + i );
|
||||||
|
|
||||||
tmp = json_object_get(val, "workid");
|
tmp = json_object_get( val, "workid" );
|
||||||
if (tmp)
|
if ( tmp )
|
||||||
{
|
{
|
||||||
if (!json_is_string(tmp)) {
|
if ( !json_is_string( tmp ) )
|
||||||
applog(LOG_ERR, "JSON invalid workid");
|
{
|
||||||
|
applog( LOG_ERR, "JSON invalid workid" );
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
work->workid = strdup(json_string_value(tmp));
|
work->workid = strdup( json_string_value( tmp ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = true;
|
rc = true;
|
||||||
out:
|
out:
|
||||||
/* Long polling */
|
/* Long polling */
|
||||||
tmp = json_object_get(val, "longpollid");
|
tmp = json_object_get( val, "longpollid" );
|
||||||
if (want_longpoll && json_is_string(tmp))
|
if ( want_longpoll && json_is_string( tmp ) )
|
||||||
{
|
{
|
||||||
free(lp_id);
|
free( lp_id );
|
||||||
lp_id = strdup(json_string_value(tmp));
|
lp_id = strdup( json_string_value( tmp ) );
|
||||||
if (!have_longpoll)
|
if ( !have_longpoll )
|
||||||
{
|
{
|
||||||
char *lp_uri;
|
char *lp_uri;
|
||||||
tmp = json_object_get(val, "longpolluri");
|
tmp = json_object_get( val, "longpolluri" );
|
||||||
lp_uri = json_is_string(tmp) ? strdup(json_string_value(tmp)) : rpc_url;
|
lp_uri = json_is_string( tmp ) ? strdup( json_string_value( tmp ) )
|
||||||
|
: rpc_url;
|
||||||
have_longpoll = true;
|
have_longpoll = true;
|
||||||
tq_push(thr_info[longpoll_thr_id].q, lp_uri);
|
tq_push(thr_info[longpoll_thr_id].q, lp_uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(merkle_tree);
|
free( merkle_tree );
|
||||||
free(cbtx);
|
free( cbtx );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,12 +1072,42 @@ bool jr2_submit_getwork_result( CURL *curl, struct work *work )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool submit_upstream_work( CURL *curl, struct work *work )
|
char* std_malloc_txs_request( struct work *work )
|
||||||
{
|
{
|
||||||
json_t *val, *res;
|
char *req;
|
||||||
char req[JSON_BUF_LEN];
|
json_t *val;
|
||||||
|
char data_str[2 * sizeof(work->data) + 1];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
for ( i = 0; i < ARRAY_SIZE(work->data); i++ )
|
||||||
|
be32enc( work->data + i, work->data[i] );
|
||||||
|
bin2hex( data_str, (unsigned char *)work->data, 80 );
|
||||||
|
if ( work->workid )
|
||||||
|
{
|
||||||
|
char *params;
|
||||||
|
val = json_object();
|
||||||
|
json_object_set_new( val, "workid", json_string( work->workid ) );
|
||||||
|
params = json_dumps( val, 0 );
|
||||||
|
json_decref( val );
|
||||||
|
req = (char*) malloc( 128 + 2 * 80 + strlen( work->txs )
|
||||||
|
+ strlen( params ) );
|
||||||
|
sprintf( req,
|
||||||
|
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":4}\r\n",
|
||||||
|
data_str, work->txs, params );
|
||||||
|
free( params );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
req = (char*) malloc( 128 + 2 * 80 + strlen( work->txs ) );
|
||||||
|
sprintf( req,
|
||||||
|
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":4}\r\n",
|
||||||
|
data_str, work->txs);
|
||||||
|
}
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool submit_upstream_work( CURL *curl, struct work *work )
|
||||||
|
{
|
||||||
/* pass if the previous hash is not the current previous hash */
|
/* pass if the previous hash is not the current previous hash */
|
||||||
if ( !submit_old && memcmp( &work->data[1], &g_work.data[1], 32 ) )
|
if ( !submit_old && memcmp( &work->data[1], &g_work.data[1], 32 ) )
|
||||||
{
|
{
|
||||||
@@ -1063,6 +1115,7 @@ static bool submit_upstream_work( CURL *curl, struct work *work )
|
|||||||
applog(LOG_DEBUG, "DEBUG: stale work detected, discarding");
|
applog(LOG_DEBUG, "DEBUG: stale work detected, discarding");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !have_stratum && allow_mininginfo )
|
if ( !have_stratum && allow_mininginfo )
|
||||||
{
|
{
|
||||||
struct work wheight;
|
struct work wheight;
|
||||||
@@ -1074,8 +1127,10 @@ static bool submit_upstream_work( CURL *curl, struct work *work )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( have_stratum )
|
if ( have_stratum )
|
||||||
{
|
{
|
||||||
|
char req[JSON_BUF_LEN];
|
||||||
stratum.sharediff = work->sharediff;
|
stratum.sharediff = work->sharediff;
|
||||||
algo_gate.build_stratum_request( req, work, &stratum );
|
algo_gate.build_stratum_request( req, work, &stratum );
|
||||||
if ( unlikely( !stratum_send_line( &stratum, req ) ) )
|
if ( unlikely( !stratum_send_line( &stratum, req ) ) )
|
||||||
@@ -1085,71 +1140,49 @@ static bool submit_upstream_work( CURL *curl, struct work *work )
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (work->txs)
|
else if ( work->txs )
|
||||||
{
|
{
|
||||||
char data_str[2 * sizeof(work->data) + 1];
|
char *req = NULL;
|
||||||
char *req;
|
json_t *val, *res;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(work->data); i++)
|
req = algo_gate.malloc_txs_request( work );
|
||||||
be32enc(work->data + i, work->data[i]);
|
val = json_rpc_call( curl, rpc_url, rpc_userpass, req, NULL, 0 );
|
||||||
bin2hex(data_str, (unsigned char *)work->data, 80);
|
free( req );
|
||||||
if (work->workid)
|
|
||||||
{
|
|
||||||
char *params;
|
|
||||||
val = json_object();
|
|
||||||
json_object_set_new(val, "workid", json_string(work->workid));
|
|
||||||
params = json_dumps(val, 0);
|
|
||||||
json_decref(val);
|
|
||||||
req = (char*) malloc(128 + 2 * 80 + strlen(work->txs) + strlen(params));
|
|
||||||
sprintf( req,
|
|
||||||
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":4}\r\n",
|
|
||||||
data_str, work->txs, params);
|
|
||||||
free(params);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
req = (char*) malloc(128 + 2 * 80 + strlen(work->txs));
|
|
||||||
sprintf(req,
|
|
||||||
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":4}\r\n",
|
|
||||||
data_str, work->txs);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = json_rpc_call(curl, rpc_url, rpc_userpass, req, NULL, 0);
|
if ( unlikely( !val ) )
|
||||||
free(req);
|
|
||||||
if (unlikely(!val))
|
|
||||||
{
|
{
|
||||||
applog(LOG_ERR, "submit_upstream_work json_rpc_call failed");
|
applog( LOG_ERR, "submit_upstream_work json_rpc_call failed" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
res = json_object_get(val, "result");
|
res = json_object_get( val, "result" );
|
||||||
if (json_is_object(res))
|
if ( json_is_object( res ) )
|
||||||
{
|
{
|
||||||
char *res_str;
|
char *res_str;
|
||||||
bool sumres = false;
|
bool sumres = false;
|
||||||
void *iter = json_object_iter(res);
|
void *iter = json_object_iter( res );
|
||||||
while (iter)
|
while ( iter )
|
||||||
{
|
{
|
||||||
if (json_is_null(json_object_iter_value(iter)))
|
if ( json_is_null( json_object_iter_value( iter ) ) )
|
||||||
{
|
{
|
||||||
sumres = true;
|
sumres = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
iter = json_object_iter_next(res, iter);
|
iter = json_object_iter_next( res, iter );
|
||||||
}
|
}
|
||||||
res_str = json_dumps(res, 0);
|
res_str = json_dumps( res, 0 );
|
||||||
share_result(sumres, work, res_str);
|
share_result( sumres, work, res_str );
|
||||||
free(res_str);
|
free( res_str );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
share_result(json_is_null(res), work, json_string_value(res));
|
share_result( json_is_null( res ), work, json_string_value( res ) );
|
||||||
json_decref(val);
|
json_decref( val );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return algo_gate.submit_getwork_result( curl, work );
|
return algo_gate.submit_getwork_result( curl, work );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *getwork_req =
|
const char *getwork_req =
|
||||||
"{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
|
"{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
|
||||||
|
|
||||||
#define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]"
|
#define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]"
|
||||||
@@ -1157,11 +1190,11 @@ static const char *getwork_req =
|
|||||||
static const char *gbt_req =
|
static const char *gbt_req =
|
||||||
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
||||||
GBT_CAPABILITIES "}], \"id\":0}\r\n";
|
GBT_CAPABILITIES "}], \"id\":0}\r\n";
|
||||||
static const char *gbt_lp_req =
|
const char *gbt_lp_req =
|
||||||
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
||||||
GBT_CAPABILITIES ", \"longpollid\": \"%s\"}], \"id\":0}\r\n";
|
GBT_CAPABILITIES ", \"longpollid\": \"%s\"}], \"id\":0}\r\n";
|
||||||
|
|
||||||
static bool get_upstream_work(CURL *curl, struct work *work)
|
static bool get_upstream_work( CURL *curl, struct work *work )
|
||||||
{
|
{
|
||||||
json_t *val;
|
json_t *val;
|
||||||
int err;
|
int err;
|
||||||
@@ -1169,68 +1202,68 @@ static bool get_upstream_work(CURL *curl, struct work *work)
|
|||||||
struct timeval tv_start, tv_end, diff;
|
struct timeval tv_start, tv_end, diff;
|
||||||
|
|
||||||
start:
|
start:
|
||||||
gettimeofday(&tv_start, NULL);
|
gettimeofday( &tv_start, NULL );
|
||||||
|
|
||||||
if (jsonrpc_2)
|
if ( jsonrpc_2 )
|
||||||
{
|
{
|
||||||
char s[128];
|
char s[128];
|
||||||
snprintf(s, 128, "{\"method\": \"getjob\", \"params\": {\"id\": \"%s\"}, \"id\":1}\r\n", rpc2_id);
|
snprintf( s, 128, "{\"method\": \"getjob\", \"params\": {\"id\": \"%s\"}, \"id\":1}\r\n", rpc2_id );
|
||||||
val = json_rpc2_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
|
val = json_rpc2_call( curl, rpc_url, rpc_userpass, s, NULL, 0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = json_rpc_call(curl, rpc_url, rpc_userpass,
|
val = json_rpc_call( curl, rpc_url, rpc_userpass,
|
||||||
have_gbt ? gbt_req : getwork_req,
|
have_gbt ? gbt_req : getwork_req, &err,
|
||||||
&err, have_gbt ? JSON_RPC_QUIET_404 : 0);
|
have_gbt ? JSON_RPC_QUIET_404 : 0);
|
||||||
}
|
}
|
||||||
gettimeofday(&tv_end, NULL);
|
gettimeofday( &tv_end, NULL );
|
||||||
|
|
||||||
if (have_stratum)
|
if ( have_stratum )
|
||||||
{
|
{
|
||||||
if (val)
|
if ( val )
|
||||||
json_decref(val);
|
json_decref(val);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!have_gbt && !allow_getwork)
|
if ( !have_gbt && !allow_getwork )
|
||||||
{
|
{
|
||||||
applog(LOG_ERR, "No usable protocol");
|
applog( LOG_ERR, "No usable protocol" );
|
||||||
if (val)
|
if ( val )
|
||||||
json_decref(val);
|
json_decref( val );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_gbt && allow_getwork && !val && err == CURLE_OK)
|
if ( have_gbt && allow_getwork && !val && err == CURLE_OK )
|
||||||
{
|
{
|
||||||
applog(LOG_NOTICE, "getblocktemplate failed, falling back to getwork");
|
applog( LOG_NOTICE, "getblocktemplate failed, falling back to getwork" );
|
||||||
have_gbt = false;
|
have_gbt = false;
|
||||||
goto start;
|
goto start;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!val)
|
if ( !val )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (have_gbt)
|
if ( have_gbt )
|
||||||
{
|
{
|
||||||
rc = gbt_work_decode(json_object_get(val, "result"), work);
|
rc = gbt_work_decode( json_object_get( val, "result" ), work );
|
||||||
if (!have_gbt)
|
if ( !have_gbt )
|
||||||
{
|
{
|
||||||
json_decref(val);
|
json_decref( val );
|
||||||
goto start;
|
goto start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rc = work_decode(json_object_get(val, "result"), work);
|
rc = work_decode( json_object_get( val, "result" ), work );
|
||||||
|
|
||||||
if (opt_protocol && rc)
|
if ( opt_protocol && rc )
|
||||||
{
|
{
|
||||||
timeval_subtract(&diff, &tv_end, &tv_start);
|
timeval_subtract( &diff, &tv_end, &tv_start );
|
||||||
applog(LOG_DEBUG, "got new work in %.2f ms",
|
applog( LOG_DEBUG, "got new work in %.2f ms",
|
||||||
(1000.0 * diff.tv_sec) + (0.001 * diff.tv_usec));
|
( 1000.0 * diff.tv_sec ) + ( 0.001 * diff.tv_usec ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
json_decref(val);
|
json_decref( val );
|
||||||
// store work height in solo
|
// store work height in solo
|
||||||
get_mininginfo(curl, work);
|
get_mininginfo(curl, work);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1881,65 +1914,59 @@ static void *miner_thread( void *userdata )
|
|||||||
gettimeofday( (struct timeval *) &tv_start, NULL );
|
gettimeofday( (struct timeval *) &tv_start, NULL );
|
||||||
|
|
||||||
// Scan for nonce
|
// Scan for nonce
|
||||||
nonce_found = (bool) algo_gate.scanhash( thr_id, &work, max_nonce,
|
nonce_found = algo_gate.scanhash( thr_id, &work, max_nonce,
|
||||||
&hashes_done );
|
&hashes_done );
|
||||||
|
|
||||||
// record scanhash elapsed time
|
// record scanhash elapsed time
|
||||||
gettimeofday(&tv_end, NULL);
|
gettimeofday( &tv_end, NULL );
|
||||||
timeval_subtract(&diff, &tv_end, &tv_start);
|
timeval_subtract( &diff, &tv_end, &tv_start );
|
||||||
if (diff.tv_usec || diff.tv_sec)
|
if ( diff.tv_usec || diff.tv_sec )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&stats_lock);
|
pthread_mutex_lock( &stats_lock );
|
||||||
thr_hashcount[thr_id] = hashes_done;
|
thr_hashcount[thr_id] = hashes_done;
|
||||||
thr_hashrates[thr_id] =
|
thr_hashrates[thr_id] =
|
||||||
hashes_done / (diff.tv_sec + diff.tv_usec * 1e-6);
|
hashes_done / ( diff.tv_sec + diff.tv_usec * 1e-6 );
|
||||||
pthread_mutex_unlock(&stats_lock);
|
pthread_mutex_unlock( &stats_lock );
|
||||||
}
|
}
|
||||||
|
|
||||||
// if nonce(s) submit work
|
// if nonce(s) found submit work
|
||||||
if ( nonce_found && !opt_benchmark )
|
if ( nonce_found && !opt_benchmark )
|
||||||
{
|
{ // 4 way with multiple nonces, copy individually to work and submit.
|
||||||
/*
|
if ( nonce_found > 1 )
|
||||||
int num_submitted = 0;
|
|
||||||
|
|
||||||
for ( int n = 0; n < nonce_found; n++ )
|
for ( int n = 0; n < nonce_found; n++ )
|
||||||
{
|
{
|
||||||
*algo_gate.get_nonceptr( work.data ) = work.nonces[n];
|
*algo_gate.get_nonceptr( work.data ) = work.nonces[n];
|
||||||
if ( submit_work( mythr, &work ) )
|
if ( submit_work( mythr, &work ) )
|
||||||
{
|
|
||||||
applog( LOG_NOTICE, "Share submitted." );
|
applog( LOG_NOTICE, "Share submitted." );
|
||||||
num_submitted++;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
applog( LOG_WARNING, "Failed to submit share." );
|
applog( LOG_WARNING, "Failed to submit share." );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// must be a one way algo, nonce is already in work data
|
else
|
||||||
if ( !num_submitted )
|
{ // only 1 nonce, in work ready to submit.
|
||||||
{
|
|
||||||
*/
|
|
||||||
if ( !submit_work( mythr, &work ) )
|
if ( !submit_work( mythr, &work ) )
|
||||||
{
|
{
|
||||||
applog( LOG_WARNING, "Failed to submit share." );
|
applog( LOG_WARNING, "Failed to submit share." );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
applog( LOG_NOTICE, "Share submitted." );
|
applog( LOG_NOTICE, "Share submitted." );
|
||||||
// }
|
}
|
||||||
|
|
||||||
// prevent stale work in solo
|
// prevent stale work in solo
|
||||||
// we can't submit twice a block!
|
// we can't submit twice a block!
|
||||||
if (!have_stratum && !have_longpoll)
|
if ( !have_stratum && !have_longpoll )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&g_work_lock);
|
pthread_mutex_lock( &g_work_lock );
|
||||||
// will force getwork
|
// will force getwork
|
||||||
g_work_time = 0;
|
g_work_time = 0;
|
||||||
pthread_mutex_unlock(&g_work_lock);
|
pthread_mutex_unlock( &g_work_lock );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// display hashrate
|
// display hashrate
|
||||||
if (!opt_quiet)
|
if ( !opt_quiet )
|
||||||
{
|
{
|
||||||
char hc[16];
|
char hc[16];
|
||||||
char hr[16];
|
char hr[16];
|
||||||
@@ -2236,27 +2263,45 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void std_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
|
// used by stratum and gbt
|
||||||
|
void std_build_block_header( struct work* g_work, uint32_t version,
|
||||||
|
uint32_t *prevhash, uint32_t *merkle_tree,
|
||||||
|
uint32_t ntime, uint32_t nbits )
|
||||||
{
|
{
|
||||||
uchar merkle_root[64] = { 0 };
|
|
||||||
size_t t;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
algo_gate.gen_merkle_root( merkle_root, sctx );
|
memset( g_work->data, 0, sizeof(g_work->data) );
|
||||||
|
g_work->data[0] = version;
|
||||||
|
|
||||||
|
if ( have_stratum )
|
||||||
|
for ( i = 0; i < 8; i++ )
|
||||||
|
g_work->data[ 1+i ] = le32dec( prevhash + i );
|
||||||
|
else
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
g_work->data[ 8-i ] = le32dec( prevhash + i );
|
||||||
|
|
||||||
|
for ( i = 0; i < 8; i++ )
|
||||||
|
g_work->data[ 9+i ] = be32dec( merkle_tree + i );
|
||||||
|
|
||||||
|
g_work->data[ algo_gate.ntime_index ] = ntime;
|
||||||
|
g_work->data[ algo_gate.nbits_index ] = nbits;
|
||||||
|
g_work->data[20] = 0x80000000;
|
||||||
|
g_work->data[31] = 0x00000280;
|
||||||
|
}
|
||||||
|
|
||||||
|
void std_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
|
||||||
|
{
|
||||||
|
uchar merkle_tree[64] = { 0 };
|
||||||
|
size_t t;
|
||||||
|
|
||||||
|
algo_gate.gen_merkle_root( merkle_tree, sctx );
|
||||||
// Increment extranonce2
|
// Increment extranonce2
|
||||||
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
|
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
|
||||||
// Assemble block header
|
// Assemble block header
|
||||||
memset( g_work->data, 0, sizeof(g_work->data) );
|
|
||||||
g_work->data[0] = le32dec( sctx->job.version );
|
|
||||||
for ( i = 0; i < 8; i++ )
|
|
||||||
g_work->data[1 + i] = le32dec( (uint32_t *) sctx->job.prevhash + i );
|
|
||||||
for ( i = 0; i < 8; i++ )
|
|
||||||
g_work->data[9 + i] = be32dec( (uint32_t *) merkle_root + i );
|
|
||||||
|
|
||||||
g_work->data[ algo_gate.ntime_index ] = le32dec(sctx->job.ntime);
|
algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
|
||||||
g_work->data[ algo_gate.nbits_index ] = le32dec(sctx->job.nbits);
|
(uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_tree,
|
||||||
g_work->data[20] = 0x80000000;
|
le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits) );
|
||||||
g_work->data[31] = 0x00000280;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
|
void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
|
||||||
|
|||||||
4
miner.h
4
miner.h
@@ -648,6 +648,10 @@ extern int opt_timeout;
|
|||||||
extern bool want_longpoll;
|
extern bool want_longpoll;
|
||||||
extern bool have_longpoll;
|
extern bool have_longpoll;
|
||||||
extern bool have_gbt;
|
extern bool have_gbt;
|
||||||
|
extern char* lp_id;
|
||||||
|
extern char *rpc_userpass;
|
||||||
|
extern const char *gbt_lp_req;
|
||||||
|
extern const char *getwork_req;
|
||||||
extern bool allow_getwork;
|
extern bool allow_getwork;
|
||||||
extern bool want_stratum;
|
extern bool want_stratum;
|
||||||
extern bool have_stratum;
|
extern bool have_stratum;
|
||||||
|
|||||||
Reference in New Issue
Block a user