This commit is contained in:
Jay D Dee
2021-03-24 18:24:20 -04:00
parent d0b4941321
commit 902ec046dd
14 changed files with 609 additions and 430 deletions

View File

@@ -89,7 +89,7 @@ Supported Algorithms
lyra2h Hppcoin
lyra2re lyra2
lyra2rev2 lyra2v2
lyra2rev3 lyrav2v3, Vertcoin
lyra2rev3 lyrav2v3
lyra2z
lyra2z330 Lyra2 330 rows, Zoin (ZOI)
m7m Magi (XMG)
@@ -122,6 +122,7 @@ Supported Algorithms
tribus Denarius (DNR)
vanilla blake256r8vnl (VCash)
veltor (VLT)
verthash Vertcoin
whirlpool
whirlpoolx
x11 Dash

View File

@@ -65,6 +65,25 @@ If not what makes it happen or not happen?
Change Log
----------
v3.16.1
New options for verthash:
--data-file to specify the name, and optionally the path, of the verthash
data file, default is "verthash.dat" in the current directory.
--verify to perform the data file integrity check at startup, default is
not to verify data file integrity.
Support for creation of default verthash data file if:
1) --data-file option is not used,
2) no default data file is found in the current directory, and,
3) --verify option is used.
More detailed logs related to verthash data file.
Small verthash performance improvement.
Fixed detection of corrupt stats caused by networking issues.
v3.16.0
Added verthash algo.

View File

