From cedcf4d0707380f24477c7a9f3771590c8c724c7 Mon Sep 17 00:00:00 2001 From: Jay D Dee Date: Fri, 28 Feb 2020 02:42:22 -0500 Subject: [PATCH] v3.12.4.5 --- RELEASE_NOTES | 14 ++- algo/scrypt/scrypt.c | 78 +++++++------ configure | 20 ++-- configure.ac | 2 +- cpu-miner.c | 260 ++++++++++++++++++++++++------------------- miner.h | 23 +++- util.c | 85 +++++++++----- 7 files changed, 288 insertions(+), 194 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 498b51d..2a187d8 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -65,7 +65,19 @@ If not what makes it happen or not happen? Change Log ---------- -v3.12.5 +v3.12.4.5 + +Issue #246: better stale share detection for getwork, and enhanced logging +of stale shares for stratum & getwork. + +Issue #251: fixed incorrect share difficulty and share ratio in share +result log. + +Changed submit log to include share diff and block height. + +Small cosmetic changes to logs. + +v3.12.4.4 Issue #246: Fixed net hashrate in getwork block log, removed duplicate getwork block log, diff --git a/algo/scrypt/scrypt.c b/algo/scrypt/scrypt.c index 2b66883..f6db6db 100644 --- a/algo/scrypt/scrypt.c +++ b/algo/scrypt/scrypt.c @@ -440,7 +440,8 @@ static bool scrypt_1024_1_1_256_4way(const uint32_t *input, for (i = 0; i < 20; i++) for (k = 0; k < 4; k++) W[4 * i + k] = input[k * 20 + i]; - for (i = 0; i < 8; i++) + + for (i = 0; i < 8; i++) for (k = 0; k < 4; k++) tstate[4 * i + k] = midstate[i]; @@ -466,6 +467,7 @@ static bool scrypt_1024_1_1_256_4way(const uint32_t *input, for (i = 0; i < 8; i++) for (k = 0; k < 4; k++) output[k * 8 + i] = W[4 * i + k]; + return true; } #endif /* HAVE_SHA256_4WAY */ @@ -505,6 +507,7 @@ static bool scrypt_1024_1_1_256_3way(const uint32_t *input, PBKDF2_SHA256_128_32(tstate + 0, ostate + 0, X + 0, output + 0); PBKDF2_SHA256_128_32(tstate + 8, ostate + 8, X + 32, output + 8); PBKDF2_SHA256_128_32(tstate + 16, ostate + 16, X + 64, output + 16); + return true; } @@ -526,7 +529,8 @@ static bool scrypt_1024_1_1_256_12way(const uint32_t *input, for (i = 0; i < 20; i++) for (k = 0; k < 4; k++) W[128 * j + 4 * i + k] = input[80 * j + k * 20 + i]; - for (j = 0; j < 3; j++) + + for (j = 0; j < 3; j++) for (i = 0; i < 8; i++) for (k = 0; k < 4; k++) tstate[32 * j + 4 * i + k] = midstate[i]; @@ -568,6 +572,7 @@ static bool scrypt_1024_1_1_256_12way(const uint32_t *input, for (i = 0; i < 8; i++) for (k = 0; k < 4; k++) output[32 * j + k * 8 + i] = W[128 * j + 4 * i + k]; + return true; } #endif /* HAVE_SHA256_4WAY */ @@ -575,9 +580,9 @@ static bool scrypt_1024_1_1_256_12way(const uint32_t *input, #endif /* HAVE_SCRYPT_3WAY */ #ifdef HAVE_SCRYPT_6WAY -static bool scrypt_1024_1_1_256_24way(const uint32_t *input, - uint32_t *output, uint32_t *midstate, unsigned char *scratchpad, int N, - int thrid ) +static bool scrypt_1024_1_1_256_24way( const uint32_t *input, + uint32_t *output, uint32_t *midstate, + unsigned char *scratchpad, int N, int thrid ) { uint32_t _ALIGN(128) tstate[24 * 8]; uint32_t _ALIGN(128) ostate[24 * 8]; @@ -586,54 +591,56 @@ static bool scrypt_1024_1_1_256_24way(const uint32_t *input, uint32_t *V; int i, j, k; - V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + V = (uint32_t *)( ( (uintptr_t)(scratchpad) + 63 ) & ~ (uintptr_t)(63) ); - for (j = 0; j < 3; j++) - for (i = 0; i < 20; i++) - for (k = 0; k < 8; k++) + for ( j = 0; j < 3; j++ ) + for ( i = 0; i < 20; i++ ) + for ( k = 0; k < 8; k++ ) W[8 * 32 * j + 8 * i + k] = input[8 * 20 * j + k * 20 + i]; - for (j = 0; j < 3; j++) - for (i = 0; i < 8; i++) - for (k = 0; k < 8; k++) + + for ( j = 0; j < 3; j++ ) + for ( i = 0; i < 8; i++ ) + for ( k = 0; k < 8; k++ ) tstate[8 * 8 * j + 8 * i + k] = midstate[i]; - HMAC_SHA256_80_init_8way(W + 0, tstate + 0, ostate + 0); - HMAC_SHA256_80_init_8way(W + 256, tstate + 64, ostate + 64); - HMAC_SHA256_80_init_8way(W + 512, tstate + 128, ostate + 128); + HMAC_SHA256_80_init_8way( W + 0, tstate + 0, ostate + 0 ); + HMAC_SHA256_80_init_8way( W + 256, tstate + 64, ostate + 64 ); + HMAC_SHA256_80_init_8way( W + 512, tstate + 128, ostate + 128 ); if ( work_restart[thrid].restart ) return false; - PBKDF2_SHA256_80_128_8way(tstate + 0, ostate + 0, W + 0, W + 0); - PBKDF2_SHA256_80_128_8way(tstate + 64, ostate + 64, W + 256, W + 256); - PBKDF2_SHA256_80_128_8way(tstate + 128, ostate + 128, W + 512, W + 512); + PBKDF2_SHA256_80_128_8way( tstate + 0, ostate + 0, W + 0, W + 0 ); + PBKDF2_SHA256_80_128_8way( tstate + 64, ostate + 64, W + 256, W + 256 ); + PBKDF2_SHA256_80_128_8way( tstate + 128, ostate + 128, W + 512, W + 512 ); if ( work_restart[thrid].restart ) return false; - for (j = 0; j < 3; j++) - for (i = 0; i < 32; i++) - for (k = 0; k < 8; k++) + for ( j = 0; j < 3; j++ ) + for ( i = 0; i < 32; i++ ) + for ( k = 0; k < 8; k++ ) X[8 * 32 * j + k * 32 + i] = W[8 * 32 * j + 8 * i + k]; - scrypt_core_6way(X + 0 * 32, V, N); - scrypt_core_6way(X + 6 * 32, V, N); - scrypt_core_6way(X + 12 * 32, V, N); - scrypt_core_6way(X + 18 * 32, V, N); + scrypt_core_6way( X + 0 * 32, V, N ); + scrypt_core_6way( X + 6 * 32, V, N ); + scrypt_core_6way( X + 12 * 32, V, N ); + scrypt_core_6way( X + 18 * 32, V, N ); if ( work_restart[thrid].restart ) return false; - for (j = 0; j < 3; j++) - for (i = 0; i < 32; i++) - for (k = 0; k < 8; k++) + for ( j = 0; j < 3; j++ ) + for ( i = 0; i < 32; i++ ) + for ( k = 0; k < 8; k++ ) W[8 * 32 * j + 8 * i + k] = X[8 * 32 * j + k * 32 + i]; - PBKDF2_SHA256_128_32_8way(tstate + 0, ostate + 0, W + 0, W + 0); - PBKDF2_SHA256_128_32_8way(tstate + 64, ostate + 64, W + 256, W + 256); - PBKDF2_SHA256_128_32_8way(tstate + 128, ostate + 128, W + 512, W + 512); + PBKDF2_SHA256_128_32_8way( tstate + 0, ostate + 0, W + 0, W + 0 ); + PBKDF2_SHA256_128_32_8way( tstate + 64, ostate + 64, W + 256, W + 256 ); + PBKDF2_SHA256_128_32_8way( tstate + 128, ostate + 128, W + 512, W + 512 ); - for (j = 0; j < 3; j++) - for (i = 0; i < 8; i++) - for (k = 0; k < 8; k++) + for ( j = 0; j < 3; j++ ) + for ( i = 0; i < 8; i++ ) + for ( k = 0; k < 8; k++ ) output[8 * 8 * j + k * 8 + i] = W[8 * 32 * j + 8 * i + k]; + return true; } #endif /* HAVE_SCRYPT_6WAY */ @@ -702,7 +709,8 @@ extern int scanhash_scrypt( struct work *work, uint32_t max_nonce, if ( unlikely( valid_hash( hash + i * 8, ptarget ) ) ) { pdata[19] = data[i * 20 + 19]; - submit_lane_solution( work, hash, mythr, i ); + test_hash_and_submit( work, hash, mythr ); +// submit_lane_solution( work, hash, mythr, i ); } } } while ( likely( ( n < ( max_nonce - throughput ) ) && !(*restart) ) ); diff --git a/configure b/configure index 1acd782..b9fc2c1 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.12.4.4. +# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.12.4.5. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='cpuminer-opt' PACKAGE_TARNAME='cpuminer-opt' -PACKAGE_VERSION='3.12.4.4' -PACKAGE_STRING='cpuminer-opt 3.12.4.4' +PACKAGE_VERSION='3.12.4.5' +PACKAGE_STRING='cpuminer-opt 3.12.4.5' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1332,7 +1332,7 @@ if test "$ac_init_help" = "long"; then # 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. cat <<_ACEOF -\`configure' configures cpuminer-opt 3.12.4.4 to adapt to many kinds of systems. +\`configure' configures cpuminer-opt 3.12.4.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1404,7 +1404,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of cpuminer-opt 3.12.4.4:";; + short | recursive ) echo "Configuration of cpuminer-opt 3.12.4.5:";; esac cat <<\_ACEOF @@ -1509,7 +1509,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -cpuminer-opt configure 3.12.4.4 +cpuminer-opt configure 3.12.4.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2012,7 +2012,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by cpuminer-opt $as_me 3.12.4.4, which was +It was created by cpuminer-opt $as_me 3.12.4.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2993,7 +2993,7 @@ fi # Define the identity of the package. PACKAGE='cpuminer-opt' - VERSION='3.12.4.4' + VERSION='3.12.4.5' cat >>confdefs.h <<_ACEOF @@ -6690,7 +6690,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by cpuminer-opt $as_me 3.12.4.4, which was +This file was extended by cpuminer-opt $as_me 3.12.4.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6756,7 +6756,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -cpuminer-opt config.status 3.12.4.4 +cpuminer-opt config.status 3.12.4.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index bcaec08..c676471 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([cpuminer-opt], [3.12.4.4]) +AC_INIT([cpuminer-opt], [3.12.4.5]) AC_PREREQ([2.59c]) AC_CANONICAL_SYSTEM diff --git a/cpu-miner.c b/cpu-miner.c index b576076..adfa5a3 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -890,16 +890,8 @@ static inline void sprintf_et( char *str, int seconds ) sprintf( str, "%um%02us", min, sec ); } -// Bitcoin formula for converting difficulty to an equivalent -// number of hashes. -// -// https://en.bitcoin.it/wiki/Difficulty -// -// hash = diff * 2**32 -// -// diff_to_hash = 2**32 = 0x100000000 = 4294967296; - -const double diff_to_hash = 4294967296.; +const double exp32 = 4294967296.; // 2**32 +const double exp64 = 4294967296. * 4294967296.; // 2**64 struct share_stats_t { @@ -954,9 +946,9 @@ void report_summary_log( bool force ) double share_time = (double)et.tv_sec + (double)et.tv_usec / 1e6; double ghrate = global_hashrate; - double shrate = share_time == 0. ? 0. : diff_to_hash * last_targetdiff + double shrate = share_time == 0. ? 0. : exp32 * last_targetdiff * (double)(accepts) / share_time; - double sess_hrate = uptime.tv_sec == 0. ? 0. : diff_to_hash * norm_diff_sum + double sess_hrate = uptime.tv_sec == 0. ? 0. : exp32 * norm_diff_sum / (double)uptime.tv_sec; double submit_rate = share_time == 0. ? 0. : (double)submits*60. / share_time; @@ -973,8 +965,8 @@ void report_summary_log( bool force ) sprintf_et( et_str, et.tv_sec ); sprintf_et( upt_str, uptime.tv_sec ); - applog( LOG_NOTICE, "Periodic Report %s %s", et_str, upt_str ); - applog2( LOG_INFO, "%s: %s", algo_names[ opt_algo ], short_url ); + applog( LOG_BLUE, "%s: %s", algo_names[ opt_algo ], short_url ); + applog2( LOG_NOTICE, "Periodic Report %s %s", et_str, upt_str ); applog2( LOG_INFO, "Share rate %.2f/min %.2f/min", submit_rate, (double)submitted_share_count*60. / ( (double)uptime.tv_sec + (double)uptime.tv_usec / 1e6 ) ); @@ -985,11 +977,11 @@ void report_summary_log( bool force ) if ( accepted_share_count < submitted_share_count ) { double lost_ghrate = uptime.tv_sec == 0. ? 0. - : diff_to_hash * last_targetdiff + : exp32 * last_targetdiff * (double)(submitted_share_count - accepted_share_count ) / (double)uptime.tv_sec; double lost_shrate = share_time == 0. ? 0. - : diff_to_hash * last_targetdiff * (double)(submits - accepts ) + : exp32 * last_targetdiff * (double)(submits - accepts ) / share_time; char lshr_units[4] = {0}; char lghr_units[4] = {0}; @@ -1016,7 +1008,7 @@ void report_summary_log( bool force ) bool lowdiff_debug = false; -static int share_result( int result, struct work *null_work, +static int share_result( int result, struct work *work, const char *reason ) { double share_time = 0., share_ratio = 0.; @@ -1062,7 +1054,6 @@ static int share_result( int result, struct work *null_work, share_ratio = my_stats.net_diff == 0. ? 0. : my_stats.share_diff / my_stats.net_diff * 100.; - // check result if ( likely( result ) ) { @@ -1087,9 +1078,10 @@ static int share_result( int result, struct work *null_work, { sprintf( ares, "A%d", accepted_share_count ); sprintf( bres, "B%d", solved_block_count ); - if ( reason && strstr( reason, "Invalid job id" ) ) + if ( work ) stale = work->stale; + if ( reason ) stale = stale || strstr( reason, "Invalid job id" ); + if ( stale ) { - stale = true; stale_share_count++; sprintf( sres, "Stale %d", stale_share_count ); sprintf( rres, "R%d", rejected_share_count ); @@ -1125,65 +1117,32 @@ static int share_result( int result, struct work *null_work, pthread_mutex_unlock( &stats_lock ); -/* - if ( likely( result ) ) - { - if ( unlikely( solved ) ) - { - sprintf( bres, "BLOCK SOLVED %d", solved_block_count ); - sprintf( ares, "A%d", accepted_share_count ); - } - else - { - sprintf( bres, "B%d", solved_block_count ); - sprintf( ares, "Accepted %d", accepted_share_count ); - } - sprintf( sres, "S%d", stale_share_count ); - sprintf( rres, "R%d", rejected_share_count ); - } - else - { - sprintf( ares, "A%d", accepted_share_count ); - sprintf( bres, "B%d", solved_block_count ); - if ( stale ) - { - sprintf( sres, "Stale %d", stale_share_count ); - sprintf( rres, "R%d", rejected_share_count ); - } - else - { - sprintf( sres, "S%d", stale_share_count ); - sprintf( rres, "Rejected %d" , rejected_share_count ); - } - } -*/ - if ( use_colors ) { - bcol = acol = scol = rcol = CL_WHT; + bcol = acol = scol = rcol = CL_N; if ( likely( result ) ) { - acol = CL_GRN; - if ( unlikely( solved ) ) bcol = CL_MAG; + acol = CL_WHT CL_GRN; + if ( unlikely( solved ) ) bcol = CL_WHT CL_MAG; } - else if ( stale ) scol = CL_YL2; - else rcol = CL_RED; + else if ( stale ) scol = CL_WHT CL_YL2; + else rcol = CL_WHT CL_RED; } else bcol = acol = scol = rcol = "\0"; - applog( LOG_NOTICE, "%d %s%s %s%s %s%s %s%s" CL_WHT ", %.3f sec (%dms)", + applog( LOG_NOTICE, "%d %s%s %s%s %s%s %s%s" CL_N ", %.3f sec (%dms)", my_stats.share_count, acol, ares, scol, sres, rcol, rres, bcol, bres, share_time, latency ); if ( !opt_quiet ) { if ( have_stratum ) - applog2( LOG_NOTICE, "Diff %.5g (%.3g%), %sBlock %d, %sJob %s" CL_WHT, + applog2( LOG_INFO, "Diff %.5g (%.3g%), %sBlock %d, %sJob %s", my_stats.share_diff, share_ratio, bcol, stratum.block_height, scol, my_stats.job_id ); else - applog2( LOG_NOTICE, "Diff %.5g (%.3g%), %sBlock %d" CL_WHT, + applog2( LOG_INFO, "Diff %.5g (%.3g%), %sBlock %d", my_stats.share_diff, share_ratio, bcol, stratum.block_height ); } @@ -1359,27 +1318,29 @@ char* std_malloc_txs_request( struct work *work ) static bool submit_upstream_work( CURL *curl, struct work *work ) { - - /* pass if the previous hash is not the current previous hash */ -/* Submit anyway, discardring here messes up the stats - if ( !submit_old && memcmp( &work->data[1], &g_work.data[1], 32 ) ) - { - applog( LOG_WARNING, "Stale work detected, discarding" ); - return true; - } - + work->stale = false; + // Submit anyway, discardring here messes up the stats if ( !have_stratum && allow_mininginfo ) { struct work mining_info; get_mininginfo( curl, &mining_info ); if ( work->height < mining_info.height ) { - applog( LOG_WARNING, "Block %u was already solved, current block %d", - work->height, mining_info.height ); - return true; + if ( !opt_quiet ) + applog( LOG_WARNING, "Block %u already solved, current block %d", + work->height, mining_info.height ); + work->stale = true; } } -*/ + + /* pass if the previous hash is not the current previous hash */ + if ( !( work->stale || submit_old ) + && memcmp( &work->data[1], &g_work.data[1], 32 ) ) + { + if ( !opt_quiet ) + applog( LOG_WARNING, "Stale work detected, submitting anyway" ); + work->stale = true; + } if ( have_stratum ) { @@ -1533,8 +1494,8 @@ start: char net_ttf[32]; char miner_ttf[32]; - sprintf_et( net_ttf, net_diff * diff_to_hash / net_hr ); - sprintf_et( miner_ttf, net_diff * diff_to_hash / miner_hr ); + sprintf_et( net_ttf, net_diff * exp32 / net_hr ); + sprintf_et( miner_ttf, net_diff * exp32 / miner_hr ); scale_hash_for_display ( &miner_hr, miner_hr_units ); scale_hash_for_display ( &net_hr, net_hr_units ); applog2(LOG_INFO, "Miner TTF @ %.2f %sh/s %s, net TTF @ %.2f %sh/s %s", @@ -1706,8 +1667,7 @@ static bool get_work(struct thr_info *thr, struct work *work) return true; } -bool submit_work( struct thr_info *thr, - const struct work *work_in ) +bool submit_work( struct thr_info *thr, const struct work *work_in ) { struct workio_cmd *wc; @@ -1731,27 +1691,42 @@ err_out: return false; } +/* // __float128? // Convert little endian 256 bit (38 decimal digits) unsigned integer to // double precision floating point with 15 decimal digits precision. -// returns u * ( 2**256 ) static inline double u256_to_double( const uint64_t *u ) { const double exp64 = 4294967296.0 * 4294967296.0; // 2**64 return ( ( u[3] * exp64 + u[2] ) * exp64 + u[1] ) * exp64 + u[0]; } +*/ +static void update_submit_stats( struct work *work, const void *hash ) +{ + pthread_mutex_lock( &stats_lock ); + + submitted_share_count++; + share_stats[ s_put_ptr ].share_count = submitted_share_count; + gettimeofday( &share_stats[ s_put_ptr ].submit_time, NULL ); + share_stats[ s_put_ptr ].share_diff = work->sharediff; + share_stats[ s_put_ptr ].net_diff = net_diff; + share_stats[ s_put_ptr ].stratum_diff = stratum_diff; + share_stats[ s_put_ptr ].target_diff = work->targetdiff; + if ( have_stratum ) + strncpy( share_stats[ s_put_ptr ].job_id, work->job_id, 30 ); + s_put_ptr = stats_ptr_incr( s_put_ptr ); + + pthread_mutex_unlock( &stats_lock ); +} + +//deprecated void work_set_target_ratio( struct work* work, const void *hash ) { - if ( likely( hash ) ) - { - double dhash = u256_to_double( (const uint64_t*)hash ); - if ( likely( dhash > 0. ) ) - work->sharediff = work->targetdiff * - u256_to_double( (const uint64_t*)( work->target ) ) / dhash; - } - else - work->sharediff = 0.; + submitted_share_count++; + work->sharediff = work->targetdiff * (double)( ((uint64_t*)hash)[3] ) + / (double)( ((uint64_t*)work->target)[3] ); +// work->sharediff = likely( hash ) ? target_to_diff( (uint32_t*)hash ) : 0.; // collect some share stats // Frequent share submission combined with high latency can caused @@ -1777,17 +1752,22 @@ bool submit_solution( struct work *work, const void *hash, { if ( likely( submit_work( thr, work ) ) ) { - submitted_share_count++; - work_set_target_ratio( work, hash ); + work->sharediff = work->targetdiff * (double)( ((uint64_t*)hash)[3] ) + / (double)( ((uint64_t*)work->target)[3] ); +// work->sharediff = likely( hash ) ? target_to_diff( (uint32_t*)hash ) : 0.; + update_submit_stats( work, hash ); +// submitted_share_count++; +// work_set_target_ratio( work, hash ); if ( !opt_quiet ) { - if ( have_stratum ) - applog( LOG_NOTICE, "%d submitted by thread %d, job %s", - submitted_share_count, thr->id, work->job_id ); - else - applog( LOG_NOTICE, "%d submitted by thread %d", - submitted_share_count, thr->id ); + if ( have_stratum ) + applog( LOG_NOTICE, "%d Submit diff %.5g, block %d, job %s", + submitted_share_count, work->sharediff, work->height, + work->job_id ); + else + applog( LOG_NOTICE, "%d Submit diff %.5g, block %d", + submitted_share_count, work->sharediff, work->height ); } if ( lowdiff_debug ) @@ -1802,7 +1782,7 @@ bool submit_solution( struct work *work, const void *hash, return true; } else - applog( LOG_WARNING, "%d failed to submit share thread %d.", + applog( LOG_WARNING, "%d failed to submit share, thread %d", submitted_share_count, thr->id ); return false; } @@ -1812,17 +1792,22 @@ bool submit_lane_solution( struct work *work, const void *hash, { if ( likely( submit_work( thr, work ) ) ) { - submitted_share_count++; - work_set_target_ratio( work, hash ); + work->sharediff = work->targetdiff * (double)( ((uint64_t*)hash)[3] ) + / (double)( ((uint64_t*)work->target)[3] ); +// work->sharediff = likely( hash ) ? target_to_diff( (uint32_t*)hash ) : 0.; + update_submit_stats( work, hash ); +// submitted_share_count++; +// work_set_target_ratio( work, hash ); if ( !opt_quiet ) { - if ( have_stratum ) - applog( LOG_NOTICE, "%d submitted by thread %d, lane %d, job %s", - submitted_share_count, thr->id, lane, work->job_id ); - else - applog( LOG_NOTICE, "%d submitted by thread %d, lane %d", - submitted_share_count, thr->id, lane ); + if ( have_stratum ) + applog( LOG_NOTICE, "%d Submit diff %.5g, block %d, job %s", + submitted_share_count, work->sharediff, work->height, + work->job_id ); + else + applog( LOG_NOTICE, "%d Submit diff %.5g, block %d", + submitted_share_count, work->sharediff, work->height ); } if ( lowdiff_debug ) @@ -1837,11 +1822,55 @@ bool submit_lane_solution( struct work *work, const void *hash, return true; } else - applog( LOG_WARNING, "%d failed to submit share, thread %d, lane %d.", + applog( LOG_WARNING, "%d failed to submit share, thread %d, lane %d", submitted_share_count, thr->id, lane ); return false; } + +// The new way, replaces fulltest and submit_solution +bool test_hash_and_submit( struct work *work, const void *hash, + struct thr_info *thr ) +{ + work->sharediff = work->targetdiff * (double)( ((uint64_t*)hash)[3] ) + / (double)( ((uint64_t*)work->target)[3] ); + +// work->sharediff = likely( hash ) ? target_to_diff( (uint32_t*)hash ) : 0.; + if ( work->sharediff >= work->targetdiff ) + { + if ( likely( submit_work( thr, work ) ) ) + { + update_submit_stats( work, hash ); + + if ( !opt_quiet ) + { + if ( have_stratum ) + applog( LOG_NOTICE, "%d Submit diff %.5g, block %d, job %s", + submitted_share_count, work->sharediff, work->height, + work->job_id ); + else + applog( LOG_NOTICE, "%d Submit diff %.5g, block %d", + submitted_share_count, work->sharediff, work->height ); + } + + if ( lowdiff_debug ) + { + uint32_t* h = (uint32_t*)hash; + uint32_t* t = (uint32_t*)work->target; + 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; + } + else + applog( LOG_WARNING, "%d failed to submit share, thread %d", + submitted_share_count, thr->id ); + } + return false; +} + static bool wanna_mine(int thr_id) { bool state = true; @@ -2249,7 +2278,7 @@ static void *miner_thread( void *userdata ) } else sprintf( tempstr, "%d C", temp ); - applog( LOG_INFO,"CPU temp: curr %s (max %d), Freq: %.3f/%.3f GHz", + applog( LOG_NOTICE,"CPU temp: curr %s (max %d), Freq: %.3f/%.3f GHz", tempstr, hi_temp, (float)lo_freq / 1e6, (float)hi_freq/ 1e6 ); if ( temp > hi_temp ) hi_temp = temp; } @@ -2567,8 +2596,12 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work ) algo_gate.build_extraheader( g_work, sctx ); net_diff = algo_gate.calc_network_diff( g_work ); algo_gate.set_work_data_endian( g_work ); - work_set_target( g_work, sctx->job.diff - / ( opt_target_factor * opt_diff_factor ) ); + g_work->height = sctx->block_height; + g_work->targetdiff = sctx->job.diff + / ( opt_target_factor * opt_diff_factor ); + diff_to_target( g_work->target, g_work->targetdiff ); +// work_set_target( g_work, sctx->job.diff +// / ( opt_target_factor * opt_diff_factor ) ); pthread_mutex_unlock( &sctx->work_lock ); @@ -2623,8 +2656,8 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work ) char block_ttf[32]; char share_ttf[32]; - sprintf_et( block_ttf, net_diff * diff_to_hash / hr ); - sprintf_et( share_ttf, last_targetdiff * diff_to_hash / hr ); + sprintf_et( block_ttf, net_diff * exp32 / hr ); + sprintf_et( share_ttf, last_targetdiff * exp32 / hr ); scale_hash_for_display ( &hr, hr_units ); applog2( LOG_INFO, "TTF @ %.2f %sh/s: block %s, share %s", hr, hr_units, block_ttf, share_ttf ); @@ -2639,7 +2672,7 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work ) : et.tv_sec / ( last_block_height - session_first_block ); if ( net_diff && net_ttf ) { - double net_hr = net_diff * diff_to_hash / net_ttf; + double net_hr = net_diff * exp32 / net_ttf; char net_ttf_str[32]; char net_hr_units[4] = {0}; @@ -3701,9 +3734,6 @@ int main(int argc, char *argv[]) */ } - applog( LOG_INFO, "Extranonce subscribe: %s", - opt_extranonce ? "YES" : "NO" ); - #ifdef HAVE_SYSLOG_H if (use_syslog) openlog("cpuminer", LOG_PID, LOG_USER); diff --git a/miner.h b/miner.h index 272b063..611a8fe 100644 --- a/miner.h +++ b/miner.h @@ -312,6 +312,19 @@ int varint_encode( unsigned char *p, uint64_t n ); size_t address_to_script( unsigned char *out, size_t outsz, const char *addr ); int timeval_subtract( struct timeval *result, struct timeval *x, struct timeval *y); + +// Bitcoin formula for converting difficulty to an equivalent +// number of hashes. +// +// https://en.bitcoin.it/wiki/Difficulty +// +// hash = diff * 2**32 +// +// diff_to_hash = 2**32 = 0x100000000 = 4294967296 = exp32; + +const double exp32; // 2**32 +const double exp64; // 2**64 + bool fulltest( const uint32_t *hash, const uint32_t *target ); bool valid_hash( const void*, const void* ); @@ -332,11 +345,12 @@ struct thr_info { //struct thr_info *thr_info; -bool submit_solution( struct work *work, const void *hash, - struct thr_info *thr ); -bool submit_lane_solution( struct work *work, const void *hash, - struct thr_info *thr, const int lane ); +bool submit_solution( struct work *work, const void *hash, + struct thr_info *thr ); +bool submit_lane_solution( struct work *work, const void *hash, + struct thr_info *thr, const int lane ); +bool test_hash_and_submit( struct work*, const void*, struct thr_info* ); bool submit_work( struct thr_info *thr, const struct work *work_in ); @@ -378,6 +392,7 @@ struct work { size_t xnonce2_len; unsigned char *xnonce2; bool sapling; + bool stale; // x16rt uint32_t merkleroothash[8]; diff --git a/util.c b/util.c index a8b2d12..3fc25c0 100644 --- a/util.c +++ b/util.c @@ -1039,37 +1039,57 @@ bool fulltest( const uint32_t *hash, const uint32_t *target ) return rc; } +/* void diff_to_target(uint32_t *target, double diff) { - uint64_t m; + uint64_t m; + int k; + + for (k = 6; k > 0 && diff > 1.0; k--) + diff /= 4294967296.0; + + m = (uint64_t)(4294901760.0 / diff); + + if (m == 0 && k == 6) + memset(target, 0xff, 32); + else { + memset(target, 0, 32); + target[k] = (uint32_t)m; + target[k + 1] = (uint32_t)(m >> 32); + } +} +*/ + + +void diff_to_target(uint32_t *target, double diff) +{ + uint64_t *t = (uint64_t*)target; + uint64_t m; int k; - const double exp64 = (double)0xffffffffffffffff + 1.; +// static const double exp64 = (double)0xffffffffffffffff + 1.; for ( k = 3; k > 0 && diff > 1.0; k-- ) diff /= exp64; -// for (k = 6; k > 0 && diff > 1.0; k--) -// diff /= 4294967296.0; - m = (uint64_t)( 0xffff0000 / diff ); - if unlikely( m == 0 && k == 3 ) - memset( target, 0xff, 32 ); + m = (uint64_t)( 0xffff0000 / diff ); + + if unlikely( m == 0 && k == 3 ) + memset( t, 0xff, 32 ); else { - memset( target, 0, 32 ); - ((uint64_t*)target)[k] = m; -// target[k] = (uint32_t)m; -// target[k + 1] = (uint32_t)(m >> 32); + memset( t, 0, 32 ); + t[k] = m; } } -// Only used by stratum pools + +// deprecated void work_set_target(struct work* work, double diff) { diff_to_target( work->target, diff ); work->targetdiff = diff; } -// Only used by longpoll pools double target_to_diff(uint32_t* target) { uchar* tgt = (uchar*) target; @@ -1546,35 +1566,44 @@ bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *p ret = true; - if (!opt_extranonce) + if ( !opt_extranonce ) goto out; // subscribe to extranonce (optional) sprintf(s, "{\"id\": 3, \"method\": \"mining.extranonce.subscribe\", \"params\": []}"); - if (!stratum_send_line(sctx, s)) + if ( !stratum_send_line( sctx, s ) ) goto out; - if (!socket_full(sctx->sock, 3)) { - applog(LOG_WARNING, "stratum extranonce subscribe timed out"); - goto out; + if ( !socket_full( sctx->sock, 3 ) ) + { + applog( LOG_WARNING, "Extranonce disabled, subscribe timed out" ); + opt_extranonce = false; + goto out; } + if ( !opt_quiet ) + applog( LOG_INFO, "Extranonce subscription enabled" ); - sret = stratum_recv_line(sctx); - if (sret) { - json_t *extra = JSON_LOADS(sret, &err); - if (!extra) { + sret = stratum_recv_line( sctx ); + if ( sret ) + { + json_t *extra = JSON_LOADS( sret, &err ); + if ( !extra ) + { applog(LOG_WARNING, "JSON decode failed(%d): %s", err.line, err.text); - } else { - if (json_integer_value(json_object_get(extra, "id")) != 3) { + } + else + { + if ( json_integer_value(json_object_get( extra, "id" ) ) != 3 ) + { // we receive a standard method if extranonce is ignored - if (!stratum_handle_method(sctx, sret)) - applog(LOG_WARNING, "Stratum answer id is not correct!"); + if ( !stratum_handle_method( sctx, sret ) ) + applog( LOG_WARNING, "Stratum answer id is not correct!" ); } - res_val = json_object_get(extra, "result"); + res_val = json_object_get( extra, "result" ); // if (opt_debug && (!res_val || json_is_false(res_val))) // applog(LOG_DEBUG, "extranonce subscribe not supported"); - json_decref(extra); + json_decref( extra ); } free(sret); }