コード例 #1
0
def deserialize_transaction_from_etherscan(
        data: Dict[str, Any],
        internal: bool,
) -> EthereumTransaction:
    """Reads dict data of a transaction from etherscan and deserializes it

    Can raise DeserializationError if something is wrong
    """
    try:
        # internal tx list contains no gasprice
        gas_price = -1 if internal else read_integer(data, 'gasPrice')
        tx_hash = read_hash(data, 'hash')
        input_data = read_hash(data, 'input')
        timestamp = deserialize_timestamp(data['timeStamp'])

        block_number = read_integer(data, 'blockNumber')
        nonce = -1 if internal else read_integer(data, 'nonce')

        return EthereumTransaction(
            timestamp=timestamp,
            block_number=block_number,
            tx_hash=tx_hash,
            from_address=to_checksum_address(data['from']),
            to_address=to_checksum_address(data['to']) if data['to'] != '' else None,
            value=read_integer(data, 'value'),
            gas=read_integer(data, 'gas'),
            gas_price=gas_price,
            gas_used=read_integer(data, 'gasUsed'),
            input_data=input_data,
            nonce=nonce,
        )
    except KeyError as e:
        raise DeserializationError(f'Etherscan ethereum transaction missing expected key {str(e)}')
コード例 #2
0
def test_purge_ethereum_transaction_data(rotkehlchen_api_server):
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    db = rotki.data.db
    db.add_ethereum_transactions(
        [EthereumTransaction(
            tx_hash=bytes(),
            timestamp=1,
            block_number=1,
            from_address=make_ethereum_address(),
            to_address=make_ethereum_address(),
            value=FVal(1),
            gas=FVal(1),
            gas_price=FVal(1),
            gas_used=FVal(1),
            input_data=bytes(),
            nonce=1,
        )],
        from_etherscan=True,
    )
    assert len(db.get_ethereum_transactions()) == 1
    response = requests.delete(
        api_url_for(
            rotkehlchen_api_server,
            "ethereumtransactionsresource",
        ),
    )
    assert_simple_ok_response(response)
    assert len(db.get_ethereum_transactions()) == 0
コード例 #3
0
ファイル: test_ethereum_manager.py プロジェクト: rotki/rotki
def test_get_transaction_by_hash(ethereum_manager, call_order,
                                 ethereum_manager_connect_at_start):
    wait_until_all_nodes_connected(
        ethereum_manager_connect_at_start=ethereum_manager_connect_at_start,
        ethereum=ethereum_manager,
    )
    result = ethereum_manager.get_transaction_by_hash(
        '0x5b180e3dcc19cd29c918b98c876f19393e07b74c07fd728102eb6241db3c2d5c',
        call_order=call_order,
    )
    expected_tx = EthereumTransaction(
        tx_hash=
        b'[\x18\x0e=\xcc\x19\xcd)\xc9\x18\xb9\x8c\x87o\x199>\x07\xb7L\x07\xfdr\x81\x02\xebbA\xdb<-\\',  # noqa: E501
        timestamp=1633128954,
        block_number=13336285,
        from_address='0x2F6789A208A05C762cA8d142A3df95d29C18b065',
        to_address='0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b',
        value=33000000000000000,
        gas=294144,
        gas_price=66936353558,
        gas_used=218523,
        input_data=
        b"\xab\x83K\xab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\xe8\x07oN\xa4\xa4\xad\x08\x07\\%\x08\xe4\x81\xd6\xc9F\xd1+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/g\x89\xa2\x08\xa0\\v,\xa8\xd1B\xa3\xdf\x95\xd2\x9c\x18\xb0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x8d\xfa\x06\xdfX\x9a\x1e\x19W9\x1b\x86.\x02\xf7\x17X$\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I_\x94rvt\x9c\xe6F\xf6\x8a\xc8\xc2HB\x00E\xcb{^\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\xe8\x07oN\xa4\xa4\xad\x08\x07\\%\x08\xe4\x81\xd6\xc9F\xd1+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x8d\xfa\x06\xdfX\x9a\x1e\x19W9\x1b\x86.\x02\xf7\x17X$\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[2V\x96^|<\xf2n\x11\xfc\xaf)m\xfc\x88\x07\xc0\x10s\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I_\x94rvt\x9c\xe6F\xf6\x8a\xc8\xc2HB\x00E\xcb{^\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xe2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u=S=\x96\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00aW\x91\x84\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x96\x18\xf8\xa6p,\x86\xbd?\xcf\x83\x8c3\xd3 \x89\x9f1\xffaX\x1a\r|\xa0\xcb\x12\xad\xbeY\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xe2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u=S=\x96\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00aU\xa9E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bDI$\x9d\xc420bKZ\xb5v\x96\xf6\xef\xa0hg\x993\x00\x07y\x07]\x83\xc6\xd2I\x1c\x87\x19\x13\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x02\xe0\x9f\xaa\xce\x1aZ\xaf\\'\xb7&\x99l\x10\xe7u4\x11\xc6V\x17\xb3\xb5)z\xd5\x04/7\xd8\x04\x07y\xb1\xa8\xfe\x0c\x1c\xa5\xc9\xc4{e\x07\xa2:\xee\x0f\xb3&\xcf_3[{\xcc\x13]~o\xe9\xd1\xd8\x02\xe0\x9f\xaa\xce\x1aZ\xaf\\'\xb7&\x99l\x10\xe7u4\x11\xc6V\x17\xb3\xb5)z\xd5\x04/7\xd8\x04\x07y\xb1\xa8\xfe\x0c\x1c\xa5\xc9\xc4{e\x07\xa2:\xee\x0f\xb3&\xcf_3[{\xcc\x13]~o\xe9\xd1\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\xf2BC*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/g\x89\xa2\x08\xa0\\v,\xa8\xd1B\xa3\xdf\x95\xd2\x9c\x18\xb0ep\x8d\xfa\x06\xdfX\x9a\x1e\x19W9\x1b\x86.\x02\xf7\x17X$\xe9\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\xf2BC*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x8d\xfa\x06\xdfX\x9a\x1e\x19W9\x1b\x86.\x02\xf7\x17X$\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x8d\xfa\x06\xdfX\x9a\x1e\x19W9\x1b\x86.\x02\xf7\x17X$\xe9\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",  # noqa: E501
        nonce=204,
    )
    assert result == expected_tx
コード例 #4
0
def test_purge_ethereum_transaction_data(rotkehlchen_api_server):
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    db = DBEthTx(rotki.data.db)
    db.add_ethereum_transactions([
        EthereumTransaction(
            tx_hash=bytes(),
            timestamp=1,
            block_number=1,
            from_address=make_ethereum_address(),
            to_address=make_ethereum_address(),
            value=FVal(1),
            gas=FVal(1),
            gas_price=FVal(1),
            gas_used=FVal(1),
            input_data=bytes(),
            nonce=1,
        )
    ], )
    filter_ = ETHTransactionsFilterQuery.make()

    result, filter_count = db.get_ethereum_transactions(filter_)
    assert len(result) == 1
    assert filter_count == 1
    response = requests.delete(
        api_url_for(
            rotkehlchen_api_server,
            "ethereumtransactionsresource",
        ), )
    assert_simple_ok_response(response)
    result, filter_count = db.get_ethereum_transactions(filter_)
    assert len(result) == 0
    assert filter_count == 0
コード例 #5
0
ファイル: transactions.py プロジェクト: pikvik/rotkehlchen
def transactions_from_dictlist(
    given_transactions: Dict,
    start_ts: Timestamp,
    end_ts: Timestamp,
) -> List[EthereumTransaction]:
    """ Gets a list of transaction, most probably read from the json files and
    a time period. Returns it as a list of the transaction tuples that are inside the time period
    """
    returned_transactions = list()
    for given_tx in given_transactions:
        if given_tx['timestamp'] < start_ts:
            continue
        if given_tx['timestamp'] > end_ts:
            break

        returned_transactions.append(
            EthereumTransaction(
                timestamp=convert_to_int(given_tx['timestamp']),
                block_number=convert_to_int(given_tx['block_number']),
                hash=given_tx['hash'],
                from_address=given_tx['from_address'],
                to_address=given_tx['to_address'],
                value=FVal(given_tx['value']),
                gas=FVal(given_tx['gas']),
                gas_price=FVal(given_tx['gas_price']),
                gas_used=FVal(given_tx['gas_used']),
            ))

    return returned_transactions
コード例 #6
0
ファイル: deserialize.py プロジェクト: rotki/rotki
def deserialize_ethereum_transaction(
    data: Dict[str, Any],
    ethereum: Optional['EthereumManager'] = None,
) -> EthereumTransaction:
    """Reads dict data of a transaction and deserializes it.
    If the transaction is not from etherscan then it's missing some data
    so ethereum manager is used to fetch it.

    Can raise DeserializationError if something is wrong
    """
    source = 'etherscan' if ethereum is None else 'web3'
    try:
        gas_price = read_integer(data=data, key='gasPrice', api=source)
        tx_hash = read_hash(data=data, key='hash', api=source)

        input_data = read_hash(data, 'input', source)
        block_number = read_integer(data, 'blockNumber', source)
        if 'timeStamp' not in data:
            if ethereum is None:
                raise DeserializationError(
                    'Got in deserialize ethereum transaction without timestamp and without ethereum manager'
                )  # noqa: E501

            block_data = ethereum.get_block_by_number(block_number)
            timestamp = Timestamp(read_integer(block_data, 'timestamp',
                                               source))
        else:
            timestamp = deserialize_timestamp(data['timeStamp'])

        if 'gasUsed' not in data:
            if ethereum is None:
                raise DeserializationError(
                    'Got in deserialize ethereum transaction without gasUsed and without ethereum manager'
                )  # noqa: E501
            receipt_data = ethereum.get_transaction_receipt(data['hash'])
            gas_used = read_integer(receipt_data, 'gasUsed', source)
        else:
            gas_used = read_integer(data, 'gasUsed', source)

        nonce = read_integer(data, 'nonce', source)
        return EthereumTransaction(
            timestamp=timestamp,
            block_number=block_number,
            tx_hash=tx_hash,
            from_address=deserialize_ethereum_address(data['from']),
            to_address=deserialize_ethereum_address(data['to'])
            if data['to'] != '' else None,
            value=read_integer(data, 'value', source),
            gas=read_integer(data, 'gas', source),
            gas_price=gas_price,
            gas_used=gas_used,
            input_data=input_data,
            nonce=nonce,
        )
    except KeyError as e:
        raise DeserializationError(
            f'ethereum transaction from {source} missing expected key {str(e)}',
        ) from e
