@ -937,12 +937,20 @@ static void __del_client(sdata_t *sdata, stratum_instance_t *client, user_instan
					 
			
		
	
		
			
				
							DL_DELETE ( user - > clients ,  client ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  connector_drop_client ( ckpool_t  * ckp ,  const  int64_t  id )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						char  buf [ 256 ] ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						LOGWARNING ( " Stratifier requesting connector drop client % " PRId64 ,  id ) ;   
			
		
	
		
			
				
						snprintf ( buf ,  255 ,  " dropclient=% " PRId64 ,  id ) ;   
			
		
	
		
			
				
						send_proc ( ckp - > connector ,  buf ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  drop_allclients ( ckpool_t  * ckp )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						stratum_instance_t  * client ,  * tmp ;   
			
		
	
		
			
				
						int  disconnects  =  0 ,  kills  =  0 ;   
			
		
	
		
			
				
						sdata_t  * sdata  =  ckp - > data ;   
			
		
	
		
			
				
						char  buf [ 128 ] ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						ck_wlock ( & sdata - > instance_lock ) ;   
			
		
	
		
			
				
						HASH_ITER ( hh ,  sdata - > stratum_instances ,  client ,  tmp )  {   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -954,8 +962,7 @@ static void drop_allclients(ckpool_t *ckp)
					 
			
		
	
		
			
				
							}  else   
			
		
	
		
			
				
								client - > dropped  =  true ;   
			
		
	
		
			
				
							kills + + ;   
			
		
	
		
			
				
							sprintf ( buf ,  " dropclient=% " PRId64 ,  client_id ) ;   
			
		
	
		
			
				
							send_proc ( ckp - > connector ,  buf ) ;   
			
		
	
		
			
				
							connector_drop_client ( ckp ,  client_id ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						HASH_ITER ( hh ,  sdata - > disconnected_instances ,  client ,  tmp )  {   
			
		
	
		
			
				
							disconnects + + ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -970,62 +977,119 @@ static void drop_allclients(ckpool_t *ckp)
					 
			
		
	
		
			
				
							LOGNOTICE ( " Dropped %d instances " ,  kills ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  proxy_t  * __generate_proxy ( sdata_t  * sdata ,  const  int  id )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						proxy_t  * proxy  =  ckzalloc ( sizeof ( proxy_t ) ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						proxy - > id  =  id ;   
			
		
	
		
			
				
						HASH_ADD_INT ( sdata - > proxies ,  id ,  proxy ) ;   
			
		
	
		
			
				
						return  proxy ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/* Find proxy by id number, generate one if none exist yet by that id */  
			
		
	
		
			
				
					static  proxy_t  * proxy_by_id ( sdata_t  * sdata ,  const  int  id )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						bool  new_proxy  =  false ;   
			
		
	
		
			
				
						proxy_t  * proxy ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						mutex_lock ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
						HASH_FIND_INT ( sdata - > proxies ,  & id ,  proxy ) ;   
			
		
	
		
			
				
						if  ( unlikely ( ! proxy ) )  {   
			
		
	
		
			
				
							new_proxy  =  true ;   
			
		
	
		
			
				
							proxy  =  __generate_proxy ( sdata ,  id ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						mutex_unlock ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( unlikely ( new_proxy ) )   
			
		
	
		
			
				
							LOGINFO ( " Stratifier added new proxy %d " ,  id ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  proxy ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  reconnect_clients ( sdata_t  * sdata ,  const  char  * cmd ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  update_subscribe ( ckpool_t  * ckp )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						sdata_t  * sdata  =  ckp - > data ;   
			
		
	
		
			
				
						proxy_t  * proxy ;   
			
		
	
		
			
				
						json_t  * val ;   
			
		
	
		
			
				
						int  id  =  0 ;   
			
		
	
		
			
				
						char  * buf ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						buf  =  send_recv_proc ( ckp - > generator ,  " getsubscribe " ) ;   
			
		
	
		
			
				
						if  ( unlikely ( ! buf ) )  {   
			
		
	
		
			
				
							LOGWARNING ( " Failed to get subscribe from generator in update_notify " ) ;   
			
		
	
		
			
				
							LOGWARNING ( " Failed to get subscribe from generator in update_subscribe  " ) ;   
			
		
	
		
			
				
							drop_allclients ( ckp ) ;   
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						LOGDEBUG ( " Update subscribe: %s " ,  buf ) ;   
			
		
	
		
			
				
						val  =  json_loads ( buf ,  0 ,  NULL ) ;   
			
		
	
		
			
				
						free ( buf ) ;   
			
		
	
		
			
				
						if  ( unlikely ( ! val ) )  {   
			
		
	
		
			
				
							LOGWARNING ( " Failed to json decode getsubscribe response in update_subscribe " ) ;   
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						json_get_int ( & id ,  val ,  " proxy " ) ;   
			
		
	
		
			
				
						proxy  =  proxy_by_id ( sdata ,  id ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						mutex_lock ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
						if  ( sdata - > proxy  ! =  proxy )   
			
		
	
		
			
				
							sdata - > proxy  =  proxy ;   
			
		
	
		
			
				
						mutex_unlock ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						ck_wlock ( & sdata - > workbase_lock ) ;   
			
		
	
		
			
				
						sdata - > proxy - > subscribed  =  true ;   
			
		
	
		
			
				
						sdata - > proxy - > diff  =  ckp - > startdiff ;   
			
		
	
		
			
				
						proxy - > subscribed  =  true ;   
			
		
	
		
			
				
						proxy - > diff  =  ckp - > startdiff ;   
			
		
	
		
			
				
						/* Length is checked by generator */   
			
		
	
		
			
				
						strcpy ( sdata - > proxy - > enonce1 ,  json_string_value ( json_object_get ( val ,  " enonce1 " ) ) ) ;   
			
		
	
		
			
				
						sdata - > proxy - > enonce1constlen  =  strlen ( sdata - > proxy - > enonce1 )  /  2 ;   
			
		
	
		
			
				
						hex2bin ( sdata - > proxy - > enonce1bin ,  sdata - > proxy - > enonce1 ,  sdata - > proxy - > enonce1constlen ) ;   
			
		
	
		
			
				
						sdata - > proxy - > nonce2len  =  json_integer_value ( json_object_get ( val ,  " nonce2len " ) ) ;   
			
		
	
		
			
				
						strcpy ( proxy - > enonce1 ,  json_string_value ( json_object_get ( val ,  " enonce1 " ) ) ) ;   
			
		
	
		
			
				
						proxy - > enonce1constlen  =  strlen ( proxy - > enonce1 )  /  2 ;   
			
		
	
		
			
				
						hex2bin ( proxy - > enonce1bin ,  proxy - > enonce1 ,  proxy - > enonce1constlen ) ;   
			
		
	
		
			
				
						proxy - > nonce2len  =  json_integer_value ( json_object_get ( val ,  " nonce2len " ) ) ;   
			
		
	
		
			
				
						if  ( ckp - > clientsvspeed )  {   
			
		
	
		
			
				
							if  ( sdata - > proxy - > nonce2len  >  5 )   
			
		
	
		
			
				
								sdata - > proxy - > enonce1varlen  =  4 ;   
			
		
	
		
			
				
							else  if  ( sdata - > proxy - > nonce2len  >  3 )   
			
		
	
		
			
				
								sdata - > proxy - > enonce1varlen  =  2 ;   
			
		
	
		
			
				
							if  ( proxy - > nonce2len  >  5 )   
			
		
	
		
			
				
								proxy - > enonce1varlen  =  4 ;   
			
		
	
		
			
				
							else  if  ( proxy - > nonce2len  >  3 )   
			
		
	
		
			
				
								proxy - > enonce1varlen  =  2 ;   
			
		
	
		
			
				
							else   
			
		
	
		
			
				
								sdata - > proxy - > enonce1varlen  =  1 ;   
			
		
	
		
			
				
								proxy - > enonce1varlen  =  1 ;   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							if  ( sdata - > proxy - > nonce2len  >  7 )   
			
		
	
		
			
				
								sdata - > proxy - > enonce1varlen  =  4 ;   
			
		
	
		
			
				
							else  if  ( sdata - > proxy - > nonce2len  >  5 )   
			
		
	
		
			
				
								sdata - > proxy - > enonce1varlen  =  2 ;   
			
		
	
		
			
				
							if  ( proxy - > nonce2len  >  7 )   
			
		
	
		
			
				
								proxy - > enonce1varlen  =  4 ;   
			
		
	
		
			
				
							else  if  ( proxy - > nonce2len  >  5 )   
			
		
	
		
			
				
								proxy - > enonce1varlen  =  2 ;   
			
		
	
		
			
				
							else   
			
		
	
		
			
				
								sdata - > proxy - > enonce1varlen  =  1 ;   
			
		
	
		
			
				
								proxy - > enonce1varlen  =  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						sdata - > proxy - > enonce2varlen  =  sdata - > proxy - > nonce2len  -  sdata - > proxy - > enonce1varlen ;   
			
		
	
		
			
				
						proxy - > enonce2varlen  =  proxy - > nonce2len  -  proxy - > enonce1varlen ;   
			
		
	
		
			
				
						ck_wunlock ( & sdata - > workbase_lock ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						LOGNOTICE ( " Upstream pool extranonce2 length %d, max proxy clients %lld " ,   
			
		
	
		
			
				
							  sdata - > proxy - > nonce2len ,  1ll  < <  ( sdata - > proxy - > enonce1varlen  *  8 ) ) ;   
			
		
	
		
			
				
							  proxy - > nonce2len ,  1ll  < <  ( proxy - > enonce1varlen  *  8 ) ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						json_decref ( val ) ;   
			
		
	
		
			
				
						drop_allclients ( ckp ) ;   
			
		
	
		
			
				
						reconnect_clients ( sdata ,  " " ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  update_diff ( ckpool_t  * ckp ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  proxy_t  * current_proxy ( sdata_t  * sdata )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						proxy_t  * proxy ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						mutex_lock ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
						proxy  =  sdata - > proxy ;   
			
		
	
		
			
				
						mutex_unlock ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  proxy ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  update_notify ( ckpool_t  * ckp )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						bool  new_block  =  false ,  clean ;   
			
		
	
		
			
				
						sdata_t  * sdata  =  ckp - > data ;   
			
		
	
		
			
				
						char  header [ 228 ] ;   
			
		
	
		
			
				
						proxy_t  * proxy ;   
			
		
	
		
			
				
						workbase_t  * wb ;   
			
		
	
		
			
				
						json_t  * val ;   
			
		
	
		
			
				
						char  * buf ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1037,7 +1101,8 @@ static void update_notify(ckpool_t *ckp)
					 
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( unlikely ( ! sdata - > proxy - > subscribed ) )  {   
			
		
	
		
			
				
						proxy  =  current_proxy ( sdata ) ;   
			
		
	
		
			
				
						if  ( unlikely ( ! proxy  | |  ! proxy - > subscribed ) )  {   
			
		
	
		
			
				
							LOGINFO ( " No valid proxy subscription to update notify yet " ) ;   
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
						}   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1088,12 +1153,12 @@ static void update_notify(ckpool_t *ckp)
					 
			
		
	
		
			
				
						update_diff ( ckp ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						ck_rlock ( & sdata - > workbase_lock ) ;   
			
		
	
		
			
				
						strcpy ( wb - > enonce1const ,  sdata - > proxy - > enonce1 ) ;   
			
		
	
		
			
				
						wb - > enonce1constlen  =  sdata - > proxy - > enonce1constlen ;   
			
		
	
		
			
				
						memcpy ( wb - > enonce1constbin ,  sdata - > proxy - > enonce1bin ,  wb - > enonce1constlen ) ;   
			
		
	
		
			
				
						wb - > enonce1varlen  =  sdata - > proxy - > enonce1varlen ;   
			
		
	
		
			
				
						wb - > enonce2varlen  =  sdata - > proxy - > enonce2varlen ;   
			
		
	
		
			
				
						wb - > diff  =  sdata - > proxy - > diff ;   
			
		
	
		
			
				
						strcpy ( wb - > enonce1const ,  proxy - > enonce1 ) ;   
			
		
	
		
			
				
						wb - > enonce1constlen  =  proxy - > enonce1constlen ;   
			
		
	
		
			
				
						memcpy ( wb - > enonce1constbin ,  proxy - > enonce1bin ,  wb - > enonce1constlen ) ;   
			
		
	
		
			
				
						wb - > enonce1varlen  =  proxy - > enonce1varlen ;   
			
		
	
		
			
				
						wb - > enonce2varlen  =  proxy - > enonce2varlen ;   
			
		
	
		
			
				
						wb - > diff  =  proxy - > diff ;   
			
		
	
		
			
				
						ck_runlock ( & sdata - > workbase_lock ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						add_base ( ckp ,  wb ,  & new_block ) ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -3291,7 +3356,6 @@ static void parse_method(sdata_t *sdata, stratum_instance_t *client, const int64
					 
			
		
	
		
			
				
								 json_t  * id_val ,  json_t  * method_val ,  json_t  * params_val ,  const  char  * address )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						const  char  * method ;   
			
		
	
		
			
				
						char  buf [ 256 ] ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* Random broken clients send something not an integer as the id so we
   
			
		
	
		
			
				
						 *  copy  the  json  item  for  id_val  as  is  for  the  response .  By  far  the   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -3328,6 +3392,8 @@ static void parse_method(sdata_t *sdata, stratum_instance_t *client, const int64
					 
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( unlikely ( cmdmatch ( method ,  " mining.passthrough " ) ) )  {   
			
		
	
		
			
				
							char  buf [ 256 ] ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							LOGNOTICE ( " Adding passthrough client % " PRId64 ,  client_id ) ;   
			
		
	
		
			
				
							/* We need to inform the connector process that this client
   
			
		
	
		
			
				
							 *  is  a  passthrough  and  to  manage  its  messages  accordingly .   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -3342,8 +3408,7 @@ static void parse_method(sdata_t *sdata, stratum_instance_t *client, const int64
					 
			
		
	
		
			
				
						/* We should only accept subscribed requests from here on */   
			
		
	
		
			
				
						if  ( ! client - > subscribed )  {   
			
		
	
		
			
				
							LOGINFO ( " Dropping unsubscribed client % " PRId64 ,  client_id ) ;   
			
		
	
		
			
				
							snprintf ( buf ,  255 ,  " dropclient=% " PRId64 ,  client_id ) ;   
			
		
	
		
			
				
							send_proc ( client - > ckp - > connector ,  buf ) ;   
			
		
	
		
			
				
							connector_drop_client ( client - > ckp ,  client_id ) ;   
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -3365,8 +3430,7 @@ static void parse_method(sdata_t *sdata, stratum_instance_t *client, const int64
					 
			
		
	
		
			
				
							 *  stratifier  process  to  restart  since  it  will  have  lost  all   
			
		
	
		
			
				
							 *  the  stratum  instance  data .  Clients  will  just  reconnect .  */   
			
		
	
		
			
				
							LOGINFO ( " Dropping unauthorised client % " PRId64 ,  client_id ) ;   
			
		
	
		
			
				
							snprintf ( buf ,  255 ,  " dropclient=% " PRId64 ,  client_id ) ;   
			
		
	
		
			
				
							send_proc ( client - > ckp - > connector ,  buf ) ;   
			
		
	
		
			
				
							connector_drop_client ( client - > ckp ,  client_id ) ;   
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -3507,6 +3571,7 @@ static void srecv_process(ckpool_t *ckp, char *buf)
					 
			
		
	
		
			
				
							/* Client may be NULL here */   
			
		
	
		
			
				
							LOGNOTICE ( " Stratifier skipped dropped instance % " PRId64 "  message from server %d " ,   
			
		
	
		
			
				
								  msg - > client_id ,  server ) ;   
			
		
	
		
			
				
							connector_drop_client ( ckp ,  msg - > client_id ) ;   
			
		
	
		
			
				
							free_smsg ( msg ) ;   
			
		
	
		
			
				
							goto  out ;   
			
		
	
		
			
				
						}   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -4339,7 +4404,6 @@ static void read_poolstats(ckpool_t *ckp)
					 
			
		
	
		
			
				
					int  stratifier ( proc_instance_t  * pi )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						pthread_t  pth_blockupdate ,  pth_statsupdate ,  pth_heartbeat ;   
			
		
	
		
			
				
						proxy_t  * proxy ,  * tmpproxy ;   
			
		
	
		
			
				
						ckpool_t  * ckp  =  pi - > ckp ;   
			
		
	
		
			
				
						int  ret  =  1 ,  threads ;   
			
		
	
		
			
				
						int64_t  randomiser ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -4410,11 +4474,7 @@ int stratifier(proc_instance_t *pi)
					 
			
		
	
		
			
				
						if  ( ! ckp - > proxy )   
			
		
	
		
			
				
							create_pthread ( & pth_blockupdate ,  blockupdate ,  ckp ) ;   
			
		
	
		
			
				
						else  {   
			
		
	
		
			
				
							/* Generate one proxy for now */   
			
		
	
		
			
				
							proxy  =  ckzalloc ( sizeof ( proxy_t ) ) ;   
			
		
	
		
			
				
							mutex_init ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
							sdata - > proxy  =  proxy ;   
			
		
	
		
			
				
							HASH_ADD_INT ( sdata - > proxies ,  id ,  proxy ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						mutex_init ( & sdata - > stats_lock ) ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -4428,6 +4488,8 @@ int stratifier(proc_instance_t *pi)
					 
			
		
	
		
			
				
						ret  =  stratum_loop ( ckp ,  pi ) ;   
			
		
	
		
			
				
					out :  
			
		
	
		
			
				
						if  ( ckp - > proxy )  {   
			
		
	
		
			
				
							proxy_t  * proxy ,  * tmpproxy ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							mutex_lock ( & sdata - > proxy_lock ) ;   
			
		
	
		
			
				
							HASH_ITER ( hh ,  sdata - > proxies ,  proxy ,  tmpproxy )  {   
			
		
	
		
			
				
								HASH_DEL ( sdata - > proxies ,  proxy ) ;