示例#1
0
    def get_or_query_transaction_receipt(
            self,
            tx_hash: str,
    ) -> Optional['EthereumTxReceipt']:
        """
        Gets the receipt from the DB if it exist. If not queries the chain for it,
        saves it in the DB and then returns it.

        Also if the actual transaction does not exist in the DB it queries it and saves it there.

        May raise:

        - DeserializationError
        - RemoteError
        """
        tx_hash_b = hexstring_to_bytes(tx_hash)
        dbethtx = DBEthTx(self.database)
        # If the transaction is not in the DB then query it and add it
        result, _ = dbethtx.get_ethereum_transactions(ETHTransactionsFilterQuery.make(tx_hash=tx_hash_b))  # noqa: E501
        if len(result) == 0:
            transaction = self.ethereum.get_transaction_by_hash(tx_hash)
            if transaction is None:
                return None  # hash does not correspond to a transaction

            dbethtx.add_ethereum_transactions([transaction])

        tx_receipt = dbethtx.get_receipt(tx_hash_b)
        if tx_receipt is not None:
            return tx_receipt

        # not in the DB, so we need to query the chain for it
        tx_receipt_data = self.ethereum.get_transaction_receipt(tx_hash=tx_hash)
        dbethtx.add_receipt_data(tx_receipt_data)
        tx_receipt = dbethtx.get_receipt(tx_hash_b)
        return tx_receipt
示例#2
0
def read_hash(data: Dict[str, Any], key: str) -> bytes:
    try:
        result = hexstring_to_bytes(data[key])
    except ValueError:
        raise DeserializationError(
            f'Failed to read {key} as a hash during etherscan transaction query',
        )
    return result
示例#3
0
    def get_validator_deposits(
        self,
        indices_or_pubkeys: Union[List[int], List[Eth2PubKey]],
    ) -> List[Eth2Deposit]:
        """Get the deposits of all the validators given from the list of indices or pubkeys

        Queries in chunks of 100 due to api limitations

        May raise:
        - RemoteError due to problems querying beaconcha.in API
        """
        chunks = _calculate_query_chunks(indices_or_pubkeys)
        data = []
        for chunk in chunks:
            result = self._query(
                module='validator',
                endpoint='deposits',
                encoded_args=','.join(str(x) for x in chunk),
            )
            if isinstance(result, list):
                data.extend(result)
            else:
                data.append(result)

        deposits = []
        for entry in data:
            try:
                amount = from_gwei(FVal(entry['amount']))
                timestamp = entry['block_ts']
                usd_price = query_usd_price_zero_if_error(
                    asset=A_ETH,
                    time=timestamp,
                    location=f'Eth2 staking deposit at time {timestamp}',
                    msg_aggregator=self.msg_aggregator,
                )
                deposits.append(
                    Eth2Deposit(
                        from_address=deserialize_ethereum_address(
                            entry['from_address']),
                        pubkey=entry['publickey'],
                        withdrawal_credentials=entry['withdrawal_credentials'],
                        value=Balance(
                            amount=amount,
                            usd_value=amount * usd_price,
                        ),
                        tx_hash=hexstring_to_bytes(entry['tx_hash']),
                        tx_index=entry['tx_index'],
                        timestamp=entry['block_ts'],
                    ))
            except (DeserializationError, KeyError) as e:
                msg = str(e)
                if isinstance(e, KeyError):
                    msg = f'Missing key entry for {msg}.'
                raise RemoteError(
                    f'Beaconchai.in deposits response processing error. {msg}',
                ) from e

        return deposits
示例#4
0
def generate_address_via_create2(
    address: HexAddress,
    salt: HexStr,
    init_code: HexStr,
) -> ChecksumEthAddress:
    """Python implementation of CREATE2 opcode.

    Given an address (deployer), a salt and an init code (contract creation
    bytecode), returns the expected contract address once it is deployed.

    Pseudocode:
        keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]

    EIP-1014:
    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md
    """
    contract_address = Web3.keccak(
        hexstring_to_bytes('0xff') + hexstring_to_bytes(address) +
        hexstring_to_bytes(salt) +
        Web3.keccak(hexstring_to_bytes(init_code)), )[12:].hex()
    return to_checksum_address(contract_address)
