diff --git a/hive/db/db_state.py b/hive/db/db_state.py index 700ac4742479cbd246bf5fb425671f611bd81def..439d69e82bc4910e75ced5d34e4fab8512814987 100644 --- a/hive/db/db_state.py +++ b/hive/db/db_state.py @@ -205,6 +205,16 @@ class DbState: cls.db().query(sql) cls._set_ver(5) + if cls._ver == 5: + # recover acct names lost to issue #151 + from hive.steem.client import SteemClient + from hive.indexer.accounts import Accounts + names = SteemClient().get_all_account_names() + Accounts.load_ids() + Accounts.register(names, '1970-01-01T00:00:00') + Accounts.clear_ids() + cls._set_ver(6) + assert cls._ver == DB_VERSION, "migration missing or invalid DB_VERSION" # Example migration: #if cls._ver == 1: diff --git a/hive/db/schema.py b/hive/db/schema.py index a29165b88a21bd3733f8e7d102e346b1e92a8828..07648c7504d27e78180ccf40c178858a1b47c534 100644 --- a/hive/db/schema.py +++ b/hive/db/schema.py @@ -10,7 +10,7 @@ from sqlalchemy.types import BOOLEAN #pylint: disable=line-too-long, too-many-lines -DB_VERSION = 5 +DB_VERSION = 6 def build_metadata(): """Build schema def with SqlAlchemy""" @@ -53,7 +53,7 @@ def build_metadata(): 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('vote_weight', sa.Float(precision=6), nullable=False, server_default='0'), - sa.Column('kb_used', sa.Integer, nullable=False, server_default='0'), + sa.Column('kb_used', sa.Integer, nullable=False, server_default='0'), # deprecated sa.Column('rank', sa.Integer, nullable=False, server_default='0'), sa.Column('active_at', sa.DateTime, nullable=False, server_default='1970-01-01 00:00:00'), diff --git a/hive/indexer/accounts.py b/hive/indexer/accounts.py index 0ec519e658de31b0e4f08e0dd46cecafda09e793..c885298f3351347e9129a67a6f87c2ed9568a899 100644 --- a/hive/indexer/accounts.py +++ b/hive/indexer/accounts.py @@ -35,6 +35,11 @@ class Accounts: assert not cls._ids, "id map already loaded" cls._ids = dict(DB.query_all("SELECT name, id FROM hive_accounts")) + @classmethod + def clear_ids(cls): + """Wipe id map. Only used for db migration #5.""" + cls._ids = None + @classmethod def get_id(cls, name): """Get account id by name. Throw if not found.""" @@ -157,15 +162,19 @@ class Accounts: profile = safe_profile_metadata(account) del account['json_metadata'] + active_at = max(account['created'], + account['last_post'], + account['last_vote_time']) + values = { 'name': account['name'], + 'created_at': account['created'], 'proxy': account['proxy'], 'post_count': account['post_count'], 'reputation': rep_log10(account['reputation']), 'proxy_weight': vests_amount(account['vesting_shares']), 'vote_weight': vote_weight, - 'kb_used': int(account['lifetime_bandwidth']) / 1e6 / 1024, - 'active_at': account['last_bandwidth_update'], + 'active_at': active_at, 'cached_at': cached_at, 'display_name': profile['name'], diff --git a/hive/indexer/blocks.py b/hive/indexer/blocks.py index 657a19e8e388119e611c6836da8f7fb3565e7752..71aa9bb9544db57643c167fb9f51e3e5304e1587 100644 --- a/hive/indexer/blocks.py +++ b/hive/indexer/blocks.py @@ -80,13 +80,12 @@ class Blocks: account_names.add(op['new_account_name']) elif op_type == 'account_create_with_delegation_operation': account_names.add(op['new_account_name']) - elif op_type == 'create_claimed_account': + elif op_type == 'create_claimed_account_operation': account_names.add(op['new_account_name']) # post ops elif op_type == 'comment_operation': comment_ops.append(op) - account_names.add(op['author']) # temp: HF20 missing account bug elif op_type == 'delete_comment_operation': delete_ops.append(op) elif op_type == 'vote_operation': diff --git a/hive/steem/client.py b/hive/steem/client.py index 1d09cbb2eab6248de795e1b7981cf123607963b5..4a56daa8a06e640464e4a93b5a23e92e0a177217 100644 --- a/hive/steem/client.py +++ b/hive/steem/client.py @@ -29,6 +29,15 @@ class SteemClient: % (len(accounts), len(ret))) return ret + def get_all_account_names(self): + """Fetch all account names.""" + ret = [] + names = self.__exec('lookup_accounts', ['', 1000]) + while names: + ret.extend(names) + names = self.__exec('lookup_accounts', [names[-1], 1000])[1:] + return ret + def get_content_batch(self, tuples): """Fetch multiple comment objects.""" posts = self.__exec_batch('get_content', tuples) diff --git a/hive/steem/http_client.py b/hive/steem/http_client.py index 1c68497d0ed19ea8a0741ffeb09afa1f4517ebb5..2a24bc1e9630dfc3a5bc415f2ee0d13400c3992a 100644 --- a/hive/steem/http_client.py +++ b/hive/steem/http_client.py @@ -82,6 +82,7 @@ class HttpClient(object): """Simple Steem JSON-HTTP-RPC API""" METHOD_API = dict( + lookup_accounts='condenser_api', get_block='block_api', get_content='condenser_api', get_accounts='condenser_api', diff --git a/hive/utils/stats.py b/hive/utils/stats.py index d0ccb587caf5cf6aa6e9bcc19e56ef209ae7d641..47be030caec6bdca328c9cd60fc4929d66ea8a06 100644 --- a/hive/utils/stats.py +++ b/hive/utils/stats.py @@ -89,6 +89,7 @@ class SteemStats(StatsAbstract): 'get_content': 4, 'get_order_book': 20, 'get_feed_history': 20, + 'lookup_accounts': 1000, } def __init__(self):