def distribution_setup(): """ Makes a preview of the distribution :return: """ snap_info = pickle.loads(Redisdb.get("snapshot_info")) holders = Redisdb.hgetall("balance:" + snap_info['asset_hold_id']) lst = [] cnt = 0 balance = 0 for h in holders: hdata = pickle.loads(holders[h]) lst.append([hdata['account'], hdata['datetime'], hdata['amount'], 0]) balance += hdata['amount'] cnt += 1 if cnt % 1000 == 0: Redisdb.rpush( "messages", datetime.datetime.now().isoformat() + " CSV list " + str(cnt)) # refresh snapshot info snap_info['total_balance'] = balance snap_info['total_owners'] = int( Redisdb.get("total_owners:" + snap_info['asset_hold_id'])) Redisdb.set("snapshot_info", pickle.dumps(snap_info)) msg = "|".join([datetime.datetime.now().isoformat(), str(int(snap_info['total_balance'])), \ str(int(snap_info['total_owners'])), str(int(snap_info['total_owners']*snap_info['transfer_fee']))]) Redisdb.rpush("messages", "*|snapshot_end|" + msg) # The list is sorted from more to less holding Redisdb.rpush("messages", datetime.datetime.now().isoformat() + " CSV list sorting") lst.sort(key=lambda x: x[2], reverse=True) Redisdb.rpush("messages", datetime.datetime.now().isoformat() + " CSV list sorting OK") # calculus of the distribution tmplt_distr = "{0:." + str( snap_info['asset_distribute']['precision']) + "f}" tmplt_hold = "{0:." + str(snap_info['asset_hold']['precision']) + "f}" total_distr_amount = 0 for l in enumerate(lst): if snap_info['distribution_amount'] > 0: amount = round( l[1][2] / balance * snap_info['distribution_amount'], snap_info['asset_distribute']['precision']) elif snap_info['distribution_ratio'] > 0: amount = round(l[1][2] * snap_info['distribution_ratio'], snap_info['asset_distribute']['precision']) if amount < snap_info['distribution_minimum']: # truncate the list lst = lst[:l[0]] break total_distr_amount += amount lst[l[0]][3] = tmplt_distr.format(amount) lst[l[0]][2] = tmplt_hold.format(l[1][2]) # feed the distribution container for l in lst: Redisdb.hset("distribute:" + snap_info['asset_hold_id'], l[0], l[3]) if snap_info['distribution_amount'] > 0: rest = snap_info['distribution_amount'] - total_distr_amount else: rest = 0 # TODO: what to do with the rest? return lst
def obtain_balances(asset_id): snap_datetime = datetime.datetime.now().isoformat() info = pickle.loads(Redisdb.get("snapshot_info")) n_from = 0 n_call = 0 total_balance = 0 batch_balance = 0 total_holders = 0 while True: data = { "jsonrpc": "2.0", "params": [ "asset", "get_asset_holders", [info['asset_hold_id'], n_from, 100] ], "method": "call", "id": n_call } try: rtn = requests.post('http://209.188.21.157:8090/rpc', data=json.dumps(data)) if rtn.status_code != 200: return False rst = rtn.json()['result'] except Exception as err: print(err.__repr__()) print() return False bal = [] to_exit = False for r in rst: amount = round( int(r['amount']) / 10**info['asset_hold']['precision'], info['asset_hold']['precision']) if amount < info['asset_hold_minimum']: to_exit = True break else: total_balance += amount batch_balance += amount total_holders += 1 Redisdb.hset( "balance:" + info['asset_hold_id'], r['account_id'], pickle.dumps({ 'account': r['account_id'], 'datetime': snap_datetime, 'amount': amount })) if len(rst) < 100 or to_exit: Redisdb.rpush( "messages", datetime.datetime.now().isoformat() + " Total count:" + str(total_holders)) Redisdb.set("total_balance:" + info['asset_hold_id'], total_balance) Redisdb.set("total_owners:" + info['asset_hold_id'], total_holders) break if total_holders % 1000 == 0: Redisdb.rpush( "messages", datetime.datetime.now().isoformat() + " Holders: {} Balance: {} Median: {}".format( total_holders, total_balance, round( batch_balance / 1000, 2))) batch_balance = 0 n_from += 100 n_call += 1 print(n_call) return True