@@ -15,8 +15,6 @@
#include <stdbool.h>
#include <memory.h>
#include <unistd.h>
#include <openssl/sha.h>
//#include "miner.h"
#include "algo-gate-api.h"
// Define null and standard functions.
@@ -279,9 +277,11 @@ void init_algo_gate( algo_gate_t* gate )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
// called by each thread that uses the gate
// Called once by main
bool register_algo_gate( int algo, algo_gate_t *gate )
{
bool rc = false;
if ( NULL == gate )
{
applog(LOG_ERR,"FAIL: algo_gate registration failed, NULL gate\n");
@@ -290,109 +290,108 @@ bool register_algo_gate( int algo, algo_gate_t *gate )
init_algo_gate( gate );
switch (algo)
switch ( algo )
{
case ALGO_ALLIUM: register_allium_algo ( gate ); break;
case ALGO_ANIME: register_anime_algo ( gate ); break;
case ALGO_ARGON2: register_argon2_algo ( gate ); break;
case ALGO_ARGON2D250: register_argon2d_crds_algo ( gate ); break;
case ALGO_ARGON2D500: register_argon2d_dyn_algo ( gate ); break;
case ALGO_ARGON2D4096: register_argon2d4096_algo ( gate ); break;
case ALGO_AXIOM: register_axiom_algo ( gate ); break;
case ALGO_BLAKE: register_blake_algo ( gate ); break;
case ALGO_BLAKE2B: register_blake2b_algo ( gate ); break;
case ALGO_BLAKE2S: register_blake2s_algo ( gate ); break;
case ALGO_BLAKECOIN: register_blakecoin_algo ( gate ); break;
case ALGO_BMW512: register_bmw512_algo ( gate ); break;
case ALGO_C11: register_c11_algo ( gate ); break;
case ALGO_DECRED: register_decred_algo ( gate ); break;
case ALGO_DEEP: register_deep_algo ( gate ); break;
case ALGO_DMD_GR: register_dmd_gr_algo ( gate ); break;
case ALGO_GROESTL: register_groestl_algo ( gate ); break;
case ALGO_HEX: register_hex_algo ( gate ); break;
case ALGO_HMQ1725: register_hmq1725_algo ( gate ); break;
case ALGO_HODL: register_hodl_algo ( gate ); break;
case ALGO_JHA: register_jha_algo ( gate ); break;
case ALGO_KECCAK: register_keccak_algo ( gate ); break;
case ALGO_KECCAKC: register_keccakc_algo ( gate ); break;
case ALGO_LBRY: register_lbry_algo ( gate ); break;
case ALGO_LYRA2H: register_lyra2h_algo ( gate ); break;
case ALGO_LYRA2RE: register_lyra2re_algo ( gate ); break;
case ALGO_LYRA2REV2: register_lyra2rev2_algo ( gate ); break;
case ALGO_LYRA2REV3: register_lyra2rev3_algo ( gate ); break;
case ALGO_LYRA2Z: register_lyra2z_algo ( gate ); break;
case ALGO_LYRA2Z330: register_lyra2z330_algo ( gate ); break;
case ALGO_M7M: register_m7m_algo ( gate ); break;
case ALGO_MINOTAUR: register_minotaur_algo ( gate ); break;
case ALGO_MYR_GR: register_myriad_algo ( gate ); break;
case ALGO_NEOSCRYPT: register_neoscrypt_algo ( gate ); break;
case ALGO_NIST5: register_nist5_algo ( gate ); break;
case ALGO_PENTABLAKE: register_pentablake_algo ( gate ); break;
case ALGO_PHI1612: register_phi1612_algo ( gate ); break;
case ALGO_PHI2: register_phi2_algo ( gate ); break;
case ALGO_POLYTIMOS: register_polytimos_algo ( gate ); break;
case ALGO_POWER2B: register_power2b_algo ( gate ); break;
case ALGO_QUARK: register_quark_algo ( gate ); break;
case ALGO_QUBIT: register_qubit_algo ( gate ); break;
case ALGO_SCRYPT: register_scrypt_algo ( gate ); break;
case ALGO_SHA256D: register_sha256d_algo ( gate ); break;
case ALGO_SHA256Q: register_sha256q_algo ( gate ); break;
case ALGO_SHA256T: register_sha256t_algo ( gate ); break;
case ALGO_SHA3D: register_sha3d_algo ( gate ); break;
case ALGO_SHAVITE3: register_shavite_algo ( gate ); break;
case ALGO_SKEIN: register_skein_algo ( gate ); break;
case ALGO_SKEIN2: register_skein2_algo ( gate ); break;
case ALGO_SKUNK: register_skunk_algo ( gate ); break;
case ALGO_SONOA: register_sonoa_algo ( gate ); break;
case ALGO_TIMETRAVEL: register_timetravel_algo ( gate ); break;
case ALGO_TIMETRAVEL10: register_timetravel10_algo ( gate ); break;
case ALGO_TRIBUS: register_tribus_algo ( gate ); break;
case ALGO_VANILLA: register_vanilla_algo ( gate ); break;
case ALGO_VELTOR: register_veltor_algo ( gate ); break;
case ALGO_VERTHASH: register_verthash_algo ( gate ); break;
case ALGO_WHIRLPOOL: register_whirlpool_algo ( gate ); break;
case ALGO_WHIRLPOOLX: register_whirlpoolx_algo ( gate ); break;
case ALGO_X11: register_x11_algo ( gate ); break;
case ALGO_X11EVO: register_x11evo_algo ( gate ); break;
case ALGO_X11GOST: register_x11gost_algo ( gate ); break;
case ALGO_X12: register_x12_algo ( gate ); break;
case ALGO_X13: register_x13_algo ( gate ); break;
case ALGO_X13BCD: register_x13bcd_algo ( gate ); break;
case ALGO_X13SM3: register_x13sm3_algo ( gate ); break;
case ALGO_X14: register_x14_algo ( gate ); break;
case ALGO_X15: register_x15_algo ( gate ); break;
case ALGO_X16R: register_x16r_algo ( gate ); break;
case ALGO_X16RV2: register_x16rv2_algo ( gate ); break;
case ALGO_X16RT: register_x16rt_algo ( gate ); break;
case ALGO_X16RT_VEIL: register_x16rt_veil_algo ( gate ); break;
case ALGO_X16S: register_x16s_algo ( gate ); break;
case ALGO_X17: register_x17_algo ( gate ); break;
case ALGO_X21S: register_x21s_algo ( gate ); break;
case ALGO_X22I: register_x22i_algo ( gate ); break;
case ALGO_X25X: register_x25x_algo ( gate ); break;
case ALGO_XEVAN: register_xevan_algo ( gate ); break;
case ALGO_YESCRYPT: register_yescrypt_05_algo ( gate ); break;
case ALGO_ALLIUM: rc = register_allium_algo ( gate ); break;
case ALGO_ANIME: rc = register_anime_algo ( gate ); break;
case ALGO_ARGON2: rc = register_argon2_algo ( gate ); break;
case ALGO_ARGON2D250: rc = register_argon2d_crds_algo ( gate ); break;
case ALGO_ARGON2D500: rc = register_argon2d_dyn_algo ( gate ); break;
case ALGO_ARGON2D4096: rc = register_argon2d4096_algo ( gate ); break;
case ALGO_AXIOM: rc = register_axiom_algo ( gate ); break;
case ALGO_BLAKE: rc = register_blake_algo ( gate ); break;
case ALGO_BLAKE2B: rc = register_blake2b_algo ( gate ); break;
case ALGO_BLAKE2S: rc = register_blake2s_algo ( gate ); break;
case ALGO_BLAKECOIN: rc = register_blakecoin_algo ( gate ); break;
case ALGO_BMW512: rc = register_bmw512_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_DMD_GR: rc = register_dmd_gr_algo ( gate ); break;
case ALGO_GROESTL: rc = register_groestl_algo ( gate ); break;
case ALGO_HEX: rc = register_hex_algo ( gate ); break;
case ALGO_HMQ1725: rc = register_hmq1725_algo ( gate ); break;
case ALGO_HODL: rc = register_hodl_algo ( gate ); break;
case ALGO_JHA: rc = register_jha_algo ( gate ); break;
case ALGO_KECCAK: rc = register_keccak_algo ( gate ); break;
case ALGO_KECCAKC: rc = register_keccakc_algo ( gate ); break;
case ALGO_LBRY: rc = register_lbry_algo ( gate ); break;
case ALGO_LYRA2H: rc = register_lyra2h_algo ( gate ); break;
case ALGO_LYRA2RE: rc = register_lyra2re_algo ( gate ); break;
case ALGO_LYRA2REV2: rc = register_lyra2rev2_algo ( gate ); break;
case ALGO_LYRA2REV3: rc = register_lyra2rev3_algo ( gate ); break;
case ALGO_LYRA2Z: rc = register_lyra2z_algo ( gate ); break;
case ALGO_LYRA2Z330: rc = register_lyra2z330_algo ( gate ); break;
case ALGO_M7M: rc = register_m7m_algo ( gate ); break;
case ALGO_MINOTAUR: rc = register_minotaur_algo ( gate ); break;
case ALGO_MYR_GR: rc = register_myriad_algo ( gate ); break;
case ALGO_NEOSCRYPT: rc = register_neoscrypt_algo ( gate ); break;
case ALGO_NIST5: rc = register_nist5_algo ( gate ); break;
case ALGO_PENTABLAKE: rc = register_pentablake_algo ( gate ); break;
case ALGO_PHI1612: rc = register_phi1612_algo ( gate ); break;
case ALGO_PHI2: rc = register_phi2_algo ( gate ); break;
case ALGO_POLYTIMOS: rc = register_polytimos_algo ( gate ); break;
case ALGO_POWER2B: rc = register_power2b_algo ( gate ); break;
case ALGO_QUARK: rc = register_quark_algo ( gate ); break;
case ALGO_QUBIT: rc = register_qubit_algo ( gate ); break;
case ALGO_SCRYPT: rc = register_scrypt_algo ( gate ); break;
case ALGO_SHA256D: rc = register_sha256d_algo ( gate ); break;
case ALGO_SHA256Q: rc = register_sha256q_algo ( gate ); break;
case ALGO_SHA256T: rc = register_sha256t_algo ( gate ); break;
case ALGO_SHA3D: rc = register_sha3d_algo ( gate ); break;
case ALGO_SHAVITE3: rc = register_shavite_algo ( gate ); break;
case ALGO_SKEIN: rc = register_skein_algo ( gate ); break;
case ALGO_SKEIN2: rc = register_skein2_algo ( gate ); break;
case ALGO_SKUNK: rc = register_skunk_algo ( gate ); break;
case ALGO_SONOA: rc = register_sonoa_algo ( gate ); break;
case ALGO_TIMETRAVEL: rc = register_timetravel_algo ( gate ); break;
case ALGO_TIMETRAVEL10: rc = register_timetravel10_algo ( gate ); break;
case ALGO_TRIBUS: rc = register_tribus_algo ( gate ); break;
case ALGO_VANILLA: rc = register_vanilla_algo ( gate ); break;
case ALGO_VELTOR: rc = register_veltor_algo ( gate ); break;
case ALGO_VERTHASH: rc = register_verthash_algo ( gate ); break;
case ALGO_WHIRLPOOL: rc = register_whirlpool_algo ( gate ); break;
case ALGO_WHIRLPOOLX: rc = register_whirlpoolx_algo ( gate ); break;
case ALGO_X11: rc = register_x11_algo ( gate ); break;
case ALGO_X11EVO: rc = register_x11evo_algo ( gate ); break;
case ALGO_X11GOST: rc = register_x11gost_algo ( gate ); break;
case ALGO_X12: rc = register_x12_algo ( gate ); break;
case ALGO_X13: rc = register_x13_algo ( gate ); break;
case ALGO_X13BCD: rc = register_x13bcd_algo ( gate ); break;
case ALGO_X13SM3: rc = register_x13sm3_algo ( gate ); break;
case ALGO_X14: rc = register_x14_algo ( gate ); break;
case ALGO_X15: rc = register_x15_algo ( gate ); break;
case ALGO_X16R: rc = register_x16r_algo ( gate ); break;
case ALGO_X16RV2: rc = register_x16rv2_algo ( gate ); break;
case ALGO_X16RT: rc = register_x16rt_algo ( gate ); break;
case ALGO_X16RT_VEIL: rc = register_x16rt_veil_algo ( gate ); break;
case ALGO_X16S: rc = register_x16s_algo ( gate ); break;
case ALGO_X17: rc = register_x17_algo ( gate ); break;
case ALGO_X21S: rc = register_x21s_algo ( gate ); break;
case ALGO_X22I: rc = register_x22i_algo ( gate ); break;
case ALGO_X25X: rc = register_x25x_algo ( gate ); break;
case ALGO_XEVAN: rc = register_xevan_algo ( gate ); break;
case ALGO_YESCRYPT: rc = register_yescrypt_05_algo ( gate ); break;
// case ALGO_YESCRYPT: register_yescrypt_algo ( gate ); break;
case ALGO_YESCRYPTR8: register_yescryptr8_05_algo ( gate ); break;
case ALGO_YESCRYPTR8: rc = register_yescryptr8_05_algo ( gate ); break;
// case ALGO_YESCRYPTR8: register_yescryptr8_algo ( gate ); break;
case ALGO_YESCRYPTR8G: register_yescryptr8g_algo ( gate ); break;
case ALGO_YESCRYPTR16: register_yescryptr16_05_algo( gate ); break;
case ALGO_YESCRYPTR8G: rc = register_yescryptr8g_algo ( gate ); break;
case ALGO_YESCRYPTR16: rc = register_yescryptr16_05_algo( gate ); break;
// case ALGO_YESCRYPTR16: register_yescryptr16_algo ( gate ); break;
case ALGO_YESCRYPTR32: register_yescryptr32_05_algo( gate ); break;
case ALGO_YESCRYPTR32: rc = register_yescryptr32_05_algo( gate ); break;
// case ALGO_YESCRYPTR32: register_yescryptr32_algo ( gate ); break;
case ALGO_YESPOWER: register_yespower_algo ( gate ); break;
case ALGO_YESPOWERR16: register_yespowerr16_algo ( gate ); break;
case ALGO_YESPOWER_B2B: register_yespower_b2b_algo ( gate ); break;
case ALGO_ZR5: register_zr5_algo ( gate ); break;
case ALGO_YESPOWER: rc = register_yespower_algo ( gate ); break;
case ALGO_YESPOWERR16: rc = register_yespowerr16_algo ( gate ); break;
case ALGO_YESPOWER_B2B: rc = register_yespower_b2b_algo ( gate ); break;
case ALGO_ZR5: rc = register_zr5_algo ( gate ); break;
default:
applog(LOG_ERR,"FAIL: algo_gate registration failed, unknown algo %s.\n", algo_names[opt_algo] );
applog(LOG_ERR,"BUG: unregistered algorithm %s.\n", algo_names[opt_algo] );
return false;
} // switch
// ensure required functions were defined.
if ( gate->scanhash == (void*)&null_scanhash )
if ( !rc )
{
applog(LOG_ERR, "FAIL: Required algo_gate functions undefined\n");
applog(LOG_ERR, "FAIL: %s algorithm failed to initialize\n", algo_names[opt_algo] );
return false;
}
return true;
@@ -434,7 +433,6 @@ const char* const algo_alias_map[][2] =
{ "flax", "c11" },
{ "hsr", "x13sm3" },
{ "jackpot", "jha" },
{ "jane", "scryptjane" },
{ "lyra2", "lyra2re" },
{ "lyra2v2", "lyra2rev2" },
{ "lyra2v3", "lyra2rev3" },

View File

@@ -114,15 +114,15 @@ typedef struct
// Mandatory functions, one of these is mandatory. If a generic scanhash
// is used a custom target hash function must be registered, with a custom
// scanhash the target hash function can be called directly and doesn't need
// to be registered in the gate.
// to be registered with the gate.
int ( *scanhash ) ( struct work*, uint32_t, uint64_t*, struct thr_info* );
int ( *hash ) ( void*, const void*, int );
//optional, safe to use default in most cases
// Allocate thread local buffers and other initialization specific to miner
// threads.
// Called once by each miner thread to allocate thread local buffers and
// other initialization specific to miner threads.
bool ( *miner_thread_init ) ( int );
// Get thread local copy of blockheader with unique nonce.
@@ -150,7 +150,7 @@ void ( *build_stratum_request ) ( char*, struct work*, struct stratum_ctx* );
char* ( *malloc_txs_request ) ( struct work* );
// Big or little
// Big endian or little endian
void ( *set_work_data_endian ) ( struct work* );
double ( *calc_network_diff ) ( struct work* );
@@ -260,7 +260,7 @@ int scanhash_8way_64in_32out( struct work *work, uint32_t max_nonce,
#endif
// displays warning
int null_hash ();
int null_hash();
// optional safe targets, default listed first unless noted.
@@ -281,7 +281,7 @@ void std_be_build_stratum_request( char *req, struct work *work );
char* std_malloc_txs_request( struct work *work );
// Default is do_nothing (assumed LE)
// Default is do_nothing, little endian is assumed
void set_work_data_big_endian( struct work *work );
double std_calc_network_diff( struct work *work );

Binary file not shown.

View File

@@ -7,7 +7,9 @@
* any later version. See LICENSE for more details.
*/
#include "algo-gate-api.h"
#include "Verthash.h"
#include "mm_malloc.h"
//-----------------------------------------------------------------------------
// Verthash info management
@@ -18,34 +20,71 @@ int verthash_info_init(verthash_info_t* info, const char* file_name)
info->data = NULL;
info->dataSize = 0;
info->bitmask = 0;
size_t fileNameLen;
// get name
if (file_name == NULL) { return 1; }
size_t fileNameLen = strlen(file_name);
if (fileNameLen == 0) { return 1; }
info->fileName = (char*)malloc(fileNameLen+1);
if (!info->fileName)
if ( !file_name || !( fileNameLen = strlen( file_name ) ) )
{
applog( LOG_ERR, "Invalid file specification" );
return -1;
}
info->fileName = (char*)malloc( fileNameLen + 1 );
if ( !info->fileName )
{
// Memory allocation fatal error.
return 2;
applog( LOG_ERR, "Failed to allocate memory for Verthash data" );
return -1;
}
memset(info->fileName, 0, fileNameLen+1);
memcpy(info->fileName, file_name, fileNameLen);
memset( info->fileName, 0, fileNameLen + 1 );
memcpy( info->fileName, file_name, fileNameLen );
// Load data
FILE *fileMiningData = fopen_utf8(info->fileName, "rb");
// Failed to open file for reading
if (!fileMiningData) { return 1; }
FILE *fileMiningData = fopen_utf8( info->fileName, "rb" );
if ( !fileMiningData )
{
if ( opt_data_file || !opt_verify )
{
if ( opt_data_file )
applog( LOG_ERR,
"Verthash data file not found or invalid: %s", info->fileName );
else
{
applog( LOG_ERR,
"No Verthash data file specified and default not found");
applog( LOG_NOTICE,
"Add '--verify' to create default 'verthash.dat'");
}
return -1;
}
else
{
applog( LOG_NOTICE, "Creating default 'verthash.dat' in current directory, this will take several minutes");
if ( verthash_generate_data_file( info->fileName ) )
return -1;
fileMiningData = fopen_utf8( info->fileName, "rb" );
if ( !fileMiningData )
{
applog( LOG_ERR, "File system error opening %s", info->fileName );
return -1;
}
applog( LOG_NOTICE, "Verthash data file created successfully" );
}
}
// Get file size
fseek(fileMiningData, 0, SEEK_END);
uint64_t fileSize = (uint64_t)ftell(fileMiningData);
int fileSize = ftell(fileMiningData);
fseek(fileMiningData, 0, SEEK_SET);
if ( fileSize < 0 )
{
fclose(fileMiningData);
return 1;
}
// Allocate data
info->data = (uint8_t *)malloc(fileSize);
info->data = (uint8_t *)_mm_malloc( fileSize, 64 );
if (!info->data)
{
fclose(fileMiningData);
@@ -54,13 +93,20 @@ int verthash_info_init(verthash_info_t* info, const char* file_name)
}
// Load data
fread(info->data, fileSize, 1, fileMiningData);
if ( !fread( info->data, fileSize, 1, fileMiningData ) )
{
applog( LOG_ERR, "File system error reading %s", info->fileName );
fclose(fileMiningData);
return -1;
}
fclose(fileMiningData);
// Update fields
info->bitmask = ((fileSize - VH_HASH_OUT_SIZE)/VH_BYTE_ALIGNMENT) + 1;
info->dataSize = fileSize;
applog( LOG_NOTICE, "Using Verthash data file '%s'", info->fileName );
return 0;
}
@@ -83,20 +129,6 @@ void verthash_info_free(verthash_info_t* info)
#define VH_N_INDEXES 4096
#define VH_BYTE_ALIGNMENT 16
static __thread sha3_ctx_t sha3_midstate_ctx;
void verthash_sha3_prehash_72( const void *data )
{
sha3_init( &sha3_midstate_ctx, 256 );
sha3_update( &sha3_midstate_ctx, data, 72 );
}
void verthash_sha3_final_8( sha3_ctx_t *ctx, void *out, const void *data )
{
sha3_update( ctx, data, 8 );
sha3_final( out, ctx );
}
static inline uint32_t fnv1a(const uint32_t a, const uint32_t b)
{
return (a ^ b) * 0x1000193;
@@ -107,16 +139,12 @@ void verthash_hash(const unsigned char* blob_bytes,
const unsigned char(*input)[VH_HEADER_SIZE],
unsigned char(*output)[VH_HASH_OUT_SIZE])
{
unsigned char p1[VH_HASH_OUT_SIZE];
// sha3_ctx_t sha3_ctx;
// memcpy ( &sha3_ctx, &sha3_midstate_ctx, sizeof sha3_ctx );
// verthash_sha3_final_8( &sha3_ctx, &p1[0], &input[72] );
unsigned char p1[VH_HASH_OUT_SIZE] __attribute__ ((aligned (64)));
sha3(&input[0], VH_HEADER_SIZE, &p1[0], VH_HASH_OUT_SIZE);
unsigned char p0[VH_N_SUBSET];
unsigned char input_header[VH_HEADER_SIZE];
unsigned char input_header[VH_HEADER_SIZE] __attribute__ ((aligned (64)));
memcpy(input_header, input, VH_HEADER_SIZE);
for (size_t i = 0; i < VH_N_ITER; ++i)
@@ -126,17 +154,47 @@ void verthash_hash(const unsigned char* blob_bytes,
}
uint32_t* p0_index = (uint32_t*)p0;
uint32_t seek_indexes[VH_N_INDEXES];
uint32_t seek_indexes[VH_N_INDEXES] __attribute__ ((aligned (64)));
for (size_t x = 0; x < VH_N_ROT; ++x)
for ( size_t x = 0; x < VH_N_ROT; ++x )
{
memcpy( seek_indexes + x * (VH_N_SUBSET / sizeof(uint32_t)),
p0, VH_N_SUBSET);
for (size_t y = 0; y < VH_N_SUBSET / sizeof(uint32_t); ++y)
//#if defined(__AVX512F__) && defined(__AVX512VL__) && defined(__AVX512DQ__) && defined(__AVX512BW__)
// 512 bit vector processing is actually slower because it reduces the CPU
// clock significantly, which also slows mem access. The AVX512 rol instruction
// is still available for smaller vectors.
// for ( size_t y = 0; y < VH_N_SUBSET / sizeof(uint32_t); y += 16 )
// {
// __m512i *p0_v = (__m512i*)( p0_index + y );
// *p0_v = mm512_rol_32( *p0_v, 1 );
// }
#if defined(__AVX2__)
for ( size_t y = 0; y < VH_N_SUBSET / sizeof(uint32_t); y += 8 )
{
*(p0_index + y) = ( *(p0_index + y) << 1 )
| ( 1 & (*(p0_index + y) >> 31) );
__m256i *p0_v = (__m256i*)( p0_index + y );
*p0_v = mm256_rol_32( *p0_v, 1 );
}
#else
for ( size_t y = 0; y < VH_N_SUBSET / sizeof(uint32_t); y += 4 )
{
__m128i *p0_v = (__m128i*)( p0_index + y );
*p0_v = mm128_rol_32( *p0_v, 1 );
}
#endif
// for (size_t y = 0; y < VH_N_SUBSET / sizeof(uint32_t); ++y)
// {
// *(p0_index + y) = ( *(p0_index + y) << 1 )
// | ( 1 & (*(p0_index + y) >> 31) );
// }
}
uint32_t* p1_32 = (uint32_t*)p1;
@@ -146,13 +204,13 @@ void verthash_hash(const unsigned char* blob_bytes,
for (size_t i = 0; i < VH_N_INDEXES; i++)
{
const uint32_t offset = (fnv1a(seek_indexes[i], value_accumulator) % mdiv) * VH_BYTE_ALIGNMENT / sizeof(uint32_t);
const uint32_t *blob_off = blob_bytes_32 + offset;
for (size_t i2 = 0; i2 < VH_HASH_OUT_SIZE / sizeof(uint32_t); i2++)
{
const uint32_t value = *(blob_bytes_32 + offset + i2);
const uint32_t value = *( blob_off + i2 );
uint32_t* p1_ptr = p1_32 + i2;
*p1_ptr = fnv1a(*p1_ptr, value);
value_accumulator = fnv1a(value_accumulator, value);
*p1_ptr = fnv1a( *p1_ptr, value );
value_accumulator = fnv1a( value_accumulator, value );
}
}
@@ -591,6 +649,9 @@ struct Graph *NewGraph(int64_t index, const char* targetFile, uint8_t *pk)
int64_t pow2 = 1 << ((uint64_t)log2);
struct Graph *g = (struct Graph *)malloc(sizeof(struct Graph));
if ( !g ) return NULL;
g->db = db;
g->log2 = log2;
g->pow2 = pow2;
@@ -607,14 +668,27 @@ struct Graph *NewGraph(int64_t index, const char* targetFile, uint8_t *pk)
}
//-----------------------------------------------------------------------------
// use info for _mm_malloc, then verify file
int verthash_generate_data_file(const char* output_file_name)
{
const char *hashInput = "Verthash Proof-of-Space Datafile";
uint8_t *pk = (uint8_t*)malloc(NODE_SIZE);
sha3(hashInput, 32, pk, NODE_SIZE);
uint8_t *pk = (uint8_t*)malloc( NODE_SIZE );
if ( !pk )
{
applog( LOG_ERR, "Verthash data memory allocation failed");
return -1;
}
sha3( hashInput, 32, pk, NODE_SIZE );
int64_t index = 17;
NewGraph(index, output_file_name, pk);
if ( !NewGraph( index, output_file_name, pk ) )
{
applog( LOG_ERR, "Verthash file creation failed");
return -1;
}
return 0;
}

View File

@@ -47,10 +47,6 @@ void verthash_info_free(verthash_info_t* info);
//! Generate verthash data file and save it to specified location.
int verthash_generate_data_file(const char* output_file_name);
void verthash_sha3_prehash_72( const void *data );
void verthash_sha3_final_8( sha3_ctx_t *ctx, void *out, const void *data );
void verthash_hash(const unsigned char* blob_bytes,
const size_t blob_size,
const unsigned char(*input)[VH_HEADER_SIZE],

View File

@@ -12,8 +12,6 @@ static const uint8_t verthashDatFileHash_bytes[32] =
0x29, 0xec, 0xf8, 0x8f, 0x8a, 0xd4, 0x76, 0x39,
0xb6, 0xed, 0xed, 0xaf, 0xd7, 0x21, 0xaa, 0x48 };
static const char* verthash_data_file_name = "verthash.dat";
int scanhash_verthash( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
@@ -28,7 +26,6 @@ int scanhash_verthash( struct work *work, uint32_t max_nonce,
const bool bench = opt_benchmark;
mm128_bswap32_80( edata, pdata );
// verthash_sha3_prehash_72( edata );
do
{
edata[19] = n;
@@ -47,6 +44,7 @@ int scanhash_verthash( struct work *work, uint32_t max_nonce,
return 0;
}
const char *default_verthash_data_file = "verthash.dat";
bool register_verthash_algo( algo_gate_t* gate )
{
@@ -55,42 +53,49 @@ bool register_verthash_algo( algo_gate_t* gate )
gate->scanhash = (void*)&scanhash_verthash;
// verthash data file
int vhLoadResult = verthash_info_init(&verthashInfo, verthash_data_file_name );
// Check Verthash initialization status
if (vhLoadResult == 0) // No Error
{
applog(LOG_INFO, "Verthash data file has been loaded succesfully!");
char *verthash_data_file = opt_data_file ? opt_data_file
: default_verthash_data_file;
int vhLoadResult = verthash_info_init( &verthashInfo, verthash_data_file );
if (vhLoadResult == 0) // No Error
{
// and verify data file(if it was enabled)
if ( true )
// if (!cmdr.disableVerthashDataFileVerification)
if ( opt_verify )
{
uint8_t vhDataFileHash[32] = { 0 };
applog( LOG_NOTICE, "Verifying Verthash data" );
sph_sha256_full( vhDataFileHash, verthashInfo.data,
verthashInfo.dataSize );
if ( memcmp( vhDataFileHash, verthashDatFileHash_bytes,
sizeof(verthashDatFileHash_bytes) ) == 0 )
applog(LOG_INFO, "Verthash data file has been verified succesfully!");
applog( LOG_NOTICE, "Verthash data has been verified" );
else
applog(LOG_ERR, "Verthash data file verification has failed!");
{
applog( LOG_ERR, "Verthash data verification has failed" );
return false;
}
}
else
applog(LOG_WARNING, "Verthash data file verification stage is disabled!");
}
else
{
// Handle Verthash error codes
if (vhLoadResult == 1)
applog(LOG_ERR, "Verthash data file name is invalid");
else if (vhLoadResult == 2)
applog(LOG_ERR, "Failed to allocate memory for Verthash data");
else // for debugging purposes
applog(LOG_ERR, "Verthash data initialization unknown error code: %d",
vhLoadResult);
return false;
// Handle Verthash error codes
if ( vhLoadResult == 1 )
{
applog( LOG_ERR, "Verthash data file not found: %s", verthash_data_file );
if ( !opt_data_file )
applog( LOG_NOTICE, "Add '--verify' to create verthash.dat");
}
else if ( vhLoadResult == 2 )
applog( LOG_ERR, "Failed to allocate memory for Verthash data" );
// else // for debugging purposes
// applog( LOG_ERR, "Verthash data initialization unknown error code: %d",
// vhLoadResult );
return false;
}
printf("\n");
return true;
}

20
configure vendored
View File

@@ -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.15.8.
# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.16.1.
#
#
# 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.15.8'
PACKAGE_STRING='cpuminer-opt 3.15.8'
PACKAGE_VERSION='3.16.1'
PACKAGE_STRING='cpuminer-opt 3.16.1'
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.15.8 to adapt to many kinds of systems.
\`configure' configures cpuminer-opt 3.16.1 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.15.8:";;
short | recursive ) echo "Configuration of cpuminer-opt 3.16.1:";;
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.15.8
cpuminer-opt configure 3.16.1
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.15.8, which was
It was created by cpuminer-opt $as_me 3.16.1, 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.15.8'
VERSION='3.16.1'
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.15.8, which was
This file was extended by cpuminer-opt $as_me 3.16.1, 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.15.8
cpuminer-opt config.status 3.16.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

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

View File

@@ -112,7 +112,6 @@ char* opt_param_key = NULL;
int opt_param_n = 0;
int opt_param_r = 0;
int opt_n_threads = 0;
bool opt_reset_on_stale = false;
bool opt_sapling = false;
// Windows doesn't support 128 bit affinity mask.
@@ -134,6 +133,8 @@ char *rpc_userpass = NULL;
char *rpc_user, *rpc_pass;
char *short_url = NULL;
char *coinbase_address;
char *opt_data_file = NULL;
bool opt_verify = false;
// pk_buffer_size is used as a version selector by b58 code, therefore
// it must be set correctly to work.
@@ -1070,12 +1071,11 @@ 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. : exp32 * last_targetdiff
* (double)(accepts) / share_time;
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;
double shrate = safe_div( exp32 * last_targetdiff * (double)(accepts),
share_time, 0. );
double sess_hrate = safe_div( exp32 * norm_diff_sum,
(double)uptime.tv_sec, 0. );
double submit_rate = safe_div( (double)submits * 60., share_time, 0. );
char shr_units[4] = {0};
char ghr_units[4] = {0};
char sess_hr_units[4] = {0};
@@ -1092,11 +1092,10 @@ void report_summary_log( bool force )
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 ) );
submit_rate, (double)submitted_share_count*60. /
( (double)uptime.tv_sec + (double)uptime.tv_usec / 1e6 ) );
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 );
if ( accepted_share_count < submitted_share_count )
{
@@ -1110,37 +1109,40 @@ void report_summary_log( bool force )
char lghr_units[4] = {0};
scale_hash_for_display( &lost_shrate, lshr_units );
scale_hash_for_display( &lost_ghrate, lghr_units );
applog2( LOG_INFO, "Lost hash rate %7.2f%sh/s %7.2f%sh/s",
lost_shrate, lshr_units, lost_ghrate, lghr_units );
applog2( LOG_INFO, "Lost hash rate %7.2f%sh/s %7.2f%sh/s",
lost_shrate, lshr_units, lost_ghrate, lghr_units );
}
applog2( LOG_INFO,"Submitted %6d %6d",
submits, submitted_share_count );
applog2( LOG_INFO,"Accepted %6d %6d %5.1f%%",
accepts, accepted_share_count,
100. * accepted_share_count / submitted_share_count );
applog2( LOG_INFO,"Submitted %7d %7d",
submits, submitted_share_count );
applog2( LOG_INFO, "Accepted %7d %7d %5.1f%%",
accepts, accepted_share_count,
100. * safe_div( (double)accepted_share_count,
(double)submitted_share_count, 0. ) );
if ( stale_share_count )
applog2( LOG_INFO,"Stale %6d %6d %5.1f%%",
stales, stale_share_count,
100. * stale_share_count / submitted_share_count );
applog2( LOG_INFO, "Stale %7d %7d %5.1f%%",
stales, stale_share_count,
100. * safe_div( (double)stale_share_count,
(double)submitted_share_count, 0. ) );
if ( rejected_share_count )
applog2( LOG_INFO,"Rejected %6d %6d %5.1f%%",
rejects, rejected_share_count,
100. * rejected_share_count / submitted_share_count );
applog2( LOG_INFO, "Rejected %7d %7d %5.1f%%",
rejects, rejected_share_count,
100. * safe_div( (double)rejected_share_count,
(double)submitted_share_count, 0. ) );
if ( solved_block_count )
applog2( LOG_INFO,"Blocks Solved %6d %6d",
solved, solved_block_count );
applog2( LOG_INFO,"Blocks Solved %7d %7d",
solved, solved_block_count );
applog2( LOG_INFO, "Hi/Lo Share Diff %.5g / %.5g",
highest_share, lowest_share );
highest_share, lowest_share );
static int64_t no_acks = 0;
if ( no_acks )
{
no_acks = submitted_share_count
int mismatch = submitted_share_count
- ( accepted_share_count + stale_share_count + rejected_share_count );
if ( no_acks ) // 2 consecutive cycles non zero
applog(LOG_WARNING,"Share count mismatch: %d, stats may be incorrect",
no_acks );
if ( mismatch )
{
if ( mismatch != 1 )
applog(LOG_WARNING,"Share count mismatch: %d, stats may be incorrect", mismatch );
else
applog(LOG_INFO,"Share count mismatch, submitted share may still be pending" );
}
}
@@ -1294,7 +1296,8 @@ static int share_result( int result, struct work *work,
if ( reason ) applog( LOG_WARNING, "Reject reason: %s", reason );
diff_to_hash( str, my_stats.share_diff );
applog2( LOG_INFO, "Hash: %08x%08x%08x...", str[7], str[6], str[5] );
applog2( LOG_INFO, "Hash: %08x%08x%08x%08x%08x%08x", str[7], str[6],
str[5], str[4], str[3],str[2], str[1], str[0] );
if ( work )
targ = work->target;
@@ -1303,7 +1306,8 @@ static int share_result( int result, struct work *work,
diff_to_hash( str, my_stats.target_diff );
targ = &str[0];
}
applog2( LOG_INFO, "Target: %08x%08x%08x...", targ[7], targ[6], targ[5] );
applog2( LOG_INFO, "Target: %08x%08x%08x%08x%08x%08x", targ[7], targ[6],
targ[5], targ[4], targ[3], targ[2], targ[1], targ[0] );
}
return 1;
}
@@ -2790,6 +2794,189 @@ out:
return NULL;
}
static void show_credits()
{
printf("\n ********** "PACKAGE_NAME" "PACKAGE_VERSION" *********** \n");
printf(" A CPU miner with multi algo support and optimized for CPUs\n");
printf(" with AVX512, SHA and VAES extensions by JayDDee.\n");
printf(" BTC donation address: 12tdvfF7KmAsihBXQXynT6E6th2c2pByTT\n\n");
}
#define check_cpu_capability() cpu_capability( false )
#define display_cpu_capability() cpu_capability( true )
static bool cpu_capability( bool display_only )
{
char cpu_brand[0x40];
bool cpu_has_sse2 = has_sse2();
bool cpu_has_aes = has_aes_ni();
bool cpu_has_sse42 = has_sse42();
bool cpu_has_avx = has_avx();
bool cpu_has_avx2 = has_avx2();
bool cpu_has_sha = has_sha();
bool cpu_has_avx512 = has_avx512();
bool cpu_has_vaes = has_vaes();
bool sw_has_aes = false;
bool sw_has_sse2 = false;
bool sw_has_sse42 = false;
bool sw_has_avx = false;
bool sw_has_avx2 = false;
bool sw_has_avx512 = false;
bool sw_has_sha = false;
bool sw_has_vaes = false;
set_t algo_features = algo_gate.optimizations;
bool algo_has_sse2 = set_incl( SSE2_OPT, algo_features );
bool algo_has_aes = set_incl( AES_OPT, algo_features );
bool algo_has_sse42 = set_incl( SSE42_OPT, algo_features );
bool algo_has_avx2 = set_incl( AVX2_OPT, algo_features );
bool algo_has_avx512 = set_incl( AVX512_OPT, algo_features );
bool algo_has_sha = set_incl( SHA_OPT, algo_features );
bool algo_has_vaes = set_incl( VAES_OPT, algo_features );
bool algo_has_vaes256 = set_incl( VAES256_OPT, algo_features );
bool use_aes;
bool use_sse2;
bool use_sse42;
bool use_avx2;
bool use_avx512;
bool use_sha;
bool use_vaes;
bool use_none;
#ifdef __AES__
sw_has_aes = true;
#endif
#ifdef __SSE2__
sw_has_sse2 = true;
#endif
#ifdef __SSE4_2__
sw_has_sse42 = true;
#endif
#ifdef __AVX__
sw_has_avx = true;
#endif
#ifdef __AVX2__
sw_has_avx2 = true;
#endif
#if (defined(__AVX512F__) && defined(__AVX512DQ__) && defined(__AVX512BW__) && defined(__AVX512VL__))
sw_has_avx512 = true;
#endif
#ifdef __SHA__
sw_has_sha = true;
#endif
#ifdef __VAES__
sw_has_vaes = true;
#endif
// #if !((__AES__) || (__SSE2__))
// printf("Neither __AES__ nor __SSE2__ defined.\n");
// #endif
cpu_brand_string( cpu_brand );
printf( "CPU: %s\n", cpu_brand );
printf("SW built on " __DATE__
#ifdef _MSC_VER
" with VC++ 2013\n");
#elif defined(__GNUC__)
" with GCC");
printf(" %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#else
printf("\n");
#endif
printf("CPU features: ");
if ( cpu_has_avx512 ) printf( " AVX512" );
else if ( cpu_has_avx2 ) printf( " AVX2 " );
else if ( cpu_has_avx ) printf( " AVX " );
else if ( cpu_has_sse42 ) printf( " SSE4.2" );
else if ( cpu_has_sse2 ) printf( " SSE2 " );
if ( cpu_has_vaes ) printf( " VAES" );
else if ( cpu_has_aes ) printf( " AES" );
if ( cpu_has_sha ) printf( " SHA" );
printf("\nSW features: ");
if ( sw_has_avx512 ) printf( " AVX512" );
else if ( sw_has_avx2 ) printf( " AVX2 " );
else if ( sw_has_avx ) printf( " AVX " );
else if ( sw_has_sse42 ) printf( " SSE4.2" );
else if ( sw_has_sse2 ) printf( " SSE2 " );
if ( sw_has_vaes ) printf( " VAES" );
else if ( sw_has_aes ) printf( " AES" );
if ( sw_has_sha ) printf( " SHA" );
printf("\nAlgo features:");
if ( algo_features == EMPTY_SET ) printf( " None" );
else
{
if ( algo_has_avx512 ) printf( " AVX512" );
else if ( algo_has_avx2 ) printf( " AVX2 " );
else if ( algo_has_sse42 ) printf( " SSE4.2" );
else if ( algo_has_sse2 ) printf( " SSE2 " );
if ( algo_has_vaes ) printf( " VAES" );
else if ( algo_has_aes ) printf( " AES" );
if ( algo_has_sha ) printf( " SHA" );
}
printf("\n");
if ( display_only ) return true;
// Check for CPU and build incompatibilities
if ( !cpu_has_sse2 )
{
printf( "A CPU with SSE2 is required to use cpuminer-opt\n" );
return false;
}
if ( sw_has_avx2 && !( cpu_has_avx2 && cpu_has_aes ) )
{
printf( "The SW build requires a CPU with AES and AVX2!\n" );
return false;
}
if ( sw_has_sse42 && !cpu_has_sse42 )
{
printf( "The SW build requires a CPU with SSE4.2!\n" );
return false;
}
if ( sw_has_aes && !cpu_has_aes )
{
printf( "The SW build requires a CPU with AES!\n" );
return false;
}
if ( sw_has_sha && !cpu_has_sha )
{
printf( "The SW build requires a CPU with SHA!\n" );
return false;
}
// Determine mining options
use_sse2 = cpu_has_sse2 && algo_has_sse2;
use_aes = cpu_has_aes && sw_has_aes && algo_has_aes;
use_sse42 = cpu_has_sse42 && sw_has_sse42 && algo_has_sse42;
use_avx2 = cpu_has_avx2 && sw_has_avx2 && algo_has_avx2;
use_avx512 = cpu_has_avx512 && sw_has_avx512 && algo_has_avx512;
use_sha = cpu_has_sha && sw_has_sha && algo_has_sha;
use_vaes = cpu_has_vaes && sw_has_vaes && algo_has_vaes
&& ( use_avx512 || algo_has_vaes256 );
use_none = !( use_sse2 || use_aes || use_sse42 || use_avx512 || use_avx2 ||
use_sha || use_vaes );
// Display best options
printf( "\nStarting miner with" );
if ( use_none ) printf( " no optimizations" );
else
{
if ( use_avx512 ) printf( " AVX512" );
else if ( use_avx2 ) printf( " AVX2" );
else if ( use_sse42 ) printf( " SSE4.2" );
else if ( use_sse2 ) printf( " SSE2" );
if ( use_vaes ) printf( " VAES" );
else if ( use_aes ) printf( " AES" );
if ( use_sha ) printf( " SHA" );
}
printf( "...\n\n" );
return true;
}
void show_version_and_exit(void)
{
printf("\n built on " __DATE__
@@ -2837,7 +3024,6 @@ void show_version_and_exit(void)
#endif
"\n\n");
/* dependencies versions */
printf("%s\n", curl_version());
#ifdef JANSSON_VERSION
printf("jansson/%s ", JANSSON_VERSION);
@@ -2849,7 +3035,6 @@ void show_version_and_exit(void)
exit(0);
}
void show_usage_and_exit(int status)
{
if (status)
@@ -3237,11 +3422,15 @@ void parse_arg(int key, char *arg )
case 1024:
opt_randomize = true;
break;
case 1026:
opt_reset_on_stale = true;
case 1027: // data-file
opt_data_file = strdup( arg );
break;
case 1028: // verify
opt_verify = true;
break;
case 'V':
show_version_and_exit();
display_cpu_capability();
exit(0);
case 'h':
show_usage_and_exit(0);
@@ -3358,185 +3547,6 @@ static int thread_create(struct thr_info *thr, void* func)
return err;
}
static void show_credits()
{
printf("\n ********** "PACKAGE_NAME" "PACKAGE_VERSION" *********** \n");
printf(" A CPU miner with multi algo support and optimized for CPUs\n");
printf(" with AVX512, SHA and VAES extensions by JayDDee.\n");
printf(" BTC donation address: 12tdvfF7KmAsihBXQXynT6E6th2c2pByTT\n\n");
}
bool check_cpu_capability ()
{
char cpu_brand[0x40];
bool cpu_has_sse2 = has_sse2();
bool cpu_has_aes = has_aes_ni();
bool cpu_has_sse42 = has_sse42();
bool cpu_has_avx = has_avx();
bool cpu_has_avx2 = has_avx2();
bool cpu_has_sha = has_sha();
bool cpu_has_avx512 = has_avx512();
bool cpu_has_vaes = has_vaes();
bool sw_has_aes = false;
bool sw_has_sse2 = false;
bool sw_has_sse42 = false;
bool sw_has_avx = false;
bool sw_has_avx2 = false;
bool sw_has_avx512 = false;
bool sw_has_sha = false;
bool sw_has_vaes = false;
set_t algo_features = algo_gate.optimizations;
bool algo_has_sse2 = set_incl( SSE2_OPT, algo_features );
bool algo_has_aes = set_incl( AES_OPT, algo_features );
bool algo_has_sse42 = set_incl( SSE42_OPT, algo_features );
bool algo_has_avx2 = set_incl( AVX2_OPT, algo_features );
bool algo_has_avx512 = set_incl( AVX512_OPT, algo_features );
bool algo_has_sha = set_incl( SHA_OPT, algo_features );
bool algo_has_vaes = set_incl( VAES_OPT, algo_features );
bool algo_has_vaes256 = set_incl( VAES256_OPT, algo_features );
bool use_aes;
bool use_sse2;
bool use_sse42;
bool use_avx2;
bool use_avx512;
bool use_sha;
bool use_vaes;
bool use_none;
#ifdef __AES__
sw_has_aes = true;
#endif
#ifdef __SSE2__
sw_has_sse2 = true;
#endif
#ifdef __SSE4_2__
sw_has_sse42 = true;
#endif
#ifdef __AVX__
sw_has_avx = true;
#endif
#ifdef __AVX2__
sw_has_avx2 = true;
#endif
#if (defined(__AVX512F__) && defined(__AVX512DQ__) && defined(__AVX512BW__) && defined(__AVX512VL__))
sw_has_avx512 = true;
#endif
#ifdef __SHA__
sw_has_sha = true;
#endif
#ifdef __VAES__
sw_has_vaes = true;
#endif
// #if !((__AES__) || (__SSE2__))
// printf("Neither __AES__ nor __SSE2__ defined.\n");
// #endif
cpu_brand_string( cpu_brand );
printf( "CPU: %s\n", cpu_brand );
printf("SW built on " __DATE__
#ifdef _MSC_VER
" with VC++ 2013\n");
#elif defined(__GNUC__)
" with GCC");
printf(" %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#else
printf("\n");
#endif
printf("CPU features: ");
if ( cpu_has_avx512 ) printf( " AVX512" );
else if ( cpu_has_avx2 ) printf( " AVX2 " );
else if ( cpu_has_avx ) printf( " AVX " );
else if ( cpu_has_sse42 ) printf( " SSE4.2" );
else if ( cpu_has_sse2 ) printf( " SSE2 " );
if ( cpu_has_vaes ) printf( " VAES" );
else if ( cpu_has_aes ) printf( " AES" );
if ( cpu_has_sha ) printf( " SHA" );
printf("\nSW features: ");
if ( sw_has_avx512 ) printf( " AVX512" );
else if ( sw_has_avx2 ) printf( " AVX2 " );
else if ( sw_has_avx ) printf( " AVX " );
else if ( sw_has_sse42 ) printf( " SSE4.2" );
else if ( sw_has_sse2 ) printf( " SSE2 " );
if ( sw_has_vaes ) printf( " VAES" );
else if ( sw_has_aes ) printf( " AES" );
if ( sw_has_sha ) printf( " SHA" );
printf("\nAlgo features:");
if ( algo_features == EMPTY_SET ) printf( " None" );
else
{
if ( algo_has_avx512 ) printf( " AVX512" );
else if ( algo_has_avx2 ) printf( " AVX2 " );
else if ( algo_has_sse42 ) printf( " SSE4.2" );
else if ( algo_has_sse2 ) printf( " SSE2 " );
if ( algo_has_vaes ) printf( " VAES" );
else if ( algo_has_aes ) printf( " AES" );
if ( algo_has_sha ) printf( " SHA" );
}
printf("\n");
// Check for CPU and build incompatibilities
if ( !cpu_has_sse2 )
{
printf( "A CPU with SSE2 is required to use cpuminer-opt\n" );
return false;
}
if ( sw_has_avx2 && !( cpu_has_avx2 && cpu_has_aes ) )
{
printf( "The SW build requires a CPU with AES and AVX2!\n" );
return false;
}
if ( sw_has_sse42 && !cpu_has_sse42 )
{
printf( "The SW build requires a CPU with SSE4.2!\n" );
return false;
}
if ( sw_has_aes && !cpu_has_aes )
{
printf( "The SW build requires a CPU with AES!\n" );
return false;
}
if ( sw_has_sha && !cpu_has_sha )
{
printf( "The SW build requires a CPU with SHA!\n" );
return false;
}
// Determine mining options
use_sse2 = cpu_has_sse2 && algo_has_sse2;
use_aes = cpu_has_aes && sw_has_aes && algo_has_aes;
use_sse42 = cpu_has_sse42 && sw_has_sse42 && algo_has_sse42;
use_avx2 = cpu_has_avx2 && sw_has_avx2 && algo_has_avx2;
use_avx512 = cpu_has_avx512 && sw_has_avx512 && algo_has_avx512;
use_sha = cpu_has_sha && sw_has_sha && algo_has_sha;
use_vaes = cpu_has_vaes && sw_has_vaes && algo_has_vaes
&& ( use_avx512 || algo_has_vaes256 );
use_none = !( use_sse2 || use_aes || use_sse42 || use_avx512 || use_avx2 ||
use_sha || use_vaes );
// Display best options
printf( "\nStarting miner with" );
if ( use_none ) printf( " no optimizations" );
else
{
if ( use_avx512 ) printf( " AVX512" );
else if ( use_avx2 ) printf( " AVX2" );
else if ( use_sse42 ) printf( " SSE4.2" );
else if ( use_sse2 ) printf( " SSE2" );
if ( use_vaes ) printf( " VAES" );
else if ( use_aes ) printf( " AES" );
if ( use_sha ) printf( " SHA" );
}
printf( "...\n\n" );
return true;
}
void get_defconfig_path(char *out, size_t bufsize, char *argv0);
int main(int argc, char *argv[])
@@ -3598,6 +3608,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "%s: no algo supplied\n", argv[0]);
show_usage_and_exit(1);
}
if ( !register_algo_gate( opt_algo, &algo_gate ) ) exit(1);
if ( !check_cpu_capability() ) exit(1);
if ( !opt_benchmark )
{
if ( !short_url )
@@ -3637,7 +3652,7 @@ int main(int argc, char *argv[])
}
// All options must be set before starting the gate
if ( !register_algo_gate( opt_algo, &algo_gate ) ) exit(1);
// if ( !register_algo_gate( opt_algo, &algo_gate ) ) exit(1);
if ( coinbase_address )
{
@@ -3656,7 +3671,7 @@ int main(int argc, char *argv[])
memcpy( &five_min_start, &last_submit_time, sizeof (struct timeval) );
memcpy( &session_start, &last_submit_time, sizeof (struct timeval) );
if ( !check_cpu_capability() ) exit(1);
// if ( !check_cpu_capability() ) exit(1);
pthread_mutex_init( &stats_lock, NULL );
pthread_rwlock_init( &g_work_lock, NULL );

View File

@@ -737,7 +737,6 @@ extern uint32_t opt_work_size;
extern double *thr_hashrates;
extern double global_hashrate;
extern double stratum_diff;
extern bool opt_reset_on_stale;
extern double net_diff;
extern double net_hashrate;
extern int opt_param_n;
@@ -762,6 +761,8 @@ extern pthread_mutex_t stats_lock;
extern bool opt_sapling;
extern const int pk_buffer_size_max;
extern int pk_buffer_size;
extern char *opt_data_file;
extern bool opt_verify;
static char const usage[] = "\
Usage: cpuminer [OPTIONS]\n\
@@ -905,6 +906,8 @@ Options:\n\
--max-rate=N[KMG] Only mine if net hashrate is less than specified value\n\
--max-diff=N Only mine if net difficulty is less than specified value\n\
-c, --config=FILE load a JSON-format configuration file\n\
--data-file path and name of data file\n\
--verify enable additional time consuming start up tests\n\
-V, --version display version information and exit\n\
-h, --help display this help text and exit\n\
";
@@ -962,7 +965,6 @@ static struct option const options[] = {
{ "retries", 1, NULL, 'r' },
{ "retry-pause", 1, NULL, 1025 },
{ "randomize", 0, NULL, 1024 },
{ "reset-on-stale", 0, NULL, 1026 },
{ "scantime", 1, NULL, 's' },
#ifdef HAVE_SYSLOG_H
{ "syslog", 0, NULL, 'S' },
@@ -973,6 +975,8 @@ static struct option const options[] = {
{ "url", 1, NULL, 'o' },
{ "user", 1, NULL, 'u' },
{ "userpass", 1, NULL, 'O' },
{ "data-file", 1, NULL, 1027 },
{ "verify", 0, NULL, 1028 },
{ "version", 0, NULL, 'V' },
{ 0, 0, 0, 0 }
};

View File

@@ -5,6 +5,10 @@
#define bswap_64( a ) __builtin_bswap64( a )
#define bswap_32( a ) __builtin_bswap32( a )
// safe division, integer or floating point
#define safe_div( dividend, divisor, safe_result ) \
( (divisor) == 0 ? safe_result : ( (dividend) / (divisor) ) )
///////////////////////////////////////
//

View File

@@ -1,17 +1,80 @@
Quickstart:
----------
The verthash data file must be named verthash.dat and located in the same
directory as the cpuminer executable. A Linux symlink works.
First time mining verthash or don't have a Verthash data file:
The verthash data file must be obtained seperately. If you already use
VerthashMiner you can simply copy or link the existing data file to the
cpuminer directory, using the required name.
--algo verthash --verify --url ...
Otherwise it may be created using
https://github.com/CryptoGraphics/VerthashMiner/releases
following the instructions. A GPU is not necessary to create the file.
Verthash data file already exists:
The same data file can be used by both cpuminer and VerthashMiner
simultaneously.
--algo verthash --data-file /path/to/verthash.dat --url ...
Background:
----------
Verthash algorithm requires a data file for hashing. This file is
static, portable, and only needs to be created once.
A Verthash data file created by VerthashMiner can also be used by cpuminer-opt
and used simultaneously by both miners.
Due to its size >1GB it is recommened one data file be created and
stored in a permanent location accessible to any miner that wants to use it.
New command line options:
------------------------
cpuminer-opt adds two new command line options for verthash. The names
and some behaviour is changed from VerthashMiner.
--data-file /path/to/verthash.dat
default when not used is verthash.dat in current working directory.
--verify
verify integrity of file specified by --data-file, or if not specified
the default data file if it exists, or create a default file and verify it
if one does not yet exist. Data file verification is disabled by default.
Detailed usage:
--------------
If a data file already exists it can be selected using the --data-file
option to specify the path and name of the file.
--algo verthash --datafile /path/to/verthash.dat --url ...
If the --data-file option is not used the default is to use 'verthash.dat'
from the current working directory.
If no data file exists it can be created by using the --verify option
without the --data-file option. If the default data file is not found in
the current directory it will be created.
--algo verthash --verify --url ...
Data file creation can take up to 30 minutes on a spinning hard drive.
Once created the new data file will be verified and used immediately
if a valid url and user were included on the command line.
A default data file can be created by ommitting the url option. That will
either verify an existing default data file or create one and verify it,
then exit.
--algo verthash --verify
A data file will never be created if --data-file is specified. The miner
will exit with an error if the file is not found. This is to avoid accidentally
creating an unwanted data file due to a typo.
After creation the data file can moved to a more convenient location and
referenced by --data-file, or left where it is and used by default without the
--data-file option.
Data file verification takes a few seconds and is disabled by default.
VerthashMiner enables data file verification by default and has an option to
disable it.
The --verify option is intended primarily to create a new file. It's
not necessary or useful to verify a file every time the miner is started.
Launching cpuminer to mine verthash is the same as any other algorithm,
no extra options are required.