示例#5
0
文件: utils.py 项目: rotki/rotki
def read_hash(data: Dict[str, Any], key: str, api: str = DEFAULT_API) -> bytes:
    if isinstance(data[key], HexBytes):
        return bytes(data[key])

    try:
        result = hexstring_to_bytes(data[key])
    except DeserializationError as e:
        raise DeserializationError(
            f'Failed to read {key} as a hash during {api} transaction query',
        ) from e

    return result
示例#6
0
def test_maybe_schedule_ethereum_txreceipts(task_manager, ethereum_manager,
                                            database,
                                            one_receipt_in_db):  # noqa: E501
    task_manager.potential_tasks = [
        task_manager._maybe_schedule_ethereum_txreceipts
    ]  # pylint: disable=protected-member  # noqa: E501
    _, receipts = setup_ethereum_transactions_test(
        database=database,
        transaction_already_queried=True,
        one_receipt_in_db=one_receipt_in_db,
    )

    dbethtx = DBEthTx(database)
    timeout = 10
    tx_hash_1 = '0x692f9a6083e905bdeca4f0293f3473d7a287260547f8cbccc38c5cb01591fcda'
    tx_hash_2 = '0x6beab9409a8f3bd11f82081e99e856466a7daf5f04cca173192f79e78ed53a77'
    receipt_task_patch = patch.object(
        task_manager,
        '_run_ethereum_txreceipts_query',
        wraps=task_manager._run_ethereum_txreceipts_query)  # pylint: disable=protected-member  # noqa: E501
    queried_receipts = set()
    try:
        with gevent.Timeout(timeout):
            with receipt_task_patch as receipt_task_mock:
                task_manager.schedule()
                while True:
                    if len(queried_receipts) == 2:
                        break

                    for txhash in (tx_hash_1, tx_hash_2):
                        if dbethtx.get_receipt(
                                hexstring_to_bytes(txhash)) is not None:
                            queried_receipts.add(txhash)

                    gevent.sleep(.3)

                task_manager.schedule()
                gevent.sleep(.5)
                assert receipt_task_mock.call_count == 1, '2nd schedule should do nothing'

    except gevent.Timeout as e:
        raise AssertionError(
            f'receipts query was not completed within {timeout} seconds'
        ) from e  # noqa: E501

    txmodule = EthTransactions(ethereum=ethereum_manager, database=database)
    receipt1 = txmodule.get_or_query_transaction_receipt(tx_hash_1)
    assert receipt1 == receipts[0]
    receipt2 = txmodule.get_or_query_transaction_receipt(tx_hash_2)
    assert receipt2 == receipts[1]
示例#7
0
文件: filtering.py 项目: rotki/rotki
    def prepare(self) -> Tuple[List[str], List[Any]]:
        if self.tx_hash is None:
            return [], []

        if isinstance(self.tx_hash, str):
            try:
                value = hexstring_to_bytes(self.tx_hash)
            except DeserializationError as e:
                log.error(f'Failed to filter a DB transaction query by tx_hash: {str(e)}')
                return [], []
        else:
            value = self.tx_hash

        return ['tx_hash=?'], [value]
示例#8
0
文件: history.py 项目: jbrit/rotki
    def check_result_of_history_creation(
            start_ts: Timestamp,
            end_ts: Timestamp,
            trade_history: List[Union[Trade, MarginPosition]],
            loan_history: List[Loan],
            asset_movements: List[AssetMovement],
            eth_transactions: List[EthereumTransaction],
    ) -> Dict[str, Any]:
        """This function offers some simple assertions on the result of the
        created history. The entire processing part of the history is mocked
        away by this checking function"""
        if history_start_ts is None:
            assert start_ts == 0, 'if no start_ts is given it should be zero'
        else:
            assert start_ts == history_start_ts, 'should be same as given to process_history'
        if history_end_ts is not None:
            assert end_ts == history_end_ts, 'should be same as given to process_history'

        # TODO: Add more assertions/check for each action
        # OR instead do it in tests for conversion of actions(trades, loans, deposits e.t.c.)
        # from exchange to our format for each exchange
        assert len(trade_history) == 11
        assert isinstance(trade_history[0], Trade)
        assert trade_history[0].location == Location.KRAKEN
        assert trade_history[0].pair == 'ETH_EUR'
        assert trade_history[0].trade_type == TradeType.BUY
        assert isinstance(trade_history[1], Trade)
        assert trade_history[1].location == Location.KRAKEN
        assert trade_history[1].pair == 'BTC_EUR'
        assert trade_history[1].trade_type == TradeType.BUY
        assert isinstance(trade_history[2], Trade)
        assert trade_history[2].location == Location.BITTREX
        assert trade_history[2].pair == 'LTC_BTC'
        assert trade_history[2].trade_type == TradeType.BUY
        assert isinstance(trade_history[3], Trade)
        assert trade_history[3].location == Location.BITTREX
        assert trade_history[3].pair == 'LTC_ETH'
        assert trade_history[3].trade_type == TradeType.SELL
        assert isinstance(trade_history[4], MarginPosition)
        assert trade_history[4].profit_loss == FVal('0.05')
        assert isinstance(trade_history[5], Trade)
        assert trade_history[5].location == Location.BINANCE
        assert trade_history[5].pair == 'ETH_BTC'
        assert trade_history[5].trade_type == TradeType.BUY
        assert isinstance(trade_history[6], Trade)
        assert trade_history[6].location == Location.BINANCE
        assert trade_history[6].pair == 'RDN_ETH'
        assert trade_history[6].trade_type == TradeType.SELL
        assert isinstance(trade_history[7], Trade)
        assert trade_history[7].location == Location.POLONIEX
        assert trade_history[7].pair == 'ETH_BTC'
        assert trade_history[7].trade_type == TradeType.SELL
        assert isinstance(trade_history[8], Trade)
        assert trade_history[8].location == Location.POLONIEX
        assert trade_history[8].pair == 'ETH_BTC'
        assert trade_history[8].trade_type == TradeType.BUY
        assert isinstance(trade_history[9], Trade)
        assert trade_history[9].location == Location.POLONIEX
        assert trade_history[9].pair == 'XMR_ETH'
        assert trade_history[9].trade_type == TradeType.BUY
        assert isinstance(trade_history[10], MarginPosition)
        assert trade_history[10].profit_loss == FVal('5E-9')

        assert len(loan_history) == 2
        assert loan_history[0].currency == A_ETH
        assert loan_history[0].earned == AssetAmount(FVal('0.00000001'))
        assert loan_history[1].currency == A_BTC
        assert loan_history[1].earned == AssetAmount(FVal('0.00000005'))

        assert len(asset_movements) == 11
        assert asset_movements[0].location == Location.POLONIEX
        assert asset_movements[0].category == AssetMovementCategory.WITHDRAWAL
        assert asset_movements[0].asset == A_BTC
        assert asset_movements[1].location == Location.POLONIEX
        assert asset_movements[1].category == AssetMovementCategory.WITHDRAWAL
        assert asset_movements[1].asset == A_ETH
        assert asset_movements[2].location == Location.POLONIEX
        assert asset_movements[2].category == AssetMovementCategory.DEPOSIT
        assert asset_movements[2].asset == A_BTC
        assert asset_movements[3].location == Location.POLONIEX
        assert asset_movements[3].category == AssetMovementCategory.DEPOSIT
        assert asset_movements[3].asset == A_ETH
        assert asset_movements[4].location == Location.BITMEX
        assert asset_movements[4].category == AssetMovementCategory.DEPOSIT
        assert asset_movements[4].asset == A_BTC
        assert asset_movements[5].location == Location.BITMEX
        assert asset_movements[5].category == AssetMovementCategory.WITHDRAWAL
        assert asset_movements[5].asset == A_BTC
        assert asset_movements[6].location == Location.BITMEX
        assert asset_movements[6].category == AssetMovementCategory.WITHDRAWAL
        assert asset_movements[6].asset == A_BTC
        assert asset_movements[7].location == Location.KRAKEN
        assert asset_movements[7].category == AssetMovementCategory.DEPOSIT
        assert asset_movements[7].asset == A_BTC
        assert asset_movements[8].location == Location.KRAKEN
        assert asset_movements[8].category == AssetMovementCategory.DEPOSIT
        assert asset_movements[8].asset == A_ETH
        assert asset_movements[9].location == Location.KRAKEN
        assert asset_movements[9].category == AssetMovementCategory.WITHDRAWAL
        assert asset_movements[9].asset == A_BTC
        assert asset_movements[10].location == Location.KRAKEN
        assert asset_movements[10].category == AssetMovementCategory.WITHDRAWAL
        assert asset_movements[10].asset == A_ETH

        # The history creation for these is not yet tested
        assert len(eth_transactions) == 3
        assert eth_transactions[0].block_number == 54092
        assert eth_transactions[0].tx_hash == hexstring_to_bytes(TX_HASH_STR1)
        assert eth_transactions[0].from_address == ETH_ADDRESS1
        assert eth_transactions[0].to_address == ''
        assert eth_transactions[0].value == FVal('11901464239480000000000000')
        assert eth_transactions[0].input_data == MOCK_INPUT_DATA
        assert eth_transactions[1].block_number == 54093
        assert eth_transactions[1].tx_hash == hexstring_to_bytes(TX_HASH_STR2)
        assert eth_transactions[1].from_address == ETH_ADDRESS2
        assert eth_transactions[1].to_address == ETH_ADDRESS1
        assert eth_transactions[1].value == FVal('40000300')
        assert eth_transactions[1].input_data == MOCK_INPUT_DATA
        assert eth_transactions[2].block_number == 54094
        assert eth_transactions[2].tx_hash == hexstring_to_bytes(TX_HASH_STR3)
        assert eth_transactions[2].from_address == ETH_ADDRESS3
        assert eth_transactions[2].to_address == ETH_ADDRESS1
        assert eth_transactions[2].value == FVal('500520300')
        assert eth_transactions[2].input_data == MOCK_INPUT_DATA

        return {}
