@ -1669,6 +1669,37 @@ static bool parse_diff(struct pool *pool, json_t *val)
return true ;
return true ;
}
}
static bool parse_extranonce ( struct pool * pool , json_t * val )
{
char s [ RBUFSIZE ] , * nonce1 ;
int n2size ;
nonce1 = json_array_string ( val , 0 ) ;
if ( ! nonce1 ) {
return false ;
}
n2size = json_integer_value ( json_array_get ( val , 1 ) ) ;
if ( ! n2size ) {
free ( nonce1 ) ;
return false ;
}
cg_wlock ( & pool - > data_lock ) ;
pool - > nonce1 = nonce1 ;
pool - > n1_len = strlen ( nonce1 ) / 2 ;
free ( pool - > nonce1bin ) ;
pool - > nonce1bin = ( unsigned char * ) calloc ( pool - > n1_len , 1 ) ;
if ( unlikely ( ! pool - > nonce1bin ) )
quithere ( 1 , " Failed to calloc pool->nonce1bin " ) ;
hex2bin ( pool - > nonce1bin , pool - > nonce1 , pool - > n1_len ) ;
pool - > n2size = n2size ;
cg_wunlock ( & pool - > data_lock ) ;
applog ( LOG_NOTICE , " %s extranonce change requested " , get_pool_name ( pool ) ) ;
return true ;
}
static void __suspend_stratum ( struct pool * pool )
static void __suspend_stratum ( struct pool * pool )
{
{
clear_sockbuf ( pool ) ;
clear_sockbuf ( pool ) ;
@ -1814,6 +1845,12 @@ bool parse_method(struct pool *pool, char *s)
return ret ;
return ret ;
}
}
if ( ! strncasecmp ( buf , " mining.set_extranonce " , 21 ) & & parse_extranonce ( pool , params ) ) {
ret = true ;
json_decref ( val ) ;
return ret ;
}
if ( ! strncasecmp ( buf , " client.reconnect " , 16 ) & & parse_reconnect ( pool , params ) ) {
if ( ! strncasecmp ( buf , " client.reconnect " , 16 ) & & parse_reconnect ( pool , params ) ) {
ret = true ;
ret = true ;
json_decref ( val ) ;
json_decref ( val ) ;
@ -1835,6 +1872,77 @@ bool parse_method(struct pool *pool, char *s)
return ret ;
return ret ;
}
}
bool subscribe_extranonce ( struct pool * pool )
{
json_t * val = NULL , * res_val , * err_val ;
char s [ RBUFSIZE ] , * sret = NULL ;
json_error_t err ;
bool ret = false ;
sprintf ( s , " { \" id \" : %d, \" method \" : \" mining.extranonce.subscribe \" , \" params \" : []} " ,
swork_id + + ) ;
if ( ! stratum_send ( pool , s , strlen ( s ) ) )
return ret ;
/* Parse all data in the queue and anything left should be the response */
while ( 42 ) {
if ( ! socket_full ( pool , DEFAULT_SOCKWAIT / 30 ) ) {
applog ( LOG_DEBUG , " Timed out waiting for response extranonce.subscribe " ) ;
/* some pool doesnt send anything, so this is normal */
ret = true ;
goto out ;
}
sret = recv_line ( pool ) ;
if ( ! sret )
return ret ;
if ( parse_method ( pool , sret ) )
free ( sret ) ;
else
break ;
}
val = JSON_LOADS ( sret , & err ) ;
free ( sret ) ;
res_val = json_object_get ( val , " result " ) ;
err_val = json_object_get ( val , " error " ) ;
if ( ! res_val | | json_is_false ( res_val ) | | ( err_val & & ! json_is_null ( err_val ) ) ) {
char * ss ;
if ( err_val ) {
ss = __json_array_string ( err_val , 1 ) ;
if ( ! ss )
ss = ( char * ) json_string_value ( err_val ) ;
if ( ss & & ( strcmp ( ss , " Method 'subscribe' not found for service 'mining.extranonce' " ) = = 0 ) ) {
applog ( LOG_INFO , " Cannot subscribe to mining.extranonce on %s " , get_pool_name ( pool ) ) ;
ret = true ;
goto out ;
}
if ( ss & & ( strcmp ( ss , " Unrecognized request provided " ) = = 0 ) ) {
applog ( LOG_INFO , " Cannot subscribe to mining.extranonce on %s " , get_pool_name ( pool ) ) ;
ret = true ;
goto out ;
}
ss = json_dumps ( err_val , JSON_INDENT ( 3 ) ) ;
}
else
ss = strdup ( " (unknown reason) " ) ;
applog ( LOG_INFO , " %s JSON stratum auth failed: %s " , get_pool_name ( pool ) , ss ) ;
free ( ss ) ;
goto out ;
}
ret = true ;
applog ( LOG_INFO , " Stratum extranonce subscribe for %s " , get_pool_name ( pool ) ) ;
out :
json_decref ( val ) ;
return ret ;
}
bool auth_stratum ( struct pool * pool )
bool auth_stratum ( struct pool * pool )
{
{
json_t * val = NULL , * res_val , * err_val ;
json_t * val = NULL , * res_val , * err_val ;
@ -2465,6 +2573,8 @@ bool restart_stratum(struct pool *pool)
suspend_stratum ( pool ) ;
suspend_stratum ( pool ) ;
if ( ! initiate_stratum ( pool ) )
if ( ! initiate_stratum ( pool ) )
return false ;
return false ;
if ( pool - > extranonce_subscribe & & ! subscribe_extranonce ( pool ) )
return false ;
if ( ! auth_stratum ( pool ) )
if ( ! auth_stratum ( pool ) )
return false ;
return false ;