diff --git a/apps/cic-eth/cic_eth/admin/ctrl.py b/apps/cic-eth/cic_eth/admin/ctrl.py index 5c9d769c..1868238e 100644 --- a/apps/cic-eth/cic_eth/admin/ctrl.py +++ b/apps/cic-eth/cic_eth/admin/ctrl.py @@ -10,12 +10,15 @@ from cic_registry import zero_address from cic_eth.db.enum import LockEnum from cic_eth.db.models.base import SessionBase from cic_eth.db.models.lock import Lock +from cic_eth.task import ( + CriticalSQLAlchemyTask, + ) from cic_eth.error import LockedError celery_app = celery.current_app logg = logging.getLogger() -@celery_app.task() +@celery_app.task(base=CriticalSQLAlchemyTask) def lock(chained_input, chain_str, address=zero_address, flags=LockEnum.ALL, tx_hash=None): """Task wrapper to set arbitrary locks @@ -33,7 +36,7 @@ def lock(chained_input, chain_str, address=zero_address, flags=LockEnum.ALL, tx_ return chained_input -@celery_app.task() +@celery_app.task(base=CriticalSQLAlchemyTask) def unlock(chained_input, chain_str, address=zero_address, flags=LockEnum.ALL): """Task wrapper to reset arbitrary locks @@ -51,7 +54,7 @@ def unlock(chained_input, chain_str, address=zero_address, flags=LockEnum.ALL): return chained_input -@celery_app.task() +@celery_app.task(base=CriticalSQLAlchemyTask) def lock_send(chained_input, chain_str, address=zero_address, tx_hash=None): """Task wrapper to set send lock @@ -67,7 +70,7 @@ def lock_send(chained_input, chain_str, address=zero_address, tx_hash=None): return chained_input -@celery_app.task() +@celery_app.task(base=CriticalSQLAlchemyTask) def unlock_send(chained_input, chain_str, address=zero_address): """Task wrapper to reset send lock @@ -83,7 +86,7 @@ def unlock_send(chained_input, chain_str, address=zero_address): return chained_input -@celery_app.task() +@celery_app.task(base=CriticalSQLAlchemyTask) def lock_queue(chained_input, chain_str, address=zero_address, tx_hash=None): """Task wrapper to set queue direct lock @@ -99,7 +102,7 @@ def lock_queue(chained_input, chain_str, address=zero_address, tx_hash=None): return chained_input -@celery_app.task() +@celery_app.task(base=CriticalSQLAlchemyTask) def unlock_queue(chained_input, chain_str, address=zero_address): """Task wrapper to reset queue direct lock @@ -115,7 +118,7 @@ def unlock_queue(chained_input, chain_str, address=zero_address): return chained_input -@celery_app.task() +@celery_app.task(base=CriticalSQLAlchemyTask) def check_lock(chained_input, chain_str, lock_flags, address=None): session = SessionBase.create_session() r = Lock.check(chain_str, lock_flags, address=zero_address, session=session) diff --git a/apps/cic-eth/cic_eth/api/api_task.py b/apps/cic-eth/cic_eth/api/api_task.py index f6e8704d..9013f26f 100644 --- a/apps/cic-eth/cic_eth/api/api_task.py +++ b/apps/cic-eth/cic_eth/api/api_task.py @@ -82,6 +82,7 @@ class Api: :returns: uuid of root task :rtype: celery.Task """ + raise NotImplementedError('out of service until new DEX migration is done') s_check = celery.signature( 'cic_eth.admin.ctrl.check_lock', [ @@ -143,6 +144,7 @@ class Api: :returns: uuid of root task :rtype: celery.Task """ + raise NotImplementedError('out of service until new DEX migration is done') s_check = celery.signature( 'cic_eth.admin.ctrl.check_lock', [ @@ -340,11 +342,6 @@ class Api: ], queue=self.queue, ) - s_nonce = celery.signature( - 'cic_eth.eth.tx.reserve_nonce', - [], - queue=self.queue, - ) s_account = celery.signature( 'cic_eth.eth.account.create', [ @@ -352,12 +349,18 @@ class Api: ], queue=self.queue, ) - s_nonce.link(s_account) - s_check.link(s_nonce) + s_check.link(s_account) if self.callback_param != None: s_account.link(self.callback_success) if register: + s_nonce = celery.signature( + 'cic_eth.eth.tx.reserve_nonce', + [ + 'ACCOUNTS_INDEX_WRITER', + ], + queue=self.queue, + ) s_register = celery.signature( 'cic_eth.eth.account.register', [ @@ -365,7 +368,8 @@ class Api: ], queue=self.queue, ) - s_account.link(s_register) + s_nonce.link(s_register) + s_account.link(s_nonce) t = s_check.apply_async(queue=self.queue) return t @@ -390,7 +394,9 @@ class Api: ) s_nonce = celery.signature( 'cic_eth.eth.tx.reserve_nonce', - [], + [ + 'GAS_GIFTER', + ], queue=self.queue, ) s_refill = celery.signature( diff --git a/apps/cic-eth/cic_eth/error.py b/apps/cic-eth/cic_eth/error.py index 8f769268..b6d615c9 100644 --- a/apps/cic-eth/cic_eth/error.py +++ b/apps/cic-eth/cic_eth/error.py @@ -73,3 +73,10 @@ class SignerError(Exception): """ pass + + +class EthError(Exception): + """Exception raised when unspecified error from evm node is encountered + + """ + pass diff --git a/apps/cic-eth/cic_eth/eth/gas.py b/apps/cic-eth/cic_eth/eth/gas.py index 8cf99055..34a2ff1a 100644 --- a/apps/cic-eth/cic_eth/eth/gas.py +++ b/apps/cic-eth/cic_eth/eth/gas.py @@ -54,6 +54,7 @@ class GasOracle(): """ session = SessionBase.create_session() a = AccountRole.get_address('GAS_GIFTER', session) + logg.debug('gasgifter {}'.format(a)) session.close() return a diff --git a/apps/cic-eth/cic_eth/eth/tx.py b/apps/cic-eth/cic_eth/eth/tx.py index 2780faa7..ec87ba3b 100644 --- a/apps/cic-eth/cic_eth/eth/tx.py +++ b/apps/cic-eth/cic_eth/eth/tx.py @@ -14,6 +14,7 @@ from cic_eth.db import Otx, SessionBase from cic_eth.db.models.tx import TxCache from cic_eth.db.models.nonce import NonceReservation from cic_eth.db.models.lock import Lock +from cic_eth.db.models.role import AccountRole from cic_eth.db.enum import ( LockEnum, StatusBits, @@ -38,6 +39,7 @@ from cic_eth.task import ( CriticalWeb3Task, CriticalWeb3AndSignerTask, CriticalSQLAlchemyAndSignerTask, + CriticalSQLAlchemyAndWeb3Task, ) celery_app = celery.current_app @@ -47,7 +49,7 @@ MAX_NONCE_ATTEMPTS = 3 # TODO this function is too long -@celery_app.task(bind=True, throws=(OutOfGasError), base=CriticalSQLAlchemyTask) +@celery_app.task(bind=True, throws=(OutOfGasError), base=CriticalSQLAlchemyAndWeb3Task) def check_gas(self, tx_hashes, chain_str, txs=[], address=None, gas_required=None): """Check the gas level of the sender address of a transaction. @@ -75,6 +77,9 @@ def check_gas(self, tx_hashes, chain_str, txs=[], address=None, gas_required=Non if address == None: address = o['address'] + if not web3.Web3.isChecksumAddress(address): + raise ValueError('invalid address {}'.format(address)) + chain_spec = ChainSpec.from_chain_str(chain_str) queue = self.request.delivery_info['routing_key'] @@ -83,7 +88,12 @@ def check_gas(self, tx_hashes, chain_str, txs=[], address=None, gas_required=Non c = RpcClient(chain_spec) # TODO: it should not be necessary to pass address explicitly, if not passed should be derived from the tx - balance = c.w3.eth.getBalance(address) + balance = 0 + try: + balance = c.w3.eth.getBalance(address) + except ValueError as e: + raise EthError('balance call for {}'.format()) + logg.debug('address {} has gas {} needs {}'.format(address, balance, gas_required)) if gas_required > balance: @@ -590,11 +600,23 @@ def resend_with_higher_gas(self, txold_hash_hex, chain_str, gas=None, default_fa @celery_app.task(bind=True, base=CriticalSQLAlchemyTask) -def reserve_nonce(self, chained_input, address=None): +def reserve_nonce(self, chained_input, signer=None): session = SessionBase.create_session() - if address == None: + address = None + if signer == None: address = chained_input + logg.debug('non-explicit address for reserve nonce, using arg head {}'.format(chained_input)) + else: + if web3.Web3.isChecksumAddress(signer): + address = signer + logg.debug('explicit address for reserve nonce {}'.format(signer)) + else: + address = AccountRole.get_address(signer, session=session) + logg.debug('role for reserve nonce {} -> {}'.format(signer, address)) + + if not web3.Web3.isChecksumAddress(address): + raise ValueError('invalid result when resolving address for nonce {}'.format(address)) root_id = self.request.root_id nonce = NonceReservation.next(address, root_id) diff --git a/apps/cic-eth/cic_eth/runnable/create.py b/apps/cic-eth/cic_eth/runnable/create.py index 8371b0eb..532878b4 100644 --- a/apps/cic-eth/cic_eth/runnable/create.py +++ b/apps/cic-eth/cic_eth/runnable/create.py @@ -5,6 +5,7 @@ import os import logging import uuid import json +from xdg.BaseDirectory import xdg_config_home import celery from cic_eth.api import Api diff --git a/apps/cic-eth/cic_eth/runnable/ctrl.py b/apps/cic-eth/cic_eth/runnable/ctrl.py index 2aae7be5..b73f3bd6 100644 --- a/apps/cic-eth/cic_eth/runnable/ctrl.py +++ b/apps/cic-eth/cic_eth/runnable/ctrl.py @@ -25,7 +25,7 @@ logging.getLogger('urllib3').setLevel(logging.WARNING) default_abi_dir = '/usr/share/local/cic/solidity/abi' -default_config_dir = os.path.join('/usr/local/etc/cic-eth') +default_config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic') argparser = argparse.ArgumentParser() argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') diff --git a/apps/cic-eth/cic_eth/runnable/resend.py b/apps/cic-eth/cic_eth/runnable/resend.py index b455b772..77faf95a 100644 --- a/apps/cic-eth/cic_eth/runnable/resend.py +++ b/apps/cic-eth/cic_eth/runnable/resend.py @@ -22,7 +22,7 @@ logg = logging.getLogger() logging.getLogger('web3').setLevel(logging.WARNING) logging.getLogger('urllib3').setLevel(logging.WARNING) -default_config_dir = os.path.join('/usr/local/etc/cic-eth') +default_config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic') argparser = argparse.ArgumentParser() diff --git a/apps/cic-eth/cic_eth/runnable/view.py b/apps/cic-eth/cic_eth/runnable/view.py index 144f0940..0cd6f8d2 100644 --- a/apps/cic-eth/cic_eth/runnable/view.py +++ b/apps/cic-eth/cic_eth/runnable/view.py @@ -37,7 +37,7 @@ logging.getLogger('urllib3').setLevel(logging.WARNING) default_abi_dir = '/usr/share/local/cic/solidity/abi' -default_config_dir = os.path.join('/usr/local/etc/cic-eth') +default_config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic') argparser = argparse.ArgumentParser() argparser.add_argument('-p', '--provider', dest='p', type=str, help='Web3 provider url (http only)') diff --git a/apps/cic-eth/cic_eth/task.py b/apps/cic-eth/cic_eth/task.py index 2b5f6af2..5d34e5af 100644 --- a/apps/cic-eth/cic_eth/task.py +++ b/apps/cic-eth/cic_eth/task.py @@ -6,7 +6,10 @@ import celery import sqlalchemy # local imports -from cic_eth.error import SignerError +from cic_eth.error import ( + SignerError, + EthError, + ) class CriticalTask(celery.Task): @@ -33,6 +36,7 @@ class CriticalSQLAlchemyAndWeb3Task(CriticalTask): sqlalchemy.exc.DatabaseError, sqlalchemy.exc.TimeoutError, requests.exceptions.ConnectionError, + EthError, ) class CriticalSQLAlchemyAndSignerTask(CriticalTask): diff --git a/apps/cic-eth/cic_eth/version.py b/apps/cic-eth/cic_eth/version.py index 66a1f091..6da7a124 100644 --- a/apps/cic-eth/cic_eth/version.py +++ b/apps/cic-eth/cic_eth/version.py @@ -10,7 +10,7 @@ version = ( 0, 10, 0, - 'alpha.39', + 'alpha.41', ) version_object = semver.VersionInfo( diff --git a/apps/cic-eth/requirements.txt b/apps/cic-eth/requirements.txt index 96b4c93e..ef85b3c4 100644 --- a/apps/cic-eth/requirements.txt +++ b/apps/cic-eth/requirements.txt @@ -1,4 +1,4 @@ -cic-base~=0.1.1a10 +cic-base~=0.1.1a20 web3==5.12.2 celery==4.4.7 crypto-dev-signer~=0.4.13rc4 diff --git a/apps/cic-notify/setup.cfg b/apps/cic-notify/setup.cfg index d421d373..4ef87f2c 100644 --- a/apps/cic-notify/setup.cfg +++ b/apps/cic-notify/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = cic-notify -version= attr: cic_notify.version.__version_string__ +version= 0.4.0a2 description = CIC notifications service author = Louis Holbrook author_email = dev@holbrook.no diff --git a/apps/cic-ussd/emulator/cli/config/app.ini b/apps/cic-ussd/.config_client/app.ini similarity index 100% rename from apps/cic-ussd/emulator/cli/config/app.ini rename to apps/cic-ussd/.config_client/app.ini diff --git a/apps/cic-ussd/emulator/cli/config/client.ini b/apps/cic-ussd/.config_client/client.ini similarity index 100% rename from apps/cic-ussd/emulator/cli/config/client.ini rename to apps/cic-ussd/.config_client/client.ini diff --git a/apps/cic-ussd/emulator/cli/config/ussd.ini b/apps/cic-ussd/.config_client/ussd.ini similarity index 100% rename from apps/cic-ussd/emulator/cli/config/ussd.ini rename to apps/cic-ussd/.config_client/ussd.ini diff --git a/apps/cic-ussd/emulator/cli/cli.py b/apps/cic-ussd/cic_ussd/runnable/client.py similarity index 93% rename from apps/cic-ussd/emulator/cli/cli.py rename to apps/cic-ussd/cic_ussd/runnable/client.py index bf280756..f6fc050b 100644 --- a/apps/cic-ussd/emulator/cli/cli.py +++ b/apps/cic-ussd/cic_ussd/runnable/client.py @@ -21,10 +21,10 @@ from confini import Config logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() -config_dir = os.path.join(xdg_config_home, 'cli-ussd') +default_config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic') argparser = argparse.ArgumentParser(description='CLI tool to interface a Sempo USSD session') -argparser.add_argument('-c', type=str, default=config_dir, help='config root to use') +argparser.add_argument('-c', type=str, default=default_config_dir, help='config root to use') #argparser.add_argument('-d', type=str, default='local', help='deployment name to interface (config root subdirectory)') argparser.add_argument('--host', type=str, default='localhost') argparser.add_argument('--port', type=int, default=9000) @@ -64,7 +64,7 @@ else: ssl = True -if __name__ == "__main__": +def main(): # TODO: improve url building url = 'http' @@ -101,3 +101,7 @@ if __name__ == "__main__": state = response_data[:3] out = response_data[4:] print(out) + + +if __name__ == "__main__": + main() diff --git a/apps/cic-ussd/cic_ussd/version.py b/apps/cic-ussd/cic_ussd/version.py index 17432524..2161a75c 100644 --- a/apps/cic-ussd/cic_ussd/version.py +++ b/apps/cic-ussd/cic_ussd/version.py @@ -1,7 +1,7 @@ # standard imports import semver -version = (0, 3, 0, 'alpha.1') +version = (0, 3, 0, 'alpha.5') version_object = semver.VersionInfo( major=version[0], diff --git a/apps/cic-ussd/emulator/browser/index.html b/apps/cic-ussd/emulator/browser/index.html index 1dd5c890..642ddfe7 100644 --- a/apps/cic-ussd/emulator/browser/index.html +++ b/apps/cic-ussd/emulator/browser/index.html @@ -16,9 +16,16 @@ div#session {