| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -41,6 +41,8 @@ struct pool_stats { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int workers; | 
					 | 
					 | 
					 | 
						int workers; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int users; | 
					 | 
					 | 
					 | 
						int users; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						int disconnected; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						int dead; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Absolute shares stats */ | 
					 | 
					 | 
					 | 
						/* Absolute shares stats */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int64_t unaccounted_shares; | 
					 | 
					 | 
					 | 
						int64_t unaccounted_shares; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -856,6 +858,12 @@ static void update_base(ckpool_t *ckp, int prio) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						create_pthread(pth, do_update, ur); | 
					 | 
					 | 
					 | 
						create_pthread(pth, do_update, ur); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void __del_disconnected(sdata_t *sdata, stratum_instance_t *client) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						HASH_DEL(sdata->disconnected_instances, client); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						sdata->stats.disconnected--; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void drop_allclients(ckpool_t *ckp) | 
					 | 
					 | 
					 | 
					static void drop_allclients(ckpool_t *ckp) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmp; | 
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmp; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -868,8 +876,9 @@ static void drop_allclients(ckpool_t *ckp) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sprintf(buf, "dropclient=%ld", client->id); | 
					 | 
					 | 
					 | 
							sprintf(buf, "dropclient=%ld", client->id); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							send_proc(ckp->connector, buf); | 
					 | 
					 | 
					 | 
							send_proc(ckp->connector, buf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						HASH_ITER(hh, sdata->disconnected_instances, client, tmp) | 
					 | 
					 | 
					 | 
						HASH_ITER(hh, sdata->disconnected_instances, client, tmp) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							HASH_DEL(sdata->disconnected_instances, client); | 
					 | 
					 | 
					 | 
							__del_disconnected(sdata, client); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sdata->stats.users = sdata->stats.workers = 0; | 
					 | 
					 | 
					 | 
						sdata->stats.users = sdata->stats.workers = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ck_wunlock(&sdata->instance_lock); | 
					 | 
					 | 
					 | 
						ck_wunlock(&sdata->instance_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -1213,6 +1222,18 @@ static void dec_worker(ckpool_t *ckp, user_instance_t *instance) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mutex_unlock(&sdata->stats_lock); | 
					 | 
					 | 
					 | 
						mutex_unlock(&sdata->stats_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void __add_dead(sdata_t *sdata, stratum_instance_t *client) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						LL_PREPEND(sdata->dead_instances, client); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						sdata->stats.dead++; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void __del_dead(sdata_t *sdata, stratum_instance_t *client) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						LL_DELETE(sdata->dead_instances, client); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						sdata->stats.dead--; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void drop_client(sdata_t *sdata, int64_t id) | 
					 | 
					 | 
					 | 
					static void drop_client(sdata_t *sdata, int64_t id) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmp; | 
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmp; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -1237,12 +1258,13 @@ static void drop_client(sdata_t *sdata, int64_t id) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							HASH_DEL(sdata->stratum_instances, client); | 
					 | 
					 | 
					 | 
							HASH_DEL(sdata->stratum_instances, client); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							HASH_FIND(hh, sdata->disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client); | 
					 | 
					 | 
					 | 
							HASH_FIND(hh, sdata->disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							/* Only keep around one copy of the old client in server mode */ | 
					 | 
					 | 
					 | 
							/* Only keep around one copy of the old client in server mode */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!client->ckp->proxy && !old_client && client->enonce1_64 && dec) | 
					 | 
					 | 
					 | 
							if (!client->ckp->proxy && !old_client && client->enonce1_64 && dec) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								HASH_ADD(hh, sdata->disconnected_instances, enonce1_64, sizeof(uint64_t), client); | 
					 | 
					 | 
					 | 
								HASH_ADD(hh, sdata->disconnected_instances, enonce1_64, sizeof(uint64_t), client); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							else { | 
					 | 
					 | 
					 | 
								sdata->stats.disconnected++; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (client->user_instance) | 
					 | 
					 | 
					 | 
								if (client->user_instance) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									DL_DELETE(client->user_instance->instances, client); | 
					 | 
					 | 
					 | 
									DL_DELETE(client->user_instance->instances, client); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								LL_PREPEND(sdata->dead_instances, client); | 
					 | 
					 | 
					 | 
								__add_dead(sdata, client); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Cull old unused clients lazily when there are no more reference
 | 
					 | 
					 | 
					 | 
						/* Cull old unused clients lazily when there are no more reference
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -1250,7 +1272,7 @@ static void drop_client(sdata_t *sdata, int64_t id) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						LL_FOREACH_SAFE(sdata->dead_instances, client, tmp) { | 
					 | 
					 | 
					 | 
						LL_FOREACH_SAFE(sdata->dead_instances, client, tmp) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!client->ref) { | 
					 | 
					 | 
					 | 
							if (!client->ref) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								LOGINFO("Stratifier discarding instance %ld", client->id); | 
					 | 
					 | 
					 | 
								LOGINFO("Stratifier discarding instance %ld", client->id); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								LL_DELETE(sdata->dead_instances, client); | 
					 | 
					 | 
					 | 
								__del_dead(sdata, client); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								free(client->workername); | 
					 | 
					 | 
					 | 
								free(client->workername); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								free(client->useragent); | 
					 | 
					 | 
					 | 
								free(client->useragent); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								free(client); | 
					 | 
					 | 
					 | 
								free(client); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -3484,6 +3506,7 @@ static void *statsupdate(void *arg) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							user_instance_t *instance, *tmpuser; | 
					 | 
					 | 
					 | 
							user_instance_t *instance, *tmpuser; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							stratum_instance_t *client, *tmp; | 
					 | 
					 | 
					 | 
							stratum_instance_t *client, *tmp; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							double sps1, sps5, sps15, sps60; | 
					 | 
					 | 
					 | 
							double sps1, sps5, sps15, sps60; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							int idle_workers = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							char fname[512] = {}; | 
					 | 
					 | 
					 | 
							char fname[512] = {}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							tv_t now, diff; | 
					 | 
					 | 
					 | 
							tv_t now, diff; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ts_t ts_now; | 
					 | 
					 | 
					 | 
							ts_t ts_now; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -3496,78 +3519,6 @@ static void *statsupdate(void *arg) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							timersub(&now, &stats->start_time, &diff); | 
					 | 
					 | 
					 | 
							timersub(&now, &stats->start_time, &diff); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							tdiff = diff.tv_sec + (double)diff.tv_usec / 1000000; | 
					 | 
					 | 
					 | 
							tdiff = diff.tv_sec + (double)diff.tv_usec / 1000000; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ghs1 = stats->dsps1 * nonces; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							suffix_string(ghs1, suffix1, 16, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sps1 = stats->sps1; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 300); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ghs5 = stats->dsps5 * nonces / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sps5 = stats->sps5 / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							suffix_string(ghs5, suffix5, 16, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 900); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ghs15 = stats->dsps15 * nonces / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							suffix_string(ghs15, suffix15, 16, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sps15 = stats->sps15 / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 3600); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ghs60 = stats->dsps60 * nonces / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sps60 = stats->sps60 / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							suffix_string(ghs60, suffix60, 16, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 21600); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ghs360 = stats->dsps360 * nonces / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							suffix_string(ghs360, suffix360, 16, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 86400); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ghs1440 = stats->dsps1440 * nonces / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							suffix_string(ghs1440, suffix1440, 16, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 604800); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ghs10080 = stats->dsps10080 * nonces / bias; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							suffix_string(ghs10080, suffix10080, 16, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							snprintf(fname, 511, "%s/pool/pool.status", ckp->logdir); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							fp = fopen(fname, "we"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (unlikely(!fp)) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								LOGERR("Failed to fopen %s", fname); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{si,si,si}", | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"runtime", diff.tv_sec, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"Users", stats->users, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"Workers", stats->workers); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							json_decref(val); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGNOTICE("Pool:%s", s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							fprintf(fp, "%s\n", s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							dealloc(s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{ss,ss,ss,ss,ss,ss,ss}", | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"hashrate1m", suffix1, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"hashrate5m", suffix5, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"hashrate15m", suffix15, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"hashrate1hr", suffix60, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"hashrate6hr", suffix360, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"hashrate1d", suffix1440, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"hashrate7d", suffix10080); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							json_decref(val); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGNOTICE("Pool:%s", s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							fprintf(fp, "%s\n", s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							dealloc(s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{sf,sf,sf,sf}", | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"SPS1m", sps1, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"SPS5m", sps5, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"SPS15m", sps15, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"SPS1h", sps60); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							json_decref(val); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGNOTICE("Pool:%s", s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							fprintf(fp, "%s\n", s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							dealloc(s); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							fclose(fp); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ck_rlock(&sdata->instance_lock); | 
					 | 
					 | 
					 | 
							ck_rlock(&sdata->instance_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							HASH_ITER(hh, sdata->stratum_instances, client, tmp) { | 
					 | 
					 | 
					 | 
							HASH_ITER(hh, sdata->stratum_instances, client, tmp) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (!client->authorised) | 
					 | 
					 | 
					 | 
								if (!client->authorised) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -3582,6 +3533,7 @@ static void *statsupdate(void *arg) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									decay_time(&client->dsps60, 0, per_tdiff, 3600); | 
					 | 
					 | 
					 | 
									decay_time(&client->dsps60, 0, per_tdiff, 3600); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									decay_time(&client->dsps1440, 0, per_tdiff, 86400); | 
					 | 
					 | 
					 | 
									decay_time(&client->dsps1440, 0, per_tdiff, 86400); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									decay_time(&client->dsps10080, 0, per_tdiff, 604800); | 
					 | 
					 | 
					 | 
									decay_time(&client->dsps10080, 0, per_tdiff, 604800); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									idle_workers++; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (per_tdiff > 600) | 
					 | 
					 | 
					 | 
									if (per_tdiff > 600) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										client->idle = true; | 
					 | 
					 | 
					 | 
										client->idle = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									continue; | 
					 | 
					 | 
					 | 
									continue; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -3687,6 +3639,81 @@ static void *statsupdate(void *arg) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ck_runlock(&sdata->instance_lock); | 
					 | 
					 | 
					 | 
							ck_runlock(&sdata->instance_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							ghs1 = stats->dsps1 * nonces; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							suffix_string(ghs1, suffix1, 16, 0); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							sps1 = stats->sps1; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 300); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							ghs5 = stats->dsps5 * nonces / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							sps5 = stats->sps5 / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							suffix_string(ghs5, suffix5, 16, 0); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 900); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							ghs15 = stats->dsps15 * nonces / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							suffix_string(ghs15, suffix15, 16, 0); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							sps15 = stats->sps15 / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 3600); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							ghs60 = stats->dsps60 * nonces / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							sps60 = stats->sps60 / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							suffix_string(ghs60, suffix60, 16, 0); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 21600); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							ghs360 = stats->dsps360 * nonces / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							suffix_string(ghs360, suffix360, 16, 0); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 86400); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							ghs1440 = stats->dsps1440 * nonces / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							suffix_string(ghs1440, suffix1440, 16, 0); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 604800); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							ghs10080 = stats->dsps10080 * nonces / bias; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							suffix_string(ghs10080, suffix10080, 16, 0); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							snprintf(fname, 511, "%s/pool/pool.status", ckp->logdir); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							fp = fopen(fname, "we"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (unlikely(!fp)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								LOGERR("Failed to fopen %s", fname); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{si,si,si,si,si,si}", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"runtime", diff.tv_sec, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"Users", stats->users, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"Workers", stats->workers, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"Idle", idle_workers, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"Disconnected", stats->disconnected, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"Dead", stats->dead); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							json_decref(val); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							LOGNOTICE("Pool:%s", s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							fprintf(fp, "%s\n", s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							dealloc(s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{ss,ss,ss,ss,ss,ss,ss}", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"hashrate1m", suffix1, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"hashrate5m", suffix5, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"hashrate15m", suffix15, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"hashrate1hr", suffix60, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"hashrate6hr", suffix360, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"hashrate1d", suffix1440, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"hashrate7d", suffix10080); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							json_decref(val); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							LOGNOTICE("Pool:%s", s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							fprintf(fp, "%s\n", s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							dealloc(s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{sf,sf,sf,sf}", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"SPS1m", sps1, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"SPS5m", sps5, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"SPS15m", sps15, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									"SPS1h", sps60); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							json_decref(val); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							LOGNOTICE("Pool:%s", s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							fprintf(fp, "%s\n", s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							dealloc(s); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							fclose(fp); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ts_realtime(&ts_now); | 
					 | 
					 | 
					 | 
							ts_realtime(&ts_now); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec); | 
					 | 
					 | 
					 | 
							sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{ss,si,si,si,sf,sf,sf,sf,ss,ss,ss,ss}", | 
					 | 
					 | 
					 | 
							JSON_CPACK(val, "{ss,si,si,si,sf,sf,sf,sf,ss,ss,ss,ss}", | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |