Beispiel #1
0
def test_binance_query_trade_history_custom_markets(function_scope_binance,
                                                    user_data_dir):
    """Test that custom pairs are queried correctly"""
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)

    binance_api_key = ApiKey('binance_api_key')
    binance_api_secret = ApiSecret(b'binance_api_secret')
    db.add_exchange('binance', Location.BINANCE, binance_api_key,
                    binance_api_secret)

    binance = function_scope_binance

    markets = ['ETHBTC', 'BNBBTC', 'BTCUSDC']
    db.set_binance_pairs('binance', markets, Location.BINANCE)

    count = 0
    p = re.compile(r'symbol=[A-Z]*')
    seen = set()

    def mock_my_trades(url, timeout):  # pylint: disable=unused-argument
        nonlocal count
        count += 1
        market = p.search(url).group()[7:]
        assert market in markets and market not in seen
        seen.add(market)
        text = '[]'
        return MockResponse(200, text)

    with patch.object(binance.session, 'get', side_effect=mock_my_trades):
        binance.query_trade_history(start_ts=0,
                                    end_ts=1564301134,
                                    only_cache=False)

    assert count == len(markets)
Beispiel #2
0
def test_upgrade_db_10_to_11(data_dir, username):
    """Test upgrading the DB from version 10 to version 11.

    Deleting all entries from used_query_ranges"""
    msg_aggregator = MessagesAggregator()
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    dir_path = os.path.dirname(os.path.realpath(__file__))
    copyfile(
        os.path.join(os.path.dirname(dir_path), 'data', 'v10_rotkehlchen.db'),
        os.path.join(userdata_dir, 'rotkehlchen.db'),
    )

    with target_patch(target_version=11):
        db = DBHandler(user_data_dir=userdata_dir,
                       password='******',
                       msg_aggregator=msg_aggregator)

    # Make sure that the blockchain accounts table is upgraded
    expected_results = [
        ('ETH', '0xB2CEB220df2e4a5ec6A0aC93d79655895E9886Bc', None),
        ('ETH', '0x926cbe37d3487a881F9EB18F4746Ee09557D79cB', None),
        ('BTC', '37SQZzaCPbDno9aFBjaVKhA9KkzTbt94x2', None),
    ]
    cursor = db.conn.cursor()
    results = cursor.execute(
        'SELECT blockchain, account, label FROM blockchain_accounts;', )
    for idx, entry in enumerate(results):
        assert entry == expected_results[idx]

    # Finally also make sure that we have updated to the target version
    assert db.get_version() == 11
Beispiel #3
0
def test_upgrade_sqlcipher_v3_to_v4_with_dbinfo(data_dir):
    sqlcipher_version = detect_sqlcipher_version()
    if sqlcipher_version != 4:
        # nothing to test
        return

    username = '******'
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    # get the v3 database file and copy it into the user's data directory
    dir_path = os.path.dirname(os.path.realpath(__file__))
    copyfile(
        os.path.join(os.path.dirname(dir_path), 'data',
                     'sqlcipher_v3_rotkehlchen.db'),
        os.path.join(userdata_dir, 'rotkehlchen.db'),
    )
    dbinfo = {
        'sqlcipher_version': 3,
        'md5_hash': '20c910c28ca42370e4a5f24d6d4a73d2'
    }
    with open(os.path.join(userdata_dir, DBINFO_FILENAME), 'w') as f:
        f.write(rlk_jsondumps(dbinfo))

    # the constructor should migrate it in-place and we should have a working DB
    msg_aggregator = MessagesAggregator()
    db = DBHandler(userdata_dir, '123', msg_aggregator)
    assert db.get_version() == ROTKEHLCHEN_DB_VERSION
Beispiel #4
0
 def __init__(self, args: argparse.Namespace) -> None:
     self.db = DBHandler(
         user_data_dir=default_data_directory() / args.user_name,
         password=args.user_password,
         msg_aggregator=MessagesAggregator(),
         initial_settings=None,
     )
