feat: Threaded resolution of txs and tokens #12

Open
lash wants to merge 11 commits from lash/thread into master
3 changed files with 79 additions and 48 deletions
Showing only changes of commit 4f6abf5d05 - Show all commits

View File

@ -160,6 +160,8 @@ class CmdCtrl:
'_FORCE', '_FORCE',
'_FORCE_ALL', '_FORCE_ALL',
'_RAW_TX', '_RAW_TX',
'_NO_RESOLVE',
'_NO_TX',
]: ]:
if r == None: if r == None:
return False return False

View File

@ -16,7 +16,10 @@ from hexathon import (
) )
# local imports # local imports
from clicada.tx import TxGetter from clicada.tx import (
TxGetter,
FormattedTokenTx,
)
from clicada.user import FileUserStore from clicada.user import FileUserStore
from clicada.token import FileTokenStore from clicada.token import FileTokenStore
from clicada.tx import ResolvedTokenTx from clicada.tx import ResolvedTokenTx
@ -38,6 +41,8 @@ def process_args(argparser):
argparser.add_argument('--meta-url', dest='meta_url', type=str, help='Url to retrieve metadata from') argparser.add_argument('--meta-url', dest='meta_url', type=str, help='Url to retrieve metadata from')
argparser.add_argument('-f', '--force-update', dest='force_update', action='store_true', help='Update records of mutable entries') argparser.add_argument('-f', '--force-update', dest='force_update', action='store_true', help='Update records of mutable entries')
argparser.add_argument('-ff', '--force-update-all', dest='force_update_all', action='store_true', help='Update records of mutable entries and immutable entries') argparser.add_argument('-ff', '--force-update-all', dest='force_update_all', action='store_true', help='Update records of mutable entries and immutable entries')
argparser.add_argument('-N', '--no-resolve', dest='no_resolve', action='store_true', help='Resolve no metadata')
argparser.add_argument('--no-tx', dest='no_tx', action='store_true', help='Do not fetch transactions')
argparser.add_argument('--raw-tx', dest='raw_tx', action='store_true', help='Also cache raw transaction data') argparser.add_argument('--raw-tx', dest='raw_tx', action='store_true', help='Also cache raw transaction data')
argparser.add_argument('identifier', type=str, help='user identifier') argparser.add_argument('identifier', type=str, help='user identifier')
@ -50,6 +55,8 @@ def extra_args():
'method': 'META_LOOKUP_METHOD', 'method': 'META_LOOKUP_METHOD',
'meta_url': 'META_URL', 'meta_url': 'META_URL',
'identifier': '_IDENTIFIER', 'identifier': '_IDENTIFIER',
'no_resolve': '_NO_RESOLVE',
'no_tx': '_NO_TX',
} }
@ -85,8 +92,16 @@ def execute(ctrl):
logg.debug('loaded user address {} for {}'.format(user_address, ctrl.get('_IDENTIFIER'))) logg.debug('loaded user address {} for {}'.format(user_address, ctrl.get('_IDENTIFIER')))
user_address_normal = tx_normalizer.wallet_address(user_address) user_address_normal = tx_normalizer.wallet_address(user_address)
ctrl.notify('retrieving txs for address {}'.format(user_address_normal)) ctrl.write("""Results for lookup by phone {}:
txs = tx_getter.get(user_address)
Metadata:
Network address: {}""".format(
ctrl.get('_IDENTIFIER'),
add_0x(user_address),
)
)
if not ctrl.get('_NO_RESOLVE'):
token_store = FileTokenStore(ctrl.chain(), ctrl.conn(), 'token', store_path) token_store = FileTokenStore(ctrl.chain(), ctrl.conn(), 'token', store_path)
@ -100,17 +115,13 @@ def execute(ctrl):
ctrl.ouch('could not resolve metadata for user: {}'.format(e)) ctrl.ouch('could not resolve metadata for user: {}'.format(e))
sys.exit(1) sys.exit(1)
ctrl.write("""Phone: {} ctrl.write(""" Chain: {}
Network address: {}
Chain: {}
Name: {} Name: {}
Registered: {} Registered: {}
Gender: {} Gender: {}
Location: {} Location: {}
Products: {} Products: {}
Tags: {}""".format( Tags: {}""".format(
ctrl.get('_IDENTIFIER'),
add_0x(user_address),
ctrl.chain().common_name(), ctrl.chain().common_name(),
str(r), str(r),
datetime.datetime.fromtimestamp(r.date_registered).ctime(), datetime.datetime.fromtimestamp(r.date_registered).ctime(),
@ -121,10 +132,23 @@ Tags: {}""".format(
) )
) )
if ctrl.get('_NO_TX'):
sys.exit(0)
raw_rpc = None raw_rpc = None
if ctrl.get('_RAW_TX'): if ctrl.get('_RAW_TX'):
raw_rpc = ctrl.rpc raw_rpc = ctrl.rpc
ctrl.notify('retrieving txs for address {}'.format(user_address_normal))
txs = tx_getter.get(user_address)
if ctrl.get('_NO_RESOLVE'):
for v in txs['data']:
tx = FormattedTokenTx.from_dict(v)
ctrl.write(tx)
sys.exit(0)
token_resolver_queue = Queue() token_resolver_queue = Queue()
token_result_queue = Queue() token_result_queue = Queue()
token_resolver_worker = TokenResolverWorker(user_address, ctrl, token_store, token_resolver_queue, token_result_queue) token_resolver_worker = TokenResolverWorker(user_address, ctrl, token_store, token_resolver_queue, token_result_queue)
@ -191,9 +215,9 @@ Tags: {}""".format(
ctrl.notify('wait for token resolver to finish work') ctrl.notify('wait for token resolver to finish work')
token_resolver_worker.join() token_resolver_worker.join()
ctrl.write('')
ctrl.write("Balances:") ctrl.write("Balances:")
ctrl.write(token_buf) ctrl.write(token_buf)
ctrl.write('')
ks = list(tx_buf.keys()) ks = list(tx_buf.keys())
ks.sort() ks.sort()
ks.reverse() ks.reverse()

View File

@ -23,7 +23,24 @@ logg = logging.getLogger(__name__)
address_checksummer = AddressChecksum() address_checksummer = AddressChecksum()
class ResolvedTokenTx(TokenTx): class FormattedTokenTx(TokenTx):
def __init__(self):
super(FormattedTokenTx, self).__init__()
self.symmetric = True
def __str__(self):
if self.symmetric:
return '{} {} => {} {} {}'.format(
self.date_block_label,
self.sender_label,
self.recipient_label,
self.destination_token_label,
self.to_value_label,
)
class ResolvedTokenTx(FormattedTokenTx):
def __init__(self): def __init__(self):
@ -32,7 +49,6 @@ class ResolvedTokenTx(TokenTx):
self.destination_token_name = None self.destination_token_name = None
self.source_token_decimals = None self.source_token_decimals = None
self.destination_token_decimals = None self.destination_token_decimals = None
self.symmetric = True
self.sender_entity = None self.sender_entity = None
self.recipient_entity = None self.recipient_entity = None
@ -91,17 +107,6 @@ class ResolvedTokenTx(TokenTx):
self.resolve_entities(user_store, update=update) self.resolve_entities(user_store, update=update)
def __str__(self):
if self.symmetric:
return '{} {} => {} {} {}'.format(
self.date_block_label,
self.sender_label,
self.recipient_label,
self.destination_token_label,
self.to_value_label,
)
class TxGetter: class TxGetter:
def __init__(self, cache_url, limit=0): def __init__(self, cache_url, limit=0):