diff --git a/apps/cic-cache/cic_cache/runnable/daemons/filters/__init__.py b/apps/cic-cache/cic_cache/runnable/daemons/filters/__init__.py index e8c9c530..af3eac98 100644 --- a/apps/cic-cache/cic_cache/runnable/daemons/filters/__init__.py +++ b/apps/cic-cache/cic_cache/runnable/daemons/filters/__init__.py @@ -1 +1,2 @@ from .erc20 import * +from .faucet import * diff --git a/apps/cic-cache/cic_cache/runnable/daemons/filters/faucet.py b/apps/cic-cache/cic_cache/runnable/daemons/filters/faucet.py new file mode 100644 index 00000000..f8fc67b7 --- /dev/null +++ b/apps/cic-cache/cic_cache/runnable/daemons/filters/faucet.py @@ -0,0 +1,73 @@ +# standard imports +import logging + +# external imports +from erc20_faucet import Faucet +from chainlib.eth.address import to_checksum_address +from chainlib.eth.constant import ZERO_ADDRESS +from chainlib.status import Status +from hexathon import strip_0x + +# local imports +import cic_cache.db as cic_cache_db +from .base import TagSyncFilter + +#logg = logging.getLogger().getChild(__name__) +logg = logging.getLogger() + + +class FaucetFilter(TagSyncFilter): + + def __init__(self, chain_spec, sender_address=ZERO_ADDRESS): + super(FaucetFilter, self).__init__('give_to', domain='faucet') + self.chain_spec = chain_spec + self.sender_address = sender_address + + + def filter(self, conn, block, tx, db_session=None): + try: + data = strip_0x(tx.payload) + except ValueError: + return False + logg.debug('data {}'.format(data)) + if Faucet.method_for(data[:8]) == None: + return False + + token_sender = tx.inputs[0] + token_recipient = data[64+8-40:] + logg.debug('token recipient {}'.format(token_recipient)) + + f = Faucet(self.chain_spec) + o = f.token(token_sender, sender_address=self.sender_address) + r = conn.do(o) + token = f.parse_token(r) + + f = Faucet(self.chain_spec) + o = f.token_amount(token_sender, sender_address=self.sender_address) + r = conn.do(o) + token_value = f.parse_token_amount(r) + + cic_cache_db.add_transaction( + db_session, + tx.hash, + block.number, + tx.index, + to_checksum_address(token_sender), + to_checksum_address(token_recipient), + token, + token, + token_value, + token_value, + tx.status == Status.SUCCESS, + block.timestamp, + ) + db_session.flush() + cic_cache_db.tag_transaction( + db_session, + tx.hash, + self.tag_name, + domain=self.tag_domain, + ) + db_session.commit() + + return True diff --git a/apps/cic-cache/cic_cache/runnable/daemons/tracker.py b/apps/cic-cache/cic_cache/runnable/daemons/tracker.py index ceac150b..279176bd 100644 --- a/apps/cic-cache/cic_cache/runnable/daemons/tracker.py +++ b/apps/cic-cache/cic_cache/runnable/daemons/tracker.py @@ -41,6 +41,7 @@ from cic_cache.db import ( ) from cic_cache.runnable.daemons.filters import ( ERC20TransferFilter, + FaucetFilter, ) script_dir = os.path.realpath(os.path.dirname(__file__)) @@ -71,6 +72,7 @@ def register_filter_tags(filters, session): session.commit() logg.info('added tag name "{}" domain "{}"'.format(tag[0], tag[1])) except sqlalchemy.exc.IntegrityError: + session.rollback() logg.debug('already have tag name "{}" domain "{}"'.format(tag[0], tag[1])) @@ -112,9 +114,11 @@ def main(): logg.info('using trusted address {}'.format(address)) erc20_transfer_filter = ERC20TransferFilter(chain_spec) + faucet_filter = FaucetFilter(chain_spec) filters = [ erc20_transfer_filter, + faucet_filter, ] session = SessionBase.create_session() diff --git a/apps/cic-cache/docker/Dockerfile b/apps/cic-cache/docker/Dockerfile index 83304027..c4c783dd 100644 --- a/apps/cic-cache/docker/Dockerfile +++ b/apps/cic-cache/docker/Dockerfile @@ -17,7 +17,7 @@ RUN apt-get update && \ # Copy shared requirements from top of mono-repo RUN echo "copying root req file ${root_requirement_file}" -RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2a76 +RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2b9 COPY cic-cache/requirements.txt ./ COPY cic-cache/setup.cfg \ diff --git a/apps/cic-cache/requirements.txt b/apps/cic-cache/requirements.txt index 9ea4ffd3..6095d479 100644 --- a/apps/cic-cache/requirements.txt +++ b/apps/cic-cache/requirements.txt @@ -1,4 +1,4 @@ -cic-base~=0.1.2b8 +cic-base~=0.1.2b9 alembic==1.4.2 confini~=0.3.6rc3 uwsgi==2.0.19.1 diff --git a/apps/cic-cache/tests/filters/test_erc20.py b/apps/cic-cache/tests/filters/test_erc20.py index d7582ed1..fb44e29a 100644 --- a/apps/cic-cache/tests/filters/test_erc20.py +++ b/apps/cic-cache/tests/filters/test_erc20.py @@ -22,7 +22,7 @@ from cic_cache.runnable.daemons.filters.erc20 import ERC20TransferFilter logg = logging.getLogger() -def test_cache( +def test_erc20_filter( eth_rpc, foo_token, init_database, diff --git a/apps/cic-cache/tests/filters/test_faucet.py b/apps/cic-cache/tests/filters/test_faucet.py new file mode 100644 index 00000000..c1f0dc10 --- /dev/null +++ b/apps/cic-cache/tests/filters/test_faucet.py @@ -0,0 +1,71 @@ +# standard imports +import logging + +# external imports +from chainlib.chain import ChainSpec +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.block import ( + block_by_hash, + Block, + ) +from chainlib.eth.tx import ( + receipt, + unpack, + transaction, + Tx, + ) +from hexathon import strip_0x +from erc20_faucet.faucet import SingleShotFaucet +from sqlalchemy import text + +# local imports +from cic_cache.db import add_tag +from cic_cache.runnable.daemons.filters.faucet import FaucetFilter + +logg = logging.getLogger() + + +def test_filter_faucet( + eth_rpc, + eth_signer, + foo_token, + faucet_noregistry, + init_database, + list_defaults, + contract_roles, + agent_roles, + tags, + ): + + chain_spec = ChainSpec('foo', 'bar', 42, 'baz') + + fltr = FaucetFilter(chain_spec, contract_roles['CONTRACT_DEPLOYER']) + + add_tag(init_database, fltr.tag_name, domain=fltr.tag_domain) + + nonce_oracle = RPCNonceOracle(agent_roles['ALICE'], eth_rpc) + c = SingleShotFaucet(chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.give_to(faucet_noregistry, agent_roles['ALICE'], agent_roles['ALICE']) + r = eth_rpc.do(o) + + tx_src = unpack(bytes.fromhex(strip_0x(o['params'][0])), chain_spec) + + o = receipt(r) + r = eth_rpc.do(o) + rcpt = Tx.src_normalize(r) + + assert r['status'] == 1 + + o = block_by_hash(r['block_hash']) + r = eth_rpc.do(o) + block_object = Block(r) + + tx = Tx(tx_src, block_object) + tx.apply_receipt(rcpt) + + r = fltr.filter(eth_rpc, block_object, tx, init_database) + assert r + + s = text("SELECT x.tx_hash FROM tag a INNER JOIN tag_tx_link l ON l.tag_id = a.id INNER JOIN tx x ON x.id = l.tx_id WHERE a.domain = :a AND a.value = :b") + r = init_database.execute(s, {'a': fltr.tag_domain, 'b': fltr.tag_name}).fetchone() + assert r[0] == tx.hash diff --git a/apps/cic-eth/cic_eth/eth/account.py b/apps/cic-eth/cic_eth/eth/account.py index de2e7f0b..0cf636b1 100644 --- a/apps/cic-eth/cic_eth/eth/account.py +++ b/apps/cic-eth/cic_eth/eth/account.py @@ -20,7 +20,8 @@ from chainlib.eth.tx import ( ) from chainlib.chain import ChainSpec from chainlib.error import JSONRPCException -from eth_accounts_index.registry import AccountRegistry # TODO, use interface module instead (needs gas limit method) +from eth_accounts_index.registry import AccountRegistry +from eth_accounts_index import AccountsIndex from sarafu_faucet import MinterFaucet from chainqueue.db.models.tx import TxCache @@ -127,12 +128,12 @@ def register(self, account_address, chain_spec_dict, writer_address=None): if writer_address == ZERO_ADDRESS: session.close() raise RoleMissingError('call address for resgistering {}'.format(account_address)) - account_registry_address = registry.by_name('AccountsIndex', sender_address=call_address) + account_registry_address = registry.by_name('AccountRegistry', sender_address=call_address) # 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, AccountsIndex.gas) + gas_oracle = self.create_gas_oracle(rpc, 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() diff --git a/apps/cic-eth/cic_eth/runnable/daemons/filters/callback.py b/apps/cic-eth/cic_eth/runnable/daemons/filters/callback.py index e47c4a65..4fb6b543 100644 --- a/apps/cic-eth/cic_eth/runnable/daemons/filters/callback.py +++ b/apps/cic-eth/cic_eth/runnable/daemons/filters/callback.py @@ -8,11 +8,11 @@ from chainlib.status import Status as TxStatus from chainlib.eth.address import to_checksum_address from chainlib.eth.error import RequestMismatchException from chainlib.eth.constant import ZERO_ADDRESS -from chainlib.eth.erc20 import ERC20 from hexathon import ( strip_0x, add_0x, ) +from eth_erc20 import ERC20 from erc20_faucet import Faucet # local imports diff --git a/apps/cic-eth/cic_eth/runnable/daemons/filters/register.py b/apps/cic-eth/cic_eth/runnable/daemons/filters/register.py index 841e7d75..dc1bd778 100644 --- a/apps/cic-eth/cic_eth/runnable/daemons/filters/register.py +++ b/apps/cic-eth/cic_eth/runnable/daemons/filters/register.py @@ -14,7 +14,7 @@ from .base import SyncFilter logg = logging.getLogger().getChild(__name__) -account_registry_add_log_hash = '0x5ed3bdd47b9af629827a8d129aa39c870b10c03f0153fe9ddb8e84b665061acd' +account_registry_add_log_hash = '0x9cc987676e7d63379f176ea50df0ae8d2d9d1141d1231d4ce15b5965f73c9430' class RegistrationFilter(SyncFilter): diff --git a/apps/cic-eth/cic_eth/runnable/daemons/filters/tx.py b/apps/cic-eth/cic_eth/runnable/daemons/filters/tx.py index 4e06e4d8..e2e4ed1f 100644 --- a/apps/cic-eth/cic_eth/runnable/daemons/filters/tx.py +++ b/apps/cic-eth/cic_eth/runnable/daemons/filters/tx.py @@ -30,7 +30,7 @@ class TxFilter(SyncFilter): if otx == None: logg.debug('tx {} not found locally, skipping'.format(tx_hash_hex)) return None - logg.info('tx filter match on {}'.format(otx.tx_hash)) + logg.debug('otx filter match on {}'.format(otx.tx_hash)) db_session.flush() SessionBase.release_session(db_session) s_final_state = celery.signature( diff --git a/apps/cic-eth/cic_eth/version.py b/apps/cic-eth/cic_eth/version.py index 1f75076e..1382b9cf 100644 --- a/apps/cic-eth/cic_eth/version.py +++ b/apps/cic-eth/cic_eth/version.py @@ -10,7 +10,7 @@ version = ( 0, 11, 0, - 'beta.12', + 'beta.13', ) version_object = semver.VersionInfo( diff --git a/apps/cic-eth/docker/Dockerfile b/apps/cic-eth/docker/Dockerfile index 163b3016..45902995 100644 --- a/apps/cic-eth/docker/Dockerfile +++ b/apps/cic-eth/docker/Dockerfile @@ -19,7 +19,7 @@ RUN apt-get update && \ apt install -y gcc gnupg libpq-dev wget make g++ gnupg bash procps git # Copy shared requirements from top of mono-repo -RUN echo "copying root req file ${root_requirement_file}" +RUN echo "copying root req file: ${root_requirement_file}" #COPY $root_requirement_file . #RUN pip install -r $root_requirement_file $pip_extra_index_url_flag RUN /usr/local/bin/python -m pip install --upgrade pip @@ -29,7 +29,7 @@ RUN /usr/local/bin/python -m pip install --upgrade pip # python merge_requirements.py | tee merged_requirements.txt #RUN cd cic-base && \ # pip install $pip_extra_index_url_flag -r ./merged_requirements.txt -RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2b8 +RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2b9 COPY cic-eth/scripts/ scripts/ COPY cic-eth/setup.cfg cic-eth/setup.py ./ diff --git a/apps/cic-eth/requirements.txt b/apps/cic-eth/requirements.txt index 7b57e8c3..fd48517d 100644 --- a/apps/cic-eth/requirements.txt +++ b/apps/cic-eth/requirements.txt @@ -1,4 +1,4 @@ -cic-base==0.1.2b8 +cic-base==0.1.2b9 celery==4.4.7 crypto-dev-signer~=0.4.14b3 confini~=0.3.6rc3 @@ -18,7 +18,7 @@ chainlib~=0.0.3a1 hexathon~=0.0.1a7 chainsyncer[sql]~=0.0.2a4 chainqueue~=0.0.2a2 -sarafu-faucet==0.0.3a1 +sarafu-faucet==0.0.3a3 +erc20-faucet==0.2.1a4 coincurve==15.0.0 -sarafu-faucet==0.0.3a2 -potaahto~=0.0.1a1 +potaahto~=0.0.1a2 diff --git a/apps/contract-migration/scripts/cic_eth/import_balance.py b/apps/contract-migration/scripts/cic_eth/import_balance.py index bad1d2bf..b3fb1112 100644 --- a/apps/contract-migration/scripts/cic_eth/import_balance.py +++ b/apps/contract-migration/scripts/cic_eth/import_balance.py @@ -27,7 +27,6 @@ from chainlib.eth.block import ( ) from chainlib.hash import keccak256_string_to_hex from chainlib.eth.address import to_checksum_address -from chainlib.eth.erc20 import ERC20 from chainlib.eth.gas import OverrideGasOracle from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import TxFactory @@ -37,6 +36,7 @@ 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 logging.basicConfig(level=logging.WARNING) diff --git a/apps/contract-migration/scripts/eth/import_balance.py b/apps/contract-migration/scripts/eth/import_balance.py index bad1d2bf..b3fb1112 100644 --- a/apps/contract-migration/scripts/eth/import_balance.py +++ b/apps/contract-migration/scripts/eth/import_balance.py @@ -27,7 +27,6 @@ from chainlib.eth.block import ( ) from chainlib.hash import keccak256_string_to_hex from chainlib.eth.address import to_checksum_address -from chainlib.eth.erc20 import ERC20 from chainlib.eth.gas import OverrideGasOracle from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import TxFactory @@ -37,6 +36,7 @@ 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 logging.basicConfig(level=logging.WARNING) diff --git a/apps/contract-migration/scripts/requirements.txt b/apps/contract-migration/scripts/requirements.txt index 92c179a7..f7487c3b 100644 --- a/apps/contract-migration/scripts/requirements.txt +++ b/apps/contract-migration/scripts/requirements.txt @@ -1,5 +1,5 @@ -cic-base[full_graph]==0.1.2b8 -sarafu-faucet==0.0.3a2 -cic-eth==0.11.0b12 -cic-types==0.1.0a10 +cic-base[full_graph]==0.1.2b9 +sarafu-faucet==0.0.3a3 +cic-eth==0.11.0b13 +cic-types==0.1.0a11 crypto-dev-signer==0.4.14b3 diff --git a/apps/contract-migration/scripts/verify.py b/apps/contract-migration/scripts/verify.py index 7ff0a341..5d7ffc2d 100644 --- a/apps/contract-migration/scripts/verify.py +++ b/apps/contract-migration/scripts/verify.py @@ -34,7 +34,6 @@ from chainlib.eth.block import ( ) from chainlib.hash import keccak256_string_to_hex from chainlib.eth.address import to_checksum_address -from chainlib.eth.erc20 import ERC20 from chainlib.eth.gas import ( OverrideGasOracle, balance, @@ -46,7 +45,8 @@ from cic_types.models.person import ( Person, generate_metadata_pointer, ) -from erc20_single_shot_faucet import SingleShotFaucet +from erc20_faucet import Faucet +from eth_erc20 import ERC20 logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() @@ -224,7 +224,7 @@ class Verifier: self.api = cic_eth_api self.data_dir = data_dir self.exit_on_error = exit_on_error - self.faucet_tx_factory = SingleShotFaucet(chain_spec, gas_oracle=gas_oracle) + self.faucet_tx_factory = Faucet(chain_spec, gas_oracle=gas_oracle) verifymethods = [] for k in dir(self):