Beispiel #5
0
    def unlock(self, username: str, password: str,
               create_new: bool) -> typing.FilePath:
        user_data_dir = cast(typing.FilePath,
                             os.path.join(self.data_directory, username))
        if create_new:
            if os.path.exists(user_data_dir):
                raise AuthenticationError(
                    'User {} already exists'.format(username))
            else:
                os.mkdir(user_data_dir)
        else:
            if not os.path.exists(user_data_dir):
                raise AuthenticationError(
                    'User {} does not exist'.format(username))

            if not os.path.exists(os.path.join(user_data_dir,
                                               'rotkehlchen.db')):
                # This is bad. User directory exists but database is missing.
                # Make a backup of the directory that user should probably remove
                # on his own. At the same time delete the directory so that a new
                # user account can be created
                shutil.move(
                    user_data_dir,
                    os.path.join(self.data_directory, 'backup_%s' % username))

                raise AuthenticationError(
                    'User {} exists but DB is missing. Somehow must have been manually '
                    'deleted or is corrupt. Please recreate the user account.'.
                    format(username))

        self.db: DBHandler = DBHandler(user_data_dir, username, password)
        self.user_data_dir = user_data_dir
        return user_data_dir
Beispiel #6
0
def _init_database(
    data_dir: FilePath,
    password: str,
    msg_aggregator: MessagesAggregator,
    db_settings: Optional[Dict[str, Any]],
    ignored_assets: Optional[List[Asset]],
    blockchain_accounts: BlockchainAccounts,
) -> DBHandler:
    db = DBHandler(data_dir, password, msg_aggregator)
    settings = {
        # DO not submit usage analytics during tests
        'submit_usage_analytics': False,
        'main_currency': DEFAULT_TESTS_MAIN_CURRENCY,
    }
    # Set the given db_settings. The pre-set values have priority unless overriden here
    if db_settings is not None:
        for key, value in db_settings.items():
            settings[key] = value
    db.set_settings(ModifiableDBSettings(**settings))

    if ignored_assets:
        for asset in ignored_assets:
            db.add_to_ignored_assets(asset)

    # Make sure that the fixture provided accounts are in the blockchain
    db.add_blockchain_accounts(SupportedBlockchain.ETHEREUM,
                               blockchain_accounts.eth)
    db.add_blockchain_accounts(SupportedBlockchain.BITCOIN,
                               blockchain_accounts.btc)

    return db
Beispiel #7
0
def test_add_remove_exchange(user_data_dir):
    """Tests that adding and removing an exchange in the DB works.

    Also unknown exchanges should fail
    """
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)

    # Test that an unknown exchange fails
    with pytest.raises(InputError):
        db.add_exchange('non_existing_exchange', 'api_key', 'api_secret')
    credentials = db.get_exchange_credentials()
    assert len(credentials) == 0

    kraken_api_key = ApiKey('kraken_api_key')
    kraken_api_secret = ApiSecret(b'kraken_api_secret')
    binance_api_key = ApiKey('binance_api_key')
    binance_api_secret = ApiSecret(b'binance_api_secret')

    # add mock kraken and binance
    db.add_exchange('kraken', kraken_api_key, kraken_api_secret)
    db.add_exchange('binance', binance_api_key, binance_api_secret)
    # and check the credentials can be retrieved
    credentials = db.get_exchange_credentials()
    assert len(credentials) == 2
    assert credentials['kraken'].api_key == kraken_api_key
    assert credentials['kraken'].api_secret == kraken_api_secret
    assert credentials['binance'].api_key == binance_api_key
    assert credentials['binance'].api_secret == binance_api_secret

    # remove an exchange and see it works
    db.remove_exchange('kraken')
    credentials = db.get_exchange_credentials()
    assert len(credentials) == 1
