Ejemplo n.º 1
0
def _upgrade_trades_table(db: 'DBHandler') -> None:
    """Upgrade the trades for DAI->SAI renaming"""
    cursor = db.conn.cursor()
    # This is the data we need from trades table at v6
    cursor.execute(
        'SELECT id,'
        '  time,'
        '  location,'
        '  pair,'
        '  type,'
        '  amount,'
        '  rate,'
        '  fee,'
        '  fee_currency,'
        '  link,'
        '  notes FROM trades;', )

    trades_to_edit = []
    trades_to_delete = []
    count = 0
    for result in cursor:
        count += 1
        # for each trade get all the relevant data
        old_trade_id = result[0]
        time = int(result[1])
        db_location = result[2]
        pair = result[3]
        db_trade_type = result[4]
        amount = result[5]
        rate = result[6]
        fee = result[7]
        fee_currency = result[8]
        link = result[9]
        notes = result[10]

        should_edit_trade = (time < MCDAI_LAUNCH_TS
                             and ('DAI' in pair or fee_currency == 'DAI'))

        if should_edit_trade:
            # Mark old trade for deletion
            trades_to_delete.append((old_trade_id, ))
            # Generate data for new trade
            location = v6_deserialize_location_from_db(db_location)
            trade_type = v6_deserialize_trade_type_from_db(db_trade_type)
            pair = pair.replace('DAI_', 'SAI_')
            pair = pair.replace('_DAI', '_SAI')
            if fee_currency == 'DAI':
                fee_currency = 'SAI'

            new_trade_id = v6_generate_trade_id(
                location=location,
                time=time,
                trade_type=trade_type,
                pair=pair,
                amount=amount,
                rate=rate,
                link=link,
            )
            trades_to_edit.append((
                new_trade_id,
                time,
                db_location,
                pair,
                db_trade_type,
                amount,
                rate,
                fee,
                fee_currency,
                link,
                notes,
            ))

    # and now delete all old trades
    cursor.executemany('DELETE FROM trades WHERE id = ?', trades_to_delete)
    # and add all newly edited trades back in the DB
    query = """
    INSERT INTO trades(
          id,
          time,
          location,
          pair,
          type,
          amount,
          rate,
          fee,
          fee_currency,
          link,
          notes)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    """
    cursor.executemany(query, trades_to_edit)
    db.conn.commit()
Ejemplo n.º 2
0
def test_upgrade_db_7_to_8(user_data_dir):
    """Test upgrading the DB from version 7 to version 8.

    Test that the SAI to DAI upgrade and renaming is done succesfully.
    """
    msg_aggregator = MessagesAggregator()
    _use_prepared_db(user_data_dir, 'v7_rotkehlchen.db')
    db = _init_db_with_target_version(
        target_version=8,
        user_data_dir=user_data_dir,
        msg_aggregator=msg_aggregator,
    )
    cursor = db.conn.cursor()

    # Check that trades got upgraded properly
    query = (
        'SELECT id,'
        '  time,'
        '  location,'
        '  pair,'
        '  type,'
        '  amount,'
        '  rate,'
        '  fee,'
        '  fee_currency,'
        '  link,'
        '  notes FROM trades ORDER BY time ASC;'
    )

    results = cursor.execute(query)
    count = 0
    for result in results:
        count += 1
        trade_id = result[0]
        time = int(result[1])
        location = result[2]
        pair = result[3]
        trade_type = result[4]
        amount = result[5]
        rate = result[6]
        fee_currency = result[8]
        link = result[9]

        # External trades, kraken trades
        if location in ('A', 'B'):
            if time < MCDAI_LAUNCH_TS:
                assert pair == 'SAI_EUR'
                assert fee_currency == 'EUR'
            else:
                assert pair == 'DAI_EUR'
                assert fee_currency == 'EUR'
        # coinbase trades
        elif location == 'G':
            if time < MCDAI_LAUNCH_TS:
                assert pair == 'SAI_USD'
                assert fee_currency == 'USD'
            else:
                assert pair == 'DAI_USD'
                assert fee_currency == 'USD'
        # bittrex trades
        elif location == 'D':
            if time < MCDAI_LAUNCH_TS:
                assert pair == 'SAI_BTC'
                assert fee_currency == 'SAI'
            else:
                assert pair == 'DAI_BTC'
                assert fee_currency == 'DAI'
        else:
            raise AssertionError('Unexpected location data')

        # also make sure the ids still match
        serialized_location = v6_deserialize_location_from_db(location)
        serialized_trade_type = v6_deserialize_trade_type_from_db(trade_type)
        expected_trade_id = v6_generate_trade_id(
            location=serialized_location,
            time=time,
            trade_type=serialized_trade_type,
            pair=pair,
            amount=amount,
            rate=rate,
            link=link,
        )
        assert trade_id == expected_trade_id

    assert count == 8, '8 trades should have been found'

    # Check that deposits/withdrawals got upgraded properly
    query = (
        'SELECT id,'
        '  location,'
        '  category,'
        '  time,'
        '  asset,'
        '  amount,'
        '  fee_asset,'
        '  fee,'
        '  link FROM asset_movements '
    )
    results = cursor.execute(query)
    count = 0
    for result in results:
        count += 1
        entry_id = result[0]
        location = result[1]
        category = result[2]
        time = result[3]
        asset = result[4]
        fee_asset = result[6]
        link = result[8]

        # kraken , bittrex, coinbase
        assert location in ('B', 'D', 'G'), 'Unexpected location of asset movement'
        if time < MCDAI_LAUNCH_TS:
            assert asset == 'SAI'
            assert fee_asset == 'SAI'
        else:
            assert asset == 'DAI'
            assert fee_asset == 'DAI'

        deserialized_location = v6_deserialize_location_from_db(location)
        deserialized_category = v7_deserialize_asset_movement_category(category)
        expected_id = v7_generate_asset_movement_id(
            location=deserialized_location,
            category=deserialized_category,
            time=time,
            asset=asset,
            fee_asset=fee_asset,
            link=link,
        )
        assert expected_id == entry_id

    assert count == 12, '12 asset movements should have been found'

    # Check that both SAI and DAI are included in the ETH tokens owned
    query = cursor.execute(
        'SELECT value FROM multisettings WHERE name="eth_token";',
    )
    assert [q[0] for q in query.fetchall()] == ['DAI', 'SAI']

    # Check that saved balances of DAI are upgraded to SAI if before the upgrade time
    query = cursor.execute('SELECT time, currency, amount, usd_value FROM timed_balances;')
    count = 0
    for result in query:
        count += 1
        time = int(result[0])
        asset = result[1]

        if time < MCDAI_LAUNCH_TS:
            assert asset == 'SAI'
        else:
            assert asset == 'DAI'

    assert count == 2, '2 saved balances should have been found'

    # Finally also make sure that we have updated to the target version
    assert db.get_version() == 8