mirror of
https://github.com/JayDDee/cpuminer-opt.git
synced 2025-09-17 23:44:27 +00:00
332 lines
15 KiB
C
332 lines
15 KiB
C
/////////////////////////////
|
|
////
|
|
//// NEW FEATURE: algo_gate
|
|
////
|
|
//// algos define targets for their common functions
|
|
//// and define a function for miner-thread to call to register
|
|
//// their targets. miner thread builds the gate, and array of structs
|
|
//// of function pointers, by calling each algo's register function.
|
|
// Functions in this file are used simultaneously by myultiple
|
|
// threads and must therefore be re-entrant.
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#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.
|
|
//
|
|
// Generic null functions do nothing except satisfy the syntax and
|
|
// can be used for optional safe gate functions.
|
|
//
|
|
// null gate functions are genarally used for mandatory and unsafe functions
|
|
// and will usually display an error massage and/or return a fail code.
|
|
// They are registered by default and are expected to be overwritten.
|
|
//
|
|
// std functions are non-null functions used by the most number of algos
|
|
// are are default.
|
|
//
|
|
// aux functions are functions used by many, but not most, algos and must
|
|
// be registered by eech algo using them. They usually have descriptive
|
|
// names.
|
|
//
|
|
// custom functions are algo spefic and are defined and registered in the
|
|
// algo's source file and are usually named [algo]_[function].
|
|
//
|
|
// In most cases the default is a null or std function. However in some
|
|
// cases, for convenience when the null function is not the most popular,
|
|
// the std function will be defined as default and the algo must register
|
|
// an appropriate null function.
|
|
//
|
|
// similar algos may share a gate function that may be defined here or
|
|
// in a source file common to the similar algos.
|
|
//
|
|
// gate functions may call other gate functions under the following
|
|
// restrictions. Any gate function defined here or used by more than one
|
|
// algo must call other functions using the gate: algo_gate.[function].
|
|
// custom functions may call other custom functions directly using
|
|
// [algo]_[function], howver it is recommended to alway use the gate.
|
|
//
|
|
// If, under rare circumstances, an algo with a custom gate function
|
|
// needs to call a function of another algo it must define and register
|
|
// a private gate from its rgistration function and use it to call
|
|
// forein functions: [private_gate].[function]. If the algo needs to call
|
|
// a utility function defined here it may do so directly.
|
|
//
|
|
// The algo's gate registration function is caled once from the main thread
|
|
// and can do other intialization in addition such as setting options or
|
|
// other global or local (to the algo) variables.
|
|
|
|
// A set of predefined generic null functions that can be used as any null
|
|
// gate function with the same signature.
|
|
|
|
void do_nothing () {}
|
|
bool return_true () { return true; }
|
|
bool return_false () { return false; }
|
|
void *return_null () { return NULL; }
|
|
void call_error () { printf("ERR: Uninitialized function pointer\n"); }
|
|
|
|
void algo_not_tested()
|
|
{
|
|
applog( LOG_WARNING,"Algo %s has not been tested live. It may not work",
|
|
algo_names[opt_algo] );
|
|
applog(LOG_WARNING,"and bad things may happen. Use at your own risk.");
|
|
}
|
|
|
|
void four_way_not_tested()
|
|
{
|
|
applog( LOG_WARNING,"Algo %s has not been tested using 4way. It may not", algo_names[opt_algo] );
|
|
applog( LOG_WARNING,"work or may be slower. Please report your results.");
|
|
}
|
|
|
|
void algo_not_implemented()
|
|
{
|
|
applog(LOG_ERR,"Algo %s has not been Implemented.",algo_names[opt_algo]);
|
|
}
|
|
|
|
// default null functions
|
|
|
|
int null_scanhash()
|
|
{
|
|
applog(LOG_WARNING,"SWERR: undefined scanhash function in algo_gate");
|
|
return 0;
|
|
}
|
|
|
|
int null_hash()
|
|
{
|
|
applog(LOG_WARNING,"SWERR: null_hash unsafe null function");
|
|
return 0;
|
|
};
|
|
/*
|
|
void null_hash_suw()
|
|
{
|
|
applog(LOG_WARNING,"SWERR: null_hash_suw unsafe null function");
|
|
};
|
|
*/
|
|
void init_algo_gate( algo_gate_t* gate )
|
|
{
|
|
gate->miner_thread_init = (void*)&return_true;
|
|
gate->scanhash = (void*)&null_scanhash;
|
|
gate->hash = (void*)&null_hash;
|
|
// gate->hash_suw = (void*)&null_hash_suw;
|
|
gate->get_new_work = (void*)&std_get_new_work;
|
|
gate->work_decode = (void*)&std_le_work_decode;
|
|
gate->decode_extra_data = (void*)&do_nothing;
|
|
gate->gen_merkle_root = (void*)&sha256d_gen_merkle_root;
|
|
gate->stratum_gen_work = (void*)&std_stratum_gen_work;
|
|
gate->build_stratum_request = (void*)&std_le_build_stratum_request;
|
|
gate->malloc_txs_request = (void*)&std_malloc_txs_request;
|
|
gate->submit_getwork_result = (void*)&std_le_submit_getwork_result;
|
|
gate->build_block_header = (void*)&std_build_block_header;
|
|
gate->build_extraheader = (void*)&std_build_extraheader;
|
|
gate->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->do_this_thread = (void*)&return_true;
|
|
gate->longpoll_rpc_call = (void*)&std_longpoll_rpc_call;
|
|
gate->get_work_data_size = (void*)&std_get_work_data_size;
|
|
gate->optimizations = EMPTY_SET;
|
|
gate->ntime_index = STD_NTIME_INDEX;
|
|
gate->nbits_index = STD_NBITS_INDEX;
|
|
gate->nonce_index = STD_NONCE_INDEX;
|
|
gate->work_cmp_size = STD_WORK_CMP_SIZE;
|
|
}
|
|
|
|
// Ignore warnings for not yet defined register functions
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
|
|
|
|
// called by each thread that uses the gate
|
|
bool register_algo_gate( int algo, algo_gate_t *gate )
|
|
{
|
|
if ( NULL == gate )
|
|
{
|
|
applog(LOG_ERR,"FAIL: algo_gate registration failed, NULL gate\n");
|
|
return false;
|
|
}
|
|
|
|
init_algo_gate( gate );
|
|
|
|
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_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_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_algo ( gate ); break;
|
|
case ALGO_YESCRYPTR8: register_yescryptr8_algo ( gate ); break;
|
|
case ALGO_YESCRYPTR8G: register_yescryptr8g_algo ( gate ); break;
|
|
case ALGO_YESCRYPTR16: register_yescryptr16_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;
|
|
default:
|
|
applog(LOG_ERR,"FAIL: algo_gate registration failed, unknown algo %s.\n", algo_names[opt_algo] );
|
|
return false;
|
|
} // switch
|
|
|
|
// ensure required functions were defined.
|
|
if ( gate->scanhash == (void*)&null_scanhash )
|
|
{
|
|
applog(LOG_ERR, "FAIL: Required algo_gate functions undefined\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// restore warnings
|
|
#pragma GCC diagnostic pop
|
|
|
|
// run the alternate hash function for a specific algo
|
|
void exec_hash_function( int algo, void *output, const void *pdata )
|
|
{
|
|
algo_gate_t gate;
|
|
gate.hash = (void*)&null_hash;
|
|
register_algo_gate( algo, &gate );
|
|
gate.hash( output, pdata, 0 );
|
|
}
|
|
|
|
#define PROPER (1)
|
|
#define ALIAS (0)
|
|
|
|
// The only difference between the alias and the proper algo name is the
|
|
// proper name is the one that is defined in ALGO_NAMES. There may be
|
|
// multiple aliases that map to the same proper name.
|
|
// New aliases can be added anywhere in the array as long as NULL is last.
|
|
// Alphabetic order of alias is recommended.
|
|
const char* const algo_alias_map[][2] =
|
|
{
|
|
// alias proper
|
|
{ "argon2d-crds", "argon2d250" },
|
|
{ "argon2d-dyn", "argon2d500" },
|
|
{ "argon2d-uis", "argon2d4096" },
|
|
{ "bcd", "x13bcd" },
|
|
{ "bitcore", "timetravel10" },
|
|
{ "bitzeny", "yescryptr8" },
|
|
{ "blake256r8", "blakecoin" },
|
|
{ "blake256r8vnl", "vanilla" },
|
|
{ "blake256r14", "blake" },
|
|
{ "blake256r14dcr", "decred" },
|
|
{ "diamond", "dmd-gr" },
|
|
{ "espers", "hmq1725" },
|
|
{ "flax", "c11" },
|
|
{ "hsr", "x13sm3" },
|
|
{ "jackpot", "jha" },
|
|
{ "jane", "scryptjane" },
|
|
{ "lyra2", "lyra2re" },
|
|
{ "lyra2v2", "lyra2rev2" },
|
|
{ "lyra2v3", "lyra2rev3" },
|
|
{ "myrgr", "myr-gr" },
|
|
{ "myriad", "myr-gr" },
|
|
{ "neo", "neoscrypt" },
|
|
{ "phi", "phi1612" },
|
|
{ "scryptn2", "scrypt:1048576" },
|
|
{ "sib", "x11gost" },
|
|
{ "timetravel8", "timetravel" },
|
|
{ "veil", "x16rt-veil" },
|
|
{ "x16r-hex", "hex" },
|
|
{ "yenten", "yescryptr16" },
|
|
{ "ziftr", "zr5" },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
// if arg is a valid alias for a known algo it is updated with the proper
|
|
// name. No validation of the algo or alias is done, It is the responsinility
|
|
// of the calling function to validate the algo after return.
|
|
void get_algo_alias( char** algo_or_alias )
|
|
{
|
|
int i;
|
|
for ( i=0; algo_alias_map[i][ALIAS]; i++ )
|
|
if ( !strcasecmp( *algo_or_alias, algo_alias_map[i][ ALIAS ] ) )
|
|
{
|
|
// found valid alias, return proper name
|
|
*algo_or_alias = (char*)( algo_alias_map[i][ PROPER ] );
|
|
return;
|
|
}
|
|
}
|
|
|
|
#undef ALIAS
|
|
#undef PROPER
|
|
|