示例#9
0
文件: history.py 项目: jsloane/rotki
    def check_result_of_history_creation(
        start_ts: Timestamp,
        end_ts: Timestamp,
        trade_history: List[Union[Trade, MarginPosition, AMMTrade]],
        loan_history: List[Loan],
        asset_movements: List[AssetMovement],
        eth_transactions: List[EthereumTransaction],
        defi_events: List[DefiEvent],
        ledger_actions: List[LedgerAction],
    ) -> Dict[str, Any]:
        """This function offers some simple assertions on the result of the
        created history. The entire processing part of the history is mocked
        away by this checking function"""
        if history_start_ts is None:
            assert start_ts == 0, 'if no start_ts is given it should be zero'
        else:
            assert start_ts == history_start_ts, 'should be same as given to process_history'
        if history_end_ts is not None:
            assert end_ts == history_end_ts, 'should be same as given to process_history'

        # TODO: terrible way to check. Figure out something better
        # This whole function needs better thinking also on the order it expects
        # the events to be. It's super brittle right now
        limited_range_test = False
        expected_trades_num = 11
        expected_asset_movements_num = 11
        if end_ts == 1539713238:
            limited_range_test = True
            expected_trades_num = 10
            expected_asset_movements_num = 10

        # TODO: Add more assertions/check for each action
        # OR instead do it in tests for conversion of actions(trades, loans, deposits e.t.c.)
        # from exchange to our format for each exchange
        assert len(trade_history) == expected_trades_num
        assert isinstance(trade_history[0], Trade)
        assert trade_history[0].location == Location.KRAKEN
        assert trade_history[0].base_asset == A_ETH
        assert trade_history[0].quote_asset == A_EUR
        assert trade_history[0].trade_type == TradeType.BUY
        assert isinstance(trade_history[1], Trade)
        assert trade_history[1].location == Location.KRAKEN
        assert trade_history[1].base_asset == A_BTC
        assert trade_history[1].quote_asset == A_EUR
        assert trade_history[1].trade_type == TradeType.BUY
        assert isinstance(trade_history[2], Trade)
        assert trade_history[2].location == Location.BITTREX
        assert trade_history[2].base_asset == A_LTC
        assert trade_history[2].quote_asset == A_BTC
        assert trade_history[2].trade_type == TradeType.BUY
        assert isinstance(trade_history[3], Trade)
        assert trade_history[3].location == Location.BITTREX
        assert trade_history[3].base_asset == A_LTC
        assert trade_history[3].quote_asset == A_ETH
        assert trade_history[3].trade_type == TradeType.SELL
        assert isinstance(trade_history[4], MarginPosition)
        assert trade_history[4].profit_loss == FVal('0.05')
        assert isinstance(trade_history[5], Trade)
        assert trade_history[5].location == Location.BINANCE
        assert trade_history[5].base_asset == A_ETH
        assert trade_history[5].quote_asset == A_BTC
        assert trade_history[5].trade_type == TradeType.BUY
        assert isinstance(trade_history[6], Trade)
        assert trade_history[6].location == Location.BINANCE
        assert trade_history[6].base_asset == A_RDN
        assert trade_history[6].quote_asset == A_ETH
        assert trade_history[6].trade_type == TradeType.SELL
        assert isinstance(trade_history[7], Trade)
        assert trade_history[7].location == Location.POLONIEX
        assert trade_history[7].base_asset == A_ETH
        assert trade_history[7].quote_asset == A_BTC
        assert trade_history[7].trade_type == TradeType.SELL
        assert isinstance(trade_history[8], Trade)
        assert trade_history[8].location == Location.POLONIEX
        assert trade_history[8].base_asset == A_ETH
        assert trade_history[8].quote_asset == A_BTC
        assert trade_history[8].trade_type == TradeType.BUY
        assert isinstance(trade_history[9], Trade)
        assert trade_history[9].location == Location.POLONIEX
        assert trade_history[9].base_asset == A_XMR
        assert trade_history[9].quote_asset == A_ETH
        assert trade_history[9].trade_type == TradeType.BUY
        if not limited_range_test:
            assert isinstance(trade_history[10], MarginPosition)
            assert trade_history[10].profit_loss == FVal('5E-9')

        assert len(loan_history) == 2
        assert loan_history[0].currency == A_ETH
        assert loan_history[0].earned == AssetAmount(FVal('0.00000001'))
        assert loan_history[1].currency == A_BTC
        assert loan_history[1].earned == AssetAmount(FVal('0.00000005'))

        assert len(asset_movements) == expected_asset_movements_num
        if not limited_range_test:
            assert asset_movements[0].location == Location.POLONIEX
            assert asset_movements[
                0].category == AssetMovementCategory.WITHDRAWAL
            assert asset_movements[0].asset == A_BTC
            assert asset_movements[1].location == Location.POLONIEX
            assert asset_movements[
                1].category == AssetMovementCategory.WITHDRAWAL
            assert asset_movements[1].asset == A_ETH
            assert asset_movements[2].location == Location.POLONIEX
            assert asset_movements[2].category == AssetMovementCategory.DEPOSIT
            assert asset_movements[2].asset == A_BTC
            assert asset_movements[3].location == Location.POLONIEX
            assert asset_movements[3].category == AssetMovementCategory.DEPOSIT
            assert asset_movements[3].asset == A_ETH
            assert asset_movements[4].location == Location.BITMEX
            assert asset_movements[4].category == AssetMovementCategory.DEPOSIT
            assert asset_movements[4].asset == A_BTC
            assert asset_movements[5].location == Location.BITMEX
            assert asset_movements[
                5].category == AssetMovementCategory.WITHDRAWAL
            assert asset_movements[5].asset == A_BTC
            assert asset_movements[6].location == Location.BITMEX
            assert asset_movements[
                6].category == AssetMovementCategory.WITHDRAWAL
            assert asset_movements[6].asset == A_BTC
            assert asset_movements[7].location == Location.KRAKEN
            assert asset_movements[7].category == AssetMovementCategory.DEPOSIT
            assert asset_movements[7].asset == A_BTC
            assert asset_movements[8].location == Location.KRAKEN
            assert asset_movements[8].category == AssetMovementCategory.DEPOSIT
            assert asset_movements[8].asset == A_ETH
            assert asset_movements[9].location == Location.KRAKEN
            assert asset_movements[
                9].category == AssetMovementCategory.WITHDRAWAL
            assert asset_movements[9].asset == A_BTC
            assert asset_movements[10].location == Location.KRAKEN
            assert asset_movements[
                10].category == AssetMovementCategory.WITHDRAWAL
            assert asset_movements[10].asset == A_ETH

        # The history creation for these is not yet tested
        assert len(eth_transactions) == 3
        assert eth_transactions[0].block_number == 54092
        assert eth_transactions[0].tx_hash == hexstring_to_bytes(TX_HASH_STR1)
        assert eth_transactions[0].from_address == ETH_ADDRESS1
        assert eth_transactions[0].to_address is None
        assert eth_transactions[0].value == FVal('11901464239480000000000000')
        assert eth_transactions[0].input_data == MOCK_INPUT_DATA
        assert eth_transactions[1].block_number == 54093
        assert eth_transactions[1].tx_hash == hexstring_to_bytes(TX_HASH_STR2)
        assert eth_transactions[1].from_address == ETH_ADDRESS2
        assert eth_transactions[1].to_address == ETH_ADDRESS1
        assert eth_transactions[1].value == FVal('40000300')
        assert eth_transactions[1].input_data == MOCK_INPUT_DATA
        assert eth_transactions[2].block_number == 54094
        assert eth_transactions[2].tx_hash == hexstring_to_bytes(TX_HASH_STR3)
        assert eth_transactions[2].from_address == ETH_ADDRESS3
        assert eth_transactions[2].to_address == ETH_ADDRESS1
        assert eth_transactions[2].value == FVal('500520300')
        assert eth_transactions[2].input_data == MOCK_INPUT_DATA

        assert len(defi_events) == 0
        assert len(ledger_actions) == 0

        return {}
示例#10
0
文件: test_eth2.py 项目: rotki/rotki
def test_eth2_deposits_serialization():
    addr1 = make_ethereum_address()
    addr2 = make_ethereum_address()
    deposits = [
        Eth2Deposit(
            from_address=addr1,
            pubkey=
            '0xb016e31f633a21fbe42a015152399361184f1e2c0803d89823c224994af74a561c4ad8cfc94b18781d589d03e952cd5b',  # noqa: E501
            withdrawal_credentials=
            '0x004c7691c2085648f394ffaef851f3b1d51b95f7263114bc923fc5338f5fc499',  # noqa: E501
            value=Balance(FVal(32), FVal(64)),
            tx_hash=hexstring_to_bytes(
                '0xd9eca1c2a0c5ff2f25071713432b21cc4d0ff2e8963edc63a48478e395e08db1'
            ),  # noqa: E501
            tx_index=22,
            timestamp=Timestamp(int(1604506685)),
        ),
        Eth2Deposit(
            from_address=addr2,
            pubkey=
            '0xa8ff5fc88412d080a297683c25a791ef77eb52d75b265fabab1f2c2591bb927c35818ac6289bc6680ab252787d0ebab3',  # noqa: E501
            withdrawal_credentials=
            '0x00cfe1c10347d642a8b8daf86d23bcb368076972691445de2cf517ff43765817',  # noqa: E501
            value=Balance(FVal(32), FVal(64)),
            tx_hash=hexstring_to_bytes(
                '0x6905f4d1843fb8c003c1fbbc2c8e6c5f9792f4f44ddb1122553412ee0b128da7'
            ),  # noqa: E501
            tx_index=221,
            timestamp=Timestamp(int(1605043544)),
        ),
    ]

    serialized = process_result_list(deposits)
    assert serialized == [
        {
            'from_address': addr1,
            'pubkey':
            '0xb016e31f633a21fbe42a015152399361184f1e2c0803d89823c224994af74a561c4ad8cfc94b18781d589d03e952cd5b',  # noqa: E501
            'withdrawal_credentials':
            '0x004c7691c2085648f394ffaef851f3b1d51b95f7263114bc923fc5338f5fc499',  # noqa: E501
            'value': {
                'amount': '32',
                'usd_value': '64'
            },
            'tx_hash':
            '0xd9eca1c2a0c5ff2f25071713432b21cc4d0ff2e8963edc63a48478e395e08db1',
            'tx_index': 22,
            'timestamp': 1604506685,
        },
        {
            'from_address': addr2,
            'pubkey':
            '0xa8ff5fc88412d080a297683c25a791ef77eb52d75b265fabab1f2c2591bb927c35818ac6289bc6680ab252787d0ebab3',  # noqa: E501
            'withdrawal_credentials':
            '0x00cfe1c10347d642a8b8daf86d23bcb368076972691445de2cf517ff43765817',  # noqa: E501
            'value': {
                'amount': '32',
                'usd_value': '64'
            },
            'tx_hash':
            '0x6905f4d1843fb8c003c1fbbc2c8e6c5f9792f4f44ddb1122553412ee0b128da7',
            'tx_index': 221,
            'timestamp': 1605043544,
        },
    ]
示例#11
0
文件: test_eth2.py 项目: rotki/rotki
    '0x00F8a0D8EE1c21151BCcB416bCa1C152f9952D19')
ADDR3 = string_to_ethereum_address(
    '0x3266F3546a1e5Dc6A15588f3324741A0E20a3B6c')

# List of ADDR1, ADDR2 and ADDR3 deposit events from 1604506685 to 1605044577
# sorted by (timestamp, log_index).
EXPECTED_DEPOSITS = [
    Eth2Deposit(
        from_address=ADDR1,
        pubkey=
        '0xb016e31f633a21fbe42a015152399361184f1e2c0803d89823c224994af74a561c4ad8cfc94b18781d589d03e952cd5b',  # noqa: E501
        withdrawal_credentials=
        '0x004c7691c2085648f394ffaef851f3b1d51b95f7263114bc923fc5338f5fc499',  # noqa: E501
        value=Balance(FVal(32), FVal(64)),
        tx_hash=hexstring_to_bytes(
            '0xd9eca1c2a0c5ff2f25071713432b21cc4d0ff2e8963edc63a48478e395e08db1'
        ),  # noqa: E501
        tx_index=15,
        timestamp=Timestamp(int(1604506685)),
    ),
    Eth2Deposit(
        from_address=ADDR3,
        pubkey=
        '0x90b2f65cb43d9cdb2279af9f76010d667b9d8d72e908f2515497a7102820ce6bb15302fe2b8dc082fce9718569344ad8',  # noqa: E501
        withdrawal_credentials=
        '0x00a257d19e1650dec1ab59fc9e1cb9a9fc2fe7265b0f27e7d79ff61aeff0a1f0',  # noqa: E501
        value=Balance(FVal(32), FVal(64)),
        tx_hash=hexstring_to_bytes(
            '0x3403bd94a1bf185ee18a525499e408a1b9b7d801cff6418e31efda346762e754'
        ),  # noqa: E501
        tx_index=105,
示例#12
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]
示例#13
0
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
            ),
        ])
