Exemple #1
0
    def get_all_asset_data(
            mapping: bool
    ) -> Union[List[AssetData], Dict[str, Dict[str, Any]]]:
        """Return all asset data from the DB

        TODO: This can be improved. Too many sql queries.

        If mapping is True, return them as a Dict of identifier to data
        If mapping is False, return them as a List of AssetData
        """
        result: Union[List[AssetData], Dict[str, Dict[str, Any]]]
        if mapping:
            result = {}
        else:
            result = []
        cursor = GlobalDBHandler()._conn.cursor()
        querystr = """
        SELECT A.identifier, A.type, B.address, B.decimals, A.name, A.symbol, A.started, null, A.swapped_for, A.coingecko, A.cryptocompare, B.protocol from assets as A LEFT OUTER JOIN ethereum_tokens as B
        ON B.address = A.details_reference WHERE A.type=?
        UNION ALL
        SELECT A.identifier, A.type, null, null, A.name, A.symbol, A.started, B.forked, A.swapped_for, A.coingecko, A.cryptocompare, null from assets as A LEFT OUTER JOIN common_asset_details as B
        ON B.asset_id = A.identifier WHERE A.type!=?;
        """  # noqa: E501
        eth_token_type = AssetType.ETHEREUM_TOKEN.serialize_for_db()  # pylint: disable=no-member
        query = cursor.execute(querystr, (eth_token_type, eth_token_type))
        for entry in query:
            asset_type = AssetType.deserialize_from_db(entry[1])
            ethereum_address: Optional[ChecksumEthAddress]
            if asset_type == AssetType.ETHEREUM_TOKEN:
                ethereum_address = string_to_ethereum_address(entry[2])
            else:
                ethereum_address = None
            data = AssetData(
                identifier=entry[0],
                asset_type=asset_type,
                ethereum_address=ethereum_address,
                decimals=entry[3],
                name=entry[4],
                symbol=entry[5],
                started=entry[6],
                forked=entry[7],
                swapped_for=entry[8],
                coingecko=entry[9],
                cryptocompare=entry[10],
                protocol=entry[11],
            )
            if mapping:
                result[entry[0]] = data.serialize()  # type: ignore
            else:
                result.append(data)  # type: ignore

        return result
Exemple #2
0
    def _parse_full_insert(self, insert_text: str) -> AssetData:
        """Parses the full insert line for an asset to give information for the conflict to the user

        Note: In the future this needs to be different for each version
        May raise:
        - DeserializationError if the appropriate data is not found or if it can't
        be properly parsed.
        """
        asset_data = self._parse_asset_data(insert_text)
        forked = address = decimals = protocol = None
        if asset_data.asset_type == AssetType.ETHEREUM_TOKEN:
            address, decimals, protocol = self._parse_ethereum_token_data(insert_text)
        else:
            match = self.common_asset_details_re.match(insert_text)
            if match is None:
                raise DeserializationError(
                    f'At asset DB update could not parse common asset '
                    f'details data out of {insert_text}',
                )
            forked = self._parse_optional_str(match.group(2), 'forked', insert_text)

        return AssetData(  # types are not really proper here (except for asset_type)
            identifier=asset_data.identifier,
            name=asset_data.name,
            symbol=asset_data.symbol,
            asset_type=asset_data.asset_type,
            started=asset_data.started,
            forked=forked,
            swapped_for=asset_data.swapped_for,
            ethereum_address=address,
            decimals=decimals,
            cryptocompare=asset_data.cryptocompare,
            coingecko=asset_data.coingecko,
            protocol=protocol,
        )
