Compare commits

..

2 Commits

Author SHA1 Message Date
Jay D Dee
fcd7727b0d v3.22.1 2023-03-24 18:29:42 -04:00
Jay D Dee
3dd6787531 v3.22.0 2023-03-21 17:12:51 -04:00
19 changed files with 1074 additions and 2185 deletions

View File

@@ -55,9 +55,6 @@ cpuminer_SOURCES = \
algo/blake/mod_blakecoin.c \ algo/blake/mod_blakecoin.c \
algo/blake/blakecoin.c \ algo/blake/blakecoin.c \
algo/blake/blakecoin-4way.c \ algo/blake/blakecoin-4way.c \
algo/blake/decred-gate.c \
algo/blake/decred.c \
algo/blake/decred-4way.c \
algo/blake/pentablake-gate.c \ algo/blake/pentablake-gate.c \
algo/blake/pentablake-4way.c \ algo/blake/pentablake-4way.c \
algo/blake/pentablake.c \ algo/blake/pentablake.c \

View File

@@ -65,6 +65,22 @@ If not what makes it happen or not happen?
Change Log Change Log
---------- ----------
v3.22.1
#393 fixed segfault in GBT, regression from v3.22.0.
More efficient 32 bit data interleaving.
v3.22.0
Stratum: faster netdiff calculation.
Merged a few updates from Pooler/cpuminer:
Use CURLOPT_POSTFIELDS in json_rpc_call,
Use CURLINFO_ACTIVESOCKET when supported,
JSONRPC speedup,
Speed up hex2bin function.
Small log improvements, notably more frequent hash rate reports.
Removed decred algo.
v3.21.5 v3.21.5
All issues with v3.21.3 & v3.21.4 should be resolved. All issues with v3.21.3 & v3.21.4 should be resolved.
@@ -77,7 +93,7 @@ Changes since v3.21.2:
Windows binaries support CPUs with up to 64 threads. Windows binaries support CPUs with up to 64 threads.
Small optimizations to serialized vectoring. Small optimizations to serialized vectoring.
v3.21.4 v3.21.4 CANCELLED
Reapply selected changes from v3.21.3. Reapply selected changes from v3.21.3.
#392 #379 #389 Fixed misaligned address segfault solo mining. #392 #379 #389 Fixed misaligned address segfault solo mining.
@@ -86,7 +102,6 @@ Reapply selected changes from v3.21.3.
Windows binaries no longer support CPU groups, Windows binaries no longer support CPU groups,
Windows binaries support CPUs with up to 64 threads. Windows binaries support CPUs with up to 64 threads.
v3.21.3.1 UNRELEASED v3.21.3.1 UNRELEASED
Revert to 3.21.2 Revert to 3.21.2

View File

@@ -263,8 +263,6 @@ void init_algo_gate( algo_gate_t* gate )
gate->build_block_header = (void*)&std_build_block_header; 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->ready_to_mine = (void*)&std_ready_to_mine;
gate->resync_threads = (void*)&do_nothing; gate->resync_threads = (void*)&do_nothing;
gate->do_this_thread = (void*)&return_true; gate->do_this_thread = (void*)&return_true;
gate->longpoll_rpc_call = (void*)&std_longpoll_rpc_call; gate->longpoll_rpc_call = (void*)&std_longpoll_rpc_call;
@@ -308,7 +306,6 @@ bool register_algo_gate( int algo, algo_gate_t *gate )
case ALGO_BLAKECOIN: rc = register_blakecoin_algo ( gate ); break; case ALGO_BLAKECOIN: rc = register_blakecoin_algo ( gate ); break;
case ALGO_BMW512: rc = register_bmw512_algo ( gate ); break; case ALGO_BMW512: rc = register_bmw512_algo ( gate ); break;
case ALGO_C11: rc = register_c11_algo ( gate ); break; case ALGO_C11: rc = register_c11_algo ( gate ); break;
case ALGO_DECRED: rc = register_decred_algo ( gate ); break;
case ALGO_DEEP: rc = register_deep_algo ( gate ); break; case ALGO_DEEP: rc = register_deep_algo ( gate ); break;
case ALGO_DMD_GR: rc = register_dmd_gr_algo ( gate ); break; case ALGO_DMD_GR: rc = register_dmd_gr_algo ( gate ); break;
case ALGO_GROESTL: rc = register_groestl_algo ( gate ); break; case ALGO_GROESTL: rc = register_groestl_algo ( gate ); break;
@@ -427,7 +424,6 @@ const char* const algo_alias_map[][2] =
{ "blake256r8", "blakecoin" }, { "blake256r8", "blakecoin" },
{ "blake256r8vnl", "vanilla" }, { "blake256r8vnl", "vanilla" },
{ "blake256r14", "blake" }, { "blake256r14", "blake" },
{ "blake256r14dcr", "decred" },
{ "diamond", "dmd-gr" }, { "diamond", "dmd-gr" },
{ "espers", "hmq1725" }, { "espers", "hmq1725" },
{ "flax", "c11" }, { "flax", "c11" },

View File

@@ -155,18 +155,12 @@ char* ( *malloc_txs_request ) ( struct work* );
// Big endian or little endian // Big endian or little endian
void ( *set_work_data_endian ) ( struct work* ); void ( *set_work_data_endian ) ( struct work* );
double ( *calc_network_diff ) ( struct work* );
// Wait for first work
bool ( *ready_to_mine ) ( struct work*, struct stratum_ctx*, int );
// Diverge mining threads // Diverge mining threads
bool ( *do_this_thread ) ( int ); bool ( *do_this_thread ) ( int );
// After do_this_thread // After do_this_thread
void ( *resync_threads ) ( int, struct work* ); void ( *resync_threads ) ( int, struct work* );
// No longer needed
json_t* ( *longpoll_rpc_call ) ( CURL*, int*, char* ); json_t* ( *longpoll_rpc_call ) ( CURL*, int*, char* );
set_t optimizations; set_t optimizations;
@@ -286,8 +280,6 @@ char* std_malloc_txs_request( struct work *work );
// Default is do_nothing, little endian is assumed // Default is do_nothing, little endian is assumed
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 );
void std_build_block_header( struct work* g_work, uint32_t version, void std_build_block_header( struct work* g_work, uint32_t version,
uint32_t *prevhash, uint32_t *merkle_root, uint32_t *prevhash, uint32_t *merkle_root,
uint32_t ntime, uint32_t nbits, uint32_t ntime, uint32_t nbits,
@@ -297,9 +289,6 @@ 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 );
bool std_ready_to_mine( struct work* work, struct stratum_ctx* stratum,
int thr_id );
int std_get_work_data_size(); int std_get_work_data_size();
// Gate admin functions // Gate admin functions

View File

@@ -1,74 +0,0 @@
#include "decred-gate.h"
#include "blake-hash-4way.h"
#include <string.h>
#include <stdint.h>
#include <memory.h>
#include <unistd.h>
#if defined (DECRED_4WAY)
static __thread blake256_4way_context blake_mid;
void decred_hash_4way( void *state, const void *input )
{
uint32_t vhash[8*4] __attribute__ ((aligned (64)));
// uint32_t hash0[8] __attribute__ ((aligned (32)));
// uint32_t hash1[8] __attribute__ ((aligned (32)));
// uint32_t hash2[8] __attribute__ ((aligned (32)));
// uint32_t hash3[8] __attribute__ ((aligned (32)));
const void *tail = input + ( DECRED_MIDSTATE_LEN << 2 );
int tail_len = 180 - DECRED_MIDSTATE_LEN;
blake256_4way_context ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &blake_mid, sizeof(blake_mid) );
blake256_4way_update( &ctx, tail, tail_len );
blake256_4way_close( &ctx, vhash );
dintrlv_4x32( state, state+32, state+64, state+96, vhash, 256 );
}
int scanhash_decred_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t vdata[48*4] __attribute__ ((aligned (64)));
uint32_t hash[8*4] __attribute__ ((aligned (32)));
uint32_t _ALIGN(64) edata[48];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[DECRED_NONCE_INDEX];
uint32_t n = first_nonce;
const uint32_t HTarget = opt_benchmark ? 0x7f : ptarget[7];
int thr_id = mythr->id; // thr_id arg is deprecated
// copy to buffer guaranteed to be aligned.
memcpy( edata, pdata, 180 );
// use the old way until new way updated for size.
mm128_intrlv_4x32x( vdata, edata, edata, edata, edata, 180*8 );
blake256_4way_init( &blake_mid );
blake256_4way_update( &blake_mid, vdata, DECRED_MIDSTATE_LEN );
uint32_t *noncep = vdata + DECRED_NONCE_INDEX * 4;
do {
* noncep = n;
*(noncep+1) = n+1;
*(noncep+2) = n+2;
*(noncep+3) = n+3;
decred_hash_4way( hash, vdata );
for ( int i = 0; i < 4; i++ )
if ( (hash+(i<<3))[7] <= HTarget )
if ( fulltest( hash+(i<<3), ptarget ) && !opt_benchmark )
{
pdata[DECRED_NONCE_INDEX] = n+i;
submit_solution( work, hash+(i<<3), mythr );
}
n += 4;
} while ( (n < max_nonce) && !work_restart[thr_id].restart );
*hashes_done = n - first_nonce + 1;
return 0;
}
#endif

View File