コード例 #7
0
    def get_ethereum_transactions(
            self,
            filter_: ETHTransactionsFilterQuery,
    ) -> Tuple[List[EthereumTransaction], int]:
        """Returns a tuple with 2 entries.
        First entry is a list of ethereum transactions optionally filtered by
        time and/or from address and pagination.
        Second is the number of entries found for the current filter ignoring pagination.

        This function can raise:
        - pysqlcipher3.dbapi2.OperationalError if the SQL query fails due to invalid
        filtering arguments.
        """
        cursor = self.db.conn.cursor()
        query, bindings = filter_.prepare()
        query = 'SELECT * FROM ethereum_transactions ' + query
        results = cursor.execute(query, bindings)

        ethereum_transactions = []
        for result in results:
            try:
                tx = EthereumTransaction(
                    tx_hash=result[0],
                    timestamp=deserialize_timestamp(result[1]),
                    block_number=result[2],
                    from_address=result[3],
                    to_address=result[4],
                    value=int(result[5]),
                    gas=int(result[6]),
                    gas_price=int(result[7]),
                    gas_used=int(result[8]),
                    input_data=result[9],
                    nonce=result[10],
                )
            except DeserializationError as e:
                self.db.msg_aggregator.add_error(
                    f'Error deserializing ethereum transaction from the DB. '
                    f'Skipping it. Error was: {str(e)}',
                )
                continue

            ethereum_transactions.append(tx)

        if filter_.pagination is not None:
            no_pagination_filter = deepcopy(filter_)
            no_pagination_filter.pagination = None
            query, bindings = no_pagination_filter.prepare()
            query = 'SELECT COUNT(*) FROM ethereum_transactions ' + query
            results = cursor.execute(query, bindings).fetchone()
            total_filter_count = results[0]
        else:
            total_filter_count = len(ethereum_transactions)

        return ethereum_transactions, total_filter_count
コード例 #8
0
def transactions_from_dictlist(
    given_transactions: List[Dict[str, Any]],
    start_ts: Timestamp,
    end_ts: Timestamp,
) -> List[EthereumTransaction]:
    """ Gets a list of transaction, most probably read from the json files and
    a time period. Returns it as a list of the transaction tuples that are inside the time period

    May raise:
        - KeyError: If the given_transactions contain data in an unexpected format
    """
    returned_transactions = list()
    for given_tx in given_transactions:
        if given_tx['timestamp'] < start_ts:
            continue
        if given_tx['timestamp'] > end_ts:
            break

        timestamp = Timestamp(convert_to_int(given_tx['timestamp']))
        tx_hash = given_tx['hash']
        from_address = given_tx['from_address']
        to_address = given_tx['to_address']
        value = FVal(given_tx['value'])
        gas = FVal(given_tx['gas'])
        gas_price = FVal(given_tx['gas_price'])
        gas_used = FVal(given_tx['gas_used'])
        log.debug(
            'Processing eth transaction',
            sensitive_log=True,
            timestamp=timestamp,
            eth_tx_hash=tx_hash,
            from_eth_address=from_address,
            to_eth_address=to_address,
            tx_value=value,
            gas=gas,
            gas_price=gas_price,
            gas_used=gas_used,
        )

        returned_transactions.append(
            EthereumTransaction(
                timestamp=timestamp,
                block_number=convert_to_int(given_tx['block_number']),
                hash=tx_hash,
                from_address=from_address,
                to_address=to_address,
                value=value,
                gas=gas,
                gas_price=gas_price,
                gas_used=gas_used,
            ))

    return returned_transactions
コード例 #9
0
def test_not_include_gas_costs(accountant):
    """
    Added ignored assets here only to have a test for
    https://github.com/rotki/rotki/issues/399
    """
    history = [{
        'timestamp': 1476979735,
        'base_asset': 'BTC',
        'quote_asset': 'EUR',
        'trade_type': 'buy',
        'rate': 578.505,
        'fee': 0.0012,
        'fee_currency': 'BTC',
        'amount': 5,
        'location': 'kraken',
    }, {
        'timestamp': 1496979735,
        'base_asset': 'BTC',
        'quote_asset': 'EUR',
        'trade_type': 'sell',
        'rate': 2519.62,
        'fee': 0.02,
        'fee_currency': 'EUR',
        'amount': 1,
        'location': 'kraken',
    }]
    eth_tx_list = [
        EthereumTransaction(
            timestamp=1491062063,  # 01/04/2017
            block_number=3458409,
            tx_hash=DUMMY_HASH,
            from_address=DUMMY_ADDRESS,
            to_address=DUMMY_ADDRESS,
            value=FVal('12323'),
            gas=FVal('5000000'),
            gas_price=FVal('2000000000'),
            gas_used=FVal('1000000'),
            input_data=DUMMY_HASH,
            nonce=0,
        ),
    ]
    result = accounting_history_process(
        accountant,
        1436979735,
        1519693374,
        history,
        eth_transaction_list=eth_tx_list,
    )
    assert FVal(result['overview']['total_taxable_profit_loss']).is_close(
        '1940.9561588')