Exemple #3
0
    def get_assets_with_symbol(
        symbol: str,
        asset_type: Optional[AssetType] = None
    ) -> List[AssetData]:  # noqa: E501
        """Find all asset entries that have the given symbol"""
        connection = GlobalDBHandler()._conn
        cursor = connection.cursor()
        query_tuples: Union[Tuple[str, str, str, str], Tuple[str, str, str,
                                                             str, str]]
        eth_token_type = AssetType.ETHEREUM_TOKEN.serialize_for_db()  # pylint: disable=no-member
        if asset_type is not None:
            asset_type_check = ' AND A.type=?'
            query_tuples = (symbol, eth_token_type, symbol, eth_token_type,
                            asset_type.serialize_for_db())  # noqa: E501
        else:
            asset_type_check = ''
            query_tuples = (symbol, eth_token_type, symbol, eth_token_type)
        querystr = f"""
        SELECT A.identifier, A.type, B.address, B.decimals, A.name, A.symbol, A.started, null, A.swapped_for, A.coingecko, A.cryptocompare, B.protocol from assets as A LEFT OUTER JOIN ethereum_tokens as B
        ON B.address = A.details_reference WHERE A.symbol=? COLLATE NOCASE AND A.type=?
        UNION ALL
        SELECT A.identifier, A.type, null, null, A.name, A.symbol, A.started, B.forked, A.swapped_for, A.coingecko, A.cryptocompare, null from assets as A LEFT OUTER JOIN common_asset_details as B
        ON B.asset_id = A.identifier WHERE A.symbol=? COLLATE NOCASE AND A.type!=?{asset_type_check};
        """  # noqa: E501
        query = cursor.execute(querystr, query_tuples)
        assets = []
        for entry in query:
            asset_type = AssetType.deserialize_from_db(entry[1])
            ethereum_address: Optional[ChecksumEthAddress]
            if asset_type == AssetType.ETHEREUM_TOKEN:
                ethereum_address = string_to_ethereum_address(entry[2])
            else:
                ethereum_address = None
            assets.append(
                AssetData(
                    identifier=entry[0],
                    asset_type=asset_type,
                    ethereum_address=ethereum_address,
                    decimals=entry[3],
                    name=entry[4],
                    symbol=entry[5],
                    started=entry[6],
                    forked=entry[7],
                    swapped_for=entry[8],
                    coingecko=entry[9],
                    cryptocompare=entry[10],
                    protocol=entry[11],
                ))

        return assets
Exemple #4
0
def test_get_all_asset_data_specific_ids(globaldb):
    btc_asset_data = AssetData(
        identifier='BTC',
        name='Bitcoin',
        symbol='BTC',
        asset_type=AssetType.OWN_CHAIN,
        started=Timestamp(1231006505),
        forked=None,
        swapped_for=None,
        ethereum_address=None,
        decimals=None,
        cryptocompare=None,
        coingecko='bitcoin',
        protocol=None,
    )
    eth_asset_data = AssetData(
        identifier='ETH',
        name='Ethereum',
        symbol='ETH',
        asset_type=AssetType.OWN_CHAIN,
        started=Timestamp(1438214400),
        forked=None,
        swapped_for=None,
        ethereum_address=None,
        decimals=None,
        cryptocompare=None,
        coingecko='ethereum',
        protocol=None,
    )

    asset_data = globaldb.get_all_asset_data(
        mapping=False,
        specific_ids=['BTC', 'ETH', selfkey_id, 'BIDR'],
    )
    assert asset_data == [
        selfkey_asset_data,
        bidr_asset_data,
        btc_asset_data,
        eth_asset_data,
    ]

    asset_data = globaldb.get_all_asset_data(
        mapping=True,
        serialized=True,
        specific_ids=['BTC', 'ETH', selfkey_id, 'BIDR'],
    )
    assert asset_data == {
        selfkey_id: selfkey_asset_data.serialize(),
        'BIDR': bidr_asset_data.serialize(),
        'BTC': btc_asset_data.serialize(),
        'ETH': eth_asset_data.serialize(),
    }
    asset_data = globaldb.get_all_asset_data(
        mapping=True,
        serialized=False,
        specific_ids=['BTC', 'ETH', selfkey_id, 'BIDR'],
    )
    assert asset_data == {
        selfkey_id: selfkey_asset_data,
        'BIDR': bidr_asset_data,
        'BTC': btc_asset_data,
        'ETH': eth_asset_data,
    }

    # unknown ids
    assert globaldb.get_all_asset_data(
        mapping=False,
        specific_ids=['INVALIDIDSS!@!1', 'DSAD#@$DSAD@EAS'],
    ) == []
    assert globaldb.get_all_asset_data(
        mapping=True,
        specific_ids=['INVALIDIDSS!@!1', 'DSAD#@$DSAD@EAS'],
    ) == {}

    # empty list
    assert globaldb.get_all_asset_data(
        mapping=False,
        specific_ids=[],
    ) == []
    assert globaldb.get_all_asset_data(
        mapping=True,
        specific_ids=[],
    ) == {}
