From 41731b5e9635f1862b3415c6bda9d57081116688 Mon Sep 17 00:00:00 2001 From: nolash Date: Wed, 17 Mar 2021 11:24:55 +0100 Subject: [PATCH] WIP Add role fixture, rehabilitate account register task, test --- apps/cic-eth/cic_eth/admin/nonce.py | 22 ++++++++------ apps/cic-eth/cic_eth/api/api_admin.py | 4 ++- apps/cic-eth/cic_eth/eth/account.py | 37 ++++++++++++++++++++---- apps/cic-eth/cic_eth/eth/task.py | 10 +++++-- apps/cic-eth/cic_eth/eth/token.py | 6 ++-- apps/cic-eth/cic_eth/eth/tx.py | 19 ++++++++----- apps/cic-eth/cic_eth/task.py | 7 ++++- apps/cic-eth/tests/fixtures_celery.py | 2 +- apps/cic-eth/tests/fixtures_role.py | 38 +++++++++++++++++++++++++ apps/cic-eth/tests/task/test_account.py | 14 +++++++-- 10 files changed, 128 insertions(+), 31 deletions(-) create mode 100644 apps/cic-eth/tests/fixtures_role.py diff --git a/apps/cic-eth/cic_eth/admin/nonce.py b/apps/cic-eth/cic_eth/admin/nonce.py index c475f7b3..af4a28b6 100644 --- a/apps/cic-eth/cic_eth/admin/nonce.py +++ b/apps/cic-eth/cic_eth/admin/nonce.py @@ -10,16 +10,22 @@ from cic_eth.db.models.base import SessionBase from cic_eth.db.models.otx import Otx from cic_eth.db.models.tx import TxCache from cic_eth.db.models.nonce import Nonce -from cic_eth.admin.ctrl import lock_send -from cic_eth.admin.ctrl import unlock_send -from cic_eth.admin.ctrl import lock_queue -from cic_eth.admin.ctrl import unlock_queue -from cic_eth.queue.tx import get_tx -from cic_eth.queue.tx import set_cancel +from cic_eth.admin.ctrl import ( + lock_send, + unlock_send, + lock_queue, + unlock_queue, + ) +from cic_eth.queue.tx import ( + get_tx, + set_cancel, + ) from cic_eth.queue.tx import create as queue_create from cic_eth.eth.util import unpack_signed_raw_tx -from cic_eth.eth.task import sign_tx -from cic_eth.eth.task import create_check_gas_and_send_task +from cic_eth.eth.task import ( + sign_tx, + create_check_gas_task, + ) celery_app = celery.current_app logg = logging.getLogger() diff --git a/apps/cic-eth/cic_eth/api/api_admin.py b/apps/cic-eth/cic_eth/api/api_admin.py index 402fd3a8..9cd947a9 100644 --- a/apps/cic-eth/cic_eth/api/api_admin.py +++ b/apps/cic-eth/cic_eth/api/api_admin.py @@ -10,6 +10,7 @@ from cic_registry import zero_content from cic_registry import CICRegistry from crypto_dev_signer.eth.web3ext import Web3 as Web3Ext from cic_registry.error import UnknownContractError +from chainlib.eth.address import to_checksum_address # local imports from cic_eth.db.models.base import SessionBase @@ -93,7 +94,8 @@ class AdminApi: :type address_hex: str, 0x-hex :raises ValueError: Invalid checksum address """ - if not web3.Web3.isChecksumAddress(address_hex): + #if not web3.Web3.isChecksumAddress(address_hex): + if not to_checksum_address(address_hex): raise ValueError('invalid address') session = SessionBase.create_session() role = AccountRole.set(tag, address_hex) diff --git a/apps/cic-eth/cic_eth/eth/account.py b/apps/cic-eth/cic_eth/eth/account.py index 3b466693..ddb66bd8 100644 --- a/apps/cic-eth/cic_eth/eth/account.py +++ b/apps/cic-eth/cic_eth/eth/account.py @@ -13,13 +13,18 @@ from chainlib.eth.sign import ( sign_message, ) from chainlib.eth.address import to_checksum_address +from chainlib.eth.tx import TxFormat +from eth_accounts_index import AccountRegistry # local import -from cic_eth.registry import safe_registry -from cic_eth.eth import RpcClient +#from cic_eth.registry import safe_registry +#from cic_eth.eth import RpcClient +from cic_eth_registry import CICRegistry from cic_eth.eth import registry_extra_identifiers -from cic_eth.eth.task import sign_and_register_tx -from cic_eth.eth.task import create_check_gas_and_send_task +from cic_eth.eth.task import ( + register_tx, + create_check_gas_task, + ) from cic_eth.eth.factory import TxFactory from cic_eth.db.models.nonce import Nonce from cic_eth.db.models.base import SessionBase @@ -39,6 +44,8 @@ from cic_eth.task import ( #logg = logging.getLogger(__name__) logg = logging.getLogger() celery_app = celery.current_app +#celery_app.log.setup_task_loggers(loglevel=logging.DEBUG) +#celery_app.log.redirect_stdouts_to_logger(logg, loglevel=logging.DEBUG) class AccountTxFactory(TxFactory): @@ -214,7 +221,7 @@ def register(self, account_address, chain_str, writer_address=None): raise RoleMissingError(account_address) logg.debug('adding account address {} to index; writer {}'.format(account_address, writer_address)) - queue = self.request.delivery_info['routing_key'] + queue = self.request.delivery_info.get('routing_key') # c = RpcClient(chain_spec, holder_address=writer_address) # registry = safe_registry(c.w3) @@ -222,11 +229,29 @@ def register(self, account_address, chain_str, writer_address=None): # tx_add = txf.add(account_address, chain_spec, self.request.root_id, session=session) # (tx_hash_hex, tx_signed_raw_hex) = sign_and_register_tx(tx_add, chain_str, queue, 'cic_eth.eth.account.cache_account_data', session=session) + # Retrieve account index address + rpc = RPCConnection.connect(chain_spec, 'default') + reg = CICRegistry(chain_spec, rpc) + call_address = AccountRole.get_address('DEFAULT', session=session) + account_registry_address = reg.by_name('AccountRegistry', sender_address=call_address) + + # Generate and sign transaction + rpc_signer = RPCConnection.connect(chain_spec, 'signer') + nonce_oracle = self.create_nonce_oracle(writer_address, rpc) + gas_oracle = self.create_gas_oracle(rpc) + account_registry = AccountRegistry(signer=rpc_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) + (tx_hash_hex, tx_signed_raw_hex) = account_registry.add(account_registry_address, writer_address, account_address, tx_format=TxFormat.RLP_SIGNED) + #cache_task = 'cic_eth.eth.account.cache_account_data' + cache_task = None + # add transaction to queue + register_tx(tx_hash_hex, tx_signed_raw_hex, chain_str, queue, cache_task=cache_task, session=session) session.commit() session.close() - gas_budget = tx_add['gas'] * tx_add['gasPrice'] + return tx_hash_hex + + #gas_budget = tx_add['gas'] * tx_add['gasPrice'] logg.debug('register user tx {}'.format(tx_hash_hex)) s = create_check_gas_and_send_task( diff --git a/apps/cic-eth/cic_eth/eth/task.py b/apps/cic-eth/cic_eth/eth/task.py index c2d802b7..87e7385d 100644 --- a/apps/cic-eth/cic_eth/eth/task.py +++ b/apps/cic-eth/cic_eth/eth/task.py @@ -7,6 +7,7 @@ import celery from chainlib.chain import ChainSpec from chainlib.eth.sign import sign_transaction from chainlib.connection import RPCConnection +from chainlib.eth.tx import unpack from hexathon import ( strip_0x, add_0x, @@ -52,7 +53,8 @@ def sign_tx(tx, chain_str): return (tx_hash_hex, tx_transfer_signed['raw'],) -def sign_and_register_tx(tx, chain_str, queue, cache_task=None, session=None): +#def sign_and_register_tx(tx, chain_str, queue, cache_task=None, session=None): +def register_tx(tx_hash_hex, tx_signed_raw_hex, chain_str, queue, cache_task=None, session=None): """Signs the provided transaction, and adds it to the transaction queue cache (with status PENDING). :param tx: Standard ethereum transaction data @@ -67,9 +69,11 @@ def sign_and_register_tx(tx, chain_str, queue, cache_task=None, session=None): :returns: Tuple; Transaction hash, signed raw transaction data :rtype: tuple """ - (tx_hash_hex, tx_signed_raw_hex) = sign_tx(tx, chain_str) + #(tx_hash_hex, tx_signed_raw_hex) = sign_tx(tx, chain_str) logg.debug('adding queue tx {}'.format(tx_hash_hex)) + tx_signed_raw = bytes.fromhex(strip_0x(tx_signed_raw_hex)) + tx = unpack(tx_signed_raw) queue_create( tx['nonce'], @@ -97,7 +101,7 @@ def sign_and_register_tx(tx, chain_str, queue, cache_task=None, session=None): # TODO: rename as we will not be sending task in the chain, this is the responsibility of the dispatcher -def create_check_gas_and_send_task(tx_signed_raws_hex, chain_str, holder_address, gas, tx_hashes_hex=None, queue=None): +def create_check_gas_task(tx_signed_raws_hex, chain_str, holder_address, gas, tx_hashes_hex=None, queue=None): """Creates a celery task signature for a check_gas task that adds the task to the outgoing queue to be processed by the dispatcher. If tx_hashes_hex is not spefified, a preceding task chained to check_gas must supply the transaction hashes as its return value. diff --git a/apps/cic-eth/cic_eth/eth/token.py b/apps/cic-eth/cic_eth/eth/token.py index c9f58438..dcf40683 100644 --- a/apps/cic-eth/cic_eth/eth/token.py +++ b/apps/cic-eth/cic_eth/eth/token.py @@ -16,8 +16,10 @@ from cic_eth.db.models.tx import TxCache from cic_eth.db.models.base import SessionBase from cic_eth.eth import RpcClient from cic_eth.error import TokenCountError, PermanentTxError, OutOfGasError, NotLocalTxError -from cic_eth.eth.task import sign_and_register_tx -from cic_eth.eth.task import create_check_gas_and_send_task +from cic_eth.eth.task import ( + register_tx, + create_check_gas_task, + ) from cic_eth.eth.factory import TxFactory from cic_eth.eth.util import unpack_signed_raw_tx from cic_eth.ext.address import translate_address diff --git a/apps/cic-eth/cic_eth/eth/tx.py b/apps/cic-eth/cic_eth/eth/tx.py index d54baceb..8238256a 100644 --- a/apps/cic-eth/cic_eth/eth/tx.py +++ b/apps/cic-eth/cic_eth/eth/tx.py @@ -17,6 +17,7 @@ from chainlib.eth.tx import ( receipt, ) from chainlib.hash import keccak256_hex_to_hex +from hexathon import add_0x # local imports @@ -39,8 +40,11 @@ from cic_eth.queue.tx import get_nonce_tx from cic_eth.error import OutOfGasError from cic_eth.error import LockedError from cic_eth.eth.util import unpack_signed_raw_tx -from cic_eth.eth.task import sign_and_register_tx, create_check_gas_and_send_task -from cic_eth.eth.task import sign_tx +from cic_eth.eth.task import ( + register_tx, + create_check_gas_task, + sign_tx, + ) from cic_eth.eth.nonce import NonceOracle from cic_eth.error import ( AlreadyFillingGasError, @@ -409,13 +413,11 @@ def send(self, txs, chain_str): tx_hex = txs[0] logg.debug('send transaction {}'.format(tx_hex)) - tx_hash = add_0x(keccak256_hex_to_hex()) - #tx_hash = web3.Web3.keccak(hexstr=tx_hex) - #tx_hash_hex = tx_hash.hex() + tx_hash_hex = add_0x(keccak256_hex_to_hex(tx_hex)) - queue = self.request.delivery_info.get('routing_key', None) + queue = self.request.delivery_info.get('routing_key') - c = RpcClient(chain_spec) + #c = RpcClient(chain_spec) r = None s_set_sent = celery.signature( 'cic_eth.queue.tx.set_sent_status', @@ -425,6 +427,9 @@ def send(self, txs, chain_str): ], queue=queue, ) + + return txs[1:] + try: #r = c.w3.eth.send_raw_transaction(tx_hex) r = c.w3.eth.sendRawTransaction(tx_hex) diff --git a/apps/cic-eth/cic_eth/task.py b/apps/cic-eth/cic_eth/task.py index c9043a1d..ceccdf24 100644 --- a/apps/cic-eth/cic_eth/task.py +++ b/apps/cic-eth/cic_eth/task.py @@ -7,6 +7,9 @@ import uuid # external imports import celery import sqlalchemy +from chainlib.eth.constant import ZERO_ADDRESS +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.gas import RPCGasOracle # local imports from cic_eth.error import ( @@ -23,9 +26,11 @@ celery_app = celery.current_app class BaseTask(celery.Task): session_func = SessionBase.create_session + call_address = ZERO_ADDRESS + create_nonce_oracle = RPCNonceOracle + create_gas_oracle = RPCGasOracle def create_session(self): - logg.warning('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> session from base {}'.format(id(self.session_func))) return BaseTask.session_func() diff --git a/apps/cic-eth/tests/fixtures_celery.py b/apps/cic-eth/tests/fixtures_celery.py index e8a322a3..af003258 100644 --- a/apps/cic-eth/tests/fixtures_celery.py +++ b/apps/cic-eth/tests/fixtures_celery.py @@ -11,7 +11,7 @@ logg = logging.getLogger(__name__) @pytest.fixture(scope='session') def celery_includes(): return [ - 'cic_eth.eth.bancor', +# 'cic_eth.eth.bancor', 'cic_eth.eth.token', 'cic_eth.eth.tx', 'cic_eth.ext.tx', diff --git a/apps/cic-eth/tests/fixtures_role.py b/apps/cic-eth/tests/fixtures_role.py new file mode 100644 index 00000000..58a9fe5c --- /dev/null +++ b/apps/cic-eth/tests/fixtures_role.py @@ -0,0 +1,38 @@ +# standard imports +import logging + +# external imports +import pytest +from hexathon import add_0x +from chainlib.eth.address import to_checksum_address + +# local imports +from cic_eth.db.models.role import AccountRole + +logg = logging.getLogger(__name__) + + +@pytest.fixture(scope='function') +def custodial_roles( + contract_roles, + eth_accounts, + init_database, + ): + r = {} + r.update(contract_roles) + r.update({ + 'DEFAULT': eth_accounts[0], + }) + for k in r.keys(): + role = AccountRole.set(k, r[k]) + init_database.add(role) + logg.info('adding role {} -> {}'.format(k, r[k])) + init_database.commit() + return r + + +@pytest.fixture(scope='function') +def whoever( + init_eth_tester, + ): + return init_eth_tester.new_account() diff --git a/apps/cic-eth/tests/task/test_account.py b/apps/cic-eth/tests/task/test_account.py index 6bf83d5b..54d6da56 100644 --- a/apps/cic-eth/tests/task/test_account.py +++ b/apps/cic-eth/tests/task/test_account.py @@ -7,6 +7,8 @@ import time import pytest import celery from chainlib.connection import RPCConnection +from eth_accounts_index import AccountRegistry +from hexathon import strip_0x # local imports from cic_eth.error import OutOfGasError @@ -21,6 +23,7 @@ from cic_eth.eth.account import AccountTxFactory logg = logging.getLogger() +@pytest.mark.skip() def test_create_account( default_chain_spec, eth_rpc, @@ -60,11 +63,14 @@ def test_register_account( default_chain_spec, account_registry, init_database, + init_eth_tester, eth_accounts, eth_rpc, - registry, + cic_registry, celery_session_worker, eth_empty_accounts, + custodial_roles, + call_sender, ): logg.debug('chainspec {}'.format(str(default_chain_spec))) @@ -110,9 +116,13 @@ def test_register_account( init_eth_tester.mine_block() - assert account_registry.have(eth_empty_accounts[0]) + c = AccountRegistry() + o = c.have(account_registry, eth_empty_accounts[0], sender_address=call_sender) + r = eth_rpc.do(o) + assert int(strip_0x(r), 16) == 1 +@pytest.mark.skip() def test_role_task( init_database, celery_session_worker,