Beispiel #8
0
def test_add_remove_exchange(data_dir, username):
    """Tests that adding and removing an exchange in the DB works.

    Also unknown exchanges should fail
    """
    msg_aggregator = MessagesAggregator()
    username = '******'
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    db = DBHandler(userdata_dir, '123', msg_aggregator)

    # Test that an unknown exchange fails
    with pytest.raises(InputError):
        db.add_exchange('non_existing_exchange', 'api_key', 'api_secret')
    credentials = db.get_exchange_credentials()
    assert len(credentials) == 0

    # add mock kraken and binance
    db.add_exchange('kraken', 'kraken_api_key', 'kraken_api_secret')
    db.add_exchange('binance', 'binance_api_key', 'binance_api_secret')
    # and check the credentials can be retrieved
    credentials = db.get_exchange_credentials()
    assert len(credentials) == 2
    assert credentials['kraken'].api_key == b'kraken_api_key'
    assert credentials['kraken'].api_secret == b'kraken_api_secret'
    assert credentials['binance'].api_key == b'binance_api_key'
    assert credentials['binance'].api_secret == b'binance_api_secret'

    # remove an exchange and see it works
    db.remove_exchange('kraken')
    credentials = db.get_exchange_credentials()
    assert len(credentials) == 1
Beispiel #9
0
def _init_database(
    data_dir: Path,
    password: str,
    msg_aggregator: MessagesAggregator,
    db_settings: Optional[Dict[str, Any]],
    ignored_assets: Optional[List[Asset]],
    blockchain_accounts: BlockchainAccounts,
    include_etherscan_key: bool,
    include_cryptocompare_key: bool,
    tags: List[Dict[str, Any]],
    manually_tracked_balances: List[ManuallyTrackedBalance],
    data_migration_version: int,
    use_custom_database: Optional[str],
) -> DBHandler:
    if use_custom_database is not None:
        _use_prepared_db(data_dir, use_custom_database)

    db = DBHandler(
        user_data_dir=data_dir,
        password=password,
        msg_aggregator=msg_aggregator,
        initial_settings=None,
    )
    # Make sure that the fixture provided data are included in the DB
    add_settings_to_test_db(db, db_settings, ignored_assets,
                            data_migration_version)
    add_blockchain_accounts_to_db(db, blockchain_accounts)
    maybe_include_etherscan_key(db, include_etherscan_key)
    maybe_include_cryptocompare_key(db, include_cryptocompare_key)
    add_tags_to_test_db(db, tags)
    add_manually_tracked_balances_to_test_db(db, manually_tracked_balances)

    return db
Beispiel #10
0
 def __init__(self, args: argparse.Namespace) -> None:
     user_path = FilePath(
         os.path.join(str(default_data_directory()), args.user_name))
     self.db = DBHandler(
         user_data_dir=user_path,
         password=args.user_password,
         msg_aggregator=MessagesAggregator(),
     )
Beispiel #11
0
def trades_historian(accounting_data_dir, function_scope_messages_aggregator):
    database = DBHandler(accounting_data_dir, '123',
                         function_scope_messages_aggregator)
    historian = TradesHistorian(
        user_directory=accounting_data_dir,
        db=database,
        eth_accounts=[],
        msg_aggregator=function_scope_messages_aggregator,
    )
    return historian
Beispiel #12
0
def test_multiple_location_data_and_balances_same_timestamp(user_data_dir):
    """
    Test that adding location and balance data with same timestamp raises an error
    and no balance/location is added.
    Regression test for https://github.com/rotki/rotki/issues/1043
    """
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)

    balances = [
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_BTC,
            amount='1.0',
            usd_value='8500',
        ),
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_BTC,
            amount='1.1',
            usd_value='9100',
        ),
    ]
    with pytest.raises(InputError) as exc_info:
        db.add_multiple_balances(balances)
    assert 'Adding timed_balance failed.' in str(exc_info.value)
    assert exc_info.errisinstance(InputError)

    balances = db.query_timed_balances(from_ts=0,
                                       to_ts=1590676728,
                                       asset=A_BTC)
    assert len(balances) == 0

    locations = [
        LocationData(
            time=1590676728,
            location='H',
            usd_value='55',
        ),
        LocationData(
            time=1590676728,
            location='H',
            usd_value='56',
        ),
    ]
    with pytest.raises(InputError) as exc_info:
        db.add_multiple_location_data(locations)
    assert 'Tried to add a timed_location_data for' in str(exc_info.value)
    assert exc_info.errisinstance(InputError)

    locations = db.get_latest_location_value_distribution()
    assert len(locations) == 0