コード例 #10
0
ファイル: transactions.py プロジェクト: pikvik/rotkehlchen
def query_ethereum_txlist(
    address: EthAddress,
    internal: bool,
    from_block: int = None,
    to_block: int = None,
) -> List[EthereumTransaction]:
    result = list()
    if internal:
        reqstring = ('https://api.etherscan.io/api?module=account&action='
                     'txlistinternal&address={}'.format(address))
    else:
        reqstring = ('https://api.etherscan.io/api?module=account&action='
                     'txlist&address={}'.format(address))
    if from_block:
        reqstring += '&startblock={}'.format(from_block)
    if to_block:
        reqstring += '&endblock={}'.format(to_block)

    resp = request_get(reqstring)

    if 'status' not in resp or convert_to_int(resp['status']) != 1:
        status = convert_to_int(resp['status'])
        if status == 0 and resp['message'] == 'No transactions found':
            return list()

        # else unknown error
        raise ValueError(
            'Failed to query txlist from etherscan with query: {} . '
            'Response was: {}'.format(reqstring, resp))

    for v in resp['result']:
        # internal tx list contains no gasprice
        gas_price = FVal(-1) if internal else FVal(v['gasPrice'])
        result.append(
            EthereumTransaction(
                timestamp=convert_to_int(v['timeStamp']),
                block_number=convert_to_int(v['blockNumber']),
                hash=v['hash'],
                from_address=v['from'],
                to_address=v['to'],
                value=FVal(v['value']),
                gas=FVal(v['gas']),
                gas_price=gas_price,
                gas_used=FVal(v['gasUsed']),
            ))

    return result
コード例 #11
0
def test_deserialize_transaction_from_etherscan():
    # Make sure that a missing to address due to contract creation is handled
    data = {'blockNumber': 54092, 'timeStamp': 1439048640, 'hash': '0x9c81f44c29ff0226f835cd0a8a2f2a7eca6db52a711f8211b566fd15d3e0e8d4', 'nonce': 0, 'blockHash': '0xd3cabad6adab0b52ea632c386ea19403680571e682c62cb589b5abcd76de2159', 'transactionIndex': 0, 'from': '0x5153493bB1E1642A63A098A65dD3913daBB6AE24', 'to': '', 'value': 11901464239480000000000000, 'gas': 2000000, 'gasPrice': 10000000000000, 'isError': 0, 'txreceipt_status': '', 'input': '0x313233', 'contractAddress': '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae', 'cumulativeGasUsed': 1436963, 'gasUsed': 1436963, 'confirmations': 8569454}  # noqa: E501
    transaction = deserialize_transaction_from_etherscan(data, internal=False)
    assert transaction == EthereumTransaction(
        tx_hash=bytes.fromhex(data['hash'][2:]),
        timestamp=1439048640,
        block_number=54092,
        from_address='0x5153493bB1E1642A63A098A65dD3913daBB6AE24',
        to_address=None,
        value=11901464239480000000000000,
        gas=2000000,
        gas_price=10000000000000,
        gas_used=1436963,
        input_data=bytes.fromhex(data['input'][2:]),
        nonce=0,
    )
コード例 #12
0
def test_query_transactions_from_to_address(
    rotkehlchen_api_server,
    ethereum_accounts,
):
    """Make sure that if a transaction is just being sent to an address it's also returned."""
    start_ts = 0
    end_ts = 1598453214
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    db = rotki.data.db
    transactions = [
        EthereumTransaction(
            tx_hash=b'1',
            timestamp=0,
            block_number=0,
            from_address=ethereum_accounts[0],
            to_address=make_ethereum_address(),
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=0,
        ),
        EthereumTransaction(
            tx_hash=b'2',
            timestamp=0,
            block_number=0,
            from_address=ethereum_accounts[0],
            to_address=ethereum_accounts[1],
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=1,
        ),
        EthereumTransaction(
            tx_hash=b'3',
            timestamp=0,
            block_number=0,
            from_address=make_ethereum_address(),
            to_address=ethereum_accounts[0],
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=55,
        )
    ]
    dbethtx = DBEthTx(db)
    dbethtx.add_ethereum_transactions(transactions)
    # Also make sure to update query ranges so as not to query etherscan at all
    for address in ethereum_accounts:
        DBQueryRanges(db).update_used_query_range(
            location_string=f'ethtxs_{address}',
            start_ts=start_ts,
            end_ts=end_ts,
            ranges_to_query=[],
        )

    expected_entries = {ethereum_accounts[0]: 3, ethereum_accounts[1]: 1}
    # Check that we get all transactions correctly even if we query two times
    for _ in range(2):
        for address in ethereum_accounts:
            response = requests.get(
                api_url_for(
                    rotkehlchen_api_server,
                    'ethereumtransactionsresource',
                ),
                json={
                    'from_timestamp': start_ts,
                    'to_timestamp': end_ts,
                    'address': address
                },
            )
            result = assert_proper_response_with_result(response)
            assert len(result['entries']) == expected_entries[address]
            assert result['entries_limit'] == FREE_ETH_TX_LIMIT
            assert result['entries_found'] == expected_entries[address]
            assert result['entries_total'] == 3
