Skip to content
Snippets Groups Projects
Commit f5a3bb82 authored by Mariusz Trela's avatar Mariusz Trela
Browse files

Merge branch 'mt-get-profile' of https://gitlab.syncad.com/hive/hivemind into mt-get-profile

parents 3bd73fbc 20d9f430
No related branches found
No related tags found
5 merge requests!456Release candidate v1 24,!230Setup monitoring with pghero,!138Small typos fixed,!135Enable postgres monitoring on CI server,!110Teh call `get_profile` works
...@@ -128,7 +128,6 @@ class DbState: ...@@ -128,7 +128,6 @@ class DbState:
#'hive_posts_cache_ix32', # API: community created #'hive_posts_cache_ix32', # API: community created
#'hive_posts_cache_ix33', # API: community payout #'hive_posts_cache_ix33', # API: community payout
#'hive_posts_cache_ix34', # API: community muted #'hive_posts_cache_ix34', # API: community muted
'hive_accounts_ix1', # (cached_at, name)
'hive_accounts_ix5' # (cached_at, name) 'hive_accounts_ix5' # (cached_at, name)
] ]
...@@ -297,7 +296,6 @@ class DbState: ...@@ -297,7 +296,6 @@ class DbState:
cls._set_ver(3) cls._set_ver(3)
if cls._ver == 3: if cls._ver == 3:
cls.db().query("CREATE INDEX hive_accounts_ix3 ON hive_accounts (vote_weight, name varchar_pattern_ops)")
cls._set_ver(4) cls._set_ver(4)
if cls._ver == 4: if cls._ver == 4:
......
...@@ -49,19 +49,15 @@ def build_metadata(): ...@@ -49,19 +49,15 @@ def build_metadata():
sa.Column('following', sa.Integer, nullable=False, server_default='0'), sa.Column('following', sa.Integer, nullable=False, server_default='0'),
sa.Column('proxy', VARCHAR(16), nullable=False, server_default=''), sa.Column('proxy', VARCHAR(16), nullable=False, server_default=''),
sa.Column('post_count', sa.Integer, nullable=False, server_default='0'),
sa.Column('proxy_weight', sa.Float(precision=6), nullable=False, server_default='0'), sa.Column('proxy_weight', sa.Float(precision=6), nullable=False, server_default='0'),
sa.Column('vote_weight', sa.Float(precision=6), nullable=False, server_default='0'),
sa.Column('kb_used', sa.Integer, nullable=False, server_default='0'), # deprecated sa.Column('kb_used', sa.Integer, nullable=False, server_default='0'), # deprecated
sa.Column('rank', sa.Integer, nullable=False, server_default='0'), sa.Column('rank', sa.Integer, nullable=False, server_default='0'),
sa.Column('lastread_at', sa.DateTime, nullable=False, server_default='1970-01-01 00:00:00'), sa.Column('lastread_at', sa.DateTime, nullable=False, server_default='1970-01-01 00:00:00'),
sa.Column('active_at', sa.DateTime, nullable=False, server_default='1970-01-01 00:00:00'),
sa.Column('cached_at', sa.DateTime, nullable=False, server_default='1970-01-01 00:00:00'), sa.Column('cached_at', sa.DateTime, nullable=False, server_default='1970-01-01 00:00:00'),
sa.Column('raw_json', sa.Text), sa.Column('raw_json', sa.Text),
sa.UniqueConstraint('name', name='hive_accounts_ux1'), sa.UniqueConstraint('name', name='hive_accounts_ux1'),
sa.Index('hive_accounts_ix1', 'vote_weight'), # core: quick ranks
sa.Index('hive_accounts_ix5', 'cached_at'), # core/listen sweep sa.Index('hive_accounts_ix5', 'cached_at'), # core/listen sweep
) )
...@@ -560,6 +556,74 @@ def setup(db): ...@@ -560,6 +556,74 @@ def setup(db):
""" """
db.query_no_return(sql) db.query_no_return(sql)
# In original hivemind, a value of 'active_at' was calculated from
# max
# {
# created ( account_create_operation ),
# last_account_update ( account_update_operation/account_update2_operation ),
# last_post ( comment_operation - only creation )
# last_root_post ( comment_operation - only creation + only ROOT ),
# last_vote_time ( vote_operation )
# }
# In order to simplify calculations, `last_account_update` is not taken into consideration, because this updating accounts is very rare
# and posting/voting after an account updating, fixes `active_at` value immediately.
sql = """
DROP VIEW IF EXISTS public.hive_accounts_info_view;
CREATE OR REPLACE VIEW public.hive_accounts_info_view
AS
SELECT
id,
name,
(
select count(*) post_count
FROM hive_posts hp
WHERE ha.id=hp.author_id
) post_count,
created_at,
(
SELECT GREATEST
(
created_at,
COALESCE(
(
select max(hp.created_at)
FROM hive_posts hp
WHERE ha.id=hp.author_id
),
'1970-01-01 00:00:00.0'
),
COALESCE(
(
select max(hv.last_update)
from hive_votes hv
WHERE ha.id=hv.voter_id
),
'1970-01-01 00:00:00.0'
)
)
) active_at,
display_name,
about,
reputation,
profile_image,
location,
website,
cover_image,
rank,
following,
followers,
proxy,
proxy_weight,
lastread_at,
cached_at,
raw_json
FROM
hive_accounts ha
"""
db.query_no_return(sql)
sql = """ sql = """
DROP VIEW IF EXISTS public.hive_posts_view; DROP VIEW IF EXISTS public.hive_posts_view;
......
...@@ -140,13 +140,6 @@ class Accounts: ...@@ -140,13 +140,6 @@ class Accounts:
cls._cache_accounts(accounts, steem, trx=trx) cls._cache_accounts(accounts, steem, trx=trx)
return count return count
@classmethod
def fetch_ranks(cls):
"""Rebuild account ranks and store in memory for next update."""
sql = "SELECT id FROM hive_accounts ORDER BY vote_weight DESC"
for rank, _id in enumerate(DB.query_col(sql)):
cls._ranks[_id] = rank + 1
@classmethod @classmethod
def _cache_accounts(cls, accounts, steem, trx=True): def _cache_accounts(cls, accounts, steem, trx=True):
"""Fetch all `accounts` and write to db.""" """Fetch all `accounts` and write to db."""
...@@ -170,9 +163,10 @@ class Accounts: ...@@ -170,9 +163,10 @@ class Accounts:
"""Prepare a SQL query from a steemd account.""" """Prepare a SQL query from a steemd account."""
vests = vests_amount(account['vesting_shares']) vests = vests_amount(account['vesting_shares'])
vote_weight = (vests #Not used. The member `vote_weight` from `hive_accounts` is removed.
+ vests_amount(account['received_vesting_shares']) # vote_weight = (vests
- vests_amount(account['delegated_vesting_shares'])) # + vests_amount(account['received_vesting_shares'])
# - vests_amount(account['delegated_vesting_shares']))
proxy_weight = 0 if account['proxy'] else float(vests) proxy_weight = 0 if account['proxy'] else float(vests)
for satoshis in account['proxied_vsf_votes']: for satoshis in account['proxied_vsf_votes']:
...@@ -190,21 +184,12 @@ class Accounts: ...@@ -190,21 +184,12 @@ class Accounts:
del account['json_metadata'] del account['json_metadata']
del account['posting_json_metadata'] del account['posting_json_metadata']
active_at = max(account['created'],
account['last_account_update'],
account['last_post'],
account['last_root_post'],
account['last_vote_time'])
values = { values = {
'name': account['name'], 'name': account['name'],
'created_at': account['created'], 'created_at': account['created'],
'proxy': account['proxy'], 'proxy': account['proxy'],
'post_count': account['post_count'],
'reputation': rep_log10(account['reputation']), 'reputation': rep_log10(account['reputation']),
'proxy_weight': proxy_weight, 'proxy_weight': proxy_weight,
'vote_weight': vote_weight,
'active_at': active_at,
'cached_at': cached_at, 'cached_at': cached_at,
'display_name': profile['name'], 'display_name': profile['name'],
......
...@@ -224,7 +224,6 @@ class Sync: ...@@ -224,7 +224,6 @@ class Sync:
# prefetch id->name and id->rank memory maps # prefetch id->name and id->rank memory maps
Accounts.load_ids() Accounts.load_ids()
Accounts.fetch_ranks()
# load irredeemables # load irredeemables
mutes = Mutes( mutes = Mutes(
...@@ -388,7 +387,6 @@ class Sync: ...@@ -388,7 +387,6 @@ class Sync:
if num % 1200 == 0: #1hr if num % 1200 == 0: #1hr
log.warning("head block %d @ %s", num, block['timestamp']) log.warning("head block %d @ %s", num, block['timestamp'])
log.info("[LIVE] hourly stats") log.info("[LIVE] hourly stats")
Accounts.fetch_ranks()
#Community.recalc_pending_payouts() #Community.recalc_pending_payouts()
if num % 200 == 0: #10min if num % 200 == 0: #10min
Community.recalc_pending_payouts() Community.recalc_pending_payouts()
......
...@@ -16,10 +16,8 @@ log = logging.getLogger(__name__) ...@@ -16,10 +16,8 @@ log = logging.getLogger(__name__)
async def load_profiles(db, names): async def load_profiles(db, names):
"""`get_accounts`-style lookup for `get_state` compat layer.""" """`get_accounts`-style lookup for `get_state` compat layer."""
sql = """SELECT id, name, display_name, about, reputation, vote_weight, sql = """SELECT * FROM hive_accounts_info_view
created_at, post_count, profile_image, location, website, WHERE name IN :names"""
cover_image, rank, following, followers, active_at
FROM hive_accounts WHERE name IN :names"""
rows = await db.query_all(sql, names=tuple(names)) rows = await db.query_all(sql, names=tuple(names))
return [_condenser_profile_object(row) for row in rows] return [_condenser_profile_object(row) for row in rows]
...@@ -197,6 +195,8 @@ def _condenser_profile_object(row): ...@@ -197,6 +195,8 @@ def _condenser_profile_object(row):
blacklists = Mutes.lists(row['name'], row['reputation']) blacklists = Mutes.lists(row['name'], row['reputation'])
#Important. The member `sp` in `stats` is removed, because currently the hivemind doesn't hold any balances.
# The member `vote_weight` from `hive_accounts` is removed as well.
return { return {
'id': row['id'], 'id': row['id'],
'name': row['name'], 'name': row['name'],
...@@ -206,16 +206,15 @@ def _condenser_profile_object(row): ...@@ -206,16 +206,15 @@ def _condenser_profile_object(row):
'reputation': row['reputation'], 'reputation': row['reputation'],
'blacklists': blacklists, 'blacklists': blacklists,
'stats': { 'stats': {
'sp': int(row['vote_weight'] * 0.0005037),
'rank': row['rank'], 'rank': row['rank'],
'following': row['following'], 'following': row['following'],
'followers': row['followers'], 'followers': row['followers'],
}, },
'metadata': { 'metadata': {
'profile': {'name': row['display_name'], 'profile': {'name': row['display_name'] if row['display_name'] else "",
'about': row['about'], 'about': row['about'] if row['about'] else "",
'website': row['website'], 'website': row['website'] if row['website'] else "",
'location': row['location'], 'location': row['location'] if row['location'] else "",
'cover_image': row['cover_image'], 'cover_image': row['cover_image'],
'profile_image': row['profile_image'], 'profile_image': row['profile_image'],
}}} }}}
......
...@@ -439,11 +439,8 @@ async def get_accounts(db, accounts: list): ...@@ -439,11 +439,8 @@ async def get_accounts(db, accounts: list):
ret = [] ret = []
names = ["'{}'".format(a) for a in accounts] names = ["'{}'".format(a) for a in accounts]
sql = """SELECT created_at, reputation, display_name, about, sql = """SELECT *
location, website, profile_image, cover_image, followers, following, FROM hive_accounts_info_view WHERE name IN ({})""".format(",".join(names))
proxy, post_count, proxy_weight, vote_weight, rank,
lastread_at, active_at, cached_at, raw_json
FROM hive_accounts WHERE name IN ({})""".format(",".join(names))
result = await db.query_all(sql) result = await db.query_all(sql)
for row in result: for row in result:
...@@ -463,10 +460,11 @@ async def get_accounts(db, accounts: list): ...@@ -463,10 +460,11 @@ async def get_accounts(db, accounts: list):
account_data['proxy'] = row.proxy account_data['proxy'] = row.proxy
account_data['post_count'] = row.post_count account_data['post_count'] = row.post_count
account_data['proxy_weight'] = row.proxy_weight account_data['proxy_weight'] = row.proxy_weight
account_data['vote_weight'] = row.vote_weight
account_data['rank'] = row.rank account_data['rank'] = row.rank
account_data['lastread_at'] = row.lastread_at.isoformat() account_data['lastread_at'] = row.lastread_at.isoformat()
account_data['active_at'] = row.active_at.isoformat() account_data['active_at'] = row.active_at.isoformat()
account_data['cached_at'] = row.cached_at.isoformat() account_data['cached_at'] = row.cached_at.isoformat()
ret.append(account_data) ret.append(account_data)
......
...@@ -14,10 +14,8 @@ log = logging.getLogger(__name__) ...@@ -14,10 +14,8 @@ log = logging.getLogger(__name__)
async def load_accounts(db, names): async def load_accounts(db, names):
"""`get_accounts`-style lookup for `get_state` compat layer.""" """`get_accounts`-style lookup for `get_state` compat layer."""
sql = """SELECT id, name, display_name, about, reputation, vote_weight, sql = """SELECT * FROM hive_accounts_info_view
created_at, post_count, profile_image, location, website, WHERE name IN :names"""
cover_image
FROM hive_accounts WHERE name IN :names"""
rows = await db.query_all(sql, names=tuple(names)) rows = await db.query_all(sql, names=tuple(names))
return [_condenser_account_object(row) for row in rows] return [_condenser_account_object(row) for row in rows]
...@@ -156,12 +154,13 @@ async def _query_author_rep_map(db, posts): ...@@ -156,12 +154,13 @@ async def _query_author_rep_map(db, posts):
def _condenser_account_object(row): def _condenser_account_object(row):
"""Convert an internal account record into legacy-steemd style.""" """Convert an internal account record into legacy-steemd style."""
#The member `vote_weight` from `hive_accounts` is removed, so currently the member `net_vesting_shares` is equals to zero.
return { return {
'name': row['name'], 'name': row['name'],
'created': str(row['created_at']), 'created': str(row['created_at']),
'post_count': row['post_count'], 'post_count': row['post_count'],
'reputation': rep_to_raw(row['reputation']), 'reputation': rep_to_raw(row['reputation']),
'net_vesting_shares': row['vote_weight'], 'net_vesting_shares': 0,
'transfer_history': [], 'transfer_history': [],
'json_metadata': json.dumps({ 'json_metadata': json.dumps({
'profile': {'name': row['display_name'], 'profile': {'name': row['display_name'],
......
...@@ -10,7 +10,7 @@ async def accounts_by_name(db, names, observer=None, lite=True): ...@@ -10,7 +10,7 @@ async def accounts_by_name(db, names, observer=None, lite=True):
"""Find and return accounts by `name`.""" """Find and return accounts by `name`."""
sql = """SELECT id, name, display_name, about, created_at, sql = """SELECT id, name, display_name, about, created_at,
vote_weight, rank, followers, following %s rank, followers, following %s
FROM hive_accounts WHERE name IN :names""" FROM hive_accounts WHERE name IN :names"""
fields = '' if lite else ', location, website, profile_image, cover_image' fields = '' if lite else ', location, website, profile_image, cover_image'
rows = await db.query_all(sql % fields, names=tuple(names)) rows = await db.query_all(sql % fields, names=tuple(names))
...@@ -21,7 +21,6 @@ async def accounts_by_name(db, names, observer=None, lite=True): ...@@ -21,7 +21,6 @@ async def accounts_by_name(db, names, observer=None, lite=True):
'id': row['id'], 'id': row['id'],
'name': row['name'], 'name': row['name'],
'created': str(row['created_at']).split(' ')[0], 'created': str(row['created_at']).split(' ')[0],
'sp': int(estimated_sp(row['vote_weight'])),
'rank': row['rank'], 'rank': row['rank'],
'followers': row['followers'], 'followers': row['followers'],
'following': row['following'], 'following': row['following'],
......
Subproject commit fa660ef0ee019ba9c2da91e7a9140423593d944e Subproject commit 263b3b14421f52394e344bdfb6bf0c345c5dad5a
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment