2021-02-01 18:12:51 +01:00
#!python3
# SPDX-License-Identifier: GPL-3.0-or-later
# standard imports
import os
import json
import argparse
import logging
import sys
import re
import datetime
2021-03-29 15:27:53 +02:00
# external imports
2021-02-01 18:12:51 +01:00
import confini
import celery
2021-03-29 15:27:53 +02:00
from cic_eth_registry import CICRegistry
from cic_eth_registry . lookup . declarator import AddressDeclaratorLookup
from chainlib . chain import ChainSpec
from chainlib . eth . connection import EthHTTPConnection
2021-03-01 21:15:17 +01:00
from hexathon import add_0x
2021-02-01 18:12:51 +01:00
# local imports
from cic_eth . api import AdminApi
2021-03-04 16:06:14 +01:00
from cic_eth . db . enum import (
StatusEnum ,
status_str ,
LockEnum ,
)
2021-02-01 18:12:51 +01:00
logging . basicConfig ( level = logging . WARNING )
logg = logging . getLogger ( )
2021-03-29 15:27:53 +02:00
default_format = ' terminal '
2021-03-07 19:01:44 +01:00
default_config_dir = os . environ . get ( ' CONFINI_DIR ' , ' /usr/local/etc/cic ' )
2021-02-01 18:12:51 +01:00
argparser = argparse . ArgumentParser ( )
2021-03-29 15:27:53 +02:00
argparser . add_argument ( ' -p ' , ' --provider ' , dest = ' p ' , default = ' http://localhost:8545 ' , type = str , help = ' Web3 provider url (http only) ' )
2021-03-01 21:15:17 +01:00
argparser . add_argument ( ' -r ' , ' --registry-address ' , dest = ' r ' , type = str , help = ' CIC registry address ' )
2021-03-29 15:27:53 +02:00
argparser . add_argument ( ' -f ' , ' --format ' , dest = ' f ' , default = default_format , type = str , help = ' Output format ' )
argparser . add_argument ( ' --status-raw ' , dest = ' status_raw ' , action = ' store_true ' , help = ' Output status bit enum names only ' )
2021-02-01 18:12:51 +01:00
argparser . add_argument ( ' -c ' , type = str , default = default_config_dir , help = ' config root to use ' )
argparser . add_argument ( ' -i ' , ' --chain-spec ' , dest = ' i ' , type = str , help = ' chain spec ' )
argparser . add_argument ( ' -q ' , type = str , default = ' cic-eth ' , help = ' celery queue to submit transaction tasks to ' )
argparser . add_argument ( ' --env-prefix ' , default = os . environ . get ( ' CONFINI_ENV_PREFIX ' ) , dest = ' env_prefix ' , type = str , help = ' environment prefix for variables to overwrite configuration ' )
argparser . add_argument ( ' -v ' , action = ' store_true ' , help = ' Be verbose ' )
argparser . add_argument ( ' -vv ' , help = ' be more verbose ' , action = ' store_true ' )
argparser . add_argument ( ' query ' , type = str , help = ' Transaction, transaction hash, account or " lock " ' )
args = argparser . parse_args ( )
if args . v == True :
logging . getLogger ( ) . setLevel ( logging . INFO )
elif args . vv == True :
logging . getLogger ( ) . setLevel ( logging . DEBUG )
config_dir = os . path . join ( args . c )
os . makedirs ( config_dir , 0o777 , True )
config = confini . Config ( config_dir , args . env_prefix )
config . process ( )
args_override = {
' ETH_PROVIDER ' : getattr ( args , ' p ' ) ,
' CIC_CHAIN_SPEC ' : getattr ( args , ' i ' ) ,
2021-03-01 21:15:17 +01:00
' CIC_REGISTRY_ADDRESS ' : getattr ( args , ' r ' ) ,
2021-02-01 18:12:51 +01:00
}
# override args
2021-03-01 21:15:17 +01:00
config . dict_override ( args_override , ' cli args ' )
2021-02-01 18:12:51 +01:00
config . censor ( ' PASSWORD ' , ' DATABASE ' )
config . censor ( ' PASSWORD ' , ' SSL ' )
logg . debug ( ' config loaded from {} : \n {} ' . format ( config_dir , config ) )
2021-03-29 15:27:53 +02:00
try :
config . add ( add_0x ( args . query ) , ' _QUERY ' , True )
except :
config . add ( args . query , ' _QUERY ' , True )
2021-02-01 18:12:51 +01:00
celery_app = celery . Celery ( broker = config . get ( ' CELERY_BROKER_URL ' ) , backend = config . get ( ' CELERY_RESULT_URL ' ) )
queue = args . q
chain_spec = ChainSpec . from_chain_str ( config . get ( ' CIC_CHAIN_SPEC ' ) )
2021-03-29 15:27:53 +02:00
rpc = EthHTTPConnection ( args . p )
registry_address = config . get ( ' CIC_REGISTRY_ADDRESS ' )
admin_api = AdminApi ( rpc )
trusted_addresses_src = config . get ( ' CIC_TRUST_ADDRESS ' )
if trusted_addresses_src == None :
logg . critical ( ' At least one trusted address must be declared in CIC_TRUST_ADDRESS ' )
sys . exit ( 1 )
trusted_addresses = trusted_addresses_src . split ( ' , ' )
for address in trusted_addresses :
logg . info ( ' using trusted address {} ' . format ( address ) )
2021-02-01 18:12:51 +01:00
fmt = ' terminal '
if args . f [ : 1 ] == ' j ' :
fmt = ' json '
elif args . f [ : 1 ] != ' t ' :
raise ValueError ( ' unknown output format {} ' . format ( args . f ) )
def render_tx ( o , * * kwargs ) :
content = ' '
for k in o . keys ( ) :
if not k in [ ' status_log ' ] :
content + = ' {} : {} \n ' . format ( k , o [ k ] )
content + = ' status log: \n '
for v in o . get ( ' status_log ' , [ ] ) :
d = datetime . datetime . fromisoformat ( v [ 0 ] )
2021-03-06 18:55:51 +01:00
e = status_str ( v [ 1 ] , args . status_raw )
2021-02-01 18:12:51 +01:00
content + = ' {} : {} \n ' . format ( d , e )
return content
def render_account ( o , * * kwargs ) :
return ' {} {} {} {} ' . format (
o [ ' date_updated ' ] ,
o [ ' nonce ' ] ,
o [ ' tx_hash ' ] ,
o [ ' status ' ] ,
)
def render_lock ( o , * * kwargs ) :
lockstrings = [ ]
flags = o [ ' flags ' ]
for i in range ( 31 ) :
v = 1 << i
if flags & v :
lockstrings . append ( LockEnum ( v ) . name )
s = ' {} {} {} ' . format (
o [ ' address ' ] ,
o [ ' date ' ] ,
" , " . join ( lockstrings ) ,
)
if o [ ' tx_hash ' ] != None :
s + = ' ' + o [ ' tx_hash ' ]
return s
2021-03-29 15:27:53 +02:00
def connect_registry ( registry_address , chain_spec , rpc ) :
CICRegistry . address = registry_address
registry = CICRegistry ( chain_spec , rpc )
declarator_address = registry . by_name ( ' AddressDeclarator ' )
lookup = AddressDeclaratorLookup ( declarator_address , trusted_addresses )
registry . add_lookup ( lookup )
return registry
2021-02-01 18:12:51 +01:00
# TODO: move each command to submodule
def main ( ) :
txs = [ ]
renderer = render_tx
2021-03-01 21:15:17 +01:00
if len ( config . get ( ' _QUERY ' ) ) > 66 :
2021-03-29 15:27:53 +02:00
registry = connect_registry ( registry_address , chain_spec , rpc )
txs = [ admin_api . tx ( chain_spec , tx_raw = config . get ( ' _QUERY ' ) , registry = registry ) ]
2021-03-01 21:15:17 +01:00
elif len ( config . get ( ' _QUERY ' ) ) > 42 :
2021-03-29 15:27:53 +02:00
registry = connect_registry ( registry_address , chain_spec , rpc )
txs = [ admin_api . tx ( chain_spec , tx_hash = config . get ( ' _QUERY ' ) , registry = registry ) ]
2021-03-01 21:15:17 +01:00
elif len ( config . get ( ' _QUERY ' ) ) == 42 :
2021-03-29 15:27:53 +02:00
registry = connect_registry ( registry_address , chain_spec , rpc )
2021-03-01 21:15:17 +01:00
txs = admin_api . account ( chain_spec , config . get ( ' _QUERY ' ) , include_recipient = False )
2021-02-01 18:12:51 +01:00
renderer = render_account
2021-03-01 21:15:17 +01:00
elif len ( config . get ( ' _QUERY ' ) ) > = 4 and config . get ( ' _QUERY ' ) [ : 4 ] == ' lock ' :
2021-03-29 15:27:53 +02:00
t = admin_api . get_lock ( )
txs = t . get ( )
2021-02-01 18:12:51 +01:00
renderer = render_lock
else :
2021-03-01 21:15:17 +01:00
raise ValueError ( ' cannot parse argument {} ' . format ( config . get ( ' _QUERY ' ) ) )
2021-02-01 18:12:51 +01:00
if len ( txs ) == 0 :
logg . info ( ' no matches found ' )
else :
if fmt == ' json ' :
sys . stdout . write ( json . dumps ( txs ) )
else :
m = map ( renderer , txs )
print ( * m , sep = " \n " )
if __name__ == ' __main__ ' :
main ( )