コード例 #13
0
def test_query_transactions_over_limit(
    rotkehlchen_api_server,
    ethereum_accounts,
    start_with_valid_premium,
):
    start_ts = 0
    end_ts = 1598453214
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    db = rotki.data.db
    all_transactions_num = FREE_ETH_TX_LIMIT + 50
    transactions = [
        EthereumTransaction(
            tx_hash=x.to_bytes(2, byteorder='little'),
            timestamp=x,
            block_number=x,
            from_address=ethereum_accounts[0],
            to_address=make_ethereum_address(),
            value=x,
            gas=x,
            gas_price=x,
            gas_used=x,
            input_data=x.to_bytes(2, byteorder='little'),
            nonce=x,
        ) for x in range(FREE_ETH_TX_LIMIT - 10)
    ]
    transactions.extend([
        EthereumTransaction(
            tx_hash=(x + 500).to_bytes(2, byteorder='little'),
            timestamp=x,
            block_number=x,
            from_address=ethereum_accounts[1],
            to_address=make_ethereum_address(),
            value=x,
            gas=x,
            gas_price=x,
            gas_used=x,
            input_data=x.to_bytes(2, byteorder='little'),
            nonce=x,
        ) for x in range(60)
    ])

    dbethtx = DBEthTx(db)
    dbethtx.add_ethereum_transactions(transactions)
    # Also make sure to update query ranges so as not to query etherscan at all
    for address in ethereum_accounts:
        DBQueryRanges(db).update_used_query_range(
            location_string=f'ethtxs_{address}',
            start_ts=start_ts,
            end_ts=end_ts,
            ranges_to_query=[],
        )

    free_expected_entries_total = [FREE_ETH_TX_LIMIT - 10, 10]
    free_expected_entries_found = [FREE_ETH_TX_LIMIT - 10, 60]
    premium_expected_entries = [FREE_ETH_TX_LIMIT - 10, 60]

    # Check that we get all transactions correctly even if we query two times
    for _ in range(2):
        response = requests.post(
            api_url_for(
                rotkehlchen_api_server,
                'limitscounterresetresource',
                location='ethereum_transactions',
            ), )
        assert_simple_ok_response(response)
        for idx, address in enumerate(ethereum_accounts):
            response = requests.get(
                api_url_for(
                    rotkehlchen_api_server,
                    'ethereumtransactionsresource',
                ),
                json={
                    'from_timestamp': start_ts,
                    'to_timestamp': end_ts,
                    'address': address
                },
            )
            result = assert_proper_response_with_result(response)
            if start_with_valid_premium:
                assert len(result['entries']) == premium_expected_entries[idx]
                assert result['entries_total'] == all_transactions_num
                assert result['entries_found'] == premium_expected_entries[idx]
                assert result['entries_limit'] == -1
            else:
                assert len(
                    result['entries']) == free_expected_entries_total[idx]
                assert result['entries_total'] == all_transactions_num
                assert result['entries_found'] == free_expected_entries_found[
                    idx]
                assert result['entries_limit'] == FREE_ETH_TX_LIMIT
