From e09323f99b05009850ff655bacd058a58b98b923 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Oct 2021 14:03:15 +0200 Subject: [PATCH 01/21] update db --- ethtx/decoders/abi/abc.py | 2 +- ethtx/decoders/abi/decoder.py | 1 - ethtx/decoders/abi/helpers/utils.py | 2 +- ethtx/decoders/semantic/abc.py | 2 +- ethtx/ethtx.py | 4 +- ethtx/providers/semantic_providers/base.py | 38 +++++++++++++++ ethtx/providers/semantic_providers/const.py | 18 ++++++++ .../{semantics_database.py => database.py} | 46 ++++--------------- ...{semantics_repository.py => repository.py} | 2 +- tests/conftest.py | 2 +- tests/semantics_database_test.py | 2 +- 11 files changed, 73 insertions(+), 46 deletions(-) create mode 100644 ethtx/providers/semantic_providers/base.py create mode 100644 ethtx/providers/semantic_providers/const.py rename ethtx/providers/semantic_providers/{semantics_database.py => database.py} (75%) rename ethtx/providers/semantic_providers/{semantics_repository.py => repository.py} (99%) diff --git a/ethtx/decoders/abi/abc.py b/ethtx/decoders/abi/abc.py index 7011f8ac..ea76a8f7 100644 --- a/ethtx/decoders/abi/abc.py +++ b/ethtx/decoders/abi/abc.py @@ -22,7 +22,7 @@ TransactionMetadata, BlockMetadata, ) -from ethtx.providers.semantic_providers.semantics_repository import SemanticsRepository +from ethtx.providers.semantic_providers.repository import SemanticsRepository class ABIBasic: diff --git a/ethtx/decoders/abi/decoder.py b/ethtx/decoders/abi/decoder.py index 4dd9c9b9..ff1015ad 100644 --- a/ethtx/decoders/abi/decoder.py +++ b/ethtx/decoders/abi/decoder.py @@ -206,7 +206,6 @@ def _decode_transaction( ) raise e - full_decoded_transaction.status = True return full_decoded_transaction diff --git a/ethtx/decoders/abi/helpers/utils.py b/ethtx/decoders/abi/helpers/utils.py index 288fb5ee..6c6b83c4 100644 --- a/ethtx/decoders/abi/helpers/utils.py +++ b/ethtx/decoders/abi/helpers/utils.py @@ -19,7 +19,7 @@ SignatureArg, ) from ethtx.providers import FourByteProvider -from ethtx.providers.semantic_providers.semantics_repository import SemanticsRepository +from ethtx.providers.semantic_providers.repository import SemanticsRepository from ethtx.providers.signature_provider import SignatureProvider log = logging.getLogger(__name__) diff --git a/ethtx/decoders/semantic/abc.py b/ethtx/decoders/semantic/abc.py index e6ad136c..48d5b5a0 100644 --- a/ethtx/decoders/semantic/abc.py +++ b/ethtx/decoders/semantic/abc.py @@ -22,7 +22,7 @@ Proxy, ) from ethtx.models.objects_model import BlockMetadata, TransactionMetadata -from ethtx.providers.semantic_providers.semantics_repository import SemanticsRepository +from ethtx.providers.semantic_providers.repository import SemanticsRepository class SemanticSubmoduleAbc(ABC): diff --git a/ethtx/ethtx.py b/ethtx/ethtx.py index e17477e9..2919d3c8 100644 --- a/ethtx/ethtx.py +++ b/ethtx/ethtx.py @@ -21,11 +21,11 @@ from .models.decoded_model import Proxy, DecodedTransaction from .models.objects_model import Call from .providers import EtherscanProvider, Web3Provider -from .providers.semantic_providers.semantics_database import ( +from .providers.semantic_providers.database import ( MongoSemanticsDatabase, ISemanticsDatabase, ) -from .providers.semantic_providers.semantics_repository import SemanticsRepository +from .providers.semantic_providers.repository import SemanticsRepository from .utils.validators import assert_tx_hash diff --git a/ethtx/providers/semantic_providers/base.py b/ethtx/providers/semantic_providers/base.py new file mode 100644 index 00000000..a92a763f --- /dev/null +++ b/ethtx/providers/semantic_providers/base.py @@ -0,0 +1,38 @@ +# Copyright 2021 DAI Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABC +from typing import Dict, Optional, Any, List + + +class ISemanticsDatabase(ABC): + """Semantics Database. Represents raw interface required to be + implemented by a database that provides persistent + data about semantics""" + + def get_address_semantics(self, chain_id: str, address: str) -> Optional[Dict]: + ... + + def get_contract_semantics(self, code_hash: str) -> Optional[Dict]: + ... + + def get_signature_semantics(self, signature_hash: str) -> Optional[List[Dict]]: + ... + + def insert_contract(self, contract: dict, update_if_exist: bool = False) -> Any: + ... + + def insert_address(self, address: dict, update_if_exist: bool = False) -> Any: + ... + + def insert_signature(self, signature, update_if_exist: bool = False) -> Any: + ... diff --git a/ethtx/providers/semantic_providers/const.py b/ethtx/providers/semantic_providers/const.py new file mode 100644 index 00000000..915d7276 --- /dev/null +++ b/ethtx/providers/semantic_providers/const.py @@ -0,0 +1,18 @@ +# Copyright 2021 DAI Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from enum import Enum + + +class MongoCollections(str, Enum): + ADDRESSES = "addresses" + CONTRACTS = "contracts" + SIGNATURES = "signatures" diff --git a/ethtx/providers/semantic_providers/semantics_database.py b/ethtx/providers/semantic_providers/database.py similarity index 75% rename from ethtx/providers/semantic_providers/semantics_database.py rename to ethtx/providers/semantic_providers/database.py index c3084bc1..1a4ac0dd 100644 --- a/ethtx/providers/semantic_providers/semantics_database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -10,53 +10,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -from abc import ABC -from typing import Dict, Optional, Any, List +from typing import Dict, Optional import bson from pymongo.cursor import Cursor from pymongo.database import Database as MongoDatabase - -class ISemanticsDatabase(ABC): - """Semantics Database. Represents raw interface required to be - implemented by a database that provides persistent - data about semantics""" - - def get_address_semantics(self, chain_id: str, address: str) -> Optional[Dict]: - ... - - def get_contract_semantics(self, code_hash: str) -> Optional[Dict]: - ... - - def get_signature_semantics(self, signature_hash: str) -> Optional[List[Dict]]: - ... - - def insert_contract(self, contract: dict, update_if_exist: bool = False) -> Any: - ... - - def insert_address(self, address: dict, update_if_exist: bool = False) -> Any: - ... - - def insert_signature(self, signature, update_if_exist: bool = False) -> Any: - ... - - -class MongoCollections: - ADDRESSES = "addresses" - CONTRACTS = "contracts" - SIGNATURES = "signatures" +from .base import ISemanticsDatabase +from .const import MongoCollections class MongoSemanticsDatabase(ISemanticsDatabase): - def get_collection_count(self): - return len(self._db.list_collection_names()) - def __init__(self, db: MongoDatabase): self._db = db - self._addresses = self._db["addresses"] - self._contracts = self._db["contracts"] - self._signatures = self._db["signatures"] + self._addresses = self._db[MongoCollections.ADDRESSES] + self._contracts = self._db[MongoCollections.CONTRACTS] + self._signatures = self._db[MongoCollections.SIGNATURES] + + def get_collection_count(self): + return len(self._db.list_collection_names()) def get_address_semantics(self, chain_id, address) -> Optional[Dict]: _id = f"{chain_id}-{address}" diff --git a/ethtx/providers/semantic_providers/semantics_repository.py b/ethtx/providers/semantic_providers/repository.py similarity index 99% rename from ethtx/providers/semantic_providers/semantics_repository.py rename to ethtx/providers/semantic_providers/repository.py index 4b1c3f7b..4f84537a 100644 --- a/ethtx/providers/semantic_providers/semantics_repository.py +++ b/ethtx/providers/semantic_providers/repository.py @@ -26,7 +26,7 @@ SignatureArg, ) from ethtx.providers import EtherscanProvider, Web3Provider -from ethtx.providers.semantic_providers.semantics_database import ISemanticsDatabase +from ethtx.providers.semantic_providers.database import ISemanticsDatabase from ethtx.semantics.protocols_router import amend_contract_semantics from ethtx.semantics.solidity.precompiles import precompiles from ethtx.semantics.standards.erc20 import ERC20_FUNCTIONS, ERC20_EVENTS diff --git a/tests/conftest.py b/tests/conftest.py index 827d2aa6..03801153 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ from mongoengine import connect from pymongo import MongoClient -from ethtx.providers.semantic_providers.semantics_database import MongoSemanticsDatabase +from ethtx.providers.semantic_providers.database import MongoSemanticsDatabase @pytest.fixture diff --git a/tests/semantics_database_test.py b/tests/semantics_database_test.py index d837e529..404492c5 100644 --- a/tests/semantics_database_test.py +++ b/tests/semantics_database_test.py @@ -1,6 +1,6 @@ from mongomock import Database -from ethtx.providers.semantic_providers.semantics_database import MongoCollections +from ethtx.providers.semantic_providers.const import MongoCollections class TestMongoSemanticsDatabase: From e433ba8a088a69b270dd2703973f370e2a2f3421 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Oct 2021 14:51:28 +0200 Subject: [PATCH 02/21] fix unknown args for empty functions --- ethtx/decoders/abi/helpers/utils.py | 2 +- .../semantic_providers/repository.py | 45 +++++++++---------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/ethtx/decoders/abi/helpers/utils.py b/ethtx/decoders/abi/helpers/utils.py index 6c6b83c4..1ea95bf5 100644 --- a/ethtx/decoders/abi/helpers/utils.py +++ b/ethtx/decoders/abi/helpers/utils.py @@ -32,7 +32,7 @@ def decode_function_abi_with_external_source( ) -> Iterator[FunctionSemantics]: function = repository.get_most_used_signature(signature_hash=signature) if function: - log.info( + log.debug( "Successfully guessed function from SemanticsRepository - %s.", function.json(), ) diff --git a/ethtx/providers/semantic_providers/repository.py b/ethtx/providers/semantic_providers/repository.py index 4f84537a..718d61a4 100644 --- a/ethtx/providers/semantic_providers/repository.py +++ b/ethtx/providers/semantic_providers/repository.py @@ -472,30 +472,27 @@ def insert_contract_signatures(self, contract_semantics: ContractSemantics): if v.signature.startswith("0x"): if v.inputs: if v.inputs[0].parameter_type == "tuple": - new_signature = Signature( - signature_hash=v.signature, - name=v.name, - tuple=True, - args=[ - SignatureArg( - name=param.parameter_name, type=param.parameter_type - ) - for param in v.inputs[0].components - ], - ) + args = [ + SignatureArg( + name=param.parameter_name, type=param.parameter_type + ) + for param in v.inputs[0].components + ] else: - new_signature = Signature( - signature_hash=v.signature, - name=v.name, - args=[ - SignatureArg( - name=param.parameter_name, type=param.parameter_type - ) - for param in v.inputs - ], - ) + args = [ + SignatureArg( + name=param.parameter_name, type=param.parameter_type + ) + for param in v.inputs + ] + else: + args = [] + + new_signature = Signature( + signature_hash=v.signature, name=v.name, args=args + ) - self.update_or_insert_signature(new_signature) + self.update_or_insert_signature(new_signature) def get_most_used_signature(self, signature_hash: str) -> Optional[Signature]: signatures = list( @@ -526,7 +523,9 @@ def update_or_insert_signature(self, signature: Signature): and signature.signature_hash == sig["signature_hash"] and len(signature.args) == len(sig["args"]) ): - if any(arg for arg in list(sig["args"][0].values()) if "arg" in arg): + if signature.args and any( + arg for arg in list(sig["args"][0].values()) if "arg" in arg + ): for index, argument in enumerate(sig["args"]): argument["name"] = signature.args[index].name argument["type"] = signature.args[index].type From 01574960e3f4b1ac1731a7154bba4db1500d3e30 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Oct 2021 14:54:29 +0200 Subject: [PATCH 03/21] remove useless var --- ethtx/providers/semantic_providers/repository.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ethtx/providers/semantic_providers/repository.py b/ethtx/providers/semantic_providers/repository.py index 718d61a4..46ae8a84 100644 --- a/ethtx/providers/semantic_providers/repository.py +++ b/ethtx/providers/semantic_providers/repository.py @@ -460,9 +460,7 @@ def update_semantics(self, semantics) -> None: contract_id = self.database.insert_contract( contract=contract_semantics, update_if_exist=True ) - _ = self.database.insert_address( - address=address_semantics, update_if_exist=True - ) + self.database.insert_address(address=address_semantics, update_if_exist=True) if contract_id: self.insert_contract_signatures(semantics.contract) From 79c3e82981ece158b212873cd04f59b7f591dd6f Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Oct 2021 15:22:11 +0200 Subject: [PATCH 04/21] add init db method --- .../providers/semantic_providers/database.py | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/ethtx/providers/semantic_providers/database.py b/ethtx/providers/semantic_providers/database.py index 1a4ac0dd..58bdb446 100644 --- a/ethtx/providers/semantic_providers/database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -21,11 +21,16 @@ class MongoSemanticsDatabase(ISemanticsDatabase): + _db: MongoDatabase + def __init__(self, db: MongoDatabase): self._db = db - self._addresses = self._db[MongoCollections.ADDRESSES] - self._contracts = self._db[MongoCollections.CONTRACTS] - self._signatures = self._db[MongoCollections.SIGNATURES] + + self._addresses = None + self._contracts = None + self._signatures = None + + self._init_db() def get_collection_count(self): return len(self._db.list_collection_names()) @@ -93,3 +98,18 @@ def insert_address(self, address, update_if_exist=False) -> Optional[bson.Object inserted_address = self._addresses.insert_one(address_with_id) return inserted_address.inserted_id + + def _init_db(self) -> None: + if MongoCollections.ADDRESSES not in self._db.list_collection_names(): + self._addresses = self._db[MongoCollections.ADDRESSES] + + if MongoCollections.CONTRACTS not in self._db.list_collection_names(): + self._contracts = self._db[MongoCollections.CONTRACTS] + + if MongoCollections.SIGNATURES not in self._db.list_collection_names(): + self._signatures = self._db[MongoCollections.SIGNATURES] + self._signatures.create_index( + [("signature_hash", "TEXT"), ("name", "TEXT")], + background=True, + unique=False, + ) From 56d454a47367e14f13379b55682ae2e504f6a108 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Oct 2021 15:35:39 +0200 Subject: [PATCH 05/21] rename --- ethtx/providers/semantic_providers/database.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethtx/providers/semantic_providers/database.py b/ethtx/providers/semantic_providers/database.py index 58bdb446..33731e47 100644 --- a/ethtx/providers/semantic_providers/database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -30,7 +30,7 @@ def __init__(self, db: MongoDatabase): self._contracts = None self._signatures = None - self._init_db() + self._init_collections() def get_collection_count(self): return len(self._db.list_collection_names()) @@ -99,7 +99,7 @@ def insert_address(self, address, update_if_exist=False) -> Optional[bson.Object inserted_address = self._addresses.insert_one(address_with_id) return inserted_address.inserted_id - def _init_db(self) -> None: + def _init_collections(self) -> None: if MongoCollections.ADDRESSES not in self._db.list_collection_names(): self._addresses = self._db[MongoCollections.ADDRESSES] From 420f57d5b88ffa34349ebc5199f229c37fc18812 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Oct 2021 16:28:17 +0200 Subject: [PATCH 06/21] fix log bug --- ethtx/decoders/decoder_service.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ethtx/decoders/decoder_service.py b/ethtx/decoders/decoder_service.py index 085d0133..67d34211 100644 --- a/ethtx/decoders/decoder_service.py +++ b/ethtx/decoders/decoder_service.py @@ -153,7 +153,9 @@ def decode_transaction(self, chain_id: str, tx_hash: str) -> DecodedTransaction: used_semantics = self.semantic_decoder.repository.end_record() log.info( - "Semantics used in decoding %s: %s", tx_hash, ", ".join(used_semantics) + "Semantics used in decoding %s: %s", + tx_hash, + ", ".join(used_semantics) if isinstance(used_semantics, list) else "", ) return semantically_decoded_tx From 73351f4268b5de6890881d94df8cb14195bae346 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Fri, 8 Oct 2021 16:28:24 +0200 Subject: [PATCH 07/21] add types --- .../semantic_providers/repository.py | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/ethtx/providers/semantic_providers/repository.py b/ethtx/providers/semantic_providers/repository.py index 46ae8a84..1e93283c 100644 --- a/ethtx/providers/semantic_providers/repository.py +++ b/ethtx/providers/semantic_providers/repository.py @@ -11,7 +11,7 @@ # limitations under the License. from functools import lru_cache -from typing import Optional, List +from typing import Optional, List, Dict, Tuple, Union, Any from ethtx.decoders.decoders.semantics import decode_events_and_functions from ethtx.models.semantics_model import ( @@ -45,7 +45,7 @@ def __init__( self._web3provider = web3provider self._records: Optional[List] = None - def record(self): + def record(self) -> None: """Records is an array used to hold semantics used in tx decing process. This recording is used just for logging""" self._records = [] @@ -55,7 +55,9 @@ def end_record(self) -> List: self._records = None return tmp_records - def _read_stored_semantics(self, address: str, chain_id: str): + def _read_stored_semantics( + self, address: str, chain_id: str + ) -> Optional[AddressSemantics]: def decode_parameter(_parameter): components_semantics = [] if "component" in _parameter: @@ -269,7 +271,9 @@ def get_semantics(self, chain_id: str, address: str) -> Optional[AddressSemantic return address_semantics - def _decode_standard_semantics(self, address, name, events, functions): + def _decode_standard_semantics( + self, address, name, events, functions + ) -> Tuple[Optional[str], Optional[ERC20Semantics]]: standard = None standard_semantics = None @@ -297,7 +301,7 @@ def _decode_standard_semantics(self, address, name, events, functions): return standard, standard_semantics @lru_cache(maxsize=128) - def get_event_abi(self, chain_id, address, signature): + def get_event_abi(self, chain_id, address, signature) -> Optional[EventSemantics]: if not address: return None @@ -310,7 +314,7 @@ def get_event_abi(self, chain_id, address, signature): return event_semantics @lru_cache(maxsize=128) - def get_transformations(self, chain_id, address, signature): + def get_transformations(self, chain_id, address, signature) -> Optional[str]: if not address: return None @@ -324,7 +328,7 @@ def get_transformations(self, chain_id, address, signature): return transformations @lru_cache(maxsize=128) - def get_anonymous_event_abi(self, chain_id, address): + def get_anonymous_event_abi(self, chain_id, address) -> Optional[EventSemantics]: if not address: return None @@ -344,7 +348,9 @@ def get_anonymous_event_abi(self, chain_id, address): return event_semantics @lru_cache(maxsize=128) - def get_function_abi(self, chain_id, address, signature): + def get_function_abi( + self, chain_id, address, signature + ) -> Optional[FunctionSemantics]: if not address: return None @@ -357,7 +363,7 @@ def get_function_abi(self, chain_id, address, signature): return function_semantics @lru_cache(maxsize=128) - def get_constructor_abi(self, chain_id, address): + def get_constructor_abi(self, chain_id, address) -> Optional[FunctionSemantics]: if not address: return None @@ -373,7 +379,7 @@ def get_constructor_abi(self, chain_id, address): return constructor_semantics - def get_address_label(self, chain_id, address, proxies=None): + def get_address_label(self, chain_id, address, proxies=None) -> str: if not address: return "" @@ -394,7 +400,7 @@ def get_address_label(self, chain_id, address, proxies=None): return contract_label @lru_cache(maxsize=128) - def check_is_contract(self, chain_id, address): + def check_is_contract(self, chain_id, address) -> bool: if not address: return False @@ -405,7 +411,7 @@ def check_is_contract(self, chain_id, address): return is_contract @lru_cache(maxsize=128) - def get_standard(self, chain_id, address): + def get_standard(self, chain_id, address) -> Optional[str]: if not address: return None @@ -415,7 +421,14 @@ def get_standard(self, chain_id, address): return standard - def get_token_data(self, chain_id, address, proxies=None): + def get_token_data( + self, chain_id, address, proxies=None + ) -> Tuple[ + Optional[Union[str, Any]], + Optional[Union[str, Any]], + Optional[Union[int, Any]], + Optional[str], + ]: if not address: return None, None, None, None @@ -442,7 +455,7 @@ def get_token_data(self, chain_id, address, proxies=None): return token_name, token_symbol, token_decimals, "ERC20" - def update_address(self, chain_id, address, contract): + def update_address(self, chain_id, address, contract) -> Dict: updated_address = {"network": chain_id, "address": address, **contract} self.database.insert_address(address=updated_address, update_if_exist=True) @@ -465,7 +478,7 @@ def update_semantics(self, semantics) -> None: if contract_id: self.insert_contract_signatures(semantics.contract) - def insert_contract_signatures(self, contract_semantics: ContractSemantics): + def insert_contract_signatures(self, contract_semantics: ContractSemantics) -> None: for _, v in contract_semantics.functions.items(): if v.signature.startswith("0x"): if v.inputs: @@ -511,7 +524,7 @@ def get_most_used_signature(self, signature_hash: str) -> Optional[Signature]: return None - def update_or_insert_signature(self, signature: Signature): + def update_or_insert_signature(self, signature: Signature) -> None: signatures = self.database.get_signature_semantics( signature_hash=signature.signature_hash ) From b2b86207cd860c4d266ef221df830606ef02be2a Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 14:09:53 +0200 Subject: [PATCH 08/21] add missing __init__ files --- ethtx/semantics/protocols/maker/__init__.py | 0 ethtx/semantics/protocols/wrappers/__init__.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 ethtx/semantics/protocols/maker/__init__.py create mode 100644 ethtx/semantics/protocols/wrappers/__init__.py diff --git a/ethtx/semantics/protocols/maker/__init__.py b/ethtx/semantics/protocols/maker/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ethtx/semantics/protocols/wrappers/__init__.py b/ethtx/semantics/protocols/wrappers/__init__.py new file mode 100644 index 00000000..e69de29b From 5167328789b53ce177080cfd7d65df5124038b5f Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 14:40:00 +0200 Subject: [PATCH 09/21] black code --- ethtx/decoders/decoders/parameters.py | 2 -- ethtx/decoders/semantic/balances.py | 2 +- ethtx/decoders/semantic/calls.py | 4 ++-- ethtx/decoders/semantic/helpers/utils.py | 3 +-- ethtx/decoders/semantic/transfers.py | 4 +--- ethtx/models/decoded_model.py | 2 +- ethtx/semantics/solidity/precompiles.py | 1 - ethtx/semantics/standards/eip1969.py | 2 -- ethtx/semantics/utilities/functions.py | 1 - tests/conftest.py | 2 +- 10 files changed, 7 insertions(+), 16 deletions(-) diff --git a/ethtx/decoders/decoders/parameters.py b/ethtx/decoders/decoders/parameters.py index eac2db11..d8e2c52a 100644 --- a/ethtx/decoders/decoders/parameters.py +++ b/ethtx/decoders/decoders/parameters.py @@ -20,7 +20,6 @@ def decode_event_parameters(data, topics, abi, anonymous): - # making copy to avoid modifying of the original list amended_topics = topics.copy() @@ -124,7 +123,6 @@ def decode_event_parameters(data, topics, abi, anonymous): def decode_function_parameters( input_data, output, abi, status=True, strip_signature=True ): - if strip_signature and len(input_data) >= 10: stripped_input_data = input_data[10:] else: diff --git a/ethtx/decoders/semantic/balances.py b/ethtx/decoders/semantic/balances.py index 84274818..9d80b39e 100644 --- a/ethtx/decoders/semantic/balances.py +++ b/ethtx/decoders/semantic/balances.py @@ -13,8 +13,8 @@ from typing import List from ethtx.models.decoded_model import DecodedBalance, DecodedTransactionMetadata -from .helpers.utils import get_badge from .abc import SemanticSubmoduleAbc +from .helpers.utils import get_badge class SemanticBalancesDecoder(SemanticSubmoduleAbc): diff --git a/ethtx/decoders/semantic/calls.py b/ethtx/decoders/semantic/calls.py index 74576ca7..971c8962 100644 --- a/ethtx/decoders/semantic/calls.py +++ b/ethtx/decoders/semantic/calls.py @@ -13,8 +13,8 @@ from typing import Dict from ethtx.models.decoded_model import DecodedCall, DecodedTransactionMetadata, Proxy -from ethtx.semantics.standards.erc20 import ERC20_FUNCTIONS, ERC20_TRANSFORMATIONS -from ethtx.semantics.standards.erc721 import ERC721_FUNCTIONS, ERC721_TRANSFORMATIONS +from ethtx.semantics.standards.erc20 import ERC20_TRANSFORMATIONS +from ethtx.semantics.standards.erc721 import ERC721_TRANSFORMATIONS from ethtx.utils.measurable import RecursionLimit from .abc import SemanticSubmoduleAbc from .helpers.utils import ( diff --git a/ethtx/decoders/semantic/helpers/utils.py b/ethtx/decoders/semantic/helpers/utils.py index 8bf165bd..db033b42 100644 --- a/ethtx/decoders/semantic/helpers/utils.py +++ b/ethtx/decoders/semantic/helpers/utils.py @@ -20,8 +20,8 @@ from ethtx.decoders.decoders.parameters import decode_function_parameters from ethtx.models.decoded_model import AddressInfo -from ethtx.semantics.utilities.functions import add_utils_to_context from ethtx.models.semantics_model import FunctionSemantics +from ethtx.semantics.utilities.functions import add_utils_to_context log = logging.getLogger(__name__) @@ -47,7 +47,6 @@ def get_eth_price() -> Optional[float]: def get_badge(address, sender, receiver): - sender_address = sender.address if isinstance(sender, AddressInfo) else sender receiver_address = ( receiver.address if isinstance(receiver, AddressInfo) else receiver diff --git a/ethtx/decoders/semantic/transfers.py b/ethtx/decoders/semantic/transfers.py index a51e8180..09e7c607 100644 --- a/ethtx/decoders/semantic/transfers.py +++ b/ethtx/decoders/semantic/transfers.py @@ -13,17 +13,15 @@ from typing import List from ethtx.models.decoded_model import DecodedTransfer, DecodedTransactionMetadata -from .helpers.utils import get_badge from .abc import SemanticSubmoduleAbc +from .helpers.utils import get_badge class SemanticTransfersDecoder(SemanticSubmoduleAbc): def decode( self, transfers: List[DecodedTransfer], tx_metadata: DecodedTransactionMetadata ) -> List[DecodedTransfer]: - for transfer in transfers: - # decode proper from and to addresses badges transfer.from_address.badge = get_badge( transfer.from_address.address, diff --git a/ethtx/models/decoded_model.py b/ethtx/models/decoded_model.py index 6f4520f0..5ddfa1a7 100644 --- a/ethtx/models/decoded_model.py +++ b/ethtx/models/decoded_model.py @@ -15,7 +15,7 @@ from datetime import datetime from typing import List, Any, Optional -from ethtx.models.objects_model import BlockMetadata, TransactionMetadata +from ethtx.models.objects_model import BlockMetadata from ethtx.models.semantics_model import AddressSemantics, ERC20Semantics from ethtx.utils.pickable import JsonObject diff --git a/ethtx/semantics/solidity/precompiles.py b/ethtx/semantics/solidity/precompiles.py index c542fe0b..888c5f58 100644 --- a/ethtx/semantics/solidity/precompiles.py +++ b/ethtx/semantics/solidity/precompiles.py @@ -13,7 +13,6 @@ from ethtx.models.semantics_model import FunctionSemantics, ParameterSemantics - precompiles = { 1: FunctionSemantics( "", diff --git a/ethtx/semantics/standards/eip1969.py b/ethtx/semantics/standards/eip1969.py index f76a0183..cdbfe603 100644 --- a/ethtx/semantics/standards/eip1969.py +++ b/ethtx/semantics/standards/eip1969.py @@ -2,7 +2,6 @@ def is_eip1969_proxy(chain, delegator, delegate): - implementation_slot = hex( int(Web3.keccak(text="eip1967.proxy.implementation").hex(), 16) - 1 ) @@ -19,7 +18,6 @@ def is_eip1969_proxy(chain, delegator, delegate): def is_eip1969_beacon_proxy(chain, delegator, delegate): - ibeacon_abi = """[ { "inputs": [], diff --git a/ethtx/semantics/utilities/functions.py b/ethtx/semantics/utilities/functions.py index 612d8ae7..2ed9349d 100644 --- a/ethtx/semantics/utilities/functions.py +++ b/ethtx/semantics/utilities/functions.py @@ -44,7 +44,6 @@ def string_from_bytes(raw_value): def add_utils_to_context(context): - # register additional functions available for transformations context["token_decimals"] = partial( token_decimals, context["__transaction__"], context["__repository__"] diff --git a/tests/conftest.py b/tests/conftest.py index 03801153..43d914c2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ from mongoengine import connect from pymongo import MongoClient -from ethtx.providers.semantic_providers.database import MongoSemanticsDatabase +from ethtx.providers import MongoSemanticsDatabase @pytest.fixture From ce7e70c7ff1361097b7290766e14e388a16eae30 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 14:45:46 +0200 Subject: [PATCH 10/21] fix types --- ethtx/models/semantics_model.py | 2 +- ethtx/providers/semantic_providers/repository.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ethtx/models/semantics_model.py b/ethtx/models/semantics_model.py index f9e359bf..2a8c1fbf 100644 --- a/ethtx/models/semantics_model.py +++ b/ethtx/models/semantics_model.py @@ -149,7 +149,7 @@ def __init__( name: str, events: Dict[str, EventSemantics], functions: Dict[str, FunctionSemantics], - transformations: [Dict[str, TransformationSemantics]], + transformations: [Dict[str, Dict[str, TransformationSemantics]]], ): self.code_hash = code_hash self.name = name diff --git a/ethtx/providers/semantic_providers/repository.py b/ethtx/providers/semantic_providers/repository.py index 1e93283c..bf53b6aa 100644 --- a/ethtx/providers/semantic_providers/repository.py +++ b/ethtx/providers/semantic_providers/repository.py @@ -314,7 +314,9 @@ def get_event_abi(self, chain_id, address, signature) -> Optional[EventSemantics return event_semantics @lru_cache(maxsize=128) - def get_transformations(self, chain_id, address, signature) -> Optional[str]: + def get_transformations( + self, chain_id, address, signature + ) -> Optional[Dict[str, TransformationSemantics]]: if not address: return None From a8b2a7057d90a1b495771226d2a4b58cb03a737b Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 14:47:23 +0200 Subject: [PATCH 11/21] add type --- ethtx/providers/semantic_providers/database.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethtx/providers/semantic_providers/database.py b/ethtx/providers/semantic_providers/database.py index 33731e47..43f3e3ba 100644 --- a/ethtx/providers/semantic_providers/database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -32,7 +32,7 @@ def __init__(self, db: MongoDatabase): self._init_collections() - def get_collection_count(self): + def get_collection_count(self) -> int: return len(self._db.list_collection_names()) def get_address_semantics(self, chain_id, address) -> Optional[Dict]: From 8918163be74add4f33d5a8c864c837cb556dbebb Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 14:54:51 +0200 Subject: [PATCH 12/21] fix import --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 43d914c2..03801153 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ from mongoengine import connect from pymongo import MongoClient -from ethtx.providers import MongoSemanticsDatabase +from ethtx.providers.semantic_providers.database import MongoSemanticsDatabase @pytest.fixture From 4663a9c1daaab16bee3482286dd4c9cef96671b3 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 15:44:59 +0200 Subject: [PATCH 13/21] remove useless isinstance --- ethtx/decoders/decoder_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethtx/decoders/decoder_service.py b/ethtx/decoders/decoder_service.py index 67d34211..92a9b868 100644 --- a/ethtx/decoders/decoder_service.py +++ b/ethtx/decoders/decoder_service.py @@ -155,7 +155,7 @@ def decode_transaction(self, chain_id: str, tx_hash: str) -> DecodedTransaction: log.info( "Semantics used in decoding %s: %s", tx_hash, - ", ".join(used_semantics) if isinstance(used_semantics, list) else "", + ", ".join(used_semantics) if used_semantics else "", ) return semantically_decoded_tx From 076a7db54861eb07d6cc2c39bc350af5e7adb7c9 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 15:57:45 +0200 Subject: [PATCH 14/21] refactor init collections --- .../providers/semantic_providers/database.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ethtx/providers/semantic_providers/database.py b/ethtx/providers/semantic_providers/database.py index 43f3e3ba..ffb1d382 100644 --- a/ethtx/providers/semantic_providers/database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -100,16 +100,16 @@ def insert_address(self, address, update_if_exist=False) -> Optional[bson.Object return inserted_address.inserted_id def _init_collections(self) -> None: - if MongoCollections.ADDRESSES not in self._db.list_collection_names(): - self._addresses = self._db[MongoCollections.ADDRESSES] - - if MongoCollections.CONTRACTS not in self._db.list_collection_names(): - self._contracts = self._db[MongoCollections.CONTRACTS] - - if MongoCollections.SIGNATURES not in self._db.list_collection_names(): - self._signatures = self._db[MongoCollections.SIGNATURES] - self._signatures.create_index( - [("signature_hash", "TEXT"), ("name", "TEXT")], - background=True, - unique=False, - ) + collections = self._db.list_collection_names() + + for mongo_collection in MongoCollections: + + if mongo_collection not in collections: + setattr(self, f"_{mongo_collection}", self._db[mongo_collection]) + + if mongo_collection == "signatures": + self._signatures.create_index( + [("signature_hash", "TEXT"), ("name", "TEXT")], + background=True, + unique=True, + ) From f4d9cc55012c73de7d158a1e79e555422cdbe6e2 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 16:00:20 +0200 Subject: [PATCH 15/21] fix type --- ethtx/providers/semantic_providers/__init__.py | 0 ethtx/providers/semantic_providers/repository.py | 9 ++------- 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 ethtx/providers/semantic_providers/__init__.py diff --git a/ethtx/providers/semantic_providers/__init__.py b/ethtx/providers/semantic_providers/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ethtx/providers/semantic_providers/repository.py b/ethtx/providers/semantic_providers/repository.py index bf53b6aa..5b5149c3 100644 --- a/ethtx/providers/semantic_providers/repository.py +++ b/ethtx/providers/semantic_providers/repository.py @@ -11,7 +11,7 @@ # limitations under the License. from functools import lru_cache -from typing import Optional, List, Dict, Tuple, Union, Any +from typing import Optional, List, Dict, Tuple from ethtx.decoders.decoders.semantics import decode_events_and_functions from ethtx.models.semantics_model import ( @@ -425,12 +425,7 @@ def get_standard(self, chain_id, address) -> Optional[str]: def get_token_data( self, chain_id, address, proxies=None - ) -> Tuple[ - Optional[Union[str, Any]], - Optional[Union[str, Any]], - Optional[Union[int, Any]], - Optional[str], - ]: + ) -> Tuple[Optional[str], Optional[str], Optional[int], Optional[str]]: if not address: return None, None, None, None From 50d2999f86419e21f5ae175412d0e00fd3cd22ea Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 16:13:11 +0200 Subject: [PATCH 16/21] refactored --- .../semantic_providers/repository.py | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/ethtx/providers/semantic_providers/repository.py b/ethtx/providers/semantic_providers/repository.py index 5b5149c3..1f444f32 100644 --- a/ethtx/providers/semantic_providers/repository.py +++ b/ethtx/providers/semantic_providers/repository.py @@ -477,30 +477,32 @@ def update_semantics(self, semantics) -> None: def insert_contract_signatures(self, contract_semantics: ContractSemantics) -> None: for _, v in contract_semantics.functions.items(): - if v.signature.startswith("0x"): - if v.inputs: - if v.inputs[0].parameter_type == "tuple": - args = [ - SignatureArg( - name=param.parameter_name, type=param.parameter_type - ) - for param in v.inputs[0].components - ] - else: - args = [ - SignatureArg( - name=param.parameter_name, type=param.parameter_type - ) - for param in v.inputs - ] - else: - args = [] - new_signature = Signature( - signature_hash=v.signature, name=v.name, args=args + if not v.signature.startswith("0x"): + continue + + if v.inputs and v.inputs[0].parameter_type == "tuple": + args = [ + SignatureArg(name=param.parameter_name, type=param.parameter_type) + for param in v.inputs[0].components + ] + else: + args = ( + [ + SignatureArg( + name=param.parameter_name, type=param.parameter_type + ) + for param in v.inputs + ] + if v.inputs + else [] ) - self.update_or_insert_signature(new_signature) + new_signature = Signature( + signature_hash=v.signature, name=v.name, args=args + ) + + self.update_or_insert_signature(new_signature) def get_most_used_signature(self, signature_hash: str) -> Optional[Signature]: signatures = list( From 8b1790576b8a1a1054ca6494f78e8f5892dc9c02 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 16:16:53 +0200 Subject: [PATCH 17/21] add missing file --- ethtx/providers/semantic_providers/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ethtx/providers/semantic_providers/__init__.py diff --git a/ethtx/providers/semantic_providers/__init__.py b/ethtx/providers/semantic_providers/__init__.py new file mode 100644 index 00000000..e69de29b From 4ac86186e92610edac7fa173eeeaea876418f7e6 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Mon, 11 Oct 2021 16:27:09 +0200 Subject: [PATCH 18/21] udpate imports --- ethtx/decoders/abi/abc.py | 2 +- ethtx/decoders/abi/helpers/utils.py | 5 ++--- ethtx/decoders/semantic/abc.py | 2 +- ethtx/ethtx.py | 6 +++--- ethtx/providers/semantic_providers/__init__.py | 15 +++++++++++++++ tests/conftest.py | 2 +- 6 files changed, 23 insertions(+), 9 deletions(-) diff --git a/ethtx/decoders/abi/abc.py b/ethtx/decoders/abi/abc.py index ea76a8f7..70229f88 100644 --- a/ethtx/decoders/abi/abc.py +++ b/ethtx/decoders/abi/abc.py @@ -22,7 +22,7 @@ TransactionMetadata, BlockMetadata, ) -from ethtx.providers.semantic_providers.repository import SemanticsRepository +from ethtx.providers.semantic_providers import SemanticsRepository class ABIBasic: diff --git a/ethtx/decoders/abi/helpers/utils.py b/ethtx/decoders/abi/helpers/utils.py index 1ea95bf5..a9ec8b48 100644 --- a/ethtx/decoders/abi/helpers/utils.py +++ b/ethtx/decoders/abi/helpers/utils.py @@ -18,9 +18,8 @@ Signature, SignatureArg, ) -from ethtx.providers import FourByteProvider -from ethtx.providers.semantic_providers.repository import SemanticsRepository -from ethtx.providers.signature_provider import SignatureProvider +from ethtx.providers.semantic_providers import SemanticsRepository +from ethtx.providers.signature_provider import SignatureProvider, FourByteProvider log = logging.getLogger(__name__) diff --git a/ethtx/decoders/semantic/abc.py b/ethtx/decoders/semantic/abc.py index 48d5b5a0..e0524078 100644 --- a/ethtx/decoders/semantic/abc.py +++ b/ethtx/decoders/semantic/abc.py @@ -22,7 +22,7 @@ Proxy, ) from ethtx.models.objects_model import BlockMetadata, TransactionMetadata -from ethtx.providers.semantic_providers.repository import SemanticsRepository +from ethtx.providers.semantic_providers import SemanticsRepository class SemanticSubmoduleAbc(ABC): diff --git a/ethtx/ethtx.py b/ethtx/ethtx.py index 2919d3c8..9db735d6 100644 --- a/ethtx/ethtx.py +++ b/ethtx/ethtx.py @@ -21,11 +21,11 @@ from .models.decoded_model import Proxy, DecodedTransaction from .models.objects_model import Call from .providers import EtherscanProvider, Web3Provider -from .providers.semantic_providers.database import ( - MongoSemanticsDatabase, +from .providers.semantic_providers import ( ISemanticsDatabase, + SemanticsRepository, + MongoSemanticsDatabase, ) -from .providers.semantic_providers.repository import SemanticsRepository from .utils.validators import assert_tx_hash diff --git a/ethtx/providers/semantic_providers/__init__.py b/ethtx/providers/semantic_providers/__init__.py index e69de29b..a74f4ec6 100644 --- a/ethtx/providers/semantic_providers/__init__.py +++ b/ethtx/providers/semantic_providers/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2021 DAI Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .base import ISemanticsDatabase +from .database import MongoSemanticsDatabase +from .repository import SemanticsRepository diff --git a/tests/conftest.py b/tests/conftest.py index 03801153..c5c46846 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ from mongoengine import connect from pymongo import MongoClient -from ethtx.providers.semantic_providers.database import MongoSemanticsDatabase +from ethtx.providers.semantic_providers import MongoSemanticsDatabase @pytest.fixture From f2d0b97dc19f205ba1656e148e99666f50b89bcd Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Tue, 12 Oct 2021 09:46:57 +0200 Subject: [PATCH 19/21] fix setting collections --- ethtx/providers/semantic_providers/database.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ethtx/providers/semantic_providers/database.py b/ethtx/providers/semantic_providers/database.py index ffb1d382..a07d2c98 100644 --- a/ethtx/providers/semantic_providers/database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -10,15 +10,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging from typing import Dict, Optional import bson from pymongo.cursor import Cursor from pymongo.database import Database as MongoDatabase +from pymongo.errors import OperationFailure from .base import ISemanticsDatabase from .const import MongoCollections +log = logging.getLogger(__name__) + class MongoSemanticsDatabase(ISemanticsDatabase): _db: MongoDatabase @@ -100,16 +104,15 @@ def insert_address(self, address, update_if_exist=False) -> Optional[bson.Object return inserted_address.inserted_id def _init_collections(self) -> None: - collections = self._db.list_collection_names() - for mongo_collection in MongoCollections: + setattr(self, f"_{mongo_collection}", self._db[mongo_collection]) - if mongo_collection not in collections: - setattr(self, f"_{mongo_collection}", self._db[mongo_collection]) - - if mongo_collection == "signatures": + if mongo_collection == "signatures": + try: self._signatures.create_index( [("signature_hash", "TEXT"), ("name", "TEXT")], background=True, unique=True, ) + except OperationFailure as e: + log.warning(e) From 07f83731056ffa817a9da6f07d1e77d9f41a70a7 Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Tue, 12 Oct 2021 09:51:40 +0200 Subject: [PATCH 20/21] update setattr --- ethtx/providers/semantic_providers/database.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethtx/providers/semantic_providers/database.py b/ethtx/providers/semantic_providers/database.py index a07d2c98..8e1d94a8 100644 --- a/ethtx/providers/semantic_providers/database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -105,7 +105,7 @@ def insert_address(self, address, update_if_exist=False) -> Optional[bson.Object def _init_collections(self) -> None: for mongo_collection in MongoCollections: - setattr(self, f"_{mongo_collection}", self._db[mongo_collection]) + self.__setattr__(f"_{mongo_collection}", self._db[mongo_collection]) if mongo_collection == "signatures": try: @@ -116,3 +116,4 @@ def _init_collections(self) -> None: ) except OperationFailure as e: log.warning(e) + From c6ca7012598e6f38dc05384dcbca476bc0611b5d Mon Sep 17 00:00:00 2001 From: Karol Chojnowski Date: Tue, 12 Oct 2021 09:51:54 +0200 Subject: [PATCH 21/21] update setattr --- ethtx/providers/semantic_providers/database.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ethtx/providers/semantic_providers/database.py b/ethtx/providers/semantic_providers/database.py index 8e1d94a8..5b3d8f79 100644 --- a/ethtx/providers/semantic_providers/database.py +++ b/ethtx/providers/semantic_providers/database.py @@ -116,4 +116,3 @@ def _init_collections(self) -> None: ) except OperationFailure as e: log.warning(e) -