feat: Threaded resolution of txs and tokens #12
@ -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
|
||||||
|
@ -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,46 +92,63 @@ 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)
|
|
||||||
|
|
||||||
token_store = FileTokenStore(ctrl.chain(), ctrl.conn(), 'token', store_path)
|
Metadata:
|
||||||
|
Network address: {}""".format(
|
||||||
user_address_file_label = 'address'
|
ctrl.get('_IDENTIFIER'),
|
||||||
user_address_store = FileUserStore(ctrl.opener('meta'), ctrl.chain(), user_address_file_label, store_path, int(ctrl.get('FILESTORE_TTL')), encrypter=ctrl.encrypter, notifier=ctrl)
|
add_0x(user_address),
|
||||||
|
|
||||||
ctrl.notify('resolving metadata for address {}'.format(user_address_normal))
|
|
||||||
try:
|
|
||||||
r = user_address_store.by_address(user_address_normal, update=ctrl.get('_FORCE'))
|
|
||||||
except MetadataNotFoundError as e:
|
|
||||||
ctrl.ouch('could not resolve metadata for user: {}'.format(e))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
ctrl.write("""Phone: {}
|
|
||||||
Network address: {}
|
|
||||||
Chain: {}
|
|
||||||
Name: {}
|
|
||||||
Registered: {}
|
|
||||||
Gender: {}
|
|
||||||
Location: {}
|
|
||||||
Products: {}
|
|
||||||
Tags: {}""".format(
|
|
||||||
ctrl.get('_IDENTIFIER'),
|
|
||||||
add_0x(user_address),
|
|
||||||
ctrl.chain().common_name(),
|
|
||||||
str(r),
|
|
||||||
datetime.datetime.fromtimestamp(r.date_registered).ctime(),
|
|
||||||
r.gender,
|
|
||||||
r.location['area_name'],
|
|
||||||
','.join(r.products),
|
|
||||||
','.join(r.tags),
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not ctrl.get('_NO_RESOLVE'):
|
||||||
|
|
||||||
|
token_store = FileTokenStore(ctrl.chain(), ctrl.conn(), 'token', store_path)
|
||||||
|
|
||||||
|
user_address_file_label = 'address'
|
||||||
|
user_address_store = FileUserStore(ctrl.opener('meta'), ctrl.chain(), user_address_file_label, store_path, int(ctrl.get('FILESTORE_TTL')), encrypter=ctrl.encrypter, notifier=ctrl)
|
||||||
|
|
||||||
|
ctrl.notify('resolving metadata for address {}'.format(user_address_normal))
|
||||||
|
try:
|
||||||
|
r = user_address_store.by_address(user_address_normal, update=ctrl.get('_FORCE'))
|
||||||
|
except MetadataNotFoundError as e:
|
||||||
|
ctrl.ouch('could not resolve metadata for user: {}'.format(e))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
ctrl.write(""" Chain: {}
|
||||||
|
Name: {}
|
||||||
|
Registered: {}
|
||||||
|
Gender: {}
|
||||||
|
Location: {}
|
||||||
|
Products: {}
|
||||||
|
Tags: {}""".format(
|
||||||
|
ctrl.chain().common_name(),
|
||||||
|
str(r),
|
||||||
|
datetime.datetime.fromtimestamp(r.date_registered).ctime(),
|
||||||
|
r.gender,
|
||||||
|
r.location['area_name'],
|
||||||
|
','.join(r.products),
|
||||||
|
','.join(r.tags),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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()
|
||||||
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user