| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -392,6 +392,7 @@ struct txntable { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						char hash[68]; | 
					 | 
					 | 
					 | 
						char hash[68]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						char *data; | 
					 | 
					 | 
					 | 
						char *data; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int refcount; | 
					 | 
					 | 
					 | 
						int refcount; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						bool seen; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}; | 
					 | 
					 | 
					 | 
					}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define ID_AUTH 0 | 
					 | 
					 | 
					 | 
					#define ID_AUTH 0 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -1165,7 +1166,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								txn->refcount = 100; | 
					 | 
					 | 
					 | 
								txn->refcount = 100; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							else if (txn->refcount < 20) | 
					 | 
					 | 
					 | 
							else if (txn->refcount < 20) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								txn->refcount = 20; | 
					 | 
					 | 
					 | 
								txn->refcount = 20; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							found = true; | 
					 | 
					 | 
					 | 
							txn->seen = found = true; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ck_runlock(&sdata->workbase_lock); | 
					 | 
					 | 
					 | 
						ck_runlock(&sdata->workbase_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -1175,7 +1176,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						txn = ckzalloc(sizeof(txntable_t)); | 
					 | 
					 | 
					 | 
						txn = ckzalloc(sizeof(txntable_t)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						memcpy(txn->hash, hash, 65); | 
					 | 
					 | 
					 | 
						memcpy(txn->hash, hash, 65); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						txn->data = strdup(data); | 
					 | 
					 | 
					 | 
						txn->data = strdup(data); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (ckp->node) | 
					 | 
					 | 
					 | 
						if (!local || ckp->node) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							txn->refcount = 100; | 
					 | 
					 | 
					 | 
							txn->refcount = 100; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						else | 
					 | 
					 | 
					 | 
						else | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							txn->refcount = 20; | 
					 | 
					 | 
					 | 
							txn->refcount = 20; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -1237,6 +1238,10 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * and remove them. */ | 
					 | 
					 | 
					 | 
						 * and remove them. */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ck_wlock(&sdata->workbase_lock); | 
					 | 
					 | 
					 | 
						ck_wlock(&sdata->workbase_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						HASH_ITER(hh, sdata->txns, tmp, tmpa) { | 
					 | 
					 | 
					 | 
						HASH_ITER(hh, sdata->txns, tmp, tmpa) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (tmp->seen) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								tmp->seen = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (tmp->refcount-- > 0) | 
					 | 
					 | 
					 | 
							if (tmp->refcount-- > 0) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								continue; | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							HASH_DEL(sdata->txns, tmp); | 
					 | 
					 | 
					 | 
							HASH_DEL(sdata->txns, tmp); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -1270,7 +1275,8 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Distill down a set of transactions into an efficient tree arrangement for
 | 
					 | 
					 | 
					 | 
					/* Distill down a set of transactions into an efficient tree arrangement for
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * stratum messages and fast work assembly. */ | 
					 | 
					 | 
					 | 
					 * stratum messages and fast work assembly. */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void wb_merkle_bins(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *txn_array) | 
					 | 
					 | 
					 | 
					static void wb_merkle_bins(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *txn_array, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								   bool local) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int i, j, binleft, binlen; | 
					 | 
					 | 
					 | 
						int i, j, binleft, binlen; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						txntable_t *txns = NULL; | 
					 | 
					 | 
					 | 
						txntable_t *txns = NULL; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -1317,7 +1323,7 @@ static void wb_merkle_bins(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									return; | 
					 | 
					 | 
					 | 
									return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								txn = json_string_value(json_object_get(arr_val, "data")); | 
					 | 
					 | 
					 | 
								txn = json_string_value(json_object_get(arr_val, "data")); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								add_txn(ckp, sdata, &txns, hash, txn, true); | 
					 | 
					 | 
					 | 
								add_txn(ckp, sdata, &txns, hash, txn, local); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								len = strlen(txn); | 
					 | 
					 | 
					 | 
								len = strlen(txn); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								memcpy(wb->txn_data + ofs, txn, len); | 
					 | 
					 | 
					 | 
								memcpy(wb->txn_data + ofs, txn, len); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								ofs += len; | 
					 | 
					 | 
					 | 
								ofs += len; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -1452,7 +1458,7 @@ retry: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						json_intcpy(&wb->height, val, "height"); | 
					 | 
					 | 
					 | 
						json_intcpy(&wb->height, val, "height"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						json_strdup(&wb->flags, val, "flags"); | 
					 | 
					 | 
					 | 
						json_strdup(&wb->flags, val, "flags"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						txn_array = json_object_get(val, "transactions"); | 
					 | 
					 | 
					 | 
						txn_array = json_object_get(val, "transactions"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						wb_merkle_bins(ckp, sdata, wb, txn_array); | 
					 | 
					 | 
					 | 
						wb_merkle_bins(ckp, sdata, wb, txn_array, true); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						wb->insert_witness = false; | 
					 | 
					 | 
					 | 
						wb->insert_witness = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						memset(wb->witnessdata, 0, sizeof(wb->witnessdata)); | 
					 | 
					 | 
					 | 
						memset(wb->witnessdata, 0, sizeof(wb->witnessdata)); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -1506,12 +1512,13 @@ out: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						free(prio); | 
					 | 
					 | 
					 | 
						free(prio); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					/* Rebuilds transactions from txnhashes to be able to construct wb_merkle_bins */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *txnhashes) | 
					 | 
					 | 
					 | 
					static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *txnhashes) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const char *hashes = json_string_value(txnhashes); | 
					 | 
					 | 
					 | 
						const char *hashes = json_string_value(txnhashes); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						json_t *txn_array; | 
					 | 
					 | 
					 | 
						json_t *txn_array; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						bool ret = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						txntable_t *txn; | 
					 | 
					 | 
					 | 
						txntable_t *txn; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						bool ret = true; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int i, len; | 
					 | 
					 | 
					 | 
						int i, len; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (likely(hashes)) | 
					 | 
					 | 
					 | 
						if (likely(hashes)) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -1523,8 +1530,9 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t * | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (unlikely(len < wb->txns * 65)) { | 
					 | 
					 | 
					 | 
						if (unlikely(len < wb->txns * 65)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGERR("Truncated transactions in rebuild_txns only %d long", len); | 
					 | 
					 | 
					 | 
							LOGERR("Truncated transactions in rebuild_txns only %d long", len); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return false; | 
					 | 
					 | 
					 | 
							return ret; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						ret = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						txn_array = json_array(); | 
					 | 
					 | 
					 | 
						txn_array = json_array(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ck_rlock(&sdata->workbase_lock); | 
					 | 
					 | 
					 | 
						ck_rlock(&sdata->workbase_lock); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -1536,22 +1544,25 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t * | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							hash[64] = '\0'; | 
					 | 
					 | 
					 | 
							hash[64] = '\0'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							HASH_FIND_STR(sdata->txns, hash, txn); | 
					 | 
					 | 
					 | 
							HASH_FIND_STR(sdata->txns, hash, txn); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (unlikely(!txn)) { | 
					 | 
					 | 
					 | 
							if (unlikely(!txn)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								LOGNOTICE("Failed to find txn in rebuild_txns"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								ret = false; | 
					 | 
					 | 
					 | 
								ret = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								goto out_unlock; | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							/* This is unnecessary most of the time since it will be set
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							 * in rebuild_txns as well but helps in the case we can't call | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							 * rebuild_txns due to missing some txns */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							txn->refcount = 100; | 
					 | 
					 | 
					 | 
							txn->refcount = 100; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							txn->seen = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							JSON_CPACK(txn_val, "{ss,ss}", | 
					 | 
					 | 
					 | 
							JSON_CPACK(txn_val, "{ss,ss}", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								   "hash", hash, "data", txn->data); | 
					 | 
					 | 
					 | 
								   "hash", hash, "data", txn->data); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							json_array_append_new(txn_array, txn_val); | 
					 | 
					 | 
					 | 
							json_array_append_new(txn_array, txn_val); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					out_unlock: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ck_runlock(&sdata->workbase_lock); | 
					 | 
					 | 
					 | 
						ck_runlock(&sdata->workbase_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (ret) { | 
					 | 
					 | 
					 | 
						if (ret) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGINFO("Rebuilt txns into workbase with %d transactions", (int)i); | 
					 | 
					 | 
					 | 
							LOGINFO("Rebuilt txns into workbase with %d transactions", (int)i); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							wb_merkle_bins(ckp, sdata, wb, txn_array); | 
					 | 
					 | 
					 | 
							wb_merkle_bins(ckp, sdata, wb, txn_array, false); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} else | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							LOGNOTICE("Failed to find all txns in rebuild_txns"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						json_decref(txn_array); | 
					 | 
					 | 
					 | 
						json_decref(txn_array); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return ret; | 
					 | 
					 | 
					 | 
						return ret; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |