Пример #1
0
    def _format_call(self, sender='', to='', value=0, data='',
                     startgas=default_startgas, gasprice=default_gasprice):
        """ Helper to format the transaction data. """

        json_data = dict()

        if sender is not None:
            json_data['from'] = address_encoder(sender)

        if to is not None:
            json_data['to'] = data_encoder(to)

        if value is not None:
            json_data['value'] = quantity_encoder(value)

        if gasprice is not None:
            json_data['gasPrice'] = quantity_encoder(gasprice)

        if startgas is not None:
            json_data['gas'] = quantity_encoder(startgas)

        if data is not None:
            json_data['data'] = data_encoder(data)

        return json_data
Пример #2
0
    def eth_call(self,
                 sender='',
                 to='',
                 value=0,
                 data='',
                 startgas=default_startgas,
                 gasprice=default_gasprice,
                 block_number='latest'):
        """ Executes a new message call immediately without creating a
        transaction on the block chain.

        Args:
            from: The address the transaction is send from.
            to: The address the transaction is directed to.
            gas (int): Gas provided for the transaction execution. eth_call
                consumes zero gas, but this parameter may be needed by some
                executions.
            gasPrice (int): gasPrice used for each paid gas.
            value (int): Integer of the value send with this transaction.
            data (bin): Hash of the method signature and encoded parameters.
                For details see Ethereum Contract ABI.
            block_number: Determines the state of ethereum used in the
                call.
        """

        json_data = dict()

        if sender is not None:
            json_data['from'] = address_encoder(sender)

        if to is not None:
            json_data['to'] = data_encoder(to)

        if value is not None:
            json_data['value'] = quantity_encoder(value)

        if gasprice is not None:
            json_data['gasPrice'] = quantity_encoder(gasprice)

        if startgas is not None:
            json_data['gas'] = quantity_encoder(startgas)

        if data is not None:
            json_data['data'] = data_encoder(data)

        res = self.call('eth_call', json_data, block_number)

        return data_decoder(res)
Пример #3
0
def block_tag_encoder(val):
    if isinstance(val, int):
        return quantity_encoder(val)
    elif val and isinstance(val, bytes):
        assert val in ('latest', 'pending')
        return data_encoder(val)
    else:
        assert not val
Пример #4
0
def block_tag_encoder(val):
    if isinstance(val, int):
        return quantity_encoder(val)
    elif val and isinstance(val, bytes):
        assert val in ('latest', 'pending')
        return data_encoder(val)
    else:
        assert not val
Пример #5
0
    def eth_sendTransaction(self, nonce=None, sender='', to='', value=0, data='',
                            gasPrice=default_gasprice, gas=default_startgas,
                            v=None, r=None, s=None):
        """ Creates new message call transaction or a contract creation, if the
        data field contains code.

        Note:
            The support for local signing through the variables v,r,s is not
            part of the standard spec, a extended server is required.

        Args:
            from (address): The 20 bytes address the transaction is send from.
            to (address): DATA, 20 Bytes - (optional when creating new
                contract) The address the transaction is directed to.
            gas (int): Gas provided for the transaction execution. It will
                return unused gas.
            gasPrice (int): gasPrice used for each paid gas.
            value (int): Value send with this transaction.
            data (bin): The compiled code of a contract OR the hash of the
                invoked method signature and encoded parameters.
            nonce (int): This allows to overwrite your own pending transactions
                that use the same nonce.
        """

        if to == '' and data.isalnum():
            warnings.warn(
                'Verify that the data parameter is _not_ hex encoded, if this is the case '
                'the data will be double encoded and result in unexpected '
                'behavior.'
            )

        if to == '0' * 40:
            warnings.warn('For contract creating the empty string must be used.')

        json_data = {
            'to': data_encoder(normalize_address(to, allow_blank=True)),
            'value': quantity_encoder(value),
            'gasPrice': quantity_encoder(gasPrice),
            'gas': quantity_encoder(gas),
            'data': data_encoder(data),
        }

        if not sender and not (v and r and s):
            raise ValueError('Either sender or v, r, s needs to be informed.')

        if sender is not None:
            json_data['from'] = address_encoder(sender)

        if v and r and s:
            json_data['v'] = quantity_encoder(v)
            json_data['r'] = quantity_encoder(r)
            json_data['s'] = quantity_encoder(s)

        if nonce is not None:
            json_data['nonce'] = quantity_encoder(nonce)

        res = self.call('eth_sendTransaction', json_data)

        return data_decoder(res)
Пример #6
0
 def find_block(self, condition):
     """Query all blocks one by one and return the first one for which
     `condition(block)` evaluates to `True`.
     """
     i = 0
     while True:
         block = self.call('eth_getBlockByNumber', quantity_encoder(i), True)
         if condition(block) or not block:
             return block
         i += 1
Пример #7
0
 def find_block(self, condition):
     """Query all blocks one by one and return the first one for which
     `condition(block)` evaluates to `True`.
     """
     i = 0
     while True:
         block = self.call("eth_getBlockByNumber", quantity_encoder(i), True, print_comm=False)
         if condition(block):
             return block
         i += 1
Пример #8
0
 def filter_changes(self, fid):
     changes = self.call('eth_getFilterChanges', quantity_encoder(fid))
     if not changes:
         return None
     elif isinstance(changes, bytes):
         return data_decoder(changes)
     else:
         decoders = dict(blockHash=data_decoder, transactionHash=data_decoder, data=data_decoder,
                         address=address_decoder, topics=lambda x: [topic_decoder(t) for t in x],
                         blockNumber=quantity_decoder, logIndex=quantity_decoder, transactionIndex=quantity_decoder)
         return [{k: decoders[k](v) for k, v in c.items() if v is not None} for c  in changes]
Пример #9
0
 def filter_changes(self, fid):
     changes = self.call('eth_getFilterChanges', quantity_encoder(fid))
     if not changes:
         return None
     elif isinstance(changes, bytes):
         return data_decoder(changes)
     else:
         decoders = dict(blockHash=data_decoder,
                         transactionHash=data_decoder,
                         data=data_decoder,
                         address=address_decoder,
                         topics=lambda x: [topic_decoder(t) for t in x],
                         blockNumber=quantity_decoder,
                         logIndex=quantity_decoder,
                         transactionIndex=quantity_decoder)
         return [{k: decoders[k](v) for k, v in list(c.items()) if v is not None} for c in changes]
Пример #10
0
def test_send_transaction(test_app):
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance('\xff' * 20) == 0
    tx = {
        'from': address_encoder(test_app.services.accounts.unlocked_accounts()[0].address),
        'to': address_encoder('\xff' * 20),
        'value': quantity_encoder(1)
    }
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert tx_hash == chain.head_candidate.get_transaction(0).hash
    assert chain.head_candidate.get_balance('\xff' * 20) == 1
    test_app.mine_next_block()
    assert tx_hash == chain.head.get_transaction(0).hash
    assert chain.head.get_balance('\xff' * 20) == 1

    # send transactions from account which can't pay gas
    tx['from'] = address_encoder(test_app.services.accounts.unlocked_accounts()[1].address)
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert chain.head_candidate.get_transactions() == []
Пример #11
0
def test_send_transaction(test_app):
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance('\xff' * 20) == 0
    tx = {
        'from': address_encoder(test_app.services.accounts.unlocked_accounts()[0].address),
        'to': address_encoder('\xff' * 20),
        'value': quantity_encoder(1)
    }
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert tx_hash == chain.head_candidate.get_transaction(0).hash
    assert chain.head_candidate.get_balance('\xff' * 20) == 1
    test_app.mine_next_block()
    assert tx_hash == chain.head.get_transaction(0).hash
    assert chain.head.get_balance('\xff' * 20) == 1

    # send transactions from account which can't pay gas
    tx['from'] = address_encoder(test_app.services.accounts.unlocked_accounts()[1].address)
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert chain.head_candidate.get_transactions() == []
Пример #12
0
def test_send_transaction(test_app):
    chainservice = test_app.services.chain
    chain = chainservice.chain
    hc = chainservice.head_candidate
    state = State(hc.state_root, chain.env)
    assert state.get_balance(b'\xff' * 20) == 0
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert state.get_balance(sender) > 0
    tx = {
        'from': address_encoder(sender),
        'to': address_encoder(b'\xff' * 20),
        'value': quantity_encoder(1)
    }
    tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx))
    test_app.mine_next_block()
    assert len(chain.head.transactions) == 1
    assert tx_hash == chain.head.transactions[0].hash
    assert chain.state.get_balance(b'\xff' * 20) == 1

    # send transactions from account which can't pay gas
    tx['from'] = address_encoder(
        test_app.services.accounts.unlocked_accounts[1].address)
    tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx))
    assert chainservice.head_candidate.transactions == []
Пример #13
0
def test_get_filter_changes(test_app):
    test_app.mine_next_block()  # start with a fresh block
    n0 = test_app.services.chain.chain.head.number
    sender = address_encoder(test_app.services.accounts.unlocked_accounts()[0].address)
    contract_creation = {
        'from': sender,
        'data': data_encoder(LOG_EVM)
    }
    tx_hash = test_app.rpc_request('eth_sendTransaction', contract_creation)
    test_app.mine_next_block()
    receipt = test_app.rpc_request('eth_getTransactionReceipt', tx_hash)
    contract_address = receipt['contractAddress']
    tx = {
        'from': sender,
        'to': contract_address
    }

    pending_filter_id = test_app.rpc_request('eth_newFilter', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    });
    latest_filter_id = test_app.rpc_request('eth_newFilter', {
        'fromBlock': 'latest',
        'toBlock': 'latest'
    });
    tx_hashes = []
    logs = []

    # tx in pending block
    tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx))
    logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id))
    assert len(logs[-1]) == 1
    assert logs[-1][0]['type'] == 'pending'
    assert logs[-1][0]['logIndex'] == None
    assert logs[-1][0]['transactionIndex'] == None
    assert logs[-1][0]['transactionHash'] == None
    assert logs[-1][0]['blockHash'] == None
    assert logs[-1][0]['blockNumber'] == None
    assert logs[-1][0]['address'] == contract_address
    pending_log = logs[-1][0]

    logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id))
    assert logs[-1] == []

    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert logs[-1] == []

    test_app.mine_next_block()
    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert len(logs[-1]) == 1  # log from before, but now mined
    assert logs[-1][0]['type'] == 'mined'
    assert logs[-1][0]['logIndex'] == '0x0'
    assert logs[-1][0]['transactionIndex'] == '0x0'
    assert logs[-1][0]['transactionHash'] == tx_hashes[-1]
    assert logs[-1][0]['blockHash'] == data_encoder(test_app.services.chain.chain.head.hash)
    assert logs[-1][0]['blockNumber'] == quantity_encoder(test_app.services.chain.chain.head.number)
    assert logs[-1][0]['address'] == contract_address
    logs_in_range = [logs[-1][0]]

    # send tx and mine block
    tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx))
    test_app.mine_next_block()
    logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id))
    assert len(logs[-1]) == 1
    assert logs[-1][0]['type'] == 'mined'
    assert logs[-1][0]['logIndex'] == '0x0'
    assert logs[-1][0]['transactionIndex'] == '0x0'
    assert logs[-1][0]['transactionHash'] == tx_hashes[-1]
    assert logs[-1][0]['blockHash'] == data_encoder(test_app.services.chain.chain.head.hash)
    assert logs[-1][0]['blockNumber'] == quantity_encoder(test_app.services.chain.chain.head.number)
    assert logs[-1][0]['address'] == contract_address
    logs_in_range.append(logs[-1][0])

    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert logs[-1] == logs[-2]  # latest and pending filter see same (mined) log

    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert logs[-1] == []

    test_app.mine_next_block()
    logs.append(test_app.rpc_request('eth_getFilterChanges', pending_filter_id))
    assert logs[-1] == []

    range_filter_id = test_app.rpc_request('eth_newFilter', {
        'fromBlock': quantity_encoder(test_app.services.chain.chain.head.number - 3),
        'toBlock': 'pending'
    })
    tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx))
    logs.append(test_app.rpc_request('eth_getFilterChanges', range_filter_id))
    assert sorted(logs[-1]) == sorted(logs_in_range + [pending_log])
Пример #14
0
def test_get_logs(test_app):
    test_app.mine_next_block()  # start with a fresh block
    n0 = test_app.services.chain.chain.head.number
    sender = address_encoder(test_app.services.accounts.unlocked_accounts()[0].address)
    contract_creation = {"from": sender, "data": data_encoder(LOG_EVM)}
    tx_hash = test_app.rpc_request("eth_sendTransaction", contract_creation)
    test_app.mine_next_block()
    receipt = test_app.rpc_request("eth_getTransactionReceipt", tx_hash)
    contract_address = receipt["contractAddress"]
    tx = {"from": sender, "to": contract_address}

    # single log in pending block
    test_app.rpc_request("eth_sendTransaction", tx)
    logs1 = test_app.rpc_request("eth_getLogs", {"fromBlock": "pending", "toBlock": "pending"})
    assert len(logs1) == 1
    assert logs1[0]["type"] == "pending"
    assert logs1[0]["logIndex"] == None
    assert logs1[0]["transactionIndex"] == None
    assert logs1[0]["transactionHash"] == None
    assert logs1[0]["blockHash"] == None
    assert logs1[0]["blockNumber"] == None
    assert logs1[0]["address"] == contract_address

    logs2 = test_app.rpc_request("eth_getLogs", {"fromBlock": "pending", "toBlock": "pending"})
    assert logs2 == logs1

    # same log, but now mined in head
    test_app.mine_next_block()
    logs3 = test_app.rpc_request("eth_getLogs", {"fromBlock": "latest", "toBlock": "latest"})
    assert len(logs3) == 1
    assert logs3[0]["type"] == "mined"
    assert logs3[0]["logIndex"] == "0x0"
    assert logs3[0]["transactionIndex"] == "0x0"
    assert logs3[0]["blockHash"] == data_encoder(test_app.services.chain.chain.head.hash)
    assert logs3[0]["blockNumber"] == quantity_encoder(test_app.services.chain.chain.head.number)
    assert logs3[0]["address"] == contract_address

    # another log in pending block
    test_app.rpc_request("eth_sendTransaction", tx)
    logs4 = test_app.rpc_request("eth_getLogs", {"fromBlock": "latest", "toBlock": "pending"})
    assert logs4 == [logs1[0], logs3[0]] or logs4 == [logs3[0], logs1[0]]

    # two logs in pending block
    test_app.rpc_request("eth_sendTransaction", tx)
    logs5 = test_app.rpc_request("eth_getLogs", {"fromBlock": "pending", "toBlock": "pending"})
    assert len(logs5) == 2
    assert logs5[0] == logs5[1] == logs1[0]

    # two logs in head
    test_app.mine_next_block()
    logs6 = test_app.rpc_request("eth_getLogs", {"fromBlock": "latest", "toBlock": "pending"})
    for log in logs6:
        assert log["type"] == "mined"
        assert log["logIndex"] == "0x0"
        assert log["blockHash"] == data_encoder(test_app.services.chain.chain.head.hash)
        assert log["blockNumber"] == quantity_encoder(test_app.services.chain.chain.head.number)
        assert log["address"] == contract_address
    assert sorted([log["transactionIndex"] for log in logs6]) == ["0x0", "0x1"]

    # everything together with another log in pending block
    test_app.rpc_request("eth_sendTransaction", tx)
    logs7 = test_app.rpc_request("eth_getLogs", {"fromBlock": quantity_encoder(n0), "toBlock": "pending"})
    assert sorted(logs7) == sorted(logs3 + logs6 + logs1)
Пример #15
0
def test_get_filter_changes(test_app):
    test_app.mine_next_block()  # start with a fresh block
    n0 = test_app.services.chain.chain.head.number
    sender = address_encoder(test_app.services.accounts.unlocked_accounts()[0].address)
    contract_creation = {"from": sender, "data": data_encoder(LOG_EVM)}
    tx_hash = test_app.rpc_request("eth_sendTransaction", contract_creation)
    test_app.mine_next_block()
    receipt = test_app.rpc_request("eth_getTransactionReceipt", tx_hash)
    contract_address = receipt["contractAddress"]
    tx = {"from": sender, "to": contract_address}

    pending_filter_id = test_app.rpc_request("eth_newFilter", {"fromBlock": "pending", "toBlock": "pending"})
    latest_filter_id = test_app.rpc_request("eth_newFilter", {"fromBlock": "latest", "toBlock": "latest"})
    tx_hashes = []
    logs = []

    # tx in pending block
    tx_hashes.append(test_app.rpc_request("eth_sendTransaction", tx))
    logs.append(test_app.rpc_request("eth_getFilterChanges", pending_filter_id))
    assert len(logs[-1]) == 1
    assert logs[-1][0]["type"] == "pending"
    assert logs[-1][0]["logIndex"] == None
    assert logs[-1][0]["transactionIndex"] == None
    assert logs[-1][0]["transactionHash"] == None
    assert logs[-1][0]["blockHash"] == None
    assert logs[-1][0]["blockNumber"] == None
    assert logs[-1][0]["address"] == contract_address
    pending_log = logs[-1][0]

    logs.append(test_app.rpc_request("eth_getFilterChanges", pending_filter_id))
    assert logs[-1] == []

    logs.append(test_app.rpc_request("eth_getFilterChanges", latest_filter_id))
    assert logs[-1] == []

    test_app.mine_next_block()
    logs.append(test_app.rpc_request("eth_getFilterChanges", latest_filter_id))
    assert len(logs[-1]) == 1  # log from before, but now mined
    assert logs[-1][0]["type"] == "mined"
    assert logs[-1][0]["logIndex"] == "0x0"
    assert logs[-1][0]["transactionIndex"] == "0x0"
    assert logs[-1][0]["transactionHash"] == tx_hashes[-1]
    assert logs[-1][0]["blockHash"] == data_encoder(test_app.services.chain.chain.head.hash)
    assert logs[-1][0]["blockNumber"] == quantity_encoder(test_app.services.chain.chain.head.number)
    assert logs[-1][0]["address"] == contract_address
    logs_in_range = [logs[-1][0]]

    # send tx and mine block
    tx_hashes.append(test_app.rpc_request("eth_sendTransaction", tx))
    test_app.mine_next_block()
    logs.append(test_app.rpc_request("eth_getFilterChanges", pending_filter_id))
    assert len(logs[-1]) == 1
    assert logs[-1][0]["type"] == "mined"
    assert logs[-1][0]["logIndex"] == "0x0"
    assert logs[-1][0]["transactionIndex"] == "0x0"
    assert logs[-1][0]["transactionHash"] == tx_hashes[-1]
    assert logs[-1][0]["blockHash"] == data_encoder(test_app.services.chain.chain.head.hash)
    assert logs[-1][0]["blockNumber"] == quantity_encoder(test_app.services.chain.chain.head.number)
    assert logs[-1][0]["address"] == contract_address
    logs_in_range.append(logs[-1][0])

    logs.append(test_app.rpc_request("eth_getFilterChanges", latest_filter_id))
    assert logs[-1] == logs[-2]  # latest and pending filter see same (mined) log

    logs.append(test_app.rpc_request("eth_getFilterChanges", latest_filter_id))
    assert logs[-1] == []

    test_app.mine_next_block()
    logs.append(test_app.rpc_request("eth_getFilterChanges", pending_filter_id))
    assert logs[-1] == []

    range_filter_id = test_app.rpc_request(
        "eth_newFilter",
        {"fromBlock": quantity_encoder(test_app.services.chain.chain.head.number - 3), "toBlock": "pending"},
    )
    tx_hashes.append(test_app.rpc_request("eth_sendTransaction", tx))
    logs.append(test_app.rpc_request("eth_getFilterChanges", range_filter_id))
    assert sorted(logs[-1]) == sorted(logs_in_range + [pending_log])
Пример #16
0
 def block_gas_limit(self, blocknumber):
     block = self.client.call('eth_getBlockByNumber',
                              quantity_encoder(blocknumber), False)
     return int(block['gasLimit'], 0)
Пример #17
0
def test_send_transaction(test_app):
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance("\xff" * 20) == 0
    sender = test_app.services.accounts.unlocked_accounts()[0].address
    assert chain.head_candidate.get_balance(sender) > 0
    tx = {"from": address_encoder(sender), "to": address_encoder("\xff" * 20), "value": quantity_encoder(1)}
    tx_hash = data_decoder(test_app.rpc_request("eth_sendTransaction", tx))
    assert tx_hash == chain.head_candidate.get_transaction(0).hash
    assert chain.head_candidate.get_balance("\xff" * 20) == 1
    test_app.mine_next_block()
    assert tx_hash == chain.head.get_transaction(0).hash
    assert chain.head.get_balance("\xff" * 20) == 1

    # send transactions from account which can't pay gas
    tx["from"] = address_encoder(test_app.services.accounts.unlocked_accounts()[1].address)
    tx_hash = data_decoder(test_app.rpc_request("eth_sendTransaction", tx))
    assert chain.head_candidate.get_transactions() == []
Пример #18
0
def test_logfilters_topics(test_app):
    sample_compiled = _solidity.compile_code(
        sample_sol_code,
        combined='bin,abi',
    )

    filepath = None
    contract_data = _solidity.solidity_get_contract_data(
        sample_compiled, filepath, 'SampleContract')
    theabi = contract_data['abi']
    theevm = contract_data['bin_hex']

    sender_address = test_app.services.accounts.unlocked_accounts[0].address
    sender = address_encoder(sender_address)

    event1 = get_event(theabi, 'Event1')
    event2 = get_event(theabi, 'Event2')
    event3 = get_event(theabi, 'Event3')
    event1_id = event_id(*get_eventname_types(event1))
    event2_id = event_id(*get_eventname_types(event2))
    event3_id = event_id(*get_eventname_types(event3))

    test_app.mine_next_block()  # start with a fresh block

    n0 = test_app.services.chain.chain.head.number
    assert n0 == 1

    contract_creation = {
        'from': sender,
        'data': '0x' + theevm,
        'gas': quantity_encoder(1000000)
    }

    tx_hash = test_app.client.call('eth_sendTransaction', contract_creation)
    test_app.mine_next_block()
    receipt = test_app.client.call('eth_getTransactionReceipt', tx_hash)
    contract_address = receipt['contractAddress']

    sample_contract = ContractProxy(sender_address, theabi, contract_address,
                                    test_app.client.call,
                                    test_app.client.send_transaction)

    topic1 = hex(event1_id).rstrip("L")
    topic2 = hex(event2_id).rstrip("L")
    topic3 = hex(event3_id).rstrip("L")
    topica, topicb, topicc = \
        '0x0000000000000000000000000000000000000000000000000000000000000001',\
        '0x0000000000000000000000000000000000000000000000000000000000000064',\
        '0x00000000000000000000000000000000000000000000000000000000000003e8'
    topic_filter_1 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic1]
    })
    topic_filter_2 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic2]
    })
    topic_filter_3 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic3]
    })
    topic_filter_4 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic1, topica]
    })

    topic_filter_5 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic2, topica, topicb]
    })
    topic_filter_6 = test_app.client.call(
        'eth_newFilter', {
            'fromBlock': 0,
            'toBlock': 'pending',
            'topics': [topic3, topica, topicb, topicc]
        })
    topic_filter_7 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topica, topicb, topicc]
    })
    topic_filter_8 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic3, topica, topicb]
    })
    topic_filter_9 = test_app.client.call(
        'eth_newFilter', {
            'fromBlock': 0,
            'toBlock': 'pending',
            'topics': [topicc, topicb, topica, topic3]
        })
    topic_filter_10 = test_app.client.call(
        'eth_newFilter', {
            'fromBlock': 0,
            'toBlock': 'pending',
            'topics': [topicb, topicc, topica, topic3]
        })
    topic_filter_11 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic2, topica]
    })
    topic_filter_12 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic3, topica]
    })
    topic_filter_13 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topica, topicb]
    })
    topic_filter_14 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic2, [topica, topicb]]
    })
    topic_filter_15 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [[topic1, topic2], topica]
    })
    topic_filter_16 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [[topic1, topic2, topic3]]
    })
    topic_filter_17 = test_app.client.call(
        'eth_newFilter', {
            'fromBlock': 0,
            'toBlock': 'pending',
            'topics': [[topic1, topic2, topic3, topica, topicb, topicc]]
        })
    topic_filter_18 = test_app.client.call(
        'eth_newFilter', {
            'fromBlock': 0,
            'toBlock': 'pending',
            'topics': [topic2, topica, topicb, [topic2, topica, topicb]]
        })
    topic_filter_19 = test_app.client.call('eth_newFilter', {
        'fromBlock': 0,
        'toBlock': 'pending',
        'topics': [topic1, topica, topicb]
    })
    topic_filter_20 = test_app.client.call(
        'eth_newFilter', {
            'fromBlock': 0,
            'toBlock': 'pending',
            'topics': [[topic1, topic2], [topica, topicb], [topica, topicb]]
        })
    topic_filter_21 = test_app.client.call(
        'eth_newFilter', {
            'fromBlock': 0,
            'toBlock': 'pending',
            'topics': [[topic2, topic3], [topica, topicb], [topica, topicb]]
        })

    thecode = test_app.client.call('eth_getCode',
                                   address_encoder(sample_contract.address))
    assert len(thecode) > 2

    sample_contract.trigger1(1)
    test_app.mine_next_block()
    sample_contract.trigger2(100)
    test_app.mine_next_block()
    sample_contract.trigger3(1000)
    test_app.mine_next_block()

    tl1 = test_app.client.call('eth_getFilterChanges', topic_filter_1)
    assert len(tl1) == 1
    tl2 = test_app.client.call('eth_getFilterChanges', topic_filter_2)
    assert len(tl2) == 1
    tl3 = test_app.client.call('eth_getFilterChanges', topic_filter_3)
    assert len(tl3) == 1
    tl4 = test_app.client.call('eth_getFilterChanges', topic_filter_4)
    assert len(tl4) == 1
    tl5 = test_app.client.call('eth_getFilterChanges', topic_filter_5)
    assert len(tl5) == 1
    tl6 = test_app.client.call('eth_getFilterChanges', topic_filter_6)
    assert len(tl6) == 1
    tl7 = test_app.client.call('eth_getFilterChanges', topic_filter_7)
    assert len(tl7) == 0
    tl8 = test_app.client.call('eth_getFilterChanges', topic_filter_8)
    assert len(tl8) == 1
    tl9 = test_app.client.call('eth_getFilterChanges', topic_filter_9)
    assert len(tl9) == 0
    tl10 = test_app.client.call('eth_getFilterChanges', topic_filter_10)
    assert len(tl10) == 0
    tl11 = test_app.client.call('eth_getFilterChanges', topic_filter_11)
    assert len(tl11) == 1
    tl12 = test_app.client.call('eth_getFilterChanges', topic_filter_12)
    assert len(tl12) == 1
    tl13 = test_app.client.call('eth_getFilterChanges', topic_filter_13)
    assert len(tl13) == 0
    tl14 = test_app.client.call('eth_getFilterChanges', topic_filter_14)
    assert len(tl14) == 1
    tl15 = test_app.client.call('eth_getFilterChanges', topic_filter_15)
    assert len(tl15) == 2
    tl16 = test_app.client.call('eth_getFilterChanges', topic_filter_16)
    assert len(tl16) == 3
    tl17 = test_app.client.call('eth_getFilterChanges', topic_filter_17)
    assert len(tl17) == 3
    tl18 = test_app.client.call('eth_getFilterChanges', topic_filter_18)
    assert len(tl18) == 0
    tl19 = test_app.client.call('eth_getFilterChanges', topic_filter_19)
    assert len(tl19) == 0
    tl20 = test_app.client.call('eth_getFilterChanges', topic_filter_20)
    assert len(tl20) == 1
    tl21 = test_app.client.call('eth_getFilterChanges', topic_filter_21)
    assert len(tl21) == 2
def test_get_filter_changes(test_app):
    test_app.mine_next_block()  # start with a fresh block
    n0 = test_app.services.chain.chain.head.number
    sender = address_encoder(
        test_app.services.accounts.unlocked_accounts()[0].address)
    contract_creation = {'from': sender, 'data': data_encoder(LOG_EVM)}
    tx_hash = test_app.rpc_request('eth_sendTransaction', contract_creation)
    test_app.mine_next_block()
    receipt = test_app.rpc_request('eth_getTransactionReceipt', tx_hash)
    contract_address = receipt['contractAddress']
    tx = {'from': sender, 'to': contract_address}

    pending_filter_id = test_app.rpc_request('eth_newFilter', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    })
    latest_filter_id = test_app.rpc_request('eth_newFilter', {
        'fromBlock': 'latest',
        'toBlock': 'latest'
    })
    tx_hashes = []
    logs = []

    # tx in pending block
    tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx))
    logs.append(test_app.rpc_request('eth_getFilterChanges',
                                     pending_filter_id))
    assert len(logs[-1]) == 1
    assert logs[-1][0]['type'] == 'pending'
    assert logs[-1][0]['logIndex'] == None
    assert logs[-1][0]['transactionIndex'] == None
    assert logs[-1][0]['transactionHash'] == None
    assert logs[-1][0]['blockHash'] == None
    assert logs[-1][0]['blockNumber'] == None
    assert logs[-1][0]['address'] == contract_address
    pending_log = logs[-1][0]

    logs.append(test_app.rpc_request('eth_getFilterChanges',
                                     pending_filter_id))
    assert logs[-1] == []

    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert logs[-1] == []

    test_app.mine_next_block()
    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert len(logs[-1]) == 1  # log from before, but now mined
    assert logs[-1][0]['type'] == 'mined'
    assert logs[-1][0]['logIndex'] == '0x0'
    assert logs[-1][0]['transactionIndex'] == '0x0'
    assert logs[-1][0]['transactionHash'] == tx_hashes[-1]
    assert logs[-1][0]['blockHash'] == data_encoder(
        test_app.services.chain.chain.head.hash)
    assert logs[-1][0]['blockNumber'] == quantity_encoder(
        test_app.services.chain.chain.head.number)
    assert logs[-1][0]['address'] == contract_address
    logs_in_range = [logs[-1][0]]

    # send tx and mine block
    tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx))
    test_app.mine_next_block()
    logs.append(test_app.rpc_request('eth_getFilterChanges',
                                     pending_filter_id))
    assert len(logs[-1]) == 1
    assert logs[-1][0]['type'] == 'mined'
    assert logs[-1][0]['logIndex'] == '0x0'
    assert logs[-1][0]['transactionIndex'] == '0x0'
    assert logs[-1][0]['transactionHash'] == tx_hashes[-1]
    assert logs[-1][0]['blockHash'] == data_encoder(
        test_app.services.chain.chain.head.hash)
    assert logs[-1][0]['blockNumber'] == quantity_encoder(
        test_app.services.chain.chain.head.number)
    assert logs[-1][0]['address'] == contract_address
    logs_in_range.append(logs[-1][0])

    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert logs[-1] == logs[
        -2]  # latest and pending filter see same (mined) log

    logs.append(test_app.rpc_request('eth_getFilterChanges', latest_filter_id))
    assert logs[-1] == []

    test_app.mine_next_block()
    logs.append(test_app.rpc_request('eth_getFilterChanges',
                                     pending_filter_id))
    assert logs[-1] == []

    range_filter_id = test_app.rpc_request(
        'eth_newFilter', {
            'fromBlock':
            quantity_encoder(test_app.services.chain.chain.head.number - 3),
            'toBlock':
            'pending'
        })
    tx_hashes.append(test_app.rpc_request('eth_sendTransaction', tx))
    logs.append(test_app.rpc_request('eth_getFilterChanges', range_filter_id))
    assert sorted(logs[-1]) == sorted(logs_in_range + [pending_log])
def test_get_logs(test_app):
    test_app.mine_next_block()  # start with a fresh block
    n0 = test_app.services.chain.chain.head.number
    sender = address_encoder(
        test_app.services.accounts.unlocked_accounts()[0].address)
    contract_creation = {'from': sender, 'data': data_encoder(LOG_EVM)}
    tx_hash = test_app.rpc_request('eth_sendTransaction', contract_creation)
    test_app.mine_next_block()
    receipt = test_app.rpc_request('eth_getTransactionReceipt', tx_hash)
    contract_address = receipt['contractAddress']
    tx = {'from': sender, 'to': contract_address}

    # single log in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs1 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    })
    assert len(logs1) == 1
    assert logs1[0]['type'] == 'pending'
    assert logs1[0]['logIndex'] == None
    assert logs1[0]['transactionIndex'] == None
    assert logs1[0]['transactionHash'] == None
    assert logs1[0]['blockHash'] == None
    assert logs1[0]['blockNumber'] == None
    assert logs1[0]['address'] == contract_address

    logs2 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    })
    assert logs2 == logs1

    # same log, but now mined in head
    test_app.mine_next_block()
    logs3 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'latest',
        'toBlock': 'latest'
    })
    assert len(logs3) == 1
    assert logs3[0]['type'] == 'mined'
    assert logs3[0]['logIndex'] == '0x0'
    assert logs3[0]['transactionIndex'] == '0x0'
    assert logs3[0]['blockHash'] == data_encoder(
        test_app.services.chain.chain.head.hash)
    assert logs3[0]['blockNumber'] == quantity_encoder(
        test_app.services.chain.chain.head.number)
    assert logs3[0]['address'] == contract_address

    # another log in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs4 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'latest',
        'toBlock': 'pending'
    })
    assert logs4 == [logs1[0], logs3[0]] or logs4 == [logs3[0], logs1[0]]

    # two logs in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs5 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    })
    assert len(logs5) == 2
    assert logs5[0] == logs5[1] == logs1[0]

    # two logs in head
    test_app.mine_next_block()
    logs6 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'latest',
        'toBlock': 'pending'
    })
    for log in logs6:
        assert log['type'] == 'mined'
        assert log['logIndex'] == '0x0'
        assert log['blockHash'] == data_encoder(
            test_app.services.chain.chain.head.hash)
        assert log['blockNumber'] == quantity_encoder(
            test_app.services.chain.chain.head.number)
        assert log['address'] == contract_address
    assert sorted([log['transactionIndex'] for log in logs6]) == ['0x0', '0x1']

    # everything together with another log in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs7 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': quantity_encoder(n0),
        'toBlock': 'pending'
    })
    assert sorted(logs7) == sorted(logs3 + logs6 + logs1)
Пример #21
0
 def get_block(self, num):
     return self.client.call(
         'eth_getBlockByNumber',
         quantity_encoder(num),
         True
     )
Пример #22
0
def test_get_logs(test_app):
    test_app.mine_next_block()  # start with a fresh block
    n0 = test_app.services.chain.chain.head.number
    sender = address_encoder(test_app.services.accounts.unlocked_accounts()[0].address)
    contract_creation = {
        'from': sender,
        'data': data_encoder(LOG_EVM)
    }
    tx_hash = test_app.rpc_request('eth_sendTransaction', contract_creation)
    test_app.mine_next_block()
    receipt = test_app.rpc_request('eth_getTransactionReceipt', tx_hash)
    contract_address = receipt['contractAddress']
    tx = {
        'from': sender,
        'to': contract_address
    }

    # single log in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs1 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    });
    assert len(logs1) == 1
    assert logs1[0]['type'] == 'pending'
    assert logs1[0]['logIndex'] == None
    assert logs1[0]['transactionIndex'] == None
    assert logs1[0]['transactionHash'] == None
    assert logs1[0]['blockHash'] == None
    assert logs1[0]['blockNumber'] == None
    assert logs1[0]['address'] == contract_address

    logs2 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    });
    assert logs2 == logs1

    # same log, but now mined in head
    test_app.mine_next_block()
    logs3 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'latest',
        'toBlock': 'latest'
    });
    assert len(logs3) == 1
    assert logs3[0]['type'] == 'mined'
    assert logs3[0]['logIndex'] == '0x0'
    assert logs3[0]['transactionIndex'] == '0x0'
    assert logs3[0]['blockHash'] == data_encoder(test_app.services.chain.chain.head.hash)
    assert logs3[0]['blockNumber'] == quantity_encoder(test_app.services.chain.chain.head.number)
    assert logs3[0]['address'] == contract_address

    # another log in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs4 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'latest',
        'toBlock': 'pending'
    })
    assert logs4 == [logs1[0], logs3[0]] or logs4 == [logs3[0], logs1[0]]

    # two logs in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs5 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'pending',
        'toBlock': 'pending'
    })
    assert len(logs5) == 2
    assert logs5[0] == logs5[1] == logs1[0]

    # two logs in head
    test_app.mine_next_block()
    logs6 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': 'latest',
        'toBlock': 'pending'
    })
    for log in logs6:
        assert log['type'] == 'mined'
        assert log['logIndex'] == '0x0'
        assert log['blockHash'] == data_encoder(test_app.services.chain.chain.head.hash)
        assert log['blockNumber'] == quantity_encoder(test_app.services.chain.chain.head.number)
        assert log['address'] == contract_address
    assert sorted([log['transactionIndex'] for log in logs6]) == ['0x0', '0x1']

    # everything together with another log in pending block
    test_app.rpc_request('eth_sendTransaction', tx)
    logs7 = test_app.rpc_request('eth_getLogs', {
        'fromBlock': quantity_encoder(n0),
        'toBlock': 'pending'
    })
    assert sorted(logs7) == sorted(logs3 + logs6 + logs1)