@@ -1,171 +0,0 @@
#include "decred-gate.h"
#include <unistd.h>
#include <memory.h>
#include <string.h>
uint32_t *decred_get_nonceptr( uint32_t *work_data )
{
return &work_data[ DECRED_NONCE_INDEX ];
}
long double decred_calc_network_diff( struct work* work )
{
// sample for diff 43.281 : 1c05ea29
// todo: endian reversed on longpoll could be zr5 specific...
uint32_t nbits = work->data[ DECRED_NBITS_INDEX ];
uint32_t bits = ( nbits & 0xffffff );
int16_t shift = ( swab32(nbits) & 0xff ); // 0x1c = 28
int m;
long double d = (long double)0x0000ffff / (long double)bits;
for ( m = shift; m < 29; m++ )
d *= 256.0;
for ( m = 29; m < shift; m++ )
d /= 256.0;
if ( shift == 28 )
d *= 256.0; // testnet
if ( opt_debug_diff )
applog( LOG_DEBUG, "net diff: %f -> shift %u, bits %08x", (double)d,
shift, bits );
return net_diff;
}
void decred_decode_extradata( struct work* work, uint64_t* net_blocks )
{
// some random extradata to make the work unique
work->data[ DECRED_XNONCE_INDEX ] = (rand()*4);
work->height = work->data[32];
if (!have_longpoll && work->height > *net_blocks + 1)
{
char netinfo[64] = { 0 };
if ( net_diff > 0. )
{
if (net_diff != work->targetdiff)
sprintf(netinfo, ", diff %.3f, target %.1f", net_diff,
work->targetdiff);
else
sprintf(netinfo, ", diff %.3f", net_diff);
}
applog(LOG_BLUE, "%s block %d%s", algo_names[opt_algo], work->height,
netinfo);
*net_blocks = work->height - 1;
}
}
void decred_be_build_stratum_request( char *req, struct work *work,
struct stratum_ctx *sctx )
{
unsigned char *xnonce2str;
uint32_t ntime, nonce;
char ntimestr[9], noncestr[9];
be32enc( &ntime, work->data[ DECRED_NTIME_INDEX ] );
be32enc( &nonce, work->data[ DECRED_NONCE_INDEX ] );
bin2hex( ntimestr, (char*)(&ntime), sizeof(uint32_t) );
bin2hex( noncestr, (char*)(&nonce), sizeof(uint32_t) );
xnonce2str = abin2hex( (char*)( &work->data[ DECRED_XNONCE_INDEX ] ),
sctx->xnonce1_size );
snprintf( req, JSON_BUF_LEN,
"{\"method\": \"mining.submit\", \"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\":4}",
rpc_user, work->job_id, xnonce2str, ntimestr, noncestr );
free(xnonce2str);
}
#if !defined(min)
#define min(a,b) (a>b ? (b) :(a))
#endif
void decred_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
{
uchar merkle_root[64] = { 0 };
uint32_t extraheader[32] = { 0 };
int headersize = 0;
uint32_t* extradata = (uint32_t*) sctx->xnonce1;
int i;
// getwork over stratum, getwork merkle + header passed in coinb1
memcpy(merkle_root, sctx->job.coinbase, 32);
headersize = min((int)sctx->job.coinbase_size - 32,
sizeof(extraheader) );
memcpy( extraheader, &sctx->job.coinbase[32], headersize );
// 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] = swab32(
le32dec( (uint32_t *) sctx->job.prevhash + i ) );
for ( i = 0; i < 8; i++ )
g_work->data[9 + i] = swab32( be32dec( (uint32_t *) merkle_root + i ) );
// for ( i = 0; i < 8; i++ ) // prevhash
// g_work->data[1 + i] = swab32( g_work->data[1 + i] );
// for ( i = 0; i < 8; i++ ) // merkle
// g_work->data[9 + i] = swab32( g_work->data[9 + i] );
for ( i = 0; i < headersize/4; i++ ) // header
g_work->data[17 + i] = extraheader[i];
// extradata
for ( i = 0; i < sctx->xnonce1_size/4; i++ )
g_work->data[ DECRED_XNONCE_INDEX + i ] = extradata[i];
for ( i = DECRED_XNONCE_INDEX + sctx->xnonce1_size/4; i < 45; i++ )
g_work->data[i] = 0;
g_work->data[37] = (rand()*4) << 8;
// block header suffix from coinb2 (stake version)
memcpy( &g_work->data[44],
&sctx->job.coinbase[ sctx->job.coinbase_size-4 ], 4 );
sctx->block_height = g_work->data[32];
//applog_hex(work->data, 180);
//applog_hex(&work->data[36], 36);
}
#undef min
bool decred_ready_to_mine( struct work* work, struct stratum_ctx* stratum,
int thr_id )
{
if ( have_stratum && strcmp(stratum->job.job_id, work->job_id) )
// need to regen g_work..
return false;
if ( have_stratum && !work->data[0] && !opt_benchmark )
{
sleep(1);
return false;
}
// extradata: prevent duplicates
work->data[ DECRED_XNONCE_INDEX ] += 1;
work->data[ DECRED_XNONCE_INDEX + 1 ] |= thr_id;
return true;
}
int decred_get_work_data_size() { return DECRED_DATA_SIZE; }
bool register_decred_algo( algo_gate_t* gate )
{
#if defined(DECRED_4WAY)
four_way_not_tested();
gate->scanhash = (void*)&scanhash_decred_4way;
gate->hash = (void*)&decred_hash_4way;
#else
gate->scanhash = (void*)&scanhash_decred;
gate->hash = (void*)&decred_hash;
#endif
gate->optimizations = AVX2_OPT;
// gate->get_nonceptr = (void*)&decred_get_nonceptr;
gate->decode_extra_data = (void*)&decred_decode_extradata;
gate->build_stratum_request = (void*)&decred_be_build_stratum_request;
gate->work_decode = (void*)&std_be_work_decode;
gate->submit_getwork_result = (void*)&std_be_submit_getwork_result;
gate->build_extraheader = (void*)&decred_build_extraheader;
gate->ready_to_mine = (void*)&decred_ready_to_mine;
gate->nbits_index = DECRED_NBITS_INDEX;
gate->ntime_index = DECRED_NTIME_INDEX;
gate->nonce_index = DECRED_NONCE_INDEX;
gate->get_work_data_size = (void*)&decred_get_work_data_size;
gate->work_cmp_size = DECRED_WORK_COMPARE_SIZE;
allow_mininginfo = false;
have_gbt = false;
return true;
}

View File

