def estimate_gps_for_all_sizes(user_id, window): first_height = window[0].height last_height = window[-1].height print("estimate_gps_for_all_sizes: user_id: {}".format(user_id)) # print("All Worker_shares in the window:") # pp.pprint(window) first_grin_block = Blocks.get_by_height(first_height) last_grin_block = Blocks.get_by_height(last_height) assert first_grin_block is not None, "Missing grin block at height: {}".format(first_height) assert last_grin_block is not None, "Missing grin block at height: {}".format(last_height) # Get the Worker_shares in the window *for this user_id* this_workers_shares = [ws for ws in window if ws.user_id == user_id] print("This workers Shares records for the entire window: {}".format(len(this_workers_shares))) #pp.pprint(this_workers_shares) # Get a count of number of each valid solution size in this_workers_shares in this window valid_cnt = {} for worker_shares_rec in this_workers_shares: for shares in worker_shares_rec.shares: if shares.edge_bits not in valid_cnt: valid_cnt[shares.edge_bits] = 0 valid_cnt[shares.edge_bits] += shares.valid #print("Valid Share Counts entire window for {}:".format(user_id)) #pp.pprint(valid_cnt) # Calcualte the gps for each graph size in the window all_gps = [] for sz, cnt in valid_cnt.items(): gps = lib.calculate_graph_rate(window[0].timestamp, window[-1].timestamp, cnt) all_gps.append((sz, gps, )) sys.stdout.flush() return all_gps
def estimate_gps_for_all_sizes(window): print("estimate_gps_for_all_sizes across all workers") sys.stdout.flush() if len(window) < 2: return [] first_height = window[0].height last_height = window[-1].height first_grin_block = Blocks.get_by_height(first_height) last_grin_block = Blocks.get_by_height(last_height) assert first_grin_block is not None, "Missing grin block at height: {}".format( first_height) assert last_grin_block is not None, "Missing grin block at height: {}".format( last_height) valid_cnt = {} for pool_shares_rec in window: for shares in pool_shares_rec.shares: if shares.edge_bits not in valid_cnt: valid_cnt[shares.edge_bits] = 0 valid_cnt[shares.edge_bits] += shares.valid print("Valid Share Counts entire window:") pp.pprint(valid_cnt) all_gps = [] for sz, cnt in valid_cnt.items(): gps = lib.calculate_graph_rate(window[0].timestamp, window[-1].timestamp, cnt, sz, last_height) all_gps.append(( sz, gps, )) sys.stdout.flush() return all_gps
def calculate(height, avg_range): # Get the most recent pool data from which to generate the stats previous_stats_record = Pool_stats.get_by_height(height - 1) assert previous_stats_record is not None, "No previous stats record found" avg_over_first_grin_block = Blocks.get_by_height(max( height - avg_range, 1)) assert avg_over_first_grin_block is not None, "Missing grin block: {}".format( max(height - avg_range, 1)) grin_block = Blocks.get_by_height(height) assert grin_block is not None, "Missing grin block: {}".format(height) latest_worker_shares = Worker_shares.get_by_height(height) # If no shares are found for this height, we have 2 options: # 1) Assume the share data is *delayed* so dont create the stats record now # assert len(latest_worker_shares) > 0, "No worker shares found" # 2) If we want we can create the record without share data and then when shares are added later this record will be recalculated avg_over_worker_shares = Worker_shares.get_by_height(height, avg_range) # Calculate the stats data timestamp = grin_block.timestamp difficulty = POOL_MIN_DIFF # XXX TODO - enchance to support multiple difficulties gps = 0 active_miners = 0 shares_processed = 0 num_shares_in_range = 0 if len(avg_over_worker_shares) > 0: num_shares_in_range = sum( [shares.valid for shares in avg_over_worker_shares]) gps = lib.calculate_graph_rate(difficulty, avg_over_first_grin_block.timestamp, grin_block.timestamp, num_shares_in_range) print("XXX: difficulty={}, {}-{}, len={}".format( difficulty, avg_over_first_grin_block.timestamp, grin_block.timestamp, num_shares_in_range)) if latest_worker_shares is not None: active_miners = len(latest_worker_shares) # XXX NO, FIX THIS num_valid = sum([shares.valid for shares in latest_worker_shares]) num_invalid = sum([shares.invalid for shares in latest_worker_shares]) shares_processed = num_valid + num_invalid total_shares_processed = previous_stats_record.total_shares_processed + shares_processed total_grin_paid = previous_stats_record.total_grin_paid # XXX TODO total_blocks_found = previous_stats_record.total_blocks_found if Pool_blocks.get_by_height(height - 1) is not None: total_blocks_found = total_blocks_found + 1 return Pool_stats(height=height, timestamp=timestamp, gps=gps, active_miners=active_miners, shares_processed=shares_processed, total_shares_processed=total_shares_processed, total_grin_paid=total_grin_paid, total_blocks_found=total_blocks_found)
def calculate(height, avg_range): # Get the most recent blocks from which to generate the stats recent_blocks = [] previous_stats_record = Grin_stats.get_by_height(height - 1) print("XXX: {}".format(previous_stats_record)) assert previous_stats_record is not None, "No provious stats record found" recent_blocks = Blocks.get_by_height(height, avg_range) if len(recent_blocks) < min(avg_range, height): # We dont have all of these blocks in the DB raise AssertionError("Missing blocks in range: {}:{}".format( height - avg_range, height)) print(recent_blocks[-1]) print(recent_blocks[-2]) print(recent_blocks[-3]) print(recent_blocks[-4]) assert recent_blocks[ -1].height == height, "Invalid height in recent_blocks[-1]" assert recent_blocks[ -2].height == height - 1, "Invalid height in recent_blocks[-2]: {} vs {}".format( recent_blocks[-2].height, height - 1) # Calculate the stats data first_block = recent_blocks[0] last_block = recent_blocks[-1] timestamp = last_block.timestamp difficulty = recent_blocks[-1].total_difficulty - recent_blocks[ -2].total_difficulty gps = lib.calculate_graph_rate(difficulty, first_block.timestamp, last_block.timestamp, len(recent_blocks)) # utxo set size = sum outputs - sum inputs total_utxoset_size = previous_stats_record.total_utxoset_size + last_block.num_outputs - last_block.num_inputs return Grin_stats( height=height, timestamp=timestamp, gps=gps, difficulty=difficulty, total_utxoset_size=total_utxoset_size, )
def calculate(height, avg_range): avg_over_first_grin_block = Blocks.get_by_height(max( height - avg_range, 1)) assert avg_over_first_grin_block is not None, "Missing grin block: {}".format( max(height - avg_range, 1)) grin_block = Blocks.get_by_height(height) assert grin_block is not None, "Missing grin block: {}".format(height) # Get all workers share records for the current range of blocks latest_worker_shares = Worker_shares.get_by_height(height) # assert len(latest_worker_shares) != 0, "Missing worker shares record for height {}".format(height) avg_over_worker_shares = Worker_shares.get_by_height(height, avg_range) # Create a worker_stats for each user who submitted a share in this range workers = list(set([share.worker for share in avg_over_worker_shares])) new_stats = [] for worker in workers: # Get this workers most recent worker_stats record (for running totals) last_stat = Worker_stats.get_latest_by_id(worker) if last_stat is None: # A new worker last_stat = Worker_stats(None, datetime.utcnow(), height - 1, worker, 0, 0, 0, 0, 0, 0) new_stats.append(last_stat) # Calculate this workers stats data timestamp = grin_block.timestamp difficulty = POOL_MIN_DIFF # XXX TODO - enchance to support multiple difficulties num_shares_in_range = sum([ shares.valid for shares in avg_over_worker_shares if shares.worker == worker ]) gps = lib.calculate_graph_rate(difficulty, avg_over_first_grin_block.timestamp, grin_block.timestamp, num_shares_in_range) tmp = [ shares.valid for shares in latest_worker_shares if shares.worker == worker ] if len(tmp) > 0: num_valid_this_block = tmp[0] else: num_valid_this_block = 0 tmp = [ shares.invalid for shares in latest_worker_shares if shares.worker == worker ] if len(tmp) > 0: num_invalid_this_block = tmp[0] else: num_invalid_this_block = 0 shares_processed = num_valid_this_block + num_invalid_this_block # latest_worker_shares = [share for share in latest_pool_shares if share.found_by == worker] #shares_processed = len(worker_shares_this_block) total_shares_processed = last_stat.total_shares_processed + shares_processed stats = Worker_stats( id=None, height=height, timestamp=timestamp, worker=worker, gps=gps, shares_processed=shares_processed, total_shares_processed=total_shares_processed, grin_paid=123, # XXX TODO total_grin_paid=456, # XXX TODO balance=1) # XXX TODO new_stats.append(stats) return new_stats