コード例 #14
0
ファイル: test_ethereum_manager.py プロジェクト: rotki/rotki
def test_get_transaction_receipt(
    ethereum_manager,
    call_order,
    ethereum_manager_connect_at_start,
    database,
):
    wait_until_all_nodes_connected(
        ethereum_manager_connect_at_start=ethereum_manager_connect_at_start,
        ethereum=ethereum_manager,
    )
    tx_hash = '0x12d474b6cbba04fd1a14e55ef45b1eb175985612244631b4b70450c888962a89'
    result = ethereum_manager.get_transaction_receipt(tx_hash,
                                                      call_order=call_order)
    block_hash = '0x6f3a7838a8788c3371b88df170c3643d19bad896c915a7368681292882b6ad61'
    assert result['blockHash'] == block_hash
    assert len(result['logs']) == 2
    assert result['gasUsed'] == 144046
    assert result['blockNumber'] == 10840714
    assert result['logs'][0]['blockNumber'] == 10840714
    assert result['logs'][1]['blockNumber'] == 10840714
    assert result['status'] == 1
    assert result['transactionIndex'] == 110
    assert result['logs'][0]['transactionIndex'] == 110
    assert result['logs'][1]['transactionIndex'] == 110
    assert result['logs'][0]['logIndex'] == 235
    assert result['logs'][1]['logIndex'] == 236

    tx_hash_bytes = hexstring_to_bytes(tx_hash)
    db = DBEthTx(database)
    db.add_ethereum_transactions([
        EthereumTransaction(  # need to add the tx first
            tx_hash=tx_hash_bytes,
            timestamp=1,  # all other fields don't matter for this test
            block_number=1,
            from_address='0x0',
            to_address='0x0',
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=1,
        )
    ])

    # also test receipt can be stored and retrieved from the DB.
    # This tests that all node types (say openethereum) are processed properly
    db.add_receipt_data(result)
    receipt = db.get_receipt(tx_hash_bytes)
    assert receipt == EthereumTxReceipt(
        tx_hash=tx_hash_bytes,
        contract_address=None,
        status=True,
        type=0,
        logs=[
            EthereumTxReceiptLog(
                log_index=235,
                data=
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02T\x0b\xe4\x00',  # noqa: E501
                address='0x5bEaBAEBB3146685Dd74176f68a0721F91297D37',
                removed=False,
                topics=[
                    b'\xdd\xf2R\xad\x1b\xe2\xc8\x9bi\xc2\xb0h\xfc7\x8d\xaa\x95+\xa7\xf1c\xc4\xa1\x16(\xf5ZM\xf5#\xb3\xef',  # noqa: E501
                    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s(*c\xf0\xe3\xd7\xe9`EuB\x0fwsa\xec\xa3\xc8j',  # noqa: E501
                    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6 \xf1\x93ME\x84\xdd\xa6\x99\x9e\xdc\xad\xd3)\x81)dj\xa5',  # noqa: E501
                ]),
            EthereumTxReceiptLog(
                log_index=236,
                data=
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6 \xf1\x93ME\x84\xdd\xa6\x99\x9e\xdc\xad\xd3)\x81)dj\xa5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6 \xf1\x93ME\x84\xdd\xa6\x99\x9e\xdc\xad\xd3)\x81)dj\xa5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\xea\xba\xeb\xb3\x14f\x85\xddt\x17oh\xa0r\x1f\x91)}7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02T\x0b\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xe0\xb6\xb3\xa7d\x00\x00',  # noqa: E501
                address='0x73282A63F0e3D7e9604575420F777361ecA3C86A',
                removed=False,
                topics=[
                    b'\xd6\xd4\xf5h\x1c$l\x9fB\xc2\x03\xe2\x87\x97Z\xf1`\x1f\x8d\xf8\x03Z\x92Q\xf7\x9a\xab\\\x8f\t\xe2\xf8'
                ],  # noqa: E501
            ),
        ])
コード例 #15
0
def test_add_ethereum_transactions(data_dir, username):
    """Test that adding and retrieving ethereum transactions from the DB works fine.

    Also duplicates should be ignored and an error returned
    """
    msg_aggregator = MessagesAggregator()
    data = DataHandler(data_dir, msg_aggregator)
    data.unlock(username, '123', create_new=True)

    tx1 = EthereumTransaction(
        tx_hash=b'1',
        timestamp=Timestamp(1451606400),
        block_number=1,
        from_address=ETH_ADDRESS1,
        to_address=ETH_ADDRESS3,
        value=FVal('2000000'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
        gas_used=FVal('25000000'),
        input_data=MOCK_INPUT_DATA,
        nonce=1,
    )
    tx2 = EthereumTransaction(
        tx_hash=b'2',
        timestamp=Timestamp(1451706400),
        block_number=3,
        from_address=ETH_ADDRESS2,
        to_address=ETH_ADDRESS3,
        value=FVal('4000000'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
        gas_used=FVal('25000000'),
        input_data=MOCK_INPUT_DATA,
        nonce=1,
    )
    tx3 = EthereumTransaction(
        tx_hash=b'3',
        timestamp=Timestamp(1452806400),
        block_number=5,
        from_address=ETH_ADDRESS3,
        to_address=ETH_ADDRESS1,
        value=FVal('1000000'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
        gas_used=FVal('25000000'),
        input_data=MOCK_INPUT_DATA,
        nonce=3,
    )

    # Add and retrieve the first 2 margins. All should be fine.
    data.db.add_ethereum_transactions([tx1, tx2], from_etherscan=True)
    errors = msg_aggregator.consume_errors()
    warnings = msg_aggregator.consume_warnings()
    assert len(errors) == 0
    assert len(warnings) == 0
    returned_transactions = data.db.get_ethereum_transactions()
    assert returned_transactions == [tx1, tx2]

    # Add the last 2 transactions. Since tx2 already exists in the DB it should be
    # ignored (no errors shown for attempting to add already existing transaction)
    data.db.add_ethereum_transactions([tx2, tx3], from_etherscan=True)
    errors = msg_aggregator.consume_errors()
    warnings = msg_aggregator.consume_warnings()
    assert len(errors) == 0
    assert len(warnings) == 0
    returned_transactions = data.db.get_ethereum_transactions()
    assert returned_transactions == [tx1, tx2, tx3]
コード例 #16
0
ファイル: ethereum.py プロジェクト: rotki/rotki
def setup_ethereum_transactions_test(
    database: DBHandler,
    transaction_already_queried: bool,
    one_receipt_in_db: bool = False,
) -> Tuple[List[EthereumTransaction], List[EthereumTxReceipt]]:
    dbethtx = DBEthTx(database)
    tx_hash1 = '0x692f9a6083e905bdeca4f0293f3473d7a287260547f8cbccc38c5cb01591fcda'
    tx_hash1_b = hexstring_to_bytes(tx_hash1)
    transaction1 = EthereumTransaction(
        tx_hash=tx_hash1_b,
        timestamp=Timestamp(1630532276),
        block_number=13142218,
        from_address=string_to_ethereum_address(
            '0x443E1f9b1c866E54e914822B7d3d7165EdB6e9Ea'),
        to_address=string_to_ethereum_address(
            '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D'),
        value=int(10 * 10**18),
        gas=194928,
        gas_price=int(0.000000204 * 10**18),
        gas_used=136675,
        input_data=hexstring_to_bytes(
            '0x7ff36ab5000000000000000000000000000000000000000000000367469995d0723279510000000000000000000000000000000000000000000000000000000000000080000000000000000000000000443e1f9b1c866e54e914822b7d3d7165edb6e9ea00000000000000000000000000000000000000000000000000000000612ff9b50000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002a3bff78b79a009976eea096a51a948a3dc00e34'
        ),  # noqa: E501
        nonce=13,
    )
    tx_hash2 = '0x6beab9409a8f3bd11f82081e99e856466a7daf5f04cca173192f79e78ed53a77'
    tx_hash2_b = hexstring_to_bytes(tx_hash2)
    transaction2 = EthereumTransaction(
        tx_hash=tx_hash2_b,
        timestamp=Timestamp(1631013757),
        block_number=13178342,
        from_address=string_to_ethereum_address(
            '0x442068F934BE670aDAb81242C87144a851d56d16'),
        to_address=string_to_ethereum_address(
            '0xEaDD9B69F96140283F9fF75DA5FD33bcF54E6296'),
        value=0,
        gas=77373,
        gas_price=int(0.000000100314697497 * 10**18),
        gas_used=46782,
        input_data=hexstring_to_bytes(
            '0xa9059cbb00000000000000000000000020c8032d4f7d4a380385f87aeadf05bed84504cb000000000000000000000000000000000000000000000000000000003b9deec6'
        ),  # noqa: E501
        nonce=3,
    )
    transactions = [transaction1, transaction2]
    if transaction_already_queried is True:
        dbethtx.add_ethereum_transactions(ethereum_transactions=transactions)
        result, _ = dbethtx.get_ethereum_transactions(
            ETHTransactionsFilterQuery.make())
        assert result == transactions

    expected_receipt1 = EthereumTxReceipt(
        tx_hash=tx_hash1_b,
        contract_address=None,
        status=True,
        type=0,
        logs=[
            EthereumTxReceiptLog(
                log_index=295,
                data=hexstring_to_bytes(
                    '0x0000000000000000000000000000000000000000000000008ac7230489e80000'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d'
                    ),  # noqa: E501
                ],
            ),
            EthereumTxReceiptLog(
                log_index=296,
                data=hexstring_to_bytes(
                    '0x0000000000000000000000000000000000000000000000008ac7230489e80000'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x000000000000000000000000caa004418eb42cdf00cb057b7c9e28f0ffd840a5'
                    ),  # noqa: E501
                ],
            ),
            EthereumTxReceiptLog(
                log_index=297,
                data=hexstring_to_bytes(
                    '0x00000000000000000000000000000000000000000000036ba1d53baeeda5ed20'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0x2a3bFF78B79A009976EeA096a51A948a3dC00e34'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x000000000000000000000000caa004418eb42cdf00cb057b7c9e28f0ffd840a5'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x000000000000000000000000443e1f9b1c866e54e914822b7d3d7165edb6e9ea'
                    ),  # noqa: E501
                ],
            ),
            EthereumTxReceiptLog(
                log_index=298,
                data=hexstring_to_bytes(
                    '0x000000000000000000000000000000000000000000007b6ea033189ba7d047e30000000000000000000000000000000000000000000000140bc8194dd0f5e4be'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0xcaA004418eB42cdf00cB057b7C9E28f0FfD840a5'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1'
                    )
                ],  # noqa: E501
            ),
            EthereumTxReceiptLog(
                log_index=299,
                data=hexstring_to_bytes(
                    '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000036ba1d53baeeda5ed200000000000000000000000000000000000000000000000000000000000000000'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0xcaA004418eB42cdf00cB057b7C9E28f0FfD840a5'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x000000000000000000000000443e1f9b1c866e54e914822b7d3d7165edb6e9ea'
                    ),  # noqa: E501
                ],
            ),
        ],
    )
    expected_receipt2 = EthereumTxReceipt(
        tx_hash=tx_hash2_b,
        contract_address=None,
        status=True,
        type=2,
        logs=[
            EthereumTxReceiptLog(
                log_index=438,
                data=hexstring_to_bytes(
                    '0x000000000000000000000000000000000000000000000000000000003b9deec6'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0xEaDD9B69F96140283F9fF75DA5FD33bcF54E6296'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x000000000000000000000000442068f934be670adab81242c87144a851d56d16'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x00000000000000000000000020c8032d4f7d4a380385f87aeadf05bed84504cb'
                    ),  # noqa: E501
                ],
            ),
        ],
    )

    if one_receipt_in_db:
        dbethtx.add_receipt_data(txreceipt_to_data(expected_receipt1))

    return transactions, [expected_receipt1, expected_receipt2]