@@ -1,36 +0,0 @@
#ifndef __DECRED_GATE_H__
#define __DECRED_GATE_H__
#include "algo-gate-api.h"
#include <stdint.h>
#define DECRED_NBITS_INDEX 29
#define DECRED_NTIME_INDEX 34
#define DECRED_NONCE_INDEX 35
#define DECRED_XNONCE_INDEX 36
#define DECRED_DATA_SIZE 192
#define DECRED_WORK_COMPARE_SIZE 140
#define DECRED_MIDSTATE_LEN 128
#if defined (__AVX2__)
//void blakehash_84way(void *state, const void *input);
//int scanhash_blake_8way( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done );
#endif
#if defined(__SSE4_2__)
#define DECRED_4WAY
#endif
#if defined (DECRED_4WAY)
void decred_hash_4way(void *state, const void *input);
int scanhash_decred_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
#endif
void decred_hash( void *state, const void *input );
int scanhash_decred( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
#endif

View File

@@ -1,282 +0,0 @@
#include "decred-gate.h"
#if !defined(DECRED_8WAY) && !defined(DECRED_4WAY)
#include "sph_blake.h"
#include <string.h>
#include <stdint.h>
#include <memory.h>
#include <unistd.h>
/*
#ifndef min
#define min(a,b) (a>b ? b : a)
#endif
#ifndef max
#define max(a,b) (a<b ? b : a)
#endif
*/
/*
#define DECRED_NBITS_INDEX 29
#define DECRED_NTIME_INDEX 34
#define DECRED_NONCE_INDEX 35
#define DECRED_XNONCE_INDEX 36
#define DECRED_DATA_SIZE 192
#define DECRED_WORK_COMPARE_SIZE 140
*/
static __thread sph_blake256_context blake_mid;
static __thread bool ctx_midstate_done = false;
void decred_hash(void *state, const void *input)
{
// #define MIDSTATE_LEN 128
sph_blake256_context ctx __attribute__ ((aligned (64)));
uint8_t *ending = (uint8_t*) input;
ending += DECRED_MIDSTATE_LEN;
if (!ctx_midstate_done) {
sph_blake256_init(&blake_mid);
sph_blake256(&blake_mid, input, DECRED_MIDSTATE_LEN);
ctx_midstate_done = true;
}
memcpy(&ctx, &blake_mid, sizeof(blake_mid));
sph_blake256(&ctx, ending, (180 - DECRED_MIDSTATE_LEN));
sph_blake256_close(&ctx, state);
}
void decred_hash_simple(void *state, const void *input)
{
sph_blake256_context ctx;
sph_blake256_init(&ctx);
sph_blake256(&ctx, input, 180);
sph_blake256_close(&ctx, state);
}
int scanhash_decred( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t _ALIGN(64) endiandata[48];
uint32_t _ALIGN(64) hash32[8];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
int thr_id = mythr->id; // thr_id arg is deprecated
// #define DCR_NONCE_OFT32 35
const uint32_t first_nonce = pdata[DECRED_NONCE_INDEX];
const uint32_t HTarget = opt_benchmark ? 0x7f : ptarget[7];
uint32_t n = first_nonce;
ctx_midstate_done = false;
#if 1
memcpy(endiandata, pdata, 180);
#else
for (int k=0; k < (180/4); k++)
be32enc(&endiandata[k], pdata[k]);
#endif
do {
//be32enc(&endiandata[DCR_NONCE_OFT32], n);
endiandata[DECRED_NONCE_INDEX] = n;
decred_hash(hash32, endiandata);
if (hash32[7] <= HTarget && fulltest(hash32, ptarget))
{
pdata[DECRED_NONCE_INDEX] = n;
submit_solution( work, hash32, mythr );
}
n++;
} while (n < max_nonce && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;
pdata[DECRED_NONCE_INDEX] = n;
return 0;
}
/*
uint32_t *decred_get_nonceptr( uint32_t *work_data )
{
return &work_data[ DECRED_NONCE_INDEX ];
}
double decred_calc_network_diff( struct work* work )
{
// sample for diff 43.281 : 1c05ea29
// todo: endian reversed on longpoll could be zr5 specific...
uint32_t nbits = work->data[ DECRED_NBITS_INDEX ];
uint32_t bits = ( nbits & 0xffffff );
int16_t shift = ( swab32(nbits) & 0xff ); // 0x1c = 28
int m;
double d = (double)0x0000ffff / (double)bits;
for ( m = shift; m < 29; m++ )
d *= 256.0;
for ( m = 29; m < shift; m++ )
d /= 256.0;
if ( shift == 28 )
d *= 256.0; // testnet
if ( opt_debug_diff )
applog( LOG_DEBUG, "net diff: %f -> shift %u, bits %08x", d,
shift, bits );
return net_diff;
}
void decred_decode_extradata( struct work* work, uint64_t* net_blocks )
{
// some random extradata to make the work unique
work->data[ DECRED_XNONCE_INDEX ] = (rand()*4);
work->height = work->data[32];
if (!have_longpoll && work->height > *net_blocks + 1)
{
char netinfo[64] = { 0 };
if (net_diff > 0.)
{
if (net_diff != work->targetdiff)
sprintf(netinfo, ", diff %.3f, target %.1f", net_diff,
work->targetdiff);
else
sprintf(netinfo, ", diff %.3f", net_diff);
}
applog(LOG_BLUE, "%s block %d%s", algo_names[opt_algo], work->height,
netinfo);
*net_blocks = work->height - 1;
}
}
void decred_be_build_stratum_request( char *req, struct work *work,
struct stratum_ctx *sctx )
{
unsigned char *xnonce2str;
uint32_t ntime, nonce;
char ntimestr[9], noncestr[9];
be32enc( &ntime, work->data[ DECRED_NTIME_INDEX ] );
be32enc( &nonce, work->data[ DECRED_NONCE_INDEX ] );
bin2hex( ntimestr, (char*)(&ntime), sizeof(uint32_t) );
bin2hex( noncestr, (char*)(&nonce), sizeof(uint32_t) );
xnonce2str = abin2hex( (char*)( &work->data[ DECRED_XNONCE_INDEX ] ),
sctx->xnonce1_size );
snprintf( req, JSON_BUF_LEN,
"{\"method\": \"mining.submit\", \"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\":4}",
rpc_user, work->job_id, xnonce2str, ntimestr, noncestr );
free(xnonce2str);
}
*/
/*
// data shared between gen_merkle_root and build_extraheader.
__thread uint32_t decred_extraheader[32] = { 0 };
__thread int decred_headersize = 0;
void decred_gen_merkle_root( char* merkle_root, struct stratum_ctx* sctx )
{
// getwork over stratum, getwork merkle + header passed in coinb1
memcpy(merkle_root, sctx->job.coinbase, 32);
decred_headersize = min((int)sctx->job.coinbase_size - 32,
sizeof(decred_extraheader) );
memcpy( decred_extraheader, &sctx->job.coinbase[32], decred_headersize);
}
*/
/*
#define min(a,b) (a>b ? (b) :(a))
void decred_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
{
uchar merkle_root[64] = { 0 };
uint32_t extraheader[32] = { 0 };
int headersize = 0;
uint32_t* extradata = (uint32_t*) sctx->xnonce1;
size_t t;
int i;
// getwork over stratum, getwork merkle + header passed in coinb1
memcpy(merkle_root, sctx->job.coinbase, 32);
headersize = min((int)sctx->job.coinbase_size - 32,
sizeof(extraheader) );
memcpy( extraheader, &sctx->job.coinbase[32], headersize );
// Increment extranonce2
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
// 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] = swab32(
le32dec( (uint32_t *) sctx->job.prevhash + i ) );
for ( i = 0; i < 8; i++ )
g_work->data[9 + i] = swab32( be32dec( (uint32_t *) merkle_root + i ) );
// for ( i = 0; i < 8; i++ ) // prevhash
// g_work->data[1 + i] = swab32( g_work->data[1 + i] );
// for ( i = 0; i < 8; i++ ) // merkle
// g_work->data[9 + i] = swab32( g_work->data[9 + i] );
for ( i = 0; i < headersize/4; i++ ) // header
g_work->data[17 + i] = extraheader[i];
// extradata
for ( i = 0; i < sctx->xnonce1_size/4; i++ )
g_work->data[ DECRED_XNONCE_INDEX + i ] = extradata[i];
for ( i = DECRED_XNONCE_INDEX + sctx->xnonce1_size/4; i < 45; i++ )
g_work->data[i] = 0;
g_work->data[37] = (rand()*4) << 8;
// block header suffix from coinb2 (stake version)
memcpy( &g_work->data[44],
&sctx->job.coinbase[ sctx->job.coinbase_size-4 ], 4 );
sctx->bloc_height = g_work->data[32];
//applog_hex(work->data, 180);
//applog_hex(&work->data[36], 36);
}
#undef min
bool decred_ready_to_mine( struct work* work, struct stratum_ctx* stratum,
int thr_id )
{
if ( have_stratum && strcmp(stratum->job.job_id, work->job_id) )
// need to regen g_work..
return false;
if ( have_stratum && !work->data[0] && !opt_benchmark )
{
sleep(1);
return false;
}
// extradata: prevent duplicates
work->data[ DECRED_XNONCE_INDEX ] += 1;
work->data[ DECRED_XNONCE_INDEX + 1 ] |= thr_id;
return true;
}
bool register_decred_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT;
gate->scanhash = (void*)&scanhash_decred;
gate->hash = (void*)&decred_hash;
gate->get_nonceptr = (void*)&decred_get_nonceptr;
gate->decode_extra_data = (void*)&decred_decode_extradata;
gate->build_stratum_request = (void*)&decred_be_build_stratum_request;
gate->work_decode = (void*)&std_be_work_decode;
gate->submit_getwork_result = (void*)&std_be_submit_getwork_result;
gate->build_extraheader = (void*)&decred_build_extraheader;
gate->ready_to_mine = (void*)&decred_ready_to_mine;
gate->nbits_index = DECRED_NBITS_INDEX;
gate->ntime_index = DECRED_NTIME_INDEX;
gate->nonce_index = DECRED_NONCE_INDEX;
gate->work_data_size = DECRED_DATA_SIZE;
gate->work_cmp_size = DECRED_WORK_COMPARE_SIZE;
allow_mininginfo = false;
have_gbt = false;
return true;
}
*/
#endif

View File

@@ -4,24 +4,6 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
long double lbry_calc_network_diff( struct work *work )
{
// sample for diff 43.281 : 1c05ea29
// todo: endian reversed on longpoll could be zr5 specific...
uint32_t nbits = swab32( work->data[ LBRY_NBITS_INDEX ] );
uint32_t bits = (nbits & 0xffffff);
int16_t shift = (swab32(nbits) & 0xff); // 0x1c = 28
long double d = (long double)0x0000ffff / (long double)bits;
for (int m=shift; m < 29; m++) d *= 256.0;
for (int m=29; m < shift; m++) d /= 256.0;
if (opt_debug_diff)
applog(LOG_DEBUG, "net diff: %f -> shift %u, bits %08x", d, shift, bits);
return d;
}
// std_le should work but it doesn't // std_le should work but it doesn't
void lbry_le_build_stratum_request( char *req, struct work *work, void lbry_le_build_stratum_request( char *req, struct work *work,
struct stratum_ctx *sctx ) struct stratum_ctx *sctx )
@@ -41,31 +23,6 @@ void lbry_le_build_stratum_request( char *req, struct work *work,
free(xnonce2str); free(xnonce2str);
} }
/*
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 );
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 };
@@ -112,9 +69,7 @@ bool register_lbry_algo( algo_gate_t* gate )
gate->hash = (void*)&lbry_hash; gate->hash = (void*)&lbry_hash;
gate->optimizations = AVX2_OPT | AVX512_OPT | SHA_OPT; gate->optimizations = AVX2_OPT | AVX512_OPT | SHA_OPT;
#endif #endif
gate->calc_network_diff = (void*)&lbry_calc_network_diff;
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->ntime_index = LBRY_NTIME_INDEX; gate->ntime_index = LBRY_NTIME_INDEX;
gate->nbits_index = LBRY_NBITS_INDEX; gate->nbits_index = LBRY_NBITS_INDEX;

View File

@@ -257,6 +257,7 @@ int scanhash_x17_8way( struct work *work, uint32_t max_nonce,
const __m512i eight = m512_const1_64( 8 ); const __m512i eight = m512_const1_64( 8 );
const bool bench = opt_benchmark; const bool bench = opt_benchmark;
// convert LE32 to LE64
edata[0] = mm128_swap64_32( casti_m128i( pdata, 0 ) ); edata[0] = mm128_swap64_32( casti_m128i( pdata, 0 ) );
edata[1] = mm128_swap64_32( casti_m128i( pdata, 1 ) ); edata[1] = mm128_swap64_32( casti_m128i( pdata, 1 ) );
edata[2] = mm128_swap64_32( casti_m128i( pdata, 2 ) ); edata[2] = mm128_swap64_32( casti_m128i( pdata, 2 ) );
@@ -470,6 +471,7 @@ int scanhash_x17_4way( struct work *work, uint32_t max_nonce,
const __m256i four = m256_const1_64( 4 ); const __m256i four = m256_const1_64( 4 );
const bool bench = opt_benchmark; const bool bench = opt_benchmark;
// convert LE32 to LE64
edata[0] = mm128_swap64_32( casti_m128i( pdata, 0 ) ); edata[0] = mm128_swap64_32( casti_m128i( pdata, 0 ) );
edata[1] = mm128_swap64_32( casti_m128i( pdata, 1 ) ); edata[1] = mm128_swap64_32( casti_m128i( pdata, 1 ) );
edata[2] = mm128_swap64_32( casti_m128i( pdata, 2 ) ); edata[2] = mm128_swap64_32( casti_m128i( pdata, 2 ) );

20
configure vendored
View File

@@ -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.71 for cpuminer-opt 3.21.5. # Generated by GNU Autoconf 2.71 for cpuminer-opt 3.22.1.
# #
# #
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
@@ -608,8 +608,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.21.5' PACKAGE_VERSION='3.22.1'
PACKAGE_STRING='cpuminer-opt 3.21.5' PACKAGE_STRING='cpuminer-opt 3.22.1'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' PACKAGE_URL=''
@@ -1360,7 +1360,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.21.5 to adapt to many kinds of systems. \`configure' configures cpuminer-opt 3.22.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1432,7 +1432,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.21.5:";; short | recursive ) echo "Configuration of cpuminer-opt 3.22.1:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1538,7 +1538,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.21.5 cpuminer-opt configure 3.22.1
generated by GNU Autoconf 2.71 generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc. Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1985,7 +1985,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.21.5, which was It was created by cpuminer-opt $as_me 3.22.1, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@@ -3593,7 +3593,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='cpuminer-opt' PACKAGE='cpuminer-opt'
VERSION='3.21.5' VERSION='3.22.1'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -7508,7 +7508,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.21.5, which was This file was extended by cpuminer-opt $as_me 3.22.1, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -7576,7 +7576,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
cpuminer-opt config.status 3.21.5 cpuminer-opt config.status 3.22.1
configured by $0, generated by GNU Autoconf 2.71, configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT([cpuminer-opt], [3.21.5]) AC_INIT([cpuminer-opt], [3.22.1])
AC_PREREQ([2.59c]) AC_PREREQ([2.59c])
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM

View File

@@ -432,20 +432,18 @@ static bool work_decode( const json_t *val, struct work *work )
if ( unlikely( !algo_gate.work_decode( work ) ) ) if ( unlikely( !algo_gate.work_decode( work ) ) )
return false; return false;
if ( !allow_mininginfo ) // many of these aren't used solo.
net_diff = algo_gate.calc_network_diff( work ); net_diff =
else work->targetdiff =
net_diff = hash_to_diff( work->target ); stratum_diff =
last_targetdiff = hash_to_diff( work->target );
work->targetdiff = net_diff;
stratum_diff = last_targetdiff = work->targetdiff;
work->sharediff = 0; work->sharediff = 0;
algo_gate.decode_extra_data( work, &net_blocks ); algo_gate.decode_extra_data( work, &net_blocks );
return true; return true;
} }
// good alternative for wallet mining, difficulty and net hashrate // Only used for net_hashrate with GBT/getwork, data is from previous block.
static const char *info_req = static const char *info_req =
"{\"method\": \"getmininginfo\", \"params\": [], \"id\":8}\r\n"; "{\"method\": \"getmininginfo\", \"params\": [], \"id\":8}\r\n";
@@ -471,17 +469,14 @@ static bool get_mininginfo( CURL *curl, struct work *work )
// "networkhashps": 56475980 // "networkhashps": 56475980
if ( res ) if ( res )
{ {
// net_diff is a global that is set from the work hash target by double difficulty = 0.;
// both getwork and GBT. Don't overwrite it, define a local to override
// the global.
double net_diff = 0.;
json_t *key = json_object_get( res, "difficulty" ); json_t *key = json_object_get( res, "difficulty" );
if ( key ) if ( key )
{ {
if ( json_is_object( key ) ) if ( json_is_object( key ) )
key = json_object_get( key, "proof-of-work" ); key = json_object_get( key, "proof-of-work" );
if ( json_is_real( key ) ) if ( json_is_real( key ) )
net_diff = json_real_value( key ); difficulty = json_real_value( key );
} }
key = json_object_get( res, "networkhashps" ); key = json_object_get( res, "networkhashps" );
@@ -498,12 +493,13 @@ static bool get_mininginfo( CURL *curl, struct work *work )
net_blocks = json_integer_value( key ); net_blocks = json_integer_value( key );
if ( opt_debug ) if ( opt_debug )
applog(LOG_INFO,"Mining info: diff %.5g, net_hashrate %f, height %d", applog( LOG_INFO,"getmininginfo: difficulty %.5g, networkhashps %.5g, blocks %d", difficulty, net_hashrate, net_blocks );
net_diff, net_hashrate, net_blocks );
if ( !work->height ) if ( !work->height )
{ {
// complete missing data from getwork // complete missing data from getwork
if ( opt_debug )
applog( LOG_DEBUG, "work height set by getmininginfo" );
work->height = (uint32_t) net_blocks + 1; work->height = (uint32_t) net_blocks + 1;
if ( work->height > g_work.height ) if ( work->height > g_work.height )
restart_threads(); restart_threads();
@@ -535,9 +531,8 @@ 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;
int i, n; int i, n;
// Segwit BEGIN
bool segwit = false; bool segwit = false;
tmp = json_object_get( val, "rules" ); tmp = json_object_get( val, "rules" );
if ( tmp && json_is_array( tmp ) ) if ( tmp && json_is_array( tmp ) )
{ {
@@ -555,7 +550,6 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
} }
} }
} }
// Segwit END
tmp = json_object_get( val, "mutable" ); tmp = json_object_get( val, "mutable" );
if ( tmp && json_is_array( tmp ) ) if ( tmp && json_is_array( tmp ) )
@@ -713,12 +707,7 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
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;
// Segwit BEGIN
//cbtx[cbtx_size++] = 1; /* out-counter */
cbtx[cbtx_size++] = segwit ? 2 : 1; /* out-counter */ cbtx[cbtx_size++] = segwit ? 2 : 1; /* out-counter */
// Segwit END
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;
@@ -726,7 +715,6 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
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;
// Segwit BEGIN
if ( segwit ) if ( segwit )
{ {
unsigned char (*wtree)[32] = calloc(tx_count + 2, 32); unsigned char (*wtree)[32] = calloc(tx_count + 2, 32);
@@ -761,12 +749,11 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
for ( i = 0; i < n; i++ ) for ( i = 0; i < n; i++ )
sha256d( wtree[i], wtree[2*i], 64 ); sha256d( wtree[i], wtree[2*i], 64 );
} }
memset( wtree[1], 0, 32 ); /* witness reserved value = 0 */ memset( wtree[1], 0, 32 ); // witness reserved value = 0
sha256d( cbtx+cbtx_size, wtree[0], 64 ); sha256d( cbtx+cbtx_size, wtree[0], 64 );
cbtx_size += 32; cbtx_size += 32;
free( wtree ); free( wtree );
} }
// Segwit END
le32enc( (uint32_t *)( cbtx+cbtx_size ), 0 ); /* lock time */ le32enc( (uint32_t *)( cbtx+cbtx_size ), 0 ); /* lock time */
cbtx_size += 4; cbtx_size += 4;
@@ -785,11 +772,9 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
xsig_len += n; xsig_len += n;
} }
else else
{
applog( LOG_WARNING, applog( LOG_WARNING,
"Signature does not fit in coinbase, skipping" ); "Signature does not fit in coinbase, skipping" );
} }
}
tmp = json_object_get( val, "coinbaseaux" ); tmp = json_object_get( val, "coinbaseaux" );
if ( tmp && json_is_object( tmp ) ) if ( tmp && json_is_object( tmp ) )
{ {
@@ -815,8 +800,8 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
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
cbtx[41] + 2 + xsig_len > 100 ? 0 : 2; ? 1 : 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;
@@ -843,7 +828,6 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
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;
// Segwit BEGIN
if ( segwit ) if ( segwit )
{ {
const char *txid = json_string_value( json_object_get( tmp, "txid" ) ); const char *txid = json_string_value( json_object_get( tmp, "txid" ) );
@@ -856,8 +840,6 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
} }
else else
{ {
// Segwit END
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 ) )
{ {
@@ -867,10 +849,7 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
} }
sha256d( merkle_tree[1 + i], tx, tx_size ); sha256d( merkle_tree[1 + i], tx, tx_size );
free( tx ); free( tx );
// Segwit BEGIN
} }
// Segwit END
if ( !submit_coinbase ) if ( !submit_coinbase )
strcat( work->txs, tx_hex ); strcat( work->txs, tx_hex );
@@ -1080,12 +1059,11 @@ void report_summary_log( bool force )
timeval_subtract( &et, &now, &start_time ); timeval_subtract( &et, &now, &start_time );
timeval_subtract( &uptime, &total_hashes_time, &session_start ); timeval_subtract( &uptime, &total_hashes_time, &session_start );
double share_time = (double)et.tv_sec + (double)et.tv_usec / 1e6; double share_time = (double)et.tv_sec + (double)et.tv_usec * 1e-6;
double ghrate = safe_div( total_hashes, (double)uptime.tv_sec, 0. ); double ghrate = safe_div( total_hashes, (double)uptime.tv_sec, 0. );
double target_diff = exp32 * last_targetdiff; double target_diff = exp32 * last_targetdiff;
double shrate = safe_div( target_diff * (double)(accepts), double shrate = safe_div( target_diff * (double)(accepts),
share_time, 0. ); share_time, 0. );
// global_hashrate = ghrate;
double sess_hrate = safe_div( exp32 * norm_diff_sum, double sess_hrate = safe_div( exp32 * norm_diff_sum,
(double)uptime.tv_sec, 0. ); (double)uptime.tv_sec, 0. );
double submit_rate = safe_div( (double)submits * 60., share_time, 0. ); double submit_rate = safe_div( (double)submits * 60., share_time, 0. );
@@ -1106,7 +1084,7 @@ void report_summary_log( bool force )
applog2( LOG_NOTICE, "Periodic Report %s %s", et_str, upt_str ); applog2( LOG_NOTICE, "Periodic Report %s %s", et_str, upt_str );
applog2( LOG_INFO, "Share rate %.2f/min %.2f/min", applog2( LOG_INFO, "Share rate %.2f/min %.2f/min",
submit_rate, safe_div( (double)submitted_share_count*60., submit_rate, safe_div( (double)submitted_share_count*60.,
( (double)uptime.tv_sec + (double)uptime.tv_usec / 1e6 ), 0. ) ); ( (double)uptime.tv_sec + (double)uptime.tv_usec * 1e-6 ), 0. ) );
applog2( LOG_INFO, "Hash rate %7.2f%sh/s %7.2f%sh/s (%.2f%sh/s)", applog2( LOG_INFO, "Hash rate %7.2f%sh/s %7.2f%sh/s (%.2f%sh/s)",
shrate, shr_units, sess_hrate, sess_hr_units, ghrate, ghr_units ); shrate, shr_units, sess_hrate, sess_hr_units, ghrate, ghr_units );
@@ -1553,7 +1531,6 @@ const char *getwork_req =
#define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]" #define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]"
// Segwit BEGIN
#define GBT_RULES "[\"segwit\"]" #define GBT_RULES "[\"segwit\"]"
static const char *gbt_req = static const char *gbt_req =
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": " "{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
@@ -1562,16 +1539,6 @@ const char *gbt_lp_req =
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": " "{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
GBT_CAPABILITIES ", \"rules\": " GBT_RULES ", \"longpollid\": \"%s\"}], \"id\":0}\r\n"; GBT_CAPABILITIES ", \"rules\": " GBT_RULES ", \"longpollid\": \"%s\"}], \"id\":0}\r\n";
/*
static const char *gbt_req =
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
GBT_CAPABILITIES "}], \"id\":0}\r\n";
const char *gbt_lp_req =
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
GBT_CAPABILITIES ", \"longpollid\": \"%s\"}], \"id\":0}\r\n";
*/
// Segwit END
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;
@@ -1649,6 +1616,11 @@ start:
applog( LOG_BLUE, "New Block %d, Net Diff %.5g, Ntime %08x", applog( LOG_BLUE, "New Block %d, Net Diff %.5g, Ntime %08x",
work->height, net_diff, work->height, net_diff,
work->data[ algo_gate.ntime_index ] ); work->data[ algo_gate.ntime_index ] );
}
else if ( memcmp( &work->data[1], &g_work.data[1], 32 ) )
applog( LOG_BLUE, "New Work: Block %d, Net Diff %.5g, Ntime %08x",
work->height, net_diff,
work->data[ algo_gate.ntime_index ] );
if ( !opt_quiet ) if ( !opt_quiet )
{ {
@@ -1684,11 +1656,6 @@ start:
miner_hr, miner_hr_units, miner_ttf, net_hr, miner_hr, miner_hr_units, miner_ttf, net_hr,
net_hr_units, net_ttf ); net_hr_units, net_ttf );
} }
} // work->height > last_block_height
else if ( memcmp( &work->data[1], &g_work.data[1], 32 ) )
applog( LOG_BLUE, "New Work: Block %d, Net Diff %.5g, Ntime %08x",
work->height, net_diff,
work->data[ algo_gate.ntime_index ] );
} // rc } // rc
return rc; return rc;
@@ -1899,8 +1866,8 @@ bool submit_solution( struct work *work, const void *hash,
struct thr_info *thr ) struct thr_info *thr )
{ {
// Job went stale during hashing of a valid share. // Job went stale during hashing of a valid share.
if ( !opt_quiet && work_restart[ thr->id ].restart ) // if ( !opt_quiet && work_restart[ thr->id ].restart )
applog( LOG_INFO, CL_LBL "Share may be stale, submitting anyway..." CL_N ); // applog( LOG_INFO, CL_LBL "Share may be stale, submitting anyway..." CL_N );
work->sharediff = hash_to_diff( hash ); work->sharediff = hash_to_diff( hash );
if ( likely( submit_work( thr, work ) ) ) if ( likely( submit_work( thr, work ) ) )
@@ -1918,14 +1885,22 @@ bool submit_solution( struct work *work, const void *hash,
if ( !opt_quiet ) if ( !opt_quiet )
{ {
if ( have_stratum ) if ( have_stratum )
{
applog( LOG_INFO, "%d Submitted Diff %.5g, Block %d, Job %s", applog( LOG_INFO, "%d Submitted Diff %.5g, Block %d, Job %s",
submitted_share_count, work->sharediff, work->height, submitted_share_count, work->sharediff, work->height,
work->job_id ); work->job_id );
if ( opt_debug && opt_extranonce )
{
unsigned char *xnonce2str = abin2hex( work->xnonce2,
work->xnonce2_len );
applog( LOG_INFO, "Xnonce2 %s", xnonce2str );
free( xnonce2str );
}
}
else else
applog( LOG_INFO, "%d Submitted Diff %.5g, Block %d, Ntime %08x", applog( LOG_INFO, "%d Submitted Diff %.5g, Block %d, Ntime %08x",
submitted_share_count, work->sharediff, work->height, submitted_share_count, work->sharediff, work->height,
work->data[ algo_gate.ntime_index ] ); work->data[ algo_gate.ntime_index ] );
}
if ( opt_debug ) if ( opt_debug )
{ {
@@ -1933,17 +1908,11 @@ bool submit_solution( struct work *work, const void *hash,
uint32_t* t = (uint32_t*)work->target; uint32_t* t = (uint32_t*)work->target;
uint32_t* d = (uint32_t*)work->data; uint32_t* d = (uint32_t*)work->data;
unsigned char *xnonce2str = abin2hex( work->xnonce2, applog( LOG_INFO, "Data[ 0: 9]: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9] );
work->xnonce2_len ); applog( LOG_INFO, "Data[10:19]: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x", d[10],d[11],d[12],d[13],d[14],d[15],d[16],d[17],d[18],d[19] );
applog(LOG_INFO,"Thread %d, Nonce %08x, Xnonce2 %s", thr->id, applog( LOG_INFO, "Hash[ 7: 0]: %08x %08x %08x %08x %08x %08x %08x %08x", h[7],h[6],h[5],h[4],h[3],h[2],h[1],h[0] );
work->data[ algo_gate.nonce_index ], xnonce2str ); applog( LOG_INFO, "Targ[ 7: 0]: %08x %08x %08x %08x %08x %08x %08x %08x", t[7],t[6],t[5],t[4],t[3],t[2],t[1],t[0] );
free( xnonce2str ); }
applog(LOG_INFO,"Data[0:19]: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9] );
applog(LOG_INFO," : %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x", d[10],d[11],d[12],d[13],d[14],d[15],d[16],d[17],d[18],d[19]);
applog(LOG_INFO,"Hash[7:0]: %08x %08x %08x %08x %08x %08x %08x %08x",
h[7],h[6],h[5],h[4],h[3],h[2],h[1],h[0]);
applog(LOG_INFO,"Targ[7:0]: %08x %08x %08x %08x %08x %08x %08x %08x",
t[7],t[6],t[5],t[4],t[3],t[2],t[1],t[0]);
} }
return true; return true;
} }
@@ -2019,33 +1988,6 @@ void set_work_data_big_endian( struct work *work )
be32enc( work->data + i, work->data[i] ); be32enc( work->data + i, work->data[i] );
} }
// calculate net diff from nbits.
double std_calc_network_diff( struct work* work )
{
uint32_t nbits = work->data[ algo_gate.nbits_index ];
uint32_t shift = nbits & 0xff;
uint32_t bits = bswap_32( nbits ) & 0x00ffffff;
/*
// sample for diff 43.281 : 1c05ea29
// todo: endian reversed on longpoll could be zr5 specific...
int nbits_index = algo_gate.nbits_index;
uint32_t nbits = have_longpoll ? work->data[ nbits_index]
: swab32( work->data[ nbits_index ] );
uint32_t bits = ( nbits & 0xffffff );
int16_t shift = ( swab32(nbits) & 0xff ); // 0x1c = 28
*/
int m;
long double d = (long double)0x0000ffff / (long double)bits;
for ( m = shift; m < 29; m++ )
d *= 256.0;
for ( m = 29; m < shift; m++ )
d /= 256.0;
if ( opt_debug_diff )
applog(LOG_DEBUG, "net diff: %8f -> shift %u, bits %08x", (double)d, shift, bits);
return (double)d;
}
void std_get_new_work( struct work* work, struct work* g_work, int thr_id, void std_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t *end_nonce_ptr ) uint32_t *end_nonce_ptr )
{ {
@@ -2069,17 +2011,6 @@ void std_get_new_work( struct work* work, struct work* g_work, int thr_id,
++(*nonceptr); ++(*nonceptr);
} }
bool std_ready_to_mine( struct work* work, struct stratum_ctx* stratum,
int thr_id )
{
if ( have_stratum && !work->data[0] && !opt_benchmark )
{
sleep(1);
return false;
}
return true;
}
static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work ) static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
{ {
bool new_job; bool new_job;
@@ -2096,7 +2027,7 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
g_work->xnonce2 = (uchar*) realloc( g_work->xnonce2, sctx->xnonce2_size ); g_work->xnonce2 = (uchar*) realloc( g_work->xnonce2, sctx->xnonce2_size );
memcpy( g_work->xnonce2, sctx->job.xnonce2, sctx->xnonce2_size ); memcpy( g_work->xnonce2, sctx->job.xnonce2, sctx->xnonce2_size );
algo_gate.build_extraheader( g_work, sctx ); algo_gate.build_extraheader( g_work, sctx );
net_diff = algo_gate.calc_network_diff( g_work ); net_diff = nbits_to_diff( g_work->data[ algo_gate.nbits_index ] );
algo_gate.set_work_data_endian( g_work ); algo_gate.set_work_data_endian( g_work );
g_work->height = sctx->block_height; g_work->height = sctx->block_height;
g_work->targetdiff = sctx->job.diff g_work->targetdiff = sctx->job.diff
@@ -2133,7 +2064,7 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
else if ( g_work->job_id && new_job ) else if ( g_work->job_id && new_job )
applog( LOG_BLUE, "New Work: Block %d, Net diff %.5g, Job %s", applog( LOG_BLUE, "New Work: Block %d, Net diff %.5g, Job %s",
sctx->block_height, net_diff, g_work->job_id ); sctx->block_height, net_diff, g_work->job_id );
else if ( opt_debug ) else if ( !opt_quiet )
{ {
unsigned char *xnonce2str = bebin2hex( g_work->xnonce2, unsigned char *xnonce2str = bebin2hex( g_work->xnonce2,
g_work->xnonce2_len ); g_work->xnonce2_len );
@@ -2146,8 +2077,6 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
if ( ( stratum_diff != sctx->job.diff ) if ( ( stratum_diff != sctx->job.diff )
|| ( last_block_height != sctx->block_height ) ) || ( last_block_height != sctx->block_height ) )
{ {
static bool multipool = false;
if ( stratum.block_height < last_block_height ) multipool = true;
if ( unlikely( !session_first_block ) ) if ( unlikely( !session_first_block ) )
session_first_block = stratum.block_height; session_first_block = stratum.block_height;
last_block_height = stratum.block_height; last_block_height = stratum.block_height;
@@ -2155,6 +2084,7 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
last_targetdiff = g_work->targetdiff; last_targetdiff = g_work->targetdiff;
if ( lowest_share < last_targetdiff ) if ( lowest_share < last_targetdiff )
lowest_share = 9e99; lowest_share = 9e99;
}
if ( !opt_quiet ) if ( !opt_quiet )
{ {
@@ -2167,6 +2097,9 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
char hr_units[4] = {0}; char hr_units[4] = {0};
char block_ttf[32]; char block_ttf[32];
char share_ttf[32]; char share_ttf[32];
static bool multipool = false;
if ( stratum.block_height < last_block_height ) multipool = true;
sprintf_et( block_ttf, nd / hr ); sprintf_et( block_ttf, nd / hr );
sprintf_et( share_ttf, ( g_work->targetdiff * exp32 ) / hr ); sprintf_et( share_ttf, ( g_work->targetdiff * exp32 ) / hr );
@@ -2179,12 +2112,11 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
struct timeval now, et; struct timeval now, et;
gettimeofday( &now, NULL ); gettimeofday( &now, NULL );
timeval_subtract( &et, &now, &session_start ); timeval_subtract( &et, &now, &session_start );
uint64_t net_ttf = uint64_t net_ttf = safe_div( et.tv_sec,
( last_block_height - session_first_block ) == 0 ? 0 last_block_height - session_first_block, 0 );
: et.tv_sec / ( last_block_height - session_first_block );
if ( net_diff > 0. && net_ttf ) if ( net_diff > 0. && net_ttf )
{ {
double net_hr = nd / net_ttf; double net_hr = safe_div( nd, net_ttf, 0. );
char net_hr_units[4] = {0}; char net_hr_units[4] = {0};
scale_hash_for_display ( &net_hr, net_hr_units ); scale_hash_for_display ( &net_hr, net_hr_units );
applog2( LOG_INFO, "Net hash rate (est) %.2f %sh/s", applog2( LOG_INFO, "Net hash rate (est) %.2f %sh/s",
@@ -2193,20 +2125,6 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
} }
} // hr > 0 } // hr > 0
} // !quiet } // !quiet
} // new diff/block
/*
if ( new_job && !( opt_quiet || stratum_errors ) )
{
int mismatch = submitted_share_count - ( accepted_share_count
+ stale_share_count
+ rejected_share_count );
if ( mismatch )
applog( LOG_INFO,
CL_LBL "%d Submitted share pending, maybe stale" CL_N,
submitted_share_count );
}
*/
} }
static void *miner_thread( void *userdata ) static void *miner_thread( void *userdata )
@@ -2344,9 +2262,6 @@ static void *miner_thread( void *userdata )
} // do_this_thread } // do_this_thread
algo_gate.resync_threads( thr_id, &work ); algo_gate.resync_threads( thr_id, &work );
if ( unlikely( !algo_gate.ready_to_mine( &work, &stratum, thr_id ) ) )
continue;
// conditional mining // conditional mining
if ( unlikely( !wanna_mine( thr_id ) ) ) if ( unlikely( !wanna_mine( thr_id ) ) )
{ {

11
miner.h
View File

@@ -330,7 +330,7 @@ extern void cbin2hex(char *out, const char *in, size_t len);
void bin2hex( char *s, const unsigned char *p, size_t len ); void bin2hex( char *s, const unsigned char *p, size_t len );
char *abin2hex( const unsigned char *p, size_t len ); char *abin2hex( const unsigned char *p, size_t len );
char *bebin2hex( const unsigned char *p, size_t len ); char *bebin2hex( const unsigned char *p, size_t len );
bool hex2bin( unsigned char *p, const char *hexstr, size_t len ); bool hex2bin( unsigned char *p, const char *hexstr, const size_t len );
bool jobj_binary( const json_t *obj, const char *key, void *buf, bool jobj_binary( const json_t *obj, const char *key, void *buf,
size_t buflen ); size_t buflen );
int varint_encode( unsigned char *p, uint64_t n ); int varint_encode( unsigned char *p, uint64_t n );
@@ -346,10 +346,7 @@ extern void memrev(unsigned char *p, size_t len);
// number of hashes. // number of hashes.
// //
// https://en.bitcoin.it/wiki/Difficulty // https://en.bitcoin.it/wiki/Difficulty
//
// hash = diff * 2**32 // hash = diff * 2**32
//
// diff_to_hash = 2**32 = 0x100000000 = 4294967296 = exp32;
#define EXP16 65536. #define EXP16 65536.
#define EXP32 4294967296. #define EXP32 4294967296.
@@ -363,8 +360,9 @@ extern const long double exp160; // 2**160
bool fulltest( const uint32_t *hash, const uint32_t *target ); bool fulltest( const uint32_t *hash, const uint32_t *target );
bool valid_hash( const void*, const void* ); bool valid_hash( const void*, const void* );
double hash_to_diff( const void* ); extern double hash_to_diff( const void* );
extern void diff_to_hash( uint32_t*, const double ); extern void diff_to_hash( uint32_t*, const double );
extern double nbits_to_diff( uint32_t );
double hash_target_ratio( uint32_t* hash, uint32_t* target ); double hash_target_ratio( uint32_t* hash, uint32_t* target );
void work_set_target_ratio( struct work* work, const void *hash ); void work_set_target_ratio( struct work* work, const void *hash );
@@ -553,7 +551,6 @@ enum algos {
ALGO_BMW, ALGO_BMW,
ALGO_BMW512, ALGO_BMW512,
ALGO_C11, ALGO_C11,
ALGO_DECRED,
ALGO_DEEP, ALGO_DEEP,
ALGO_DMD_GR, ALGO_DMD_GR,
ALGO_GROESTL, ALGO_GROESTL,
@@ -647,7 +644,6 @@ static const char* const algo_names[] = {
"bmw", "bmw",
"bmw512", "bmw512",
"c11", "c11",
"decred",
"deep", "deep",
"dmd-gr", "dmd-gr",
"groestl", "groestl",
@@ -808,7 +804,6 @@ Options:\n\
bmw BMW 256\n\ bmw BMW 256\n\
bmw512 BMW 512\n\ bmw512 BMW 512\n\
c11 Chaincoin\n\ c11 Chaincoin\n\
decred Blake256r14dcr\n\
deep Deepcoin (DCN)\n\ deep Deepcoin (DCN)\n\
dmd-gr Diamond\n\ dmd-gr Diamond\n\
groestl Groestl coin\n\ groestl Groestl coin\n\

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,8 @@
// //
// "_mm256_shuffle_epi8" and "_mm256_alignr_epi8" are restricted to 128 bit // "_mm256_shuffle_epi8" and "_mm256_alignr_epi8" are restricted to 128 bit
// lanes and data can't cross the 128 bit lane boundary. // lanes and data can't cross the 128 bit lane boundary.
// Full width byte shuffle is available with AVX512VL using the mask version
// with a full mask (-1).
// Instructions that can move data across 128 bit lane boundary incur a // Instructions that can move data across 128 bit lane boundary incur a
// performance penalty over those that can't. // performance penalty over those that can't.
// Some usage of index vectors may be encoded as if full vector shuffles are // Some usage of index vectors may be encoded as if full vector shuffles are
@@ -422,8 +424,7 @@ static inline __m256i mm256_shuflr128_x8( const __m256i v, const int c )
#define mm256_shuflr64_24( v ) _mm256_ror_epi64( v, 24 ) #define mm256_shuflr64_24( v ) _mm256_ror_epi64( v, 24 )
#else #else
#define mm256_shuflr64_24( v ) \ #define mm256_shuflr64_24( v ) \
_mm256_shuffle_epi8( v, _mm256_set_epi64x( \ _mm256_shuffle_epi8( v, m256_const2_64( \
0x0a09080f0e0d0c0b, 0x0201000706050403, \
0x0a09080f0e0d0c0b, 0x0201000706050403 ) ) 0x0a09080f0e0d0c0b, 0x0201000706050403 ) )
#endif #endif
@@ -431,8 +432,7 @@ static inline __m256i mm256_shuflr128_x8( const __m256i v, const int c )
#define mm256_shuflr64_16( v ) _mm256_ror_epi64( v, 16 ) #define mm256_shuflr64_16( v ) _mm256_ror_epi64( v, 16 )
#else #else
#define mm256_shuflr64_16( v ) \ #define mm256_shuflr64_16( v ) \
_mm256_shuffle_epi8( v, _mm256_set_epi64x( \ _mm256_shuffle_epi8( v, m256_const2_64( \
0x09080f0e0d0c0b0a, 0x0100070605040302, \
0x09080f0e0d0c0b0a, 0x0100070605040302 ) ) 0x09080f0e0d0c0b0a, 0x0100070605040302 ) )
#endif #endif
@@ -440,8 +440,7 @@ static inline __m256i mm256_shuflr128_x8( const __m256i v, const int c )
#define mm256_swap32_16( v ) _mm256_ror_epi32( v, 16 ) #define mm256_swap32_16( v ) _mm256_ror_epi32( v, 16 )
#else #else
#define mm256_swap32_16( v ) \ #define mm256_swap32_16( v ) \
_mm256_shuffle_epi8( v, _mm256_set_epi64x( \ _mm256_shuffle_epi8( v, m256_const2_64( \
0x0d0c0f0e09080b0a, 0x0504070601000302, \
0x0d0c0f0e09080b0a, 0x0504070601000302 ) ) 0x0d0c0f0e09080b0a, 0x0504070601000302 ) )
#endif #endif
#define mm256_shuflr32_16 mm256_swap32_16 #define mm256_shuflr32_16 mm256_swap32_16
@@ -456,35 +455,24 @@ static inline __m256i mm256_shuflr128_x8( const __m256i v, const int c )
0x0c0f0e0d080b0a09, 0x0407060500030201 ) ) 0x0c0f0e0d080b0a09, 0x0407060500030201 ) )
#endif #endif
// NOTE: _mm256_shuffle_epi8, like most shuffles, is restricted to 128 bit
// lanes. AVX512, however, supports full vector 8 bit shuffle. The AVX512VL +
// AVX512BW intrinsic _mm256_mask_shuffle_epi8 with a NULL mask, can be used if
// needed for a shuffle that crosses 128 bit lanes. BSWAP doesn't therefore the
// AVX2 version will work here. The bswap control vector is coded to work
// with both versions, bit 4 is ignored in AVX2.
// Reverse byte order in elements, endian bswap. // Reverse byte order in elements, endian bswap.
#define mm256_bswap_64( v ) \ #define mm256_bswap_64( v ) \
_mm256_shuffle_epi8( v, \ _mm256_shuffle_epi8( v, \
m256_const_64( 0x18191a1b1c1d1e1f, 0x1011121314151617, \ m256_const2_64( 0x08090a0b0c0d0e0f, 0x0001020304050607 ) )
0x08090a0b0c0d0e0f, 0x0001020304050607 ) )
#define mm256_bswap_32( v ) \ #define mm256_bswap_32( v ) \
_mm256_shuffle_epi8( v, \ _mm256_shuffle_epi8( v, \
m256_const_64( 0x1c1d1e1f18191a1b, 0x1415161710111213, \ m256_const2_64( 0x0c0d0e0f08090a0b, 0x0405060700010203 ) )
0x0c0d0e0f08090a0b, 0x0405060700010203 ) )
#define mm256_bswap_16( v ) \ #define mm256_bswap_16( v ) \
_mm256_shuffle_epi8( v, \ _mm256_shuffle_epi8( v, \
m256_const_64( 0x1e1f1c1d1a1b1819, 0x1617141512131011, \ m256_const2_64( 0x0e0f0c0d0a0b0809, 0x0607040502030001, ) )
0x0e0f0c0d0a0b0809, 0x0607040502030001, ) )
// Source and destination are pointers, may point to same memory. // Source and destination are pointers, may point to same memory.
// 8 byte qword * 8 qwords * 4 lanes = 256 bytes // 8 byte qword * 8 qwords * 4 lanes = 256 bytes
#define mm256_block_bswap_64( d, s ) do \ #define mm256_block_bswap_64( d, s ) do \
{ \ { \
__m256i ctl = m256_const_64( 0x18191a1b1c1d1e1f, 0x1011121314151617, \ __m256i ctl = m256_const2_64( 0x08090a0b0c0d0e0f, 0x0001020304050607 ) ; \
0x08090a0b0c0d0e0f, 0x0001020304050607 ) ; \
casti_m256i( d, 0 ) = _mm256_shuffle_epi8( casti_m256i( s, 0 ), ctl ); \ casti_m256i( d, 0 ) = _mm256_shuffle_epi8( casti_m256i( s, 0 ), ctl ); \
casti_m256i( d, 1 ) = _mm256_shuffle_epi8( casti_m256i( s, 1 ), ctl ); \ casti_m256i( d, 1 ) = _mm256_shuffle_epi8( casti_m256i( s, 1 ), ctl ); \
casti_m256i( d, 2 ) = _mm256_shuffle_epi8( casti_m256i( s, 2 ), ctl ); \ casti_m256i( d, 2 ) = _mm256_shuffle_epi8( casti_m256i( s, 2 ), ctl ); \
@@ -498,8 +486,7 @@ static inline __m256i mm256_shuflr128_x8( const __m256i v, const int c )
// 4 byte dword * 8 dwords * 8 lanes = 256 bytes // 4 byte dword * 8 dwords * 8 lanes = 256 bytes
#define mm256_block_bswap_32( d, s ) do \ #define mm256_block_bswap_32( d, s ) do \
{ \ { \
__m256i ctl = m256_const_64( 0x1c1d1e1f18191a1b, 0x1415161710111213, \ __m256i ctl = m256_const2_64( 0x0c0d0e0f08090a0b, 0x0405060700010203 ); \
0x0c0d0e0f08090a0b, 0x0405060700010203 ); \
casti_m256i( d, 0 ) = _mm256_shuffle_epi8( casti_m256i( s, 0 ), ctl ); \ casti_m256i( d, 0 ) = _mm256_shuffle_epi8( casti_m256i( s, 0 ), ctl ); \
casti_m256i( d, 1 ) = _mm256_shuffle_epi8( casti_m256i( s, 1 ), ctl ); \ casti_m256i( d, 1 ) = _mm256_shuffle_epi8( casti_m256i( s, 1 ), ctl ); \
casti_m256i( d, 2 ) = _mm256_shuffle_epi8( casti_m256i( s, 2 ), ctl ); \ casti_m256i( d, 2 ) = _mm256_shuffle_epi8( casti_m256i( s, 2 ), ctl ); \

View File

@@ -412,16 +412,16 @@ static inline __m512i mm512_shuflr_x32( const __m512i v, const int n )
#define mm512_shuflr_16( v ) \ #define mm512_shuflr_16( v ) \
_mm512_permutexvar_epi16( m512_const_64( \ _mm512_permutexvar_epi16( m512_const_64( \
0x0000001F001E001D, 0x001C001B001A0019, \ 0x0000001F001E001D, 0x001C001B001A0019, \
0X0018001700160015, 0X0014001300120011, \ 0x0018001700160015, 0x0014001300120011, \
0X0010000F000E000D, 0X000C000B000A0009, \ 0x0010000F000E000D, 0x000C000B000A0009, \
0X0008000700060005, 0X0004000300020001 ), v ) 0x0008000700060005, 0x0004000300020001 ), v )
#define mm512_shufll_16( v ) \ #define mm512_shufll_16( v ) \
_mm512_permutexvar_epi16( m512_const_64( \ _mm512_permutexvar_epi16( m512_const_64( \
0x001E001D001C001B, 0x001A001900180017, \ 0x001E001D001C001B, 0x001A001900180017, \
0X0016001500140013, 0X001200110010000F, \ 0x0016001500140013, 0x001200110010000F, \
0X000E000D000C000B, 0X000A000900080007, \ 0x000E000D000C000B, 0x000A000900080007, \
0X0006000500040003, 0X000200010000001F ), v ) 0x0006000500040003, 0x000200010000001F ), v )
#define mm512_shuflr_8( v ) \ #define mm512_shuflr_8( v ) \
_mm512_shuffle_epi8( v, m512_const_64( \ _mm512_shuffle_epi8( v, m512_const_64( \

245
util.c
View File

@@ -44,28 +44,22 @@
#include <libgen.h> #include <libgen.h>
#endif #endif
//#include "miner.h"
#include "elist.h" #include "elist.h"
#include "algo-gate-api.h" #include "algo-gate-api.h"
#include "algo/sha/sha256d.h" #include "algo/sha/sha256d.h"
//extern pthread_mutex_t stats_lock;
struct data_buffer {
void *buf;
size_t len;
};
struct upload_buffer {
const void *buf;
size_t len;
size_t pos;
};
struct header_info { struct header_info {
char *lp_path; char *lp_path;
char *reason; char *reason;
char *stratum_url; char *stratum_url;
size_t content_length;
};
struct data_buffer {
void *buf;
size_t len;
size_t allocated;
struct header_info *headers;
}; };
struct tq_ent { struct tq_ent {
@@ -127,7 +121,6 @@ void applog2( int prio, const char *fmt, ... )
int len; int len;
// struct tm tm; // struct tm tm;
// time_t now = time(NULL); // time_t now = time(NULL);
// localtime_r(&now, &tm); // localtime_r(&now, &tm);
switch ( prio ) switch ( prio )
@@ -395,67 +388,53 @@ static void databuf_free(struct data_buffer *db)
static size_t all_data_cb(const void *ptr, size_t size, size_t nmemb, static size_t all_data_cb(const void *ptr, size_t size, size_t nmemb,
void *user_data) void *user_data)
{ {
struct data_buffer *db = (struct data_buffer *) user_data; struct data_buffer *db = user_data;
size_t len = size * nmemb; size_t len = size * nmemb;
size_t oldlen, newlen; size_t newalloc, reqalloc;
void *newmem; void *newmem;
static const unsigned char zero = 0; static const unsigned char zero = 0;
static const size_t max_realloc_increase = 8 * 1024 * 1024;
static const size_t initial_alloc = 16 * 1024;
oldlen = db->len; /* minimum required allocation size */
newlen = oldlen + len; reqalloc = db->len + len + 1;
newmem = realloc(db->buf, newlen + 1); if (reqalloc > db->allocated) {
if (db->len > 0) {
newalloc = db->allocated * 2;
} else {
if (db->headers->content_length > 0)
newalloc = db->headers->content_length + 1;
else
newalloc = initial_alloc;
}
if (db->headers->content_length == 0) {
/* limit the maximum buffer increase */
if (newalloc - db->allocated > max_realloc_increase)
newalloc = db->allocated + max_realloc_increase;
}
/* ensure we have a big enough allocation */
if (reqalloc > newalloc)
newalloc = reqalloc;
newmem = realloc(db->buf, newalloc);
if (!newmem) if (!newmem)
return 0; return 0;
db->buf = newmem; db->buf = newmem;
db->len = newlen; db->allocated = newalloc;
memcpy((uchar*) db->buf + oldlen, ptr, len); }
memcpy((uchar*) db->buf + newlen, &zero, 1); /* null terminate */
memcpy(db->buf + db->len, ptr, len); /* append new data */
memcpy(db->buf + db->len + len, &zero, 1); /* null terminate */
db->len += len;
return len; return len;
} }
static size_t upload_data_cb(void *ptr, size_t size, size_t nmemb,
void *user_data)
{
struct upload_buffer *ub = (struct upload_buffer *) user_data;
size_t len = size * nmemb;
if (len > ub->len - ub->pos)
len = ub->len - ub->pos;
if (len) {
memcpy(ptr, ((uchar*)ub->buf) + ub->pos, len);
ub->pos += len;
}
return len;
}
#if LIBCURL_VERSION_NUM >= 0x071200
static int seek_data_cb(void *user_data, curl_off_t offset, int origin)
{
struct upload_buffer *ub = (struct upload_buffer *) user_data;
switch (origin) {
case SEEK_SET:
ub->pos = (size_t) offset;
break;
case SEEK_CUR:
ub->pos += (size_t) offset;
break;
case SEEK_END:
ub->pos = ub->len + (size_t) offset;
break;
default:
return 1; /* CURL_SEEKFUNC_FAIL */
}
return 0; /* CURL_SEEKFUNC_OK */
}
#endif
static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data) static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
{ {
struct header_info *hi = (struct header_info *) user_data; struct header_info *hi = (struct header_info *) user_data;
@@ -505,6 +484,9 @@ static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
val = NULL; val = NULL;
} }
if (!strcasecmp("Content-Length", key))
hi->content_length = strtoul(val, NULL, 10);
out: out:
free(key); free(key);
free(val); free(val);
@@ -564,48 +546,38 @@ json_t *json_rpc_call(CURL *curl, const char *url,
int rc; int rc;
long http_rc; long http_rc;
struct data_buffer all_data = {0}; struct data_buffer all_data = {0};
struct upload_buffer upload_data;
char *json_buf; char *json_buf;
json_error_t err; json_error_t err;
struct curl_slist *headers = NULL; struct curl_slist *headers = NULL;
char len_hdr[64];
char curl_err_str[CURL_ERROR_SIZE] = { 0 }; char curl_err_str[CURL_ERROR_SIZE] = { 0 };
long timeout = (flags & JSON_RPC_LONGPOLL) ? opt_timeout : 30; long timeout = (flags & JSON_RPC_LONGPOLL) ? opt_timeout : 30;
struct header_info hi = {0}; struct header_info hi = {0};
all_data.headers = &hi;
/* it is assumed that 'curl' is freshly [re]initialized at this pt */ /* it is assumed that 'curl' is freshly [re]initialized at this pt */
if (opt_protocol) if (opt_protocol) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
if (opt_cert) if (opt_cert) curl_easy_setopt(curl, CURLOPT_CAINFO, opt_cert);
curl_easy_setopt(curl, CURLOPT_CAINFO, opt_cert);
//
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_ENCODING, ""); curl_easy_setopt(curl, CURLOPT_ENCODING, "");
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_data_cb);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_data);
#if LIBCURL_VERSION_NUM >= 0x071200
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, &seek_data_cb);
curl_easy_setopt(curl, CURLOPT_SEEKDATA, &upload_data);
#endif
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
if (opt_redirect) if (opt_redirect) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hi); curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hi);
if (opt_proxy) { if (opt_proxy)
{
curl_easy_setopt(curl, CURLOPT_PROXY, opt_proxy); curl_easy_setopt(curl, CURLOPT_PROXY, opt_proxy);
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, opt_proxy_type); curl_easy_setopt(curl, CURLOPT_PROXYTYPE, opt_proxy_type);
} }
if (userpass) { if (userpass)
{
curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
} }
@@ -613,23 +585,16 @@ json_t *json_rpc_call(CURL *curl, const char *url,
if (flags & JSON_RPC_LONGPOLL) if (flags & JSON_RPC_LONGPOLL)
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb); curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb);
#endif #endif
curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, rpc_req);
if (opt_protocol) if (opt_protocol)
applog(LOG_DEBUG, "JSON protocol request:\n%s\n", rpc_req); applog(LOG_DEBUG, "JSON protocol request:\n%s\n", rpc_req);
upload_data.buf = rpc_req;
upload_data.len = strlen(rpc_req);
upload_data.pos = 0;
sprintf(len_hdr, "Content-Length: %lu",
(unsigned long) upload_data.len);
headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, len_hdr);
headers = curl_slist_append(headers, "User-Agent: " USER_AGENT); headers = curl_slist_append(headers, "User-Agent: " USER_AGENT);
headers = curl_slist_append(headers, "X-Mining-Extensions: longpoll reject-reason"); headers = curl_slist_append(headers, "X-Mining-Extensions: longpoll reject-reason");
//headers = curl_slist_append(headers, "Accept:"); /* disable Accept hdr*/ //headers = curl_slist_append(headers, "Accept:"); // disable Accept hdr
//headers = curl_slist_append(headers, "Expect:"); /* disable Expect hdr*/ //headers = curl_slist_append(headers, "Expect:"); // disable Expect hdr
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
@@ -791,7 +756,6 @@ void memrev(unsigned char *p, size_t len)
if ( len == 32 ) if ( len == 32 )
{ {
__m128i *pv = (__m128i*)p; __m128i *pv = (__m128i*)p;
__m128i t = mm128_bswap_128( pv[0] ); __m128i t = mm128_bswap_128( pv[0] );
pv[0] = mm128_bswap_128( pv[1] ); pv[0] = mm128_bswap_128( pv[1] );
pv[1] = t; pv[1] = t;
@@ -841,32 +805,42 @@ char *bebin2hex(const unsigned char *p, size_t len)
return s; return s;
} }
bool hex2bin(unsigned char *p, const char *hexstr, size_t len) bool hex2bin( unsigned char *p, const char *hexstr, const size_t len )
{ {
char hex_byte[3]; if( hexstr == NULL ) return false;
char *ep;
hex_byte[2] = '\0'; size_t hexstr_len = strlen( hexstr );
if( ( hexstr_len % 2 ) != 0 )
while (*hexstr && len) { {
if (!hexstr[1]) { applog( LOG_ERR, "hex2bin string truncated" );
applog(LOG_ERR, "hex2bin str truncated");
return false; return false;
} }
hex_byte[0] = hexstr[0]; size_t bin_len = hexstr_len / 2;
hex_byte[1] = hexstr[1]; if ( bin_len > len )
*p = (unsigned char) strtol(hex_byte, &ep, 16); {
if (*ep) { applog( LOG_ERR, "hex2bin buffer too small" );
applog(LOG_ERR, "hex2bin failed on '%s'", hex_byte);
return false; return false;
} }
p++;
hexstr += 2; memset( p, 0, len );
len--; size_t i = 0;
while ( i < hexstr_len )
{
char c = hexstr[i];
unsigned char nibble;
if ( c >= '0' && c <= '9' ) nibble = (c - '0');
else if ( c >= 'A' && c <= 'F' ) nibble = ( 10 + (c - 'A') );
else if ( c >= 'a' && c <= 'f' ) nibble = ( 10 + (c - 'a') );
else
{
applog( LOG_ERR, "hex2bin invalid hex" );
return false;
}
p[(i / 2)] |= (nibble << ( (1 - (i % 2) ) * 4) );
i++;
} }
return(!len) ? true : false; return true;
/* return (len == 0 && *hexstr == 0) ? true : false; */
} }
int varint_encode(unsigned char *p, uint64_t n) int varint_encode(unsigned char *p, uint64_t n)
@@ -1348,6 +1322,43 @@ inline bool valid_hash( const void *hash, const void *target )
#endif #endif
inline double nbits_to_diff( uint32_t nbits )
{
long double diff;
uint32_t shift = nbits & 0xff;
uint32_t bits = bswap_32( nbits ) & 0x00ffffff;
int shift_off = (int)shift - 29;
// diff = ( (2**16 -1) / ( 256**shift_off * bits )
// With uint128 byte shift is good for 16 <= shift <= 41. As unlikely
// as this may seem necessary, check just in case.
if ( shift_off >= -13 && shift_off <= 12 )
{ // fast
if ( shift_off == 0 )
diff = (long double)0xffff / (long double)bits;
else if ( shift_off < 0 ) // shift < 29
diff = (long double)( (uint128_t)0xffff << ( (-shift_off) *8 ) )
/ (long double)bits;
else // ( shift_off > 0 ) // shift > 29
diff = (long double)0xffff
/ (long double)( (uint128_t)bits << ( shift_off*8 ) );
}
else
{ // slow
int m;
diff = 0.;
for ( m = shift; m < 29; m++ ) diff *= 256.0;
for ( m = 29; m < shift; m++ ) diff /= 256.0;
}
if ( opt_debug )
applog( LOG_INFO, "nbits %08x: shift %u(%d), bits %06x, diff %8g",
nbits, shift, shift_off, bits, (double)diff );
return (double)diff;
}
#ifdef WIN32 #ifdef WIN32
#define socket_blocks() (WSAGetLastError() == WSAEWOULDBLOCK) #define socket_blocks() (WSAGetLastError() == WSAEWOULDBLOCK)
#else #else
@@ -1516,7 +1527,8 @@ out:
return sret; return sret;
} }
#if LIBCURL_VERSION_NUM >= 0x071101 #if LIBCURL_VERSION_NUM >= 0x071101 && LIBCURL_VERSION_NUM < 0x072d00
//#if LIBCURL_VERSION_NUM >= 0x071101
static curl_socket_t opensocket_grab_cb(void *clientp, curlsocktype purpose, static curl_socket_t opensocket_grab_cb(void *clientp, curlsocktype purpose,
struct curl_sockaddr *addr) struct curl_sockaddr *addr)
{ {
@@ -1584,7 +1596,8 @@ bool stratum_connect(struct stratum_ctx *sctx, const char *url)
#if LIBCURL_VERSION_NUM >= 0x070f06 #if LIBCURL_VERSION_NUM >= 0x070f06
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb); curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb);
#endif #endif
#if LIBCURL_VERSION_NUM >= 0x071101 #if LIBCURL_VERSION_NUM >= 0x071101 && LIBCURL_VERSION_NUM < 0x072d00
//#if LIBCURL_VERSION_NUM >= 0x071101
curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket_grab_cb); curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket_grab_cb);
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sctx->sock); curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sctx->sock);
#endif #endif
@@ -1598,7 +1611,10 @@ bool stratum_connect(struct stratum_ctx *sctx, const char *url)
return false; return false;
} }
#if LIBCURL_VERSION_NUM < 0x071101 #if LIBCURL_VERSION_NUM >= 0x072d00
curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sctx->sock);
#elif LIBCURL_VERSION_NUM < 0x071101
//#if LIBCURL_VERSION_NUM < 0x071101
/* CURLINFO_LASTSOCKET is broken on Win64; only use it as a last resort */ /* CURLINFO_LASTSOCKET is broken on Win64; only use it as a last resort */
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&sctx->sock); curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&sctx->sock);
#endif #endif
@@ -1894,7 +1910,8 @@ static uint32_t getblocheight(struct stratum_ctx *sctx)
// find 0xffff tag // find 0xffff tag
p = (uint8_t*) sctx->job.coinbase + 32; p = (uint8_t*) sctx->job.coinbase + 32;
m = p + 128; m = p + sctx->job.coinbase_size - 32 - 2;
// m = p + 128;
while (*p != 0xff && p < m) p++; while (*p != 0xff && p < m) p++;
while (*p == 0xff && p < m) p++; while (*p == 0xff && p < m) p++;
if (*(p-1) == 0xff && *(p-2) == 0xff) { if (*(p-1) == 0xff && *(p-2) == 0xff) {

View File

@@ -129,7 +129,7 @@ make clean || echo clean
# Native with CPU groups ennabled # Native with CPU groups ennabled
make clean || echo clean make clean || echo clean
rm -f config.status rm -f config.status
CFLAGS="-march=native $DEFAULT_CFLAGS" ./configure $CONFIGURE_ARGS CFLAGS="-march=native $DEFAULT_CFLAGS_OLD" ./configure $CONFIGURE_ARGS
make -j 8 make -j 8
strip -s cpuminer.exe strip -s cpuminer.exe