Exemple #5
0
def test_get_asset_with_symbol(globaldb):
    # both categories of assets
    asset_data = globaldb.get_assets_with_symbol('KEY')
    bihukey_address = string_to_ethereum_address(
        '0x4Cd988AfBad37289BAAf53C13e98E2BD46aAEa8c')
    aave_address = string_to_ethereum_address(
        '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9')
    renbtc_address = string_to_ethereum_address(
        '0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D')
    assert asset_data == [
        selfkey_asset_data,
        AssetData(
            identifier=ethaddress_to_identifier(bihukey_address),
            name='Bihu KEY',
            symbol='KEY',
            asset_type=AssetType.ETHEREUM_TOKEN,
            started=1507822985,
            forked=None,
            swapped_for=None,
            ethereum_address=bihukey_address,
            decimals=18,
            cryptocompare='BIHU',
            coingecko='key',
            protocol=None,
        ),
        AssetData(
            identifier='KEY-3',
            name='KeyCoin',
            symbol='KEY',
            asset_type=AssetType.OWN_CHAIN,
            started=1405382400,
            forked=None,
            swapped_for=None,
            ethereum_address=None,
            decimals=None,
            cryptocompare='KEYC',
            coingecko='',
            protocol=None,
        )
    ]
    # only non-ethereum token
    assert globaldb.get_assets_with_symbol('BIDR') == [bidr_asset_data]
    # only ethereum token
    assert globaldb.get_assets_with_symbol('AAVE') == [
        AssetData(
            identifier=ethaddress_to_identifier(aave_address),
            name='Aave Token',
            symbol='AAVE',
            asset_type=AssetType.ETHEREUM_TOKEN,
            started=1600970788,
            forked=None,
            swapped_for=None,
            ethereum_address=aave_address,
            decimals=18,
            cryptocompare=None,
            coingecko='aave',
            protocol=None,
        )
    ]
    # finally non existing asset
    assert globaldb.get_assets_with_symbol('DASDSADSDSDSAD') == []

    # also check that symbol comparison is case insensitive for many arg combinations
    expected_renbtc = [
        AssetData(
            identifier=ethaddress_to_identifier(renbtc_address),
            name='renBTC',
            symbol='renBTC',
            asset_type=AssetType.ETHEREUM_TOKEN,
            started=1585090944,
            forked=None,
            swapped_for=None,
            ethereum_address=renbtc_address,
            decimals=8,
            cryptocompare=None,
            coingecko='renbtc',
            protocol=None,
        )
    ]
    for x in itertools.product(('ReNbTc', 'renbtc', 'RENBTC', 'rEnBTc'),
                               (None, AssetType.ETHEREUM_TOKEN)):  # noqa: E501
        assert globaldb.get_assets_with_symbol(*x) == expected_renbtc
Exemple #6
0
from rotkehlchen.serialization.deserialize import deserialize_asset_amount
from rotkehlchen.tests.fixtures.globaldb import create_globaldb
from rotkehlchen.tests.utils.factories import make_ethereum_address
from rotkehlchen.tests.utils.globaldb import INITIAL_TOKENS
from rotkehlchen.typing import Location, Price, Timestamp, TradeType

selfkey_address = string_to_ethereum_address(
    '0x4CC19356f2D37338b9802aa8E8fc58B0373296E7')