示例#14
0
    def add_receipt_data(self, data: Dict[str, Any]) -> None:
        """Add tx receipt data as they are returned by the chain to the DB

        This assumes the transaction is already in the DB.

        May raise:
        - Key Error if any of the expected fields are missing
        - DeserializationError if there is a problem deserializing a value
        - sqlcipher.DatabaseError if the transaction hash is not in the DB
          or if the receipt already exists in the DB. TODO: Differentiate?
        """
        tx_hash_b = hexstring_to_bytes(data['transactionHash'])
        # some nodes miss the type field for older non EIP1559 transactions. So assume legacy (0)
        tx_type = hexstr_to_int(data.get('type', '0x0'))
        cursor = self.db.conn.cursor()
        status = data.get('status', 1)  # status may be missing for older txs. Assume 1.
        if status is None:
            status = 1
        contract_address = deserialize_ethereum_address(data['contractAddress']) if data['contractAddress'] else None  # noqa: E501
        cursor.execute(
            'INSERT INTO ethtx_receipts (tx_hash, contract_address, status, type) '
            'VALUES(?, ?, ?, ?) ',
            (tx_hash_b, contract_address, status, tx_type),
        )

        log_tuples = []
        topic_tuples = []
        for log_entry in data['logs']:
            log_index = log_entry['logIndex']
            log_tuples.append((
                tx_hash_b,
                log_index,
                hexstring_to_bytes(log_entry['data']),
                deserialize_ethereum_address(log_entry['address']),
                int(log_entry['removed']),
            ))

            for idx, topic in enumerate(log_entry['topics']):
                topic_tuples.append((
                    tx_hash_b,
                    log_index,
                    hexstring_to_bytes(topic),
                    idx,
                ))

        if len(log_tuples) != 0:
            cursor.executemany(
                'INSERT INTO ethtx_receipt_logs (tx_hash, log_index, data, address, removed) '
                'VALUES(? ,? ,? ,? ,?)',
                log_tuples,
            )

            if len(topic_tuples) != 0:
                cursor.executemany(
                    'INSERT INTO ethtx_receipt_log_topics (tx_hash, log_index, topic, topic_index) '  # noqa: E501
                    'VALUES(? ,? ,?, ?)',
                    topic_tuples,
                )

        self.db.conn.commit()
        self.db.update_last_write()