From 6ca3fd55d7075a2471bbcdfc77315b4ceec0aaf5 Mon Sep 17 00:00:00 2001 From: nolash Date: Fri, 29 Oct 2021 08:45:42 +0200 Subject: [PATCH] Add gas cache oracle connection for erc20 --- apps/cic-eth/cic_eth/check/start.py | 18 +++++++++++++ apps/cic-eth/cic_eth/data/config/cic.ini | 2 +- apps/cic-eth/cic_eth/eth/account.py | 4 +-- apps/cic-eth/cic_eth/eth/erc20.py | 25 +++++++++++-------- apps/cic-eth/cic_eth/eth/gas.py | 1 + apps/cic-eth/cic_eth/eth/util.py | 9 ++++--- .../cic_eth/runnable/daemons/filters/token.py | 3 +-- apps/cic-eth/cic_eth/task.py | 20 ++++++++++++--- .../tests/filters/test_token_filter.py | 5 ++-- 9 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 apps/cic-eth/cic_eth/check/start.py diff --git a/apps/cic-eth/cic_eth/check/start.py b/apps/cic-eth/cic_eth/check/start.py new file mode 100644 index 00000000..720c80e0 --- /dev/null +++ b/apps/cic-eth/cic_eth/check/start.py @@ -0,0 +1,18 @@ +# external imports +from chainlib.chain import ChainSpec + +# local imports +from cic_eth.admin.ctrl import check_lock +from cic_eth.enum import LockEnum +from cic_eth.error import LockedError + + +def health(*args, **kwargs): + config = kwargs['config'] + chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) + + try: + check_lock(None, chain_spec.asdict(), LockEnum.START) + except LockedError as e: + return False + return True diff --git a/apps/cic-eth/cic_eth/data/config/cic.ini b/apps/cic-eth/cic_eth/data/config/cic.ini index 3de0748a..7d36d459 100644 --- a/apps/cic-eth/cic_eth/data/config/cic.ini +++ b/apps/cic-eth/cic_eth/data/config/cic.ini @@ -2,5 +2,5 @@ registry_address = trust_address = default_token_symbol = -health_modules = cic_eth.check.db,cic_eth.check.start,cic_eth.check.redis,cic_eth.check.signer,cic_eth.check.gas +health_modules = cic_eth.check.db,cic_eth.check.redis,cic_eth.check.signer,cic_eth.check.gas,cic_eth.check.start run_dir = /run diff --git a/apps/cic-eth/cic_eth/eth/account.py b/apps/cic-eth/cic_eth/eth/account.py index 9f4916c7..61ddfba5 100644 --- a/apps/cic-eth/cic_eth/eth/account.py +++ b/apps/cic-eth/cic_eth/eth/account.py @@ -136,7 +136,7 @@ def register(self, account_address, chain_spec_dict, writer_address=None): # Generate and sign transaction rpc_signer = RPCConnection.connect(chain_spec, 'signer') nonce_oracle = CustodialTaskNonceOracle(writer_address, self.request.root_id, session=session) #, default_nonce) - gas_oracle = self.create_gas_oracle(rpc, AccountRegistry.gas) + gas_oracle = self.create_gas_oracle(rpc, code_callback=AccountRegistry.gas) account_registry = AccountsIndex(chain_spec, 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) rpc_signer.disconnect() @@ -192,7 +192,7 @@ def gift(self, account_address, chain_spec_dict): # Generate and sign transaction rpc_signer = RPCConnection.connect(chain_spec, 'signer') nonce_oracle = CustodialTaskNonceOracle(account_address, self.request.root_id, session=session) #, default_nonce) - gas_oracle = self.create_gas_oracle(rpc, MinterFaucet.gas) + gas_oracle = self.create_gas_oracle(rpc, code_callback=MinterFaucet.gas) faucet = Faucet(chain_spec, signer=rpc_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) (tx_hash_hex, tx_signed_raw_hex) = faucet.give_to(faucet_address, account_address, account_address, tx_format=TxFormat.RLP_SIGNED) rpc_signer.disconnect() diff --git a/apps/cic-eth/cic_eth/eth/erc20.py b/apps/cic-eth/cic_eth/eth/erc20.py index 52658c4a..bf34acf6 100644 --- a/apps/cic-eth/cic_eth/eth/erc20.py +++ b/apps/cic-eth/cic_eth/eth/erc20.py @@ -34,10 +34,8 @@ from cic_eth.error import ( YouAreBrokeError, ) from cic_eth.queue.tx import register_tx -from cic_eth.eth.gas import ( - create_check_gas_task, - MaxGasOracle, - ) +from cic_eth.eth.gas import create_check_gas_task +from cic_eth.eth.util import CacheGasOracle from cic_eth.ext.address import translate_address from cic_eth.task import ( CriticalSQLAlchemyTask, @@ -157,8 +155,12 @@ def transfer_from(self, tokens, holder_address, receiver_address, value, chain_s rpc_signer = RPCConnection.connect(chain_spec, 'signer') session = self.create_session() + nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session) - gas_oracle = self.create_gas_oracle(rpc, t['address'], MaxGasOracle.gas) + enc = ABIContractEncoder() + enc.method('transferFrom') + method = enc.get() + gas_oracle = self.create_gas_oracle(rpc, t['address'], method=method, session=session, min_price=self.min_fee_price) c = ERC20(chain_spec, signer=rpc_signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) try: (tx_hash_hex, tx_signed_raw_hex) = c.transfer_from(t['address'], spender_address, holder_address, receiver_address, value, tx_format=TxFormat.RLP_SIGNED) @@ -228,13 +230,12 @@ def transfer(self, tokens, holder_address, receiver_address, value, chain_spec_d rpc_signer = RPCConnection.connect(chain_spec, 'signer') session = self.create_session() - nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session) enc = ABIContractEncoder() - enc.method('transferFrom') + enc.method('transfer') method = enc.get() - - gas_oracle = self.create_gas_oracle(rpc, MaxGasOracle.gas) + gas_oracle = self.create_gas_oracle(rpc, t['address'], method=method, session=session, min_price=self.min_fee_price) + nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session) c = ERC20(chain_spec, signer=rpc_signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) try: (tx_hash_hex, tx_signed_raw_hex) = c.transfer(t['address'], holder_address, receiver_address, value, tx_format=TxFormat.RLP_SIGNED) @@ -302,8 +303,12 @@ def approve(self, tokens, holder_address, spender_address, value, chain_spec_dic rpc_signer = RPCConnection.connect(chain_spec, 'signer') session = self.create_session() + nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session) - gas_oracle = self.create_gas_oracle(rpc, MaxGasOracle.gas) + enc = ABIContractEncoder() + enc.method('approve') + method = enc.get() + gas_oracle = self.create_gas_oracle(rpc, t['address'], method=method, session=session) c = ERC20(chain_spec, signer=rpc_signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) try: (tx_hash_hex, tx_signed_raw_hex) = c.approve(t['address'], holder_address, spender_address, value, tx_format=TxFormat.RLP_SIGNED) diff --git a/apps/cic-eth/cic_eth/eth/gas.py b/apps/cic-eth/cic_eth/eth/gas.py index 0bfb666f..95e7ab58 100644 --- a/apps/cic-eth/cic_eth/eth/gas.py +++ b/apps/cic-eth/cic_eth/eth/gas.py @@ -67,6 +67,7 @@ from cic_eth.encode import ( unpack_normal, ) from cic_eth.error import SeppukuError +from cic_eth.eth.util import MAXIMUM_FEE_UNITS celery_app = celery.current_app logg = logging.getLogger() diff --git a/apps/cic-eth/cic_eth/eth/util.py b/apps/cic-eth/cic_eth/eth/util.py index d1fe55cd..5f59b75e 100644 --- a/apps/cic-eth/cic_eth/eth/util.py +++ b/apps/cic-eth/cic_eth/eth/util.py @@ -1,15 +1,18 @@ # external imports from chainlib.eth.gas import RPCGasOracle +from hexathon import strip_0x # local imports from cic_eth.db.models.gas_cache import GasCache +from cic_eth.encode import tx_normalize +from cic_eth.db.models.base import SessionBase MAXIMUM_FEE_UNITS = 8000000 class MaxGasOracle(RPCGasOracle): - def get_fee_units(code=None): + def get_fee_units(self, code=None): return MAXIMUM_FEE_UNITS @@ -28,10 +31,10 @@ class CacheGasOracle(MaxGasOracle): address = tx_normalize.executable_address(address) session = SessionBase.bind_session(session) q = session.query(GasCache) - q = q.filter(GasCache.address=address) + q = q.filter(GasCache.address==address) if method != None: method = strip_0x(method) - q = q.filter(GasCache.method=method) + q = q.filter(GasCache.method==method) o = q.first() if o != None: self.value = int(o.value) diff --git a/apps/cic-eth/cic_eth/runnable/daemons/filters/token.py b/apps/cic-eth/cic_eth/runnable/daemons/filters/token.py index b447332b..ef3352c6 100644 --- a/apps/cic-eth/cic_eth/runnable/daemons/filters/token.py +++ b/apps/cic-eth/cic_eth/runnable/daemons/filters/token.py @@ -17,8 +17,7 @@ import celery # local imports from .base import SyncFilter -#logg = logging.getLogger(__name__) -logg = logging.getLogger() +logg = logging.getLogger(__name__) class TokenFilter(SyncFilter): diff --git a/apps/cic-eth/cic_eth/task.py b/apps/cic-eth/cic_eth/task.py index a1c93b1c..8a484ac2 100644 --- a/apps/cic-eth/cic_eth/task.py +++ b/apps/cic-eth/cic_eth/task.py @@ -10,6 +10,7 @@ from chainlib.chain import ChainSpec from chainlib.connection import RPCConnection from chainlib.eth.constant import ZERO_ADDRESS from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.gas import RPCGasOracle from cic_eth_registry import CICRegistry from cic_eth_registry.error import UnknownContractError @@ -30,7 +31,6 @@ class BaseTask(celery.Task): call_address = ZERO_ADDRESS trusted_addresses = [] min_fee_price = 1 - create_gas_oracle = CacheGasOracle default_token_address = None default_token_symbol = None default_token_name = None @@ -38,8 +38,22 @@ class BaseTask(celery.Task): run_dir = '/run' - def create_gas_oracle(self, conn, code_callback=None, id_generator=None): - return RPCGasOracle(conn, code_callback=code_callback, min_price=self.min_fee_price, id_generator=id_generator) + def create_gas_oracle(self, conn, address=None, *args, **kwargs): + if address == None: + return RPCGasOracle( + conn, + code_callback=kwargs.get('code_callback'), + min_price=self.min_fee_price, + id_generator=kwargs.get('id_generator'), + ) + + return CacheGasOracle( + conn, + address, + method=kwargs.get('method'), + min_price=self.min_fee_price, + id_generator=kwargs.get('id_generator'), + ) def create_session(self): diff --git a/apps/cic-eth/tests/filters/test_token_filter.py b/apps/cic-eth/tests/filters/test_token_filter.py index 04824dfa..df2bfdba 100644 --- a/apps/cic-eth/tests/filters/test_token_filter.py +++ b/apps/cic-eth/tests/filters/test_token_filter.py @@ -18,6 +18,7 @@ from chainlib.eth.block import ( block_latest, block_by_number, ) +from chainlib.eth.address import is_same_address from chainlib.eth.contract import ABIContractEncoder from hexathon import strip_0x from eth_token_index import TokenUniqueSymbolIndex @@ -39,7 +40,7 @@ def test_filter_gas( foo_token, token_registry, register_lookups, - celery_worker, + celery_session_worker, cic_registry, ): @@ -86,7 +87,7 @@ def test_filter_gas( q = q.filter(GasCache.tx_hash==strip_0x(tx_hash_hex)) o = q.first() - assert o.address == strip_0x(foo_token) + assert is_same_address(o.address, strip_0x(foo_token)) assert o.value > 0 enc = ABIContractEncoder()