selfkey_id = ethaddress_to_identifier(selfkey_address)
selfkey_asset_data = AssetData(
    identifier=selfkey_id,
    name='Selfkey',
    symbol='KEY',
    asset_type=AssetType.ETHEREUM_TOKEN,
    started=Timestamp(1508803200),
    forked=None,
    swapped_for=None,
    ethereum_address=selfkey_address,
    decimals=18,
    cryptocompare=None,
    coingecko='selfkey',
    protocol=None,
)
bidr_asset_data = AssetData(
    identifier='BIDR',
    name='Binance IDR Stable Coin',
    symbol='BIDR',
    asset_type=AssetType.BINANCE_TOKEN,
    started=Timestamp(1593475200),
    forked=None,
    swapped_for=None,
    ethereum_address=None,
Exemple #7
0
    def get_asset_data(
        identifier: str,
        form_with_incomplete_data: bool,
    ) -> Optional[AssetData]:
        """Get all details of a single asset by identifier

        Returns None if identifier can't be matched to an asset
        """
        cursor = GlobalDBHandler()._conn.cursor()
        query = cursor.execute(
            'SELECT identifier, type, name, symbol, started, swapped_for, coingecko, '
            'cryptocompare, details_reference from assets WHERE identifier=?;',
            (identifier, ),
        )
        result = query.fetchone()
        if result is None:
            return None

        # Since comparison is case insensitive let's return original identifier
        saved_identifier = result[0]  # get the identifier as saved in the DB.
        db_serialized_type = result[1]
        name = result[2]
        symbol = result[3]
        started = result[4]
        swapped_for = result[5]
        coingecko = result[6]
        cryptocompare = result[7]
        details_reference = result[8]
        forked = None
        decimals = None
        protocol = None
        ethereum_address = None

        try:
            asset_type = AssetType.deserialize_from_db(db_serialized_type)
        except DeserializationError as e:
            log.debug(
                f'Failed to read asset {identifier} from the DB due to '
                f'{str(e)}. Skipping', )
            return None

        if asset_type == AssetType.ETHEREUM_TOKEN:
            ethereum_address = details_reference
            cursor.execute(
                'SELECT decimals, protocol from ethereum_tokens '
                'WHERE address=?',
                (ethereum_address, ),
            )
            result = query.fetchone()
            if result is None:
                log.error(
                    f'Found token {saved_identifier} in the DB assets table but not '
                    f'in the token details table.', )
                return None

            decimals = result[0]
            protocol = result[1]
            missing_basic_data = name is None or symbol is None or decimals is None
            if missing_basic_data and form_with_incomplete_data is False:
                log.debug(
                    f'Considering ethereum token with address {details_reference} '
                    f'as unknown since its missing either decimals or name or symbol',
                )
                return None
        else:
            cursor = GlobalDBHandler()._conn.cursor()
            query = cursor.execute(
                'SELECT forked FROM common_asset_details WHERE asset_id = ?;',
                (details_reference, ),
            )
            result = query.fetchone()
            if result is None:
                log.error(
                    f'Found asset {saved_identifier} in the DB assets table but not '
                    f'in the common asset details table.', )
                return None
            forked = result[0]

        return AssetData(
            identifier=saved_identifier,
            name=name,
            symbol=symbol,
            asset_type=asset_type,
            started=started,
            forked=forked,
            swapped_for=swapped_for,
            ethereum_address=ethereum_address,
            decimals=decimals,
            coingecko=coingecko,
            cryptocompare=cryptocompare,
            protocol=protocol,
        )
 INSERT INTO ethereum_tokens(address, decimals, protocol) VALUES(
 "0xD178b20c6007572bD1FD01D205cC20D32B4A6015", 18, NULL
 );
 INSERT INTO assets(identifier,type, name, symbol,
 started, swapped_for, coingecko, cryptocompare, details_reference)
 VALUES("_ceth_0xD178b20c6007572bD1FD01D205cC20D32B4A6015", "C", "Aidus", "AID"   ,
 123, NULL,   NULL, "AIDU", "0xD178b20c6007572bD1FD01D205cC20D32B4A6015");
 """,
     AssetData(
         identifier='_ceth_0xD178b20c6007572bD1FD01D205cC20D32B4A6015',
         name='Aidus',
         symbol='AID',
         asset_type=AssetType.ETHEREUM_TOKEN,
         started=Timestamp(123),
         forked=None,
         swapped_for=None,
         ethereum_address=string_to_ethereum_address(
             '0xD178b20c6007572bD1FD01D205cC20D32B4A6015'
         ),  # noqa: E501
         decimals=18,
         cryptocompare='AIDU',
         coingecko=None,
         protocol=None,
     ),
     None,
 ),
 (
     """
 INSERT INTO assets(identifier,type, name, symbol,
 started, swapped_for, coingecko, cryptocompare, details_reference)
 VALUES("121-ada-FADS-as", "F", "A name", "SYMBOL"   ,
 NULL, NULL,   "", "", "121-ada-FADS-as");