コード例 #17
0
def test_query_transactions_removed_address(
    rotkehlchen_api_server,
    ethereum_accounts,
):
    """Make sure that if an address is removed so are the transactions from the DB"""
    start_ts = 0
    end_ts = 1598453214
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    db = rotki.data.db
    transactions = [
        EthereumTransaction(
            tx_hash=b'1',
            timestamp=0,
            block_number=0,
            from_address=ethereum_accounts[0],
            to_address=make_ethereum_address(),
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=0,
        ),
        EthereumTransaction(
            tx_hash=b'2',
            timestamp=0,
            block_number=0,
            from_address=ethereum_accounts[0],
            to_address=make_ethereum_address(),
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=1,
        ),
        EthereumTransaction(  # should remain after deletining account[0]
            tx_hash=b'3',
            timestamp=0,
            block_number=0,
            from_address=make_ethereum_address(),
            to_address=ethereum_accounts[1],
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=55,
        ),
        EthereumTransaction(  # should remain after deletining account[0]
            tx_hash=b'4',
            timestamp=0,
            block_number=0,
            from_address=ethereum_accounts[1],
            to_address=ethereum_accounts[0],
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=0,
        ),
        EthereumTransaction(  # should remain after deletining account[0]
            tx_hash=b'5',
            timestamp=0,
            block_number=0,
            from_address=ethereum_accounts[0],
            to_address=ethereum_accounts[1],
            value=1,
            gas=1,
            gas_price=1,
            gas_used=1,
            input_data=b'',
            nonce=0,
        )
    ]
    dbethtx = DBEthTx(db)
    dbethtx.add_ethereum_transactions(transactions)
    # Also make sure to update query ranges so as not to query etherscan at all
    for address in ethereum_accounts:
        DBQueryRanges(db).update_used_query_range(
            location_string=f'ethtxs_{address}',
            start_ts=start_ts,
            end_ts=end_ts,
            ranges_to_query=[],
        )

    # Now remove the first account (do the mocking to not query etherscan for balances)
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=[],
        eth_balances=['10000', '10000'],
    )
    with ExitStack() as stack:
        setup.enter_ethereum_patches(stack)
        response = requests.delete(api_url_for(
            rotkehlchen_api_server,
            "blockchainsaccountsresource",
            blockchain='ETH',
        ),
                                   json={'accounts': [ethereum_accounts[0]]})
    assert_proper_response_with_result(response)

    # Check that only the 3 remanining transactions from the other account is returned
    response = requests.get(
        api_url_for(
            rotkehlchen_api_server,
            'ethereumtransactionsresource',
        ), )
    result = assert_proper_response_with_result(response)
    assert len(result['entries']) == 3
    assert result['entries_found'] == 3