Beispiel #13
0
def trades_historian(data_dir, function_scope_messages_aggregator, blockchain):
    database = DBHandler(data_dir, '123', function_scope_messages_aggregator)
    exchange_manager = ExchangeManager(
        msg_aggregator=function_scope_messages_aggregator)
    historian = TradesHistorian(
        user_directory=data_dir,
        db=database,
        msg_aggregator=function_scope_messages_aggregator,
        exchange_manager=exchange_manager,
        chain_manager=blockchain,
    )
    return historian
Beispiel #14
0
def _init_db_with_target_version(
        target_version: int,
        user_data_dir: Path,
        msg_aggregator: MessagesAggregator,
) -> DBHandler:
    with target_patch(target_version=target_version):
        db = DBHandler(
            user_data_dir=user_data_dir,
            password='******',
            msg_aggregator=msg_aggregator,
            initial_settings=None,
        )
    return db
Beispiel #15
0
def test_timed_balances_primary_key_works(user_data_dir):
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)
    balances = [
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_BTC,
            amount='1.0',
            usd_value='8500',
        ),
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_BTC,
            amount='1.1',
            usd_value='9100',
        ),
    ]
    db.add_multiple_balances(balances)
    warnings = msg_aggregator.consume_warnings()
    errors = msg_aggregator.consume_errors()
    assert len(warnings) == 1
    assert len(errors) == 0
    balances = db.query_timed_balances(asset=A_BTC)
    assert len(balances) == 1

    balances = [
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_ETH,
            amount='1.0',
            usd_value='8500',
        ),
        DBAssetBalance(
            category=BalanceType.LIABILITY,
            time=1590676728,
            asset=A_ETH,
            amount='1.1',
            usd_value='9100',
        ),
    ]
    db.add_multiple_balances(balances)
    warnings = msg_aggregator.consume_warnings()
    errors = msg_aggregator.consume_errors()
    assert len(warnings) == 0
    assert len(errors) == 0
    balances = db.query_timed_balances(asset=A_ETH)
    assert len(balances) == 2
Beispiel #16
0
def test_fresh_db_adds_version(user_data_dir):
    """Test that the DB version gets committed to a fresh DB.

    Regression test for https://github.com/rotki/rotki/issues/3744"""
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)
    cursor = db.conn.cursor()
    query = cursor.execute(
        'SELECT value FROM settings WHERE name=?;',
        ('version', ),
    )
    query = query.fetchall()
    assert len(query) != 0
    assert int(query[0][0]) == ROTKEHLCHEN_DB_VERSION
Beispiel #17
0
def test_timed_balances_primary_key_works(user_data_dir):
    """
    Test that adding two timed_balances with the same primary key
    i.e (time, currency, category) fails.
    """
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)
    balances = [
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_BTC,
            amount='1.0',
            usd_value='8500',
        ),
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_BTC,
            amount='1.1',
            usd_value='9100',
        ),
    ]
    with pytest.raises(InputError) as exc_info:
        db.add_multiple_balances(balances)
    assert exc_info.errisinstance(InputError)
    assert 'Adding timed_balance failed' in str(exc_info.value)

    balances = db.query_timed_balances(asset=A_BTC)
    assert len(balances) == 0

    balances = [
        DBAssetBalance(
            category=BalanceType.ASSET,
            time=1590676728,
            asset=A_ETH,
            amount='1.0',
            usd_value='8500',
        ),
        DBAssetBalance(
            category=BalanceType.LIABILITY,
            time=1590676728,
            asset=A_ETH,
            amount='1.1',
            usd_value='9100',
        ),
    ]
    db.add_multiple_balances(balances)
    assert len(balances) == 2
Beispiel #18
0
def test_multiple_location_data_and_balances_same_timestamp(
        data_dir, username):
    """Test that adding location and balance data with same timestamp does not crash.

    Regression test for https://github.com/rotki/rotki/issues/1043
    """
    msg_aggregator = MessagesAggregator()
    username = '******'
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    db = DBHandler(userdata_dir, '123', msg_aggregator)

    balances = [
        AssetBalance(
            time=1590676728,
            asset=A_BTC,
            amount='1.0',
            usd_value='8500',
        ),
        AssetBalance(
            time=1590676728,
            asset=A_BTC,
            amount='1.1',
            usd_value='9100',
        ),
    ]
    db.add_multiple_balances(balances)
    balances = db.query_timed_balances(from_ts=0,
                                       to_ts=1590676728,
                                       asset=A_BTC)
    assert len(balances) == 1

    locations = [
        LocationData(
            time=1590676728,
            location='H',
            usd_value='55',
        ),
        LocationData(
            time=1590676728,
            location='H',
            usd_value='56',
        ),
    ]
    db.add_multiple_location_data(locations)
    locations = db.get_latest_location_value_distribution()
    assert len(locations) == 1
    assert locations[0].usd_value == '55'
