diff --git a/apps/cic-cache/requirements.txt b/apps/cic-cache/requirements.txt index 00030b74..92e95994 100644 --- a/apps/cic-cache/requirements.txt +++ b/apps/cic-cache/requirements.txt @@ -1,13 +1,13 @@ -cic-base==0.1.3a3+build.984b5cff +cic-base~=0.2.0a2 alembic==1.4.2 -confini~=0.3.6rc3 +confini>=0.3.6rc3,<0.5.0 uwsgi==2.0.19.1 moolb~=0.1.0 -cic-eth-registry~=0.5.6a1 +cic-eth-registry~=0.5.6a2 SQLAlchemy==1.3.20 semver==2.13.0 psycopg2==2.8.6 celery==4.4.7 redis==3.5.3 -chainsyncer[sql]~=0.0.3a3 -erc20-faucet~=0.2.2a1 +chainsyncer[sql]~=0.0.3a4 +erc20-faucet~=0.2.2a2 diff --git a/apps/cic-eth/admin_requirements.txt b/apps/cic-eth/admin_requirements.txt index 2a55cc29..cc620677 100644 --- a/apps/cic-eth/admin_requirements.txt +++ b/apps/cic-eth/admin_requirements.txt @@ -1,5 +1,5 @@ SQLAlchemy==1.3.20 -cic-eth-registry~=0.5.6a1 +cic-eth-registry~=0.5.6a2 hexathon~=0.0.1a7 -chainqueue~=0.0.2b5 -eth-erc20==0.0.10a2 +chainqueue~=0.0.2b6 +eth-erc20~=0.0.10a3 diff --git a/apps/cic-eth/cic_eth/version.py b/apps/cic-eth/cic_eth/version.py index 8f85db25..a60d8726 100644 --- a/apps/cic-eth/cic_eth/version.py +++ b/apps/cic-eth/cic_eth/version.py @@ -10,7 +10,7 @@ version = ( 0, 12, 0, - 'alpha.2', + 'alpha.3', ) version_object = semver.VersionInfo( diff --git a/apps/cic-eth/requirements.txt b/apps/cic-eth/requirements.txt index 95ce95bc..35486723 100644 --- a/apps/cic-eth/requirements.txt +++ b/apps/cic-eth/requirements.txt @@ -1,3 +1,3 @@ celery==4.4.7 -chainlib~=0.0.5a1 +chainlib~=0.0.5a2 semver==2.13.0 diff --git a/apps/cic-eth/services_requirements.txt b/apps/cic-eth/services_requirements.txt index e5e7b0de..16713117 100644 --- a/apps/cic-eth/services_requirements.txt +++ b/apps/cic-eth/services_requirements.txt @@ -1,16 +1,15 @@ -chainsyncer[sql]~=0.0.3a3 -chainqueue~=0.0.2b5 +chainsyncer[sql]~=0.0.3a4 +chainqueue~=0.0.2b6 alembic==1.4.2 -confini~=0.3.6rc4 +confini>=0.3.6rc4,<0.5.0 redis==3.5.3 hexathon~=0.0.1a7 pycryptodome==3.10.1 liveness~=0.0.1a7 -eth-address-index~=0.1.2a1 -eth-accounts-index~=0.0.12a1 -cic-eth-registry~=0.5.6a1 -erc20-faucet~=0.2.2a1 -erc20-transfer-authorization~=0.3.2a1 -sarafu-faucet~=0.0.4a1 +eth-address-index~=0.1.2a2 +eth-accounts-index~=0.0.12a2 +cic-eth-registry~=0.5.6a2 +erc20-faucet~=0.2.2a2 +erc20-transfer-authorization~=0.3.2a2 +sarafu-faucet~=0.0.4a3 moolb~=0.1.1b2 -erc20-transfer-authorization~=0.3.2a1 diff --git a/apps/cic-eth/test_requirements.txt b/apps/cic-eth/test_requirements.txt index 600a7df3..088324c5 100644 --- a/apps/cic-eth/test_requirements.txt +++ b/apps/cic-eth/test_requirements.txt @@ -6,4 +6,4 @@ pytest-redis==2.0.0 redis==3.5.3 eth-tester==0.5.0b3 py-evm==0.3.0a20 -eth-erc20~=0.0.10a2 +eth-erc20~=0.0.10a3 diff --git a/apps/cic-eth/tools_requirements.txt b/apps/cic-eth/tools_requirements.txt index 67ab3257..0920b4b2 100644 --- a/apps/cic-eth/tools_requirements.txt +++ b/apps/cic-eth/tools_requirements.txt @@ -1,7 +1,7 @@ -crypto-dev-signer~=0.4.14b6 +crypto-dev-signer~=0.4.14b7 chainqueue~=0.0.2b5 -confini~=0.3.6rc4 -cic-eth-registry~=0.5.6a1 +confini>=0.3.6rc4,<0.5.0 +cic-eth-registry~=0.5.6a2 redis==3.5.3 hexathon~=0.0.1a7 pycryptodome==3.10.1 diff --git a/apps/cic-notify/cic_notify/version.py b/apps/cic-notify/cic_notify/version.py index e8f70c71..475867be 100644 --- a/apps/cic-notify/cic_notify/version.py +++ b/apps/cic-notify/cic_notify/version.py @@ -9,7 +9,7 @@ import semver logg = logging.getLogger() -version = (0, 4, 0, 'alpha.7') +version = (0, 4, 0, 'alpha.8') version_object = semver.VersionInfo( major=version[0], diff --git a/apps/cic-notify/requirements.txt b/apps/cic-notify/requirements.txt index 17b36f50..5b677093 100644 --- a/apps/cic-notify/requirements.txt +++ b/apps/cic-notify/requirements.txt @@ -1 +1 @@ -cic_base[full_graph]==0.1.3a3+build.984b5cff +cic_base[full_graph]~=0.2.0a3 diff --git a/apps/cic-ussd/.config/app.ini b/apps/cic-ussd/.config/app.ini index 1a0b5e4f..7fdb8c44 100644 --- a/apps/cic-ussd/.config/app.ini +++ b/apps/cic-ussd/.config/app.ini @@ -1,7 +1,7 @@ [app] ALLOWED_IP=0.0.0.0/0 LOCALE_FALLBACK=en -LOCALE_PATH=/usr/src/cic-ussd/var/lib/locale/ +LOCALE_PATH=var/lib/locale/ MAX_BODY_LENGTH=1024 PASSWORD_PEPPER=QYbzKff6NhiQzY3ygl2BkiKOpER8RE/Upqs/5aZWW+I= SERVICE_CODE=*483*46#,*483*061#,*384*96# @@ -11,13 +11,13 @@ SUPPORT_PHONE_NUMBER=0757628885 REGION=KE [ussd] -MENU_FILE=/usr/src/data/ussd_menu.json +MENU_FILE=data/ussd_menu.json user = pass = [statemachine] -STATES=/usr/src/cic-ussd/states/ -TRANSITIONS=/usr/src/cic-ussd/transitions/ +STATES=states/ +TRANSITIONS=transitions/ [client] host = diff --git a/apps/cic-ussd/.config/pgp.ini b/apps/cic-ussd/.config/pgp.ini index c06f2838..7d0dc63b 100644 --- a/apps/cic-ussd/.config/pgp.ini +++ b/apps/cic-ussd/.config/pgp.ini @@ -1,5 +1,5 @@ [pgp] -export_dir = /usr/src/pgp/keys/ +export_dir = pgp/keys/ keys_path = /usr/src/secrets/ private_keys = privatekeys_meta.asc passphrase = diff --git a/apps/cic-ussd/docker/start_cic_user_server.sh b/apps/cic-ussd/docker/start_cic_user_server.sh index 08742684..5d6ecb00 100644 --- a/apps/cic-ussd/docker/start_cic_user_server.sh +++ b/apps/cic-ussd/docker/start_cic_user_server.sh @@ -4,4 +4,4 @@ user_server_port=${SERVER_PORT:-9500} -/usr/local/bin/uwsgi --wsgi-file /usr/local/lib/python3.8/site-packages/cic_ussd/runnable/daemons/cic_user_server.py --http :"$user_server_port" --pyargv "$@" +/usr/local/bin/uwsgi --wsgi-file cic_ussd/runnable/daemons/cic_user_server.py --http :"$user_server_port" --pyargv "$@" diff --git a/apps/cic-ussd/docker/start_cic_user_ussd_server.sh b/apps/cic-ussd/docker/start_cic_user_ussd_server.sh index 9bb6b9b5..35b18207 100644 --- a/apps/cic-ussd/docker/start_cic_user_ussd_server.sh +++ b/apps/cic-ussd/docker/start_cic_user_ussd_server.sh @@ -4,4 +4,4 @@ user_ussd_server_port=${SERVER_PORT:-9000} -/usr/local/bin/uwsgi --wsgi-file /usr/local/lib/python3.8/site-packages/cic_ussd/runnable/daemons/cic_user_ussd_server.py --http :"$user_ussd_server_port" --pyargv "$@" +/usr/local/bin/uwsgi --wsgi-file cic_ussd/runnable/daemons/cic_user_ussd_server.py --http :"$user_ussd_server_port" --pyargv "$@" diff --git a/apps/cic-ussd/requirements.txt b/apps/cic-ussd/requirements.txt index a9c0cbf8..2b96a9d8 100644 --- a/apps/cic-ussd/requirements.txt +++ b/apps/cic-ussd/requirements.txt @@ -1,4 +1,4 @@ -cic_base[full_graph]==0.1.3a3+build.984b5cff +cic_base[full_graph]==0.2.0a3 cic-eth~=0.12.0a1 -cic-notify~=0.4.0a7 +cic-notify~=0.4.0a8 cic-types~=0.1.0a11 diff --git a/apps/contract-migration/reset.sh b/apps/contract-migration/reset.sh index 445b1e95..2066e4c5 100755 --- a/apps/contract-migration/reset.sh +++ b/apps/contract-migration/reset.sh @@ -165,4 +165,3 @@ set +e echo -n 2 > $init_level_file exec "$@" -l:83 diff --git a/apps/data-seeding/cic_eth/import_balance.py b/apps/data-seeding/cic_eth/import_balance.py index 99e8eef4..7f7c840c 100644 --- a/apps/data-seeding/cic_eth/import_balance.py +++ b/apps/data-seeding/cic_eth/import_balance.py @@ -11,7 +11,6 @@ import csv import json # external imports -import eth_abi import confini from hexathon import ( strip_0x, @@ -29,7 +28,10 @@ from chainlib.eth.gas import OverrideGasOracle from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import TxFactory from chainlib.jsonrpc import JSONRPCRequest -from chainlib.eth.error import EthException +from chainlib.eth.error import ( + EthException, + RequestMismatchException, + ) from chainlib.chain import ChainSpec from chainlib.eth.constant import ZERO_ADDRESS from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer @@ -37,6 +39,9 @@ from crypto_dev_signer.keystore.dict import DictKeystore from cic_types.models.person import Person from eth_erc20 import ERC20 from cic_base.eth.syncer import chain_interface +from eth_accounts_index import AccountsIndex +from eth_contract_registry import Registry +from eth_token_index import TokenUniqueSymbolIndex logging.basicConfig(level=logging.WARNING) @@ -131,58 +136,52 @@ class Handler: logg.debug('no payload, skipping {}'.format(tx)) return - if tx.payload[:8] == self.account_index_add_signature: - recipient = eth_abi.decode_single('address', bytes.fromhex(tx.payload[-64:])) - #original_address = to_checksum_address(self.addresses[to_checksum_address(recipient)]) - user_file = 'new/{}/{}/{}.json'.format( - recipient[2:4].upper(), - recipient[4:6].upper(), - recipient[2:].upper(), - ) - filepath = os.path.join(self.user_dir, user_file) - o = None - try: - f = open(filepath, 'r') - o = json.load(f) - f.close() - except FileNotFoundError: - logg.error('no import record of address {}'.format(recipient)) - return - u = Person.deserialize(o) - original_address = u.identities[old_chain_spec.engine()]['{}:{}'.format(old_chain_spec.common_name(), old_chain_spec.network_id())][0] - try: - balance = self.balances[original_address] - except KeyError as e: - logg.error('balance get fail orig {} new {}'.format(original_address, recipient)) - return - - # TODO: store token object in handler ,get decimals from there - multiplier = 10**6 - balance_full = balance * multiplier - logg.info('registered {} originally {} ({}) tx hash {} balance {}'.format(recipient, original_address, u, tx.hash, balance_full)) - - (tx_hash_hex, o) = self.tx_factory.transfer(self.token_address, signer_address, recipient, balance_full) - logg.info('submitting erc20 transfer tx {} for recipient {}'.format(tx_hash_hex, recipient)) - r = conn.do(o) - - tx_path = os.path.join( - user_dir, - 'txs', - strip_0x(tx_hash_hex), - ) - f = open(tx_path, 'w') - f.write(strip_0x(o['params'][0])) + recipient = None + try: + r = AccountsIndex.parse_add_request(tx.payload) + except RequestMismatchException: + return + recipient = r[0] + + user_file = 'new/{}/{}/{}.json'.format( + recipient[2:4].upper(), + recipient[4:6].upper(), + recipient[2:].upper(), + ) + filepath = os.path.join(self.user_dir, user_file) + o = None + try: + f = open(filepath, 'r') + o = json.load(f) f.close() -# except TypeError as e: -# logg.warning('typerror {}'.format(e)) -# pass -# except IndexError as e: -# logg.warning('indexerror {}'.format(e)) -# pass -# except EthException as e: -# logg.error('send error {}'.format(e).ljust(200)) - #except KeyError as e: - # logg.error('key record not found in imports: {}'.format(e).ljust(200)) + except FileNotFoundError: + logg.error('no import record of address {}'.format(recipient)) + return + u = Person.deserialize(o) + original_address = u.identities[old_chain_spec.engine()]['{}:{}'.format(old_chain_spec.common_name(), old_chain_spec.network_id())][0] + try: + balance = self.balances[original_address] + except KeyError as e: + logg.error('balance get fail orig {} new {}'.format(original_address, recipient)) + return + + # TODO: store token object in handler ,get decimals from there + multiplier = 10**6 + balance_full = balance * multiplier + logg.info('registered {} originally {} ({}) tx hash {} balance {}'.format(recipient, original_address, u, tx.hash, balance_full)) + + (tx_hash_hex, o) = self.tx_factory.transfer(self.token_address, signer_address, recipient, balance_full) + logg.info('submitting erc20 transfer tx {} for recipient {}'.format(tx_hash_hex, recipient)) + r = conn.do(o) + + tx_path = os.path.join( + user_dir, + 'txs', + strip_0x(tx_hash_hex), + ) + f = open(tx_path, 'w') + f.write(strip_0x(o['params'][0])) + f.close() def progress_callback(block_number, tx_index): @@ -198,49 +197,26 @@ def main(): nonce_oracle = RPCNonceOracle(signer_address, conn) # Get Token registry address - txf = TxFactory(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=None) - tx = txf.template(signer_address, config.get('CIC_REGISTRY_ADDRESS')) - - registry_addressof_method = keccak256_string_to_hex('addressOf(bytes32)')[:8] - data = add_0x(registry_addressof_method) - data += eth_abi.encode_single('bytes32', b'TokenRegistry').hex() - txf.set_code(tx, data) - - j = JSONRPCRequest() - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) + registry = Registry(chain_spec) + o = registry.address_of(config.get('CIC_REGISTRY_ADDRESS'), 'TokenRegistry') r = conn.do(o) - token_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) + token_index_address = registry.parse_address_of(r) + token_index_address = to_checksum_address(token_index_address) logg.info('found token index address {}'.format(token_index_address)) - - + # Get Sarafu token address - tx = txf.template(signer_address, token_index_address) - data = add_0x(registry_addressof_method) - h = hashlib.new('sha256') - h.update(token_symbol.encode('utf-8')) - z = h.digest() - data += eth_abi.encode_single('bytes32', z).hex() - txf.set_code(tx, data) - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) + token_index = TokenUniqueSymbolIndex(chain_spec) + o = token_index.address_of(token_index_address, token_symbol) r = conn.do(o) + token_address = token_index.parse_address_of(r) try: - sarafu_token_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) + token_address = to_checksum_address(token_address) except ValueError as e: logg.critical('lookup failed for token {}: {}'.format(token_symbol, e)) sys.exit(1) - - if sarafu_token_address == ZERO_ADDRESS: - raise KeyError('token address for symbol {} is zero'.format(token_symbol)) - - logg.info('found token address {}'.format(sarafu_token_address)) + logg.info('found token address {}'.format(token_address)) + + sys.exit(0) syncer_backend = MemBackend(chain_str, 0) @@ -248,22 +224,6 @@ def main(): o = block_latest() r = conn.do(o) block_offset = int(strip_0x(r), 16) + 1 -# -# addresses = {} -# f = open('{}/addresses.csv'.format(user_dir, 'r')) -# while True: -# l = f.readline() -# if l == None: -# break -# r = l.split(',') -# try: -# k = r[0] -# v = r[1].rstrip() -# addresses[k] = v -# sys.stdout.write('loading address mapping {} -> {}'.format(k, v).ljust(200) + "\r") -# except IndexError as e: -# break -# f.close() # TODO get decimals from token balances = {} diff --git a/apps/data-seeding/cic_ussd/import_ussd_data.py b/apps/data-seeding/cic_ussd/import_ussd_data.py index fddd8bb6..44f06be9 100644 --- a/apps/data-seeding/cic_ussd/import_ussd_data.py +++ b/apps/data-seeding/cic_ussd/import_ussd_data.py @@ -17,7 +17,7 @@ default_config_dir = '/usr/local/etc/cic' arg_parser = argparse.ArgumentParser() arg_parser.add_argument('-c', type=str, default=default_config_dir, help='config file') -arg_parser.add_argument('-q', type=str, default='cic-eth', help='Task queue') +arg_parser.add_argument('-q', type=str, default='cic-import-ussd', help='Task queue') arg_parser.add_argument('-v', action='store_true', help='Be verbose') arg_parser.add_argument('-vv', action='store_true', help='Be more verbose') arg_parser.add_argument('user_dir', type=str, help='path to users export dir tree') diff --git a/apps/data-seeding/eth/import_balance.py b/apps/data-seeding/eth/import_balance.py index 2d436a66..e70bce49 100644 --- a/apps/data-seeding/eth/import_balance.py +++ b/apps/data-seeding/eth/import_balance.py @@ -11,7 +11,6 @@ import csv import json # external imports -import eth_abi import confini from hexathon import ( strip_0x, @@ -29,13 +28,20 @@ from chainlib.eth.gas import OverrideGasOracle from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import TxFactory from chainlib.jsonrpc import JSONRPCRequest -from chainlib.eth.error import EthException +from chainlib.eth.error import ( + EthException, + RequestMismatchException, + ) from chainlib.chain import ChainSpec from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer from crypto_dev_signer.keystore.dict import DictKeystore from cic_types.models.person import Person from eth_erc20 import ERC20 from cic_base.eth.syncer import chain_interface +from eth_accounts_index import AccountsIndex +from eth_contract_registry import Registry +from eth_token_index import TokenUniqueSymbolIndex +from erc20_faucet import Faucet logging.basicConfig(level=logging.WARNING) @@ -50,7 +56,7 @@ argparser.add_argument('-c', type=str, default=config_dir, help='config root to argparser.add_argument('--old-chain-spec', type=str, dest='old_chain_spec', default='evm:oldchain:1', help='chain spec') argparser.add_argument('-i', '--chain-spec', type=str, dest='i', help='chain spec') argparser.add_argument('-r', '--registry-address', type=str, dest='r', help='CIC Registry address') -argparser.add_argument('--token-symbol', default='SRF', type=str, dest='token_symbol', help='Token symbol to use for trnsactions') +argparser.add_argument('--token-symbol', default='GFT', type=str, dest='token_symbol', help='Token symbol to use for trnsactions') argparser.add_argument('--head', action='store_true', help='start at current block height (overrides --offset)') 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('-q', type=str, default='cic-eth', help='celery queue to submit transaction tasks to') @@ -112,12 +118,16 @@ class Handler: account_index_add_signature = keccak256_string_to_hex('add(address)')[:8] - def __init__(self, conn, chain_spec, user_dir, balances, token_address, signer, gas_oracle, nonce_oracle): + def __init__(self, conn, chain_spec, user_dir, balances, token_address, faucet_address, signer_address, signer, gas_oracle, nonce_oracle): self.token_address = token_address + self.faucet_address = faucet_address self.user_dir = user_dir self.balances = balances self.chain_spec = chain_spec - self.tx_factory = ERC20(chain_spec, signer, gas_oracle, nonce_oracle) + self.nonce_oracle = nonce_oracle + self.gas_oracle = gas_oracle + self.signer_address = signer_address + self.signer = signer def name(self): @@ -129,58 +139,59 @@ class Handler: logg.debug('no payload, skipping {}'.format(tx)) return - if tx.payload[:8] == self.account_index_add_signature: - recipient = eth_abi.decode_single('address', bytes.fromhex(tx.payload[-64:])) - #original_address = to_checksum_address(self.addresses[to_checksum_address(recipient)]) - user_file = 'new/{}/{}/{}.json'.format( - recipient[2:4].upper(), - recipient[4:6].upper(), - recipient[2:].upper(), - ) - filepath = os.path.join(self.user_dir, user_file) - o = None - try: - f = open(filepath, 'r') - o = json.load(f) - f.close() - except FileNotFoundError: - logg.error('no import record of address {}'.format(recipient)) - return - u = Person.deserialize(o) - original_address = u.identities[old_chain_spec.engine()]['{}:{}'.format(old_chain_spec.common_name(), old_chain_spec.network_id())][0] - try: - balance = self.balances[original_address] - except KeyError as e: - logg.error('balance get fail orig {} new {}'.format(original_address, recipient)) - return - - # TODO: store token object in handler ,get decimals from there - multiplier = 10**6 - balance_full = balance * multiplier - logg.info('registered {} originally {} ({}) tx hash {} balance {}'.format(recipient, original_address, u, tx.hash, balance_full)) - - (tx_hash_hex, o) = self.tx_factory.transfer(self.token_address, signer_address, recipient, balance_full) - logg.info('submitting erc20 transfer tx {} for recipient {}'.format(tx_hash_hex, recipient)) - r = conn.do(o) - - tx_path = os.path.join( - user_dir, - 'txs', - strip_0x(tx_hash_hex), - ) - f = open(tx_path, 'w') - f.write(strip_0x(o['params'][0])) + recipient = None + try: + r = AccountsIndex.parse_add_request(tx.payload) + except RequestMismatchException: + return + recipient = r[0] + + user_file = 'new/{}/{}/{}.json'.format( + recipient[2:4].upper(), + recipient[4:6].upper(), + recipient[2:].upper(), + ) + filepath = os.path.join(self.user_dir, user_file) + o = None + try: + f = open(filepath, 'r') + o = json.load(f) f.close() -# except TypeError as e: -# logg.warning('typerror {}'.format(e)) -# pass -# except IndexError as e: -# logg.warning('indexerror {}'.format(e)) -# pass -# except EthException as e: -# logg.error('send error {}'.format(e).ljust(200)) - #except KeyError as e: - # logg.error('key record not found in imports: {}'.format(e).ljust(200)) + except FileNotFoundError: + logg.error('no import record of address {}'.format(recipient)) + return + u = Person.deserialize(o) + original_address = u.identities[old_chain_spec.engine()]['{}:{}'.format(old_chain_spec.common_name(), old_chain_spec.network_id())][0] + try: + balance = self.balances[original_address] + except KeyError as e: + logg.error('balance get fail orig {} new {}'.format(original_address, recipient)) + return + + # TODO: store token object in handler ,get decimals from there + erc20 = ERC20(self.chain_spec, signer=self.signer, gas_oracle=self.gas_oracle, nonce_oracle=self.nonce_oracle) + o = erc20.decimals(self.token_address) + r = conn.do(o) + decimals = erc20.parse_decimals(r) + multiplier = 10 ** decimals + balance_full = balance * multiplier + logg.info('registered {} originally {} ({}) tx hash {} balance {}'.format(recipient, original_address, u, tx.hash, balance_full)) + (tx_hash_hex, o) = erc20.transfer(self.token_address, self.signer_address, recipient, balance_full) + logg.info('submitting erc20 transfer tx {} for recipient {}'.format(tx_hash_hex, recipient)) + r = conn.do(o) + + tx_path = os.path.join( + user_dir, + 'txs', + strip_0x(tx_hash_hex), + ) + f = open(tx_path, 'w') + f.write(strip_0x(o['params'][0])) + f.close() + + faucet = Faucet(self.chain_spec, signer=self.signer, gas_oracle=self.gas_oracle, nonce_oracle=self.nonce_oracle) + (tx_hash, o) = faucet.give_to(self.faucet_address, self.signer_address, recipient) + r = conn.do(o) def progress_callback(block_number, tx_index): @@ -196,45 +207,31 @@ def main(): nonce_oracle = RPCNonceOracle(signer_address, conn) # Get Token registry address - txf = TxFactory(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=None) - tx = txf.template(signer_address, config.get('CIC_REGISTRY_ADDRESS')) - - registry_addressof_method = keccak256_string_to_hex('addressOf(bytes32)')[:8] - data = add_0x(registry_addressof_method) - data += eth_abi.encode_single('bytes32', b'TokenRegistry').hex() - txf.set_code(tx, data) - - j = JSONRPCRequest() - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) + registry = Registry(chain_spec) + o = registry.address_of(config.get('CIC_REGISTRY_ADDRESS'), 'TokenRegistry') r = conn.do(o) - token_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) + token_index_address = registry.parse_address_of(r) + token_index_address = to_checksum_address(token_index_address) logg.info('found token index address {}'.format(token_index_address)) - + + # Get Faucet address + o = registry.address_of(config.get('CIC_REGISTRY_ADDRESS'), 'Faucet') + r = conn.do(o) + faucet_address = registry.parse_address_of(r) + faucet_address = to_checksum_address(faucet_address) + logg.info('found faucet {}'.format(faucet_address)) # Get Sarafu token address - tx = txf.template(signer_address, token_index_address) - data = add_0x(registry_addressof_method) - h = hashlib.new('sha256') - h.update(token_symbol.encode('utf-8')) - z = h.digest() - data += eth_abi.encode_single('bytes32', z).hex() - txf.set_code(tx, data) - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) + token_index = TokenUniqueSymbolIndex(chain_spec) + o = token_index.address_of(token_index_address, token_symbol) r = conn.do(o) + token_address = token_index.parse_address_of(r) try: - sarafu_token_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) + token_address = to_checksum_address(token_address) except ValueError as e: logg.critical('lookup failed for token {}: {}'.format(token_symbol, e)) sys.exit(1) - logg.info('found token address {}'.format(sarafu_token_address)) + logg.info('found token address {}'.format(token_address)) syncer_backend = MemBackend(chain_str, 0) @@ -242,22 +239,6 @@ def main(): o = block_latest() r = conn.do(o) block_offset = int(strip_0x(r), 16) + 1 -# -# addresses = {} -# f = open('{}/addresses.csv'.format(user_dir, 'r')) -# while True: -# l = f.readline() -# if l == None: -# break -# r = l.split(',') -# try: -# k = r[0] -# v = r[1].rstrip() -# addresses[k] = v -# sys.stdout.write('loading address mapping {} -> {}'.format(k, v).ljust(200) + "\r") -# except IndexError as e: -# break -# f.close() # TODO get decimals from token balances = {} @@ -282,7 +263,7 @@ def main(): syncer_backend.set(block_offset, 0) syncer = HeadSyncer(syncer_backend, chain_interface, block_callback=progress_callback) - handler = Handler(conn, chain_spec, user_dir, balances, sarafu_token_address, signer, gas_oracle, nonce_oracle) + handler = Handler(conn, chain_spec, user_dir, balances, token_address, faucet_address, signer_address, signer, gas_oracle, nonce_oracle) syncer.add_filter(handler) syncer.loop(1, conn) diff --git a/apps/data-seeding/requirements.txt b/apps/data-seeding/requirements.txt index ab043327..0919fb95 100644 --- a/apps/data-seeding/requirements.txt +++ b/apps/data-seeding/requirements.txt @@ -1,4 +1,12 @@ -sarafu-faucet==0.0.4a1 -cic-eth[tools]==0.12.0a1 +sarafu-faucet==0.0.4a3 +cic-eth[tools]==0.12.1a1 cic-types==0.1.0a13 -crypto-dev-signer==0.4.14b6 +crypto-dev-signer==0.4.14b7 +faker==4.17.1 +chainsyncer~=0.0.3a3 +chainlib-eth~=0.0.5a1 +eth-address-index~=0.1.2a1 +eth-contract-registry~=0.5.6a1 +eth-accounts-index~=0.0.12a1 +eth-erc20~=0.0.10a3 +erc20-faucet~=0.2.2a1 diff --git a/apps/data-seeding/verify.py b/apps/data-seeding/verify.py index 09813d9b..911f0750 100644 --- a/apps/data-seeding/verify.py +++ b/apps/data-seeding/verify.py @@ -14,7 +14,6 @@ import urllib.parse # external imports import celery import confini -import eth_abi from chainlib.chain import ChainSpec from chainlib.eth.address import to_checksum_address from chainlib.eth.connection import EthHTTPConnection @@ -33,6 +32,9 @@ from cic_types.models.person import ( from erc20_faucet import Faucet from eth_erc20 import ERC20 from hexathon.parse import strip_0x, add_0x +from eth_contract_registry import Registry +from eth_accounts_index import AccountsIndex +from eth_token_index import TokenUniqueSymbolIndex logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() @@ -43,7 +45,8 @@ custodial_tests = [ 'local_key', 'gas', 'faucet', - 'ussd' + 'ussd', + 'ussd_pins', ] metadata_tests = [ @@ -71,6 +74,7 @@ argparser.add_argument('-i', '--chain-spec', type=str, dest='i', help='chain spe argparser.add_argument('--meta-provider', type=str, dest='meta_provider', default='http://localhost:63380', help='cic-meta url') argparser.add_argument('--ussd-provider', type=str, dest='ussd_provider', default='http://localhost:63315', help='cic-ussd url') argparser.add_argument('--skip-custodial', dest='skip_custodial', action='store_true', help='skip all custodial verifications') +argparser.add_argument('--skip-metadata', dest='skip_metadata', action='store_true', help='skip all metadata verifications') argparser.add_argument('--exclude', action='append', type=str, default=[], help='skip specified verification') argparser.add_argument('--include', action='append', type=str, help='include specified verification') argparser.add_argument('--token-symbol', default='GFT', type=str, dest='token_symbol', help='Token symbol to use for trnsactions') @@ -130,6 +134,11 @@ if args.skip_custodial: for t in custodial_tests: if t not in exclude: exclude.append(t) +if args.skip_metadata: + logg.info('will skip all metadata verifications ({})'.format(','.join(metadata_tests))) + for t in metadata_tests: + if t not in exclude: + exclude.append(t) for t in include: if t not in all_tests: raise ValueError('Cannot include unknown verification "{}"'.format(t)) @@ -140,7 +149,7 @@ for t in include: api = None for t in custodial_tests: if t in active_tests: - from cic_eth.api.api_admin import AdminApi + from cic_eth.api.admin import AdminApi api = AdminApi(None) logg.info('activating custodial module'.format(t)) break @@ -263,19 +272,11 @@ class Verifier: def verify_accounts_index(self, address, balance=None): - tx = self.tx_factory.template(ZERO_ADDRESS, self.index_address) - data = keccak256_string_to_hex('have(address)')[:8] - data += eth_abi.encode_single('address', address).hex() - tx = self.tx_factory.set_code(tx, data) - tx = self.tx_factory.normalize(tx) - j = JSONRPCRequest() - o = j.template() - o['method'] = 'eth_call' - o['params'].append(tx) - o = j.finalize(o) + accounts_index = AccountsIndex(self.chain_spec) + o = accounts_index.have(self.index_address, address) r = self.conn.do(o) - logg.debug('index check for {}: {}'.format(address, r)) - n = eth_abi.decode_single('uint256', bytes.fromhex(strip_0x(r))) + n = accounts_index.parse_have(r) + logg.debug('index check for {}: {}'.format(address, n)) if n != 1: raise VerifierError(n, 'accounts index') @@ -427,70 +428,39 @@ def main(): gas_oracle = OverrideGasOracle(conn=conn, limit=8000000) # Get Token registry address - txf = TxFactory(chain_spec, signer=None, gas_oracle=gas_oracle, nonce_oracle=None) - tx = txf.template(ZERO_ADDRESS, config.get('CIC_REGISTRY_ADDRESS')) - - # TODO: replace with cic-eth-registry - registry_addressof_method = keccak256_string_to_hex('addressOf(bytes32)')[:8] - data = add_0x(registry_addressof_method) - data += eth_abi.encode_single('bytes32', b'TokenRegistry').hex() - txf.set_code(tx, data) - - j = JSONRPCRequest() - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) + registry = Registry(chain_spec) + o = registry.address_of(config.get('CIC_REGISTRY_ADDRESS'), 'TokenRegistry') r = conn.do(o) - token_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) + token_index_address = registry.parse_address_of(r) + token_index_address = to_checksum_address(token_index_address) logg.info('found token index address {}'.format(token_index_address)) - data = add_0x(registry_addressof_method) - data += eth_abi.encode_single('bytes32', b'AccountRegistry').hex() - txf.set_code(tx, data) - - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) + # Get Account registry address + o = registry.address_of(config.get('CIC_REGISTRY_ADDRESS'), 'AccountRegistry') r = conn.do(o) - account_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) + account_index_address = registry.parse_address_of(r) + account_index_address = to_checksum_address(account_index_address) logg.info('found account index address {}'.format(account_index_address)) - data = add_0x(registry_addressof_method) - data += eth_abi.encode_single('bytes32', b'Faucet').hex() - txf.set_code(tx, data) - - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) + # Get Faucet address + o = registry.address_of(config.get('CIC_REGISTRY_ADDRESS'), 'Faucet') r = conn.do(o) - faucet_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) + faucet_address = registry.parse_address_of(r) + faucet_index_address = to_checksum_address(token_index_address) logg.info('found faucet {}'.format(faucet_address)) - - - # Get Sarafu token address - tx = txf.template(ZERO_ADDRESS, token_index_address) - data = add_0x(registry_addressof_method) - h = hashlib.new('sha256') - h.update(token_symbol.encode('utf-8')) - z = h.digest() - data += eth_abi.encode_single('bytes32', z).hex() - txf.set_code(tx, data) - o = j.template() - o['method'] = 'eth_call' - o['params'].append(txf.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) +# Get Sarafu token address + token_index = TokenUniqueSymbolIndex(chain_spec) + o = token_index.address_of(token_index_address, token_symbol) r = conn.do(o) - sarafu_token_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r)))) - logg.info('found token address {}'.format(sarafu_token_address)) - + token_address = token_index.parse_address_of(r) + try: + token_address = to_checksum_address(token_address) + except ValueError as e: + logg.critical('lookup failed for token {}: {}'.format(token_symbol, e)) + sys.exit(1) + logg.info('found token address {}'.format(token_address)) + balances = {} f = open('{}/balances.csv'.format(user_dir, 'r')) i = 0 @@ -511,7 +481,7 @@ def main(): f.close() - verifier = Verifier(conn, api, gas_oracle, chain_spec, account_index_address, sarafu_token_address, faucet_address, user_dir, exit_on_error) + verifier = Verifier(conn, api, gas_oracle, chain_spec, account_index_address, token_address, faucet_address, user_dir, exit_on_error) user_new_dir = os.path.join(user_dir, 'new') i = 0