コード例 #18
0
        amount=FVal('120'),
        fee_asset=A_ETH,
        fee=Fee(FVal('0.001')),
        link='bittrexid1',
    )
]

eth_tx_list = [
    # before query period: ((2000000000 * 25000000) / (10 ** 18)) * 9.185 = 0.45925
    EthereumTransaction(
        timestamp=Timestamp(1463184190),  # 14/05/2016
        block_number=1512689,  # cryptocompare hourtly ETH/EUR: 9.186
        tx_hash=b'1',
        from_address=ETH_ADDRESS1,
        to_address=ETH_ADDRESS3,
        value=FVal('12323'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
        gas_used=FVal('25000000'),
        input_data=DUMMY_HASH,
        nonce=0,
    ),
    EthereumTransaction(  # ((2000000000 * 1000000) / (10 ** 18)) * 47.5 = 0.095
        timestamp=Timestamp(1491062063),  # 01/04/2017
        block_number=3458409,  # cryptocompare hourly ETH/EUR: 47.5
        tx_hash=b'2',
        from_address=ETH_ADDRESS2,
        to_address=ETH_ADDRESS3,
        value=FVal('12323'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
コード例 #19
0
def test_add_ethereum_transactions(data_dir, username):
    """Test that adding and retrieving ethereum transactions from the DB works fine.

    Also duplicates should be ignored and an error returned
    """
    msg_aggregator = MessagesAggregator()
    data = DataHandler(data_dir, msg_aggregator)
    data.unlock(username, '123', create_new=True)
    tx2_hash_b = b'.h\xdd\x82\x85\x94\xeaq\xfe\n\xfc\xcf\xadwH\xc9\x0f\xfc\xd0\xf1\xad\xd4M\r$\x9b\xf7\x98\x87\xda\x93\x18'  # noqa: E501
    tx2_hash = '0x2e68dd828594ea71fe0afccfad7748c90ffcd0f1add44d0d249bf79887da9318'

    tx1 = EthereumTransaction(
        tx_hash=b'1',
        timestamp=Timestamp(1451606400),
        block_number=1,
        from_address=ETH_ADDRESS1,
        to_address=ETH_ADDRESS3,
        value=FVal('2000000'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
        gas_used=FVal('25000000'),
        input_data=MOCK_INPUT_DATA,
        nonce=1,
    )
    tx2 = EthereumTransaction(
        tx_hash=tx2_hash_b,
        timestamp=Timestamp(1451706400),
        block_number=3,
        from_address=ETH_ADDRESS2,
        to_address=ETH_ADDRESS3,
        value=FVal('4000000'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
        gas_used=FVal('25000000'),
        input_data=MOCK_INPUT_DATA,
        nonce=1,
    )
    tx3 = EthereumTransaction(
        tx_hash=b'3',
        timestamp=Timestamp(1452806400),
        block_number=5,
        from_address=ETH_ADDRESS3,
        to_address=ETH_ADDRESS1,
        value=FVal('1000000'),
        gas=FVal('5000000'),
        gas_price=FVal('2000000000'),
        gas_used=FVal('25000000'),
        input_data=MOCK_INPUT_DATA,
        nonce=3,
    )

    # Add and retrieve the first 2 margins. All should be fine.
    dbethtx = DBEthTx(data.db)
    dbethtx.add_ethereum_transactions([tx1, tx2])
    errors = msg_aggregator.consume_errors()
    warnings = msg_aggregator.consume_warnings()
    assert len(errors) == 0
    assert len(warnings) == 0
    filter_query = ETHTransactionsFilterQuery.make()
    returned_transactions, _ = dbethtx.get_ethereum_transactions(filter_query)
    assert returned_transactions == [tx1, tx2]

    # Add the last 2 transactions. Since tx2 already exists in the DB it should be
    # ignored (no errors shown for attempting to add already existing transaction)
    dbethtx.add_ethereum_transactions([tx2, tx3])
    errors = msg_aggregator.consume_errors()
    warnings = msg_aggregator.consume_warnings()
    assert len(errors) == 0
    assert len(warnings) == 0
    returned_transactions, _ = dbethtx.get_ethereum_transactions(filter_query)
    assert returned_transactions == [tx1, tx2, tx3]

    # try transaction query by tx_hash
    result, _ = dbethtx.get_ethereum_transactions(
        ETHTransactionsFilterQuery.make(tx_hash=tx2_hash_b))  # noqa: E501
    assert result == [tx2], 'querying transaction by hash in bytes failed'
    result, _ = dbethtx.get_ethereum_transactions(
        ETHTransactionsFilterQuery.make(tx_hash=tx2_hash))  # noqa: E501
    assert result == [tx2], 'querying transaction by hash string failed'
    result, _ = dbethtx.get_ethereum_transactions(
        ETHTransactionsFilterQuery.make(tx_hash=b'dsadsad'))  # noqa: E501
    assert result == []