Beispiel #19
0
def trades_historian(data_dir, function_scope_messages_aggregator, blockchain):
    database = DBHandler(
        user_data_dir=data_dir,
        password='******',
        msg_aggregator=function_scope_messages_aggregator,
        initial_settings=None,
    )
    exchange_manager = ExchangeManager(msg_aggregator=function_scope_messages_aggregator)
    historian = TradesHistorian(
        user_directory=data_dir,
        db=database,
        msg_aggregator=function_scope_messages_aggregator,
        exchange_manager=exchange_manager,
        chain_manager=blockchain,
    )
    return historian
Beispiel #20
0
def test_upgrade_broken_db_7_to_8(data_dir, username):
    """Test that if SAI is already in owned tokens upgrade fails"""
    msg_aggregator = MessagesAggregator()
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    dir_path = os.path.dirname(os.path.realpath(__file__))
    copyfile(
        os.path.join(os.path.dirname(dir_path), 'data',
                     'v7_rotkehlchen_broken.db'),
        os.path.join(userdata_dir, 'rotkehlchen.db'),
    )
    with pytest.raises(DBUpgradeError):
        with target_patch(target_version=8):
            DBHandler(user_data_dir=userdata_dir,
                      password='******',
                      msg_aggregator=msg_aggregator)
Beispiel #21
0
def temp_etherscan(database, inquirer, function_scope_messages_aggregator,
                   tmpdir_factory):
    api_key = os.environ.get('ETHERSCAN_API_KEY', None)
    if not api_key:
        pytest.fail('No ETHERSCAN_API_KEY environment variable found.')
    directory = tmpdir_factory.mktemp('data')
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir=directory,
                   password='******',
                   msg_aggregator=msg_aggregator)
    db.add_external_service_credentials(credentials=[
        ExternalServiceApiCredentials(service=ExternalService.ETHERSCAN,
                                      api_key=api_key),
    ])
    etherscan = Etherscan(database=db, msg_aggregator=msg_aggregator)
    return etherscan
Beispiel #22
0
def temp_etherscan(function_scope_messages_aggregator, tmpdir_factory):
    directory = tmpdir_factory.mktemp('data')
    db = DBHandler(
        user_data_dir=directory,
        password='******',
        msg_aggregator=function_scope_messages_aggregator,
    )

    # Test with etherscan API key
    api_key = os.environ.get('ETHERSCAN_API_KEY', None)
    if api_key:
        db.add_external_service_credentials(credentials=[
            ExternalServiceApiCredentials(service=ExternalService.ETHERSCAN, api_key=api_key),
        ])
    etherscan = Etherscan(database=db, msg_aggregator=function_scope_messages_aggregator)
    return etherscan
Beispiel #23
0
def test_binance_pairs(user_data_dir):
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)

    binance_api_key = ApiKey('binance_api_key')
    binance_api_secret = ApiSecret(b'binance_api_secret')
    db.add_exchange('binance', Location.BINANCE, binance_api_key,
                    binance_api_secret)

    db.set_binance_pairs('binance', ['ETHUSDC', 'ETHBTC', 'BNBBTC'],
                         Location.BINANCE)
    query = db.get_binance_pairs('binance', Location.BINANCE)
    assert query == ['ETHUSDC', 'ETHBTC', 'BNBBTC']

    db.set_binance_pairs('binance', [], Location.BINANCE)
    query = db.get_binance_pairs('binance', Location.BINANCE)
    assert query == []
