def calculate(height, avg_range=DIFFICULTY_ADJUST_WINDOW): # 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)) 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 new_stats = Grin_stats( height = height, timestamp = timestamp, difficulty = difficulty, ) # Caclulate estimated GPS for recent edge_bits sizes all_gps = estimate_all_gps(recent_blocks) for gps in all_gps: gps_rec = Gps( edge_bits = gps[0], gps = gps[1], ) new_stats.gps.append(gps_rec) return new_stats
def calculate(height, window_size): # 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 Pool_stats record found" grin_block = Blocks.get_by_height(height) assert grin_block is not None, "Missing grin block: {}".format(height) window = Worker_shares.get_by_height(height, window_size) # assert window[-1].height - window[0].height >= window_size, "Failed to get proper window size" # print("Sanity: window size: {} vs {}".format(window[-1].height - window[0].height, window_size)) # Calculate the stats data timestamp = grin_block.timestamp active_miners = len(list(set([s.user_id for s in window]))) print("active_miners = {}".format(active_miners)) # Keep track of share totals - sum counts of all share sizes submitted for this block num_shares_processed = 0 share_counts = {} for ws in Worker_shares.get_by_height(height): num_shares_processed += ws.num_shares() for size in ws.sizes(): size_str = "{}{}".format("C", size) if size_str not in share_counts: share_counts[size_str] = {"valid": 0, "invalid": 0, "stale": 0} share_counts[size_str] = { "valid": share_counts[size_str]["valid"] + ws.num_valid(size), "invalid": share_counts[size_str]["invalid"] + ws.num_invalid(size), "stale": share_counts[size_str]["stale"] + ws.num_stale(size) } print("num_shares_processed this block= {}".format(num_shares_processed)) total_shares_processed = previous_stats_record.total_shares_processed + num_shares_processed total_blocks_found = previous_stats_record.total_blocks_found # Caclulate estimated GPS for all sizes with shares submitted all_gps = estimate_gps_for_all_sizes(window) if Pool_blocks.get_by_height(height - 1) is not None: total_blocks_found = total_blocks_found + 1 new_stats = Pool_stats( height=height, timestamp=timestamp, active_miners=active_miners, share_counts=share_counts, shares_processed=num_shares_processed, total_blocks_found=total_blocks_found, total_shares_processed=total_shares_processed, dirty=False, ) print("all_gps for all pool workers") pp.pprint(all_gps) for gps_est in all_gps: gps_rec = Gps(edge_bits=gps_est[0], gps=gps_est[1]) new_stats.gps.append(gps_rec) sys.stdout.flush() return new_stats
def calculate(height, window_size): # 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 Pool_stats record found" grin_block = Blocks.get_by_height(height) assert grin_block is not None, "Missing grin block: {}".format(height) window = Worker_shares.get_by_height(height, window_size) # Calculate the stats data timestamp = grin_block.timestamp active_miners = len(list(set([s.worker for s in window]))) print("active_miners = {}".format(active_miners)) # Keep track of share totals - sum counts of all share sizes submitted for this block shares_processed = 0 if len(window) > 0: shares_processed = window[-1].num_shares() print("shares_processed this block= {}".format(shares_processed)) 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 # Caclulate estimated GPS for all sizes with shares submitted all_gps = estimate_gps_for_all_sizes(window) if Pool_blocks.get_by_height(height - 1) is not None: total_blocks_found = total_blocks_found + 1 new_stats = Pool_stats( height=height, timestamp=timestamp, active_miners=active_miners, shares_processed=shares_processed, total_blocks_found=total_blocks_found, total_shares_processed=total_shares_processed, total_grin_paid=total_grin_paid, dirty=False, ) print("all_gps for all pool workers") pp.pprint(all_gps) for gps_est in all_gps: gps_rec = Gps(edge_bits=gps_est[0], gps=gps_est[1]) new_stats.gps.append(gps_rec) sys.stdout.flush() return new_stats
def calculate(height, window_size): database = lib.get_db() grin_block = Blocks.get_by_height(height) assert grin_block is not None, "Missing grin block at height: {}".format(height) # Get all Worker_share records in the estimation window window = Worker_shares.get_by_height(height, window_size) # Get list of all workers who submitted shares OR recvd a payment at this height pmts = Pool_payment.get_by_height(height) shares_workers = [share.user_id for share in window] pmts_workers = [pmt.user_id for pmt in pmts] workers = list(set(shares_workers + pmts_workers)) # Create a new Worker_stats record for each of these workers print("Calcualte worker stats for height {}, workers {}".format(height, workers)) 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, initialize a last_stat for the previous block last_stat = Worker_stats( timestamp=datetime.utcnow(), height=height-1, user_id=worker) new_stats.append(last_stat) # Calculate this workers stats data timestamp = grin_block.timestamp # Caclulate estimated GPS for all sizes with shares submitted all_gps = estimate_gps_for_all_sizes(worker, window) # Keep track of share totals - sum counts of all share sizes submitted for this block print("Looking up shares for height {} user {}".format(height, worker)) this_workers_shares_this_block = Worker_shares.get_by_height_and_id(height, worker) print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX {}".format(this_workers_shares_this_block)) if this_workers_shares_this_block is None or len(this_workers_shares_this_block) == 0: this_workers_valid_shares = 0 this_workers_invalid_shares = 0 this_workers_stale_shares = 0 else: this_workers_shares_this_block = this_workers_shares_this_block[-1] this_workers_valid_shares = this_workers_shares_this_block.num_valid() this_workers_invalid_shares = this_workers_shares_this_block.num_invalid() this_workers_stale_shares = this_workers_shares_this_block.num_stale() this_workers_total_valid_shares = last_stat.total_valid_shares + this_workers_valid_shares this_workers_total_invalid_shares = last_stat.total_invalid_shares + this_workers_invalid_shares this_workers_total_stale_shares = last_stat.total_stale_shares + this_workers_stale_shares # XXX PERFORAMCE = removed bulk insert to debug some other issue, need to put bulk insert back!!! stats = Worker_stats( height = height, timestamp = timestamp, user_id = worker, valid_shares = this_workers_valid_shares, invalid_shares = this_workers_invalid_shares, stale_shares = this_workers_stale_shares, total_valid_shares = this_workers_total_valid_shares, total_invalid_shares = this_workers_total_invalid_shares, total_stale_shares = this_workers_total_stale_shares, ) database.db.getSession().add(stats) database.db.getSession().commit() #print("AAA: Created Worker_stats with id={}".format(stats.id)) # print("all_gps for worker {}:".format(worker)) # pp.pprint(all_gps) for gps_est in all_gps: gps_rec = Gps( edge_bits = gps_est[0], gps = gps_est[1], ) stats.gps.append(gps_rec) #print("AAA: Appended gps record to Worker_stats: {}".format(gps_rec)) # gps_rec.worker_stats_id = stats.id, # database.db.getSession().add(gps_rec) new_stats.append(stats) database.db.getSession().add(stats) database.db.getSession().commit() sys.stdout.flush() return new_stats
def calculate(height, window_size): database = lib.get_db() grin_block = Blocks.get_by_height(height) assert grin_block is not None, "Missing grin block at height: {}".format( height) # Get all Worker_share records in the estimation window window = Worker_shares.get_by_height(height, window_size) # Get list of all workers who submitted shares in the window workers = list(set([share.worker for share in window])) # Create a new Worker_stats record for each of these workers print("Calcualte worker stats for height {}, workers {}".format( height, workers)) 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, initialize a last_stat for the previous block 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 # Caclulate estimated GPS for all sizes with shares submitted all_gps = estimate_gps_for_all_sizes(worker, window) # Keep track of share totals - sum counts of all share sizes submitted for this block this_workers_shares = [ws for ws in window if ws.worker == worker] num_shares_processed = this_workers_shares[-1].num_shares() print("num_shares_processed={}".format(num_shares_processed)) total_shares_processed = last_stat.total_shares_processed + num_shares_processed print("total_shares_processed={}".format(total_shares_processed)) # XXX PERFORAMCE = could not get bulk_insert to work... stats = Worker_stats( id=None, height=height, timestamp=timestamp, worker=worker, shares_processed=num_shares_processed, total_shares_processed=total_shares_processed, grin_paid=123, # XXX TODO total_grin_paid=456, # XXX TODO balance=1) # XXX TODO database.db.getSession().add(stats) database.db.getSession().commit() #print("AAA: Created Worker_stats with id={}".format(stats.id)) # print("all_gps for worker {}:".format(worker)) # pp.pprint(all_gps) for gps_est in all_gps: gps_rec = Gps( edge_bits=gps_est[0], gps=gps_est[1], ) stats.gps.append(gps_rec) #print("AAA: Appended gps record to Worker_stats: {}".format(gps_rec)) # gps_rec.worker_stats_id = stats.id, # database.db.getSession().add(gps_rec) # new_stats.append(stats) database.db.getSession().add(stats) database.db.getSession().commit() sys.stdout.flush() return new_stats