Example #1
0
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 latest_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 = grin.calculate_graph_rate(difficulty, avg_over_first_grin_block.timestamp, grin_block.timestamp, num_shares_in_range)
        num_valid_this_block = [shares.valid for shares in latest_worker_shares if shares.worker == worker][0]
        num_invalid_this_block = [shares.invalid for shares in latest_worker_shares if shares.worker == worker][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
Example #2
0
 def get(self, id, height=0, range=None, fields=None):
     global database
     #database = lib.get_db()
     LOGGER = lib.get_logger(PROCESS)
     # AUTH FILTER
     if id != g.user.id:
         response = jsonify(
             {'message': 'Not authorized to access data for other users'})
         response.status_code = 403
         return response
     debug and LOGGER.warn(
         "WorkerAPI_stats get id:{} height:{} range:{} fields:{}".format(
             id, height, range, fields))
     # Enforce range limit
     if range is not None:
         range = min(range, worker_stats_range_limit)
     fields = lib.fields_to_list(fields)
     res = None
     if range is None:
         # Getting a single record
         if height == 0:
             # Get the most recent stats for this user
             res = Worker_stats.get_latest_by_id(id)
         else:
             res = Worker_stats.get_by_height_and_id(id, height)
         if res is None:
             return None
         return res.to_json(fields)
     else:
         # Getting a range of records
         if height == 0:
             height = Blocks.get_latest().height
         res = Worker_stats.get_by_height_and_id(id, height, range)
         if res is None:
             return None
         stats = []
         for stat in res:
             stats.append(stat.to_json(fields))
         return stats
Example #3
0
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
Example #4
0
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