Beispiel #24
0
def _init_database(
    data_dir: FilePath,
    password: str,
    msg_aggregator: MessagesAggregator,
    db_settings: Optional[Dict[str, Any]],
    ignored_assets: Optional[List[Asset]],
    blockchain_accounts: BlockchainAccounts,
    include_etherscan_key: bool,
) -> DBHandler:
    db = DBHandler(data_dir, password, msg_aggregator)
    settings = {
        # DO not submit usage analytics during tests
        'submit_usage_analytics': False,
        'main_currency': DEFAULT_TESTS_MAIN_CURRENCY,
    }
    # Set the given db_settings. The pre-set values have priority unless overriden here
    if db_settings is not None:
        for key, value in db_settings.items():
            settings[key] = value
    db.set_settings(ModifiableDBSettings(**settings))

    if ignored_assets:
        for asset in ignored_assets:
            db.add_to_ignored_assets(asset)

    # Make sure that the fixture provided accounts are in the blockchain
    db.add_blockchain_accounts(
        SupportedBlockchain.ETHEREUM,
        [BlockchainAccountData(address=x) for x in blockchain_accounts.eth],
    )
    db.add_blockchain_accounts(
        SupportedBlockchain.BITCOIN,
        [BlockchainAccountData(address=x) for x in blockchain_accounts.btc],
    )
    if include_etherscan_key:
        # Add the tests only etherscan API key
        db.add_external_service_credentials([
            ExternalServiceApiCredentials(
                service=ExternalService.ETHERSCAN,
                api_key=ApiKey('8JT7WQBB2VQP5C3416Y8X3S8GBA3CVZKP4'),
            )
        ])

    return db
    def unlock(
        self,
        username: str,
        password: str,
        create_new: bool,
    ) -> FilePath:
        user_data_dir = FilePath(os.path.join(self.data_directory, username))
        if create_new:
            if os.path.exists(user_data_dir):
                raise AuthenticationError(
                    'User {} already exists'.format(username))
            else:
                os.mkdir(user_data_dir)
        else:
            if not os.path.exists(user_data_dir):
                raise AuthenticationError(
                    'User {} does not exist'.format(username))

            if not os.path.exists(os.path.join(user_data_dir,
                                               'rotkehlchen.db')):
                # This is bad. User directory exists but database is missing.
                # Make a backup of the directory that user should probably remove
                # on their own. At the same time delete the directory so that a new
                # user account can be created
                shutil.move(
                    user_data_dir,
                    os.path.join(
                        self.data_directory,
                        f'auto_backup_{username}_{ts_now()}',
                    ),
                )

                raise AuthenticationError(
                    'User {} exists but DB is missing. Somehow must have been manually '
                    'deleted or is corrupt. Please recreate the user account. '
                    'A backup of the user directory was created.'.format(
                        username))

        self.db: DBHandler = DBHandler(user_data_dir, password,
                                       self.msg_aggregator)
        self.user_data_dir = user_data_dir
        self.logged_in = True
        self.username = username
        return user_data_dir
Beispiel #26
0
def test_upgrade_sqlcipher_v3_to_v4_without_dbinfo(user_data_dir):
    """Test that we can upgrade from an sqlcipher v3 to v4 rotkehlchen database
    Issue: https://github.com/rotki/rotki/issues/229
    """
    sqlcipher_version = detect_sqlcipher_version()
    if sqlcipher_version != 4:
        # nothing to test
        return

    # get the v3 database file and copy it into the user's data directory
    dir_path = os.path.dirname(os.path.realpath(__file__))
    copyfile(
        os.path.join(os.path.dirname(dir_path), 'data', 'sqlcipher_v3_rotkehlchen.db'),
        user_data_dir / 'rotkehlchen.db',
    )

    # the constructor should migrate it in-place and we should have a working DB
    msg_aggregator = MessagesAggregator()
    db = DBHandler(user_data_dir, '123', msg_aggregator, None)
    assert db.get_version() == ROTKEHLCHEN_DB_VERSION
Beispiel #27
0
def _init_database(
        data_dir: FilePath,
        password: str,
        msg_aggregator: MessagesAggregator,
        db_settings: Optional[Dict[str, Any]],
        ignored_assets: Optional[List[Asset]],
        blockchain_accounts: BlockchainAccounts,
        include_etherscan_key: bool,
        include_cryptocompare_key: bool,
        tags: List[Dict[str, Any]],
        manually_tracked_balances: List[ManuallyTrackedBalance],
) -> DBHandler:
    db = DBHandler(data_dir, password, msg_aggregator)
    # Make sure that the fixture provided data are included in the DB
    add_settings_to_test_db(db, db_settings, ignored_assets)
    add_blockchain_accounts_to_db(db, blockchain_accounts)
    maybe_include_etherscan_key(db, include_etherscan_key)
    maybe_include_cryptocompare_key(db, include_cryptocompare_key)
    add_tags_to_test_db(db, tags)
    add_manually_tracked_balances_to_test_db(db, manually_tracked_balances)

    return db
Beispiel #28
0
def test_upgrade_sqlcipher_v3_to_v4_without_dbinfo(data_dir):
    """Test that we can upgrade from an sqlcipher v3 to v4 rotkehlchen database
    Issue: https://github.com/rotkehlchenio/rotkehlchen/issues/229
    """
    sqlcipher_version = detect_sqlcipher_version()
    if sqlcipher_version != 4:
        # nothing to test
        return

    username = '******'
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    # get the v3 database file and copy it into the user's data directory
    dir_path = os.path.dirname(os.path.realpath(__file__))
    copyfile(
        os.path.join(dir_path, 'data', 'sqlcipher_v3_rotkehlchen.db'),
        os.path.join(userdata_dir, 'rotkehlchen.db'),
    )

    # the constructor should migrate it in-place and we should have a working DB
    db = DBHandler(userdata_dir, '123')
    assert db.get_version() == ROTKEHLCHEN_DB_VERSION
Beispiel #29
0
def test_upgrade_db_8_to_9(data_dir, username):
    """Test upgrading the DB from version 8 to version 9.

    Adding the passphrase column to user credentials"""
    msg_aggregator = MessagesAggregator()
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    dir_path = os.path.dirname(os.path.realpath(__file__))
    copyfile(
        os.path.join(os.path.dirname(dir_path), 'data', 'v8_rotkehlchen.db'),
        os.path.join(userdata_dir, 'rotkehlchen.db'),
    )

    with target_patch(target_version=9):
        db = DBHandler(user_data_dir=userdata_dir,
                       password='******',
                       msg_aggregator=msg_aggregator)

    cursor = db.conn.cursor()
    results = cursor.execute(
        'SELECT name, api_key, api_secret, passphrase FROM user_credentials;',
    )
    names = {
        'coinbase', 'coinbasepro', 'binance', 'bittrex', 'kraken', 'bitmex'
    }
    for result in results:
        assert result[0] in names
        names.remove(result[0])
        assert result[1] == '9f07a6f548f3d0ddb68fb406353063ba'  # api key
        assert result[2] == (
            'auIO4FWI3HmL1AnhYaNoK0vr4tTaZyAU3/TI9M46V9IeeCPTxyWV'
            '3JCVzHmcVV9+n+v4TbsIyRndaL9XbFkCuQ==')  # api secret
        assert result[3] is None  # passphrase

    assert len(names) == 0, 'not all exchanges were found in the new DB'
    # Finally also make sure that we have updated to the target version
    assert db.get_version() == 9
Beispiel #30
0
def test_upgrade_db_9_to_10(data_dir, username):
    """Test upgrading the DB from version 9 to version 10.

    Deleting all entries from used_query_ranges"""
    msg_aggregator = MessagesAggregator()
    userdata_dir = os.path.join(data_dir, username)
    os.mkdir(userdata_dir)
    dir_path = os.path.dirname(os.path.realpath(__file__))
    copyfile(
        os.path.join(os.path.dirname(dir_path), 'data', 'v9_rotkehlchen.db'),
        os.path.join(userdata_dir, 'rotkehlchen.db'),
    )

    with target_patch(target_version=10):
        db = DBHandler(user_data_dir=userdata_dir,
                       password='******',
                       msg_aggregator=msg_aggregator)

    cursor = db.conn.cursor()
    results = cursor.execute(
        'SELECT name, start_ts, end_ts FROM used_query_ranges;', )
    assert len(results.fetchall()) == 0
    # Finally also make sure that we have updated to the target version
    assert db.get_version() == 10