Esempio n. 1
0
def test_resending_mined_transaction_raises(
        deploy_client: JSONRPCClient) -> None:
    """ If a mined transaction is re-sent the exception `EthereumNonceTooLow` is raised. """
    # Use a _fixed_ gas price strategy so that both transactions are identical.
    deploy_client.web3.eth.setGasPriceStrategy(
        make_fixed_gas_price_strategy(GasPrice(2000000000)))
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.address
    assert len(deploy_client.web3.eth.getCode(address)) > 0

    # Create a new instance of the JSONRPCClient, this will store the current available nonce
    client_invalid_nonce = JSONRPCClient(deploy_client.web3,
                                         deploy_client.privkey)

    estimated_transaction = deploy_client.estimate_gas(contract_proxy, "ret",
                                                       {})
    assert estimated_transaction, "Gas estimation should not fail here"

    transaction_hash = deploy_client.transact(estimated_transaction)
    deploy_client.poll_transaction(transaction_hash)

    # At this point `client_invalid_nonce` has a nonce that is `1` too low,
    # since a transaction was sent using `deploy_client` above and these two
    # instances share the same underlying private key.
    #
    # Note that the same function is called in this test.
    with pytest.raises(EthereumNonceTooLow):
        proxy_invalid = client_invalid_nonce.new_contract_proxy(
            abi=contract_proxy.abi, contract_address=contract_proxy.address)
        estimated_transaction_invalid = deploy_client.estimate_gas(
            proxy_invalid, "ret", {})
        msg = "ret always succed, gas estimation should have succeed."
        assert estimated_transaction_invalid, msg
        client_invalid_nonce.transact(estimated_transaction_invalid)
Esempio n. 2
0
def test_reusing_nonce_with_lower_gas_raises(
        deploy_client: JSONRPCClient) -> None:
    """ If a _new_ transaction is sent but with a lower gas the exception
    `ReplacementTransactionUnderpriced` is raised.
    """
    # Use a _decreasing_ gas price strategy so that the second transactions is
    # lower than the first.
    deploy_client.web3.eth.setGasPriceStrategy(
        make_decreasing_gas_price_strategy(GasPrice(2000000000)))
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.address
    assert len(deploy_client.web3.eth.getCode(address)) > 0

    client_invalid_nonce = JSONRPCClient(web3=deploy_client.web3,
                                         privkey=deploy_client.privkey)

    estimated_transaction = deploy_client.estimate_gas(contract_proxy, "ret",
                                                       {})
    assert estimated_transaction, "Gas estimation should not fail here"
    deploy_client.transact(estimated_transaction)

    # At this point `client_invalid_nonce` has a nonce that is `1` too low,
    # since a transaction was sent using `deploy_client` above and these two
    # instances share the same underlying private key.
    #
    # Note that the same function is called in this test but the gas is decreasing.
    with pytest.raises(ReplacementTransactionUnderpriced):
        proxy_invalid = client_invalid_nonce.new_contract_proxy(
            abi=contract_proxy.abi, contract_address=contract_proxy.address)
        estimated_transaction = client_invalid_nonce.estimate_gas(
            proxy_invalid, "ret_str", {})
        assert estimated_transaction, "ret_str never fails, gas estimation must succeed."
        client_invalid_nonce.transact(estimated_transaction)
Esempio n. 3
0
def test_reusing_nonce_with_lower_gas_raises(
        deploy_client: JSONRPCClient) -> None:
    """ If a _new_ transaction is sent but with a lower gas the exception
    `ReplacementTransactionUnderpriced` is raised.
    """
    # Use a _decreasing_ gas price strategy so that the second transactions is
    # lower than the first.
    deploy_client.web3.eth.setGasPriceStrategy(
        make_decreasing_gas_price_strategy(GasPrice(2000000000)))
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(
        to_checksum_address(address))) > 0

    client_invalid_nonce = JSONRPCClient(web3=deploy_client.web3,
                                         privkey=deploy_client.privkey)

    check_block = deploy_client.get_checking_block()
    gas_estimate = contract_proxy.estimate_gas(check_block, "ret")
    assert gas_estimate, "Gas estimation should not fail here"
    startgas = safe_gas_limit(gas_estimate)

    contract_proxy.transact("ret", startgas)

    # At this point `client_invalid_nonce` has a nonce that is `1` too low,
    # since a transaction was sent using `deploy_client` above and these two
    # instances share the same underlying private key.
    #
    # Note that the same function is called in this test but the gas is decreasing.
    with pytest.raises(ReplacementTransactionUnderpriced):
        client_invalid_nonce.new_contract_proxy(
            abi=contract_proxy.contract.abi,
            contract_address=contract_proxy.contract_address).transact(
                "ret_str", contract_proxy.estimate_gas(check_block, "ret_str"))
Esempio n. 4
0
def test_filter_end_block_inclusive(deploy_client):
    """ A filter includes events from the block given in from_block
    until and including end_block. """
    contract_proxy = deploy_rpc_test_contract(deploy_client, "RpcTest")

    check_block = deploy_client.get_checking_block()
    # call the create event function twice and wait for confirmation each time
    startgas = safe_gas_limit(contract_proxy.estimate_gas(check_block, "createEvent", 1))
    transaction_1 = contract_proxy.transact("createEvent", startgas, 1)
    deploy_client.poll(transaction_1)
    transaction_2 = contract_proxy.transact("createEvent", startgas, 2)
    deploy_client.poll(transaction_2)

    result_1 = deploy_client.get_filter_events(contract_proxy.contract_address)
    block_number_events = get_list_of_block_numbers(result_1)
    block_number_event_1 = block_number_events[0]
    block_number_event_2 = block_number_events[1]

    # inclusive to_block should return first event
    result_2 = deploy_client.get_filter_events(
        contract_proxy.contract_address, to_block=block_number_event_1
    )
    assert get_list_of_block_numbers(result_2) == [block_number_event_1]

    # this should include the second event
    result_3 = deploy_client.get_filter_events(
        contract_proxy.contract_address, to_block=block_number_event_2
    )
    assert get_list_of_block_numbers(result_3) == block_number_events
Esempio n. 5
0
def test_reusing_nonce_from_a_mined_transaction_raises(
        deploy_client: JSONRPCClient) -> None:
    """ If a _new_ transaction is sent with an old nonce the exception
    `EthereumNonceTooLow` is raised.
    """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    # Create a new instance of the JSONRPCClient, this will store the current available nonce
    client_invalid_nonce = JSONRPCClient(deploy_client.web3,
                                         deploy_client.privkey)

    estimated_transaction = deploy_client.estimate_gas(contract_proxy, "ret",
                                                       {})
    msg = "ret always succed, gas estimation should have succeed."
    assert estimated_transaction, msg
    transaction_hash = deploy_client.transact(estimated_transaction)

    # Wait for the transaction to be mined (concurrent transactions are tested
    # by test_local_transaction_with_zero_gasprice_is_mined)
    deploy_client.poll_transaction(transaction_hash)

    # At this point `client_invalid_nonce` has a nonce that is `1` too low,
    # since a transaction was sent using `deploy_client` above and these two
    # instances share the same underlying private key.
    #
    # Note that a different function is called in this test.
    with pytest.raises(EthereumNonceTooLow):
        proxy_invalid = client_invalid_nonce.new_contract_proxy(
            abi=contract_proxy.abi, contract_address=contract_proxy.address)
        estimated_transaction_invalid = deploy_client.estimate_gas(
            proxy_invalid, "ret_str", {})
        msg = "ret_str always succed, gas estimation should have succeed."
        assert estimated_transaction_invalid, msg
        client_invalid_nonce.transact(estimated_transaction_invalid)
Esempio n. 6
0
def test_resending_mined_transaction_raises(
        deploy_client: JSONRPCClient) -> None:
    """ If a mined transaction is re-sent the exception `EthereumNonceTooLow` is raised. """
    # Use a _fixed_ gas price strategy so that both transactions are identical.
    deploy_client.web3.eth.setGasPriceStrategy(
        make_fixed_gas_price_strategy(GasPrice(2000000000)))
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(
        to_checksum_address(address))) > 0

    # Create a new instance of the JSONRPCClient, this will store the current available nonce
    client_invalid_nonce = JSONRPCClient(deploy_client.web3,
                                         deploy_client.privkey)

    check_block = deploy_client.get_checking_block()
    gas_estimate = contract_proxy.estimate_gas(check_block, "ret")
    assert gas_estimate, "Gas estimation should not fail here"
    startgas = safe_gas_limit(gas_estimate)

    txhash = contract_proxy.transact("ret", startgas)
    deploy_client.poll(txhash)

    # At this point `client_invalid_nonce` has a nonce that is `1` too low,
    # since a transaction was sent using `deploy_client` above and these two
    # instances share the same underlying private key.
    #
    # Note that the same function is called in this test.
    with pytest.raises(EthereumNonceTooLow):
        client_invalid_nonce.new_contract_proxy(
            abi=contract_proxy.contract.abi,
            contract_address=contract_proxy.contract_address).transact(
                "ret", startgas)
Esempio n. 7
0
def test_reusing_nonce_from_a_mined_transaction_raises(
        deploy_client: JSONRPCClient) -> None:
    """ If a _new_ transaction is sent with an old nonce the exception
    `EthereumNonceTooLow` is raised.
    """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    # Create a new instance of the JSONRPCClient, this will store the current available nonce
    client_invalid_nonce = JSONRPCClient(deploy_client.web3,
                                         deploy_client.privkey)

    check_block = deploy_client.get_checking_block()
    txhash = contract_proxy.transact(
        "ret", contract_proxy.estimate_gas(check_block, "ret"))

    # Wait for the transaction to be mined (concurrent transactions are tested
    # by test_local_transaction_with_zero_gasprice_is_mined)
    deploy_client.poll(txhash)

    # At this point `client_invalid_nonce` has a nonce that is `1` too low,
    # since a transaction was sent using `deploy_client` above and these two
    # instances share the same underlying private key.
    #
    # Note that a different function is called in this test.
    with pytest.raises(EthereumNonceTooLow):
        client_invalid_nonce.new_contract_proxy(
            abi=contract_proxy.contract.abi,
            contract_address=contract_proxy.contract_address).transact(
                "ret_str", contract_proxy.estimate_gas(check_block, "ret_str"))
Esempio n. 8
0
def test_local_transaction_with_zero_gasprice_is_mined(
        deploy_client: JSONRPCClient) -> None:
    """ If a transaction is sent through the eth_sendRawTransaction interface,
    directly to the miner, with a gas price of zero, it is considered local and
    mined anyways.
    """
    normal_gas_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    gas_price = GasPrice(0)
    gas_price_strategy = make_fixed_gas_price_strategy(gas_price)
    deploy_client.web3.eth.setGasPriceStrategy(gas_price_strategy)
    zero_gas_proxy = deploy_client.new_contract_proxy(
        abi=normal_gas_proxy.contract.abi,
        contract_address=normal_gas_proxy.contract_address)

    address = normal_gas_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(
        to_checksum_address(address))) > 0

    check_block = deploy_client.get_checking_block()
    gas_estimate = zero_gas_proxy.estimate_gas(check_block, "ret")
    assert gas_estimate, "Gas estimation should not fail here"

    zerogas_txhash = zero_gas_proxy.transact("ret", gas_estimate)
    zerogas_receipt = deploy_client.poll(zerogas_txhash)
    zerogas_tx = deploy_client.web3.eth.getTransaction(zerogas_txhash)

    msg = "Even thought the transaction had a zero gas price, it is not removed from the pool"
    assert zerogas_tx is not None, msg

    msg = "Even though the transaction had gas price of zero, it did get mined."
    assert zerogas_receipt["status"] != RECEIPT_FAILURE_CODE, msg
def test_filter_start_block_inclusive(deploy_client: JSONRPCClient) -> None:
    """ A filter includes events from the block given in from_block """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    # call the create event function twice and wait for confirmation each time
    estimated_transaction1 = deploy_client.estimate_gas(
        contract_proxy, "createEvent", {}, 1)
    assert estimated_transaction1
    transaction_1 = deploy_client.transact(estimated_transaction1)
    deploy_client.poll_transaction(transaction_1)

    estimated_transaction2 = deploy_client.estimate_gas(
        contract_proxy, "createEvent", {}, 1)
    assert estimated_transaction2
    transaction_2 = deploy_client.transact(estimated_transaction2)
    deploy_client.poll_transaction(transaction_2)

    result_1 = deploy_client.get_filter_events(contract_proxy.address)
    block_number_events = get_list_of_block_numbers(result_1)
    block_number_event_1 = block_number_events[0]
    block_number_event_2 = block_number_events[1]

    # inclusive from_block should return both events
    result_2 = deploy_client.get_filter_events(contract_proxy.address,
                                               from_block=block_number_event_1)
    assert get_list_of_block_numbers(result_2) == block_number_events

    # a higher from_block must not contain the first event
    result_3 = deploy_client.get_filter_events(
        contract_proxy.address, from_block=block_number_event_1 + 1)
    assert get_list_of_block_numbers(result_3) == [block_number_event_2]
def test_filter_end_block_inclusive(deploy_client: JSONRPCClient) -> None:
    """A filter includes events from the block given in from_block
    until and including end_block."""
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    # call the create event function twice and wait for confirmation each time
    estimated_transaction1 = deploy_client.estimate_gas(
        contract_proxy, "createEvent", {}, 1)
    assert estimated_transaction1
    transaction_1 = deploy_client.transact(estimated_transaction1)
    deploy_client.poll_transaction(transaction_1)

    estimated_transaction2 = deploy_client.estimate_gas(
        contract_proxy, "createEvent", {}, 1)
    assert estimated_transaction2
    transaction_2 = deploy_client.transact(estimated_transaction2)
    deploy_client.poll_transaction(transaction_2)

    result_1 = deploy_client.get_filter_events(contract_proxy.address)
    block_number_events = get_list_of_block_numbers(result_1)
    block_number_event_1 = block_number_events[0]
    block_number_event_2 = block_number_events[1]

    # inclusive to_block should return first event
    result_2 = deploy_client.get_filter_events(contract_proxy.address,
                                               to_block=block_number_event_1)
    assert get_list_of_block_numbers(result_2) == [block_number_event_1]

    # this should include the second event
    result_3 = deploy_client.get_filter_events(contract_proxy.address,
                                               to_block=block_number_event_2)
    assert get_list_of_block_numbers(result_3) == block_number_events
def test_estimate_gas_fails_if_startgas_is_higher_than_blockgaslimit(
    deploy_client: JSONRPCClient,
) -> None:
    """ Gas estimation fails if the transaction execution requires more gas
    than the block's gas limit.
    """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcWithStorageTest")

    latest_block_hash = deploy_client.blockhash_from_blocknumber(BLOCK_ID_LATEST)
    current_gas_limit = deploy_client.get_block(latest_block_hash)["gasLimit"]

    # This number of iterations is an over estimation to accomodate for races,
    # this cannot be significantly large because on parity it is a blocking
    # call.
    number_iterations = current_gas_limit // SSTORE_COST

    # This race condition cannot be fixed because geth does not support
    # block_identifier for eth_estimateGas. The test should not be flaky
    # because number_iterations is order of magnitudes larger then it needs to
    # be
    estimated_transaction = deploy_client.estimate_gas(
        contract_proxy, "waste_storage", {}, number_iterations
    )
    msg = "estimate_gas must return empty if sending the transaction would fail"
    assert estimated_transaction is None, msg
def test_parity_request_pruned_data_raises_an_exception(
        deploy_client: JSONRPCClient) -> None:
    """ Interacting with an old block identifier with a pruning client throws. """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client,
                                                 "RpcWithStorageTest")
    iterations = 1000

    def send_transaction() -> TransactionMined:
        estimated_transaction = deploy_client.estimate_gas(
            contract_proxy, "waste_storage", {}, iterations)
        assert estimated_transaction
        transaction = deploy_client.transact(estimated_transaction)
        return deploy_client.poll_transaction(transaction)

    first_receipt = send_transaction().receipt
    pruned_block_number = first_receipt["blockNumber"]

    for _ in range(10):
        send_transaction()

    with pytest.raises(ValueError):
        contract_proxy.functions.const().call(
            block_identifier=pruned_block_number)

    with pytest.raises(ValueError):
        contract_proxy.functions.get(1).call(
            block_identifier=pruned_block_number)

    with pytest.raises(ValueError):
        check_address_has_code(
            deploy_client,
            to_canonical_address(contract_proxy.address),
            "RpcWithStorageTest",
            given_block_identifier=pruned_block_number,
        )
def test_estimate_gas_defaults_to_pending(deploy_client: JSONRPCClient) -> None:
    """Estimating gas without an explicit block identifier always return an
    usable value.

    This test makes sure that the gas estimation works as expected (IOW, it
    will produce a value that can be used for start_gas and the transaction
    will be mined).

    This test was added because the clients Geth and Parity diverge in their
    estimate_gas interface. Geth never accepts a block_identifier for
    eth_estimateGas, and Parity rejects anything but `latest` if it is run with
    `--pruning=fast`.
    """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcWithStorageTest")

    estimated_first_transaction = deploy_client.estimate_gas(
        contract_proxy, "gas_increase_exponential", {}
    )
    assert estimated_first_transaction, "gas estimation should not have failed"
    first_tx = deploy_client.transact(estimated_first_transaction)

    estimated_second_transaction = deploy_client.estimate_gas(
        contract_proxy, "gas_increase_exponential", {}
    )
    assert estimated_second_transaction, "gas estimation should not have failed"
    second_tx = deploy_client.transact(estimated_second_transaction)

    first_receipt = deploy_client.poll_transaction(first_tx).receipt
    second_receipt = deploy_client.poll_transaction(second_tx).receipt

    assert second_receipt["gasLimit"] < deploy_client.get_block(BLOCK_ID_LATEST)["gasLimit"]
    assert first_receipt["status"] != RECEIPT_FAILURE_CODE
    assert second_receipt["status"] != RECEIPT_FAILURE_CODE
def test_resending_pending_transaction_raises(deploy_client: JSONRPCClient) -> None:
    """ If a pending transaction is re-sent the exception `EthereumNonceTooLow` is raised.

    This tests is only sufficient because of the companion test
    `test_resending_mined_transaction_raises` which shows that if the
    transaction has been mined a different exception is raised.
    """
    # Use a _fixed_ gas price strategy so that both transactions are identical.
    deploy_client.web3.eth.setGasPriceStrategy(make_fixed_gas_price_strategy(GasPrice(2000000000)))
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(to_checksum_address(address))) > 0

    # Create a new instance of the JSONRPCClient, this will store the current available nonce
    client_invalid_nonce = JSONRPCClient(web3=deploy_client.web3, privkey=deploy_client.privkey)

    check_block = deploy_client.get_checking_block()
    gas_estimate = contract_proxy.estimate_gas(check_block, "ret")
    assert gas_estimate, "Gas estimation should not fail here"
    startgas = safe_gas_limit(gas_estimate)

    # At this point `client_invalid_nonce` has a nonce that is `1` too low,
    # since a transaction was sent using `deploy_client` above and these two
    # instances share the same underlying private key.
    #
    # Note that it is assumed this runs fast enough so that the first transaction is not
    # mined before second is sent.
    contract_proxy.transact("ret", startgas)
    with pytest.raises(EthereumNonceTooLow):
        client_invalid_nonce.new_contract_proxy(
            abi=contract_proxy.contract.abi, contract_address=contract_proxy.contract_address
        ).transact("ret", startgas)
Esempio n. 15
0
def test_parity_request_prunned_data_raises_an_exception(deploy_client):
    """ Interacting with an old block identifier with a pruning client throws. """
    contract_proxy = deploy_rpc_test_contract(deploy_client,
                                              "RpcWithStorageTest")
    iterations = 1000

    def send_transaction():
        check_block = deploy_client.get_checking_block()
        startgas = contract_proxy.estimate_gas(check_block, "waste_storage",
                                               iterations)
        startgas = safe_gas_limit(startgas)
        transaction = contract_proxy.transact("waste_storage", startgas,
                                              iterations)
        deploy_client.poll(transaction)
        return deploy_client.get_transaction_receipt(transaction)

    first_receipt = send_transaction()
    pruned_block_number = first_receipt["blockNumber"]

    for _ in range(10):
        send_transaction()

    with pytest.raises(ValueError):
        contract_proxy.contract.functions.const().call(
            block_identifier=pruned_block_number)

    with pytest.raises(ValueError):
        contract_proxy.contract.functions.get(1).call(
            block_identifier=pruned_block_number)
def test_filter_start_block_inclusive(deploy_client):
    """ A filter includes events from the block given in from_block """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    check_block = deploy_client.get_checking_block()
    # call the create event function twice and wait for confirmation each time
    startgas = safe_gas_limit(contract_proxy.estimate_gas(check_block, "createEvent", 1))
    transaction_1 = contract_proxy.transact("createEvent", startgas, 1)
    deploy_client.poll(transaction_1)
    transaction_2 = contract_proxy.transact("createEvent", startgas, 2)
    deploy_client.poll(transaction_2)

    result_1 = deploy_client.get_filter_events(contract_proxy.contract_address)
    block_number_events = get_list_of_block_numbers(result_1)
    block_number_event_1 = block_number_events[0]
    block_number_event_2 = block_number_events[1]

    # inclusive from_block should return both events
    result_2 = deploy_client.get_filter_events(
        contract_proxy.contract_address, from_block=block_number_event_1
    )
    assert get_list_of_block_numbers(result_2) == block_number_events

    # a higher from_block must not contain the first event
    result_3 = deploy_client.get_filter_events(
        contract_proxy.contract_address, from_block=block_number_event_1 + 1
    )
    assert get_list_of_block_numbers(result_3) == [block_number_event_2]
def test_call_throws(deploy_client):
    """ A JSON RPC call to a function that throws/gets reverted returns the empty string. """
    contract_proxy = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(to_checksum_address(address))) > 0
    call = contract_proxy.contract.functions.fail().call
    assert call() == []
def test_estimate_gas_fail(deploy_client):
    """ A JSON RPC estimate gas call for a throwing transaction returns None"""
    contract_proxy = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(to_checksum_address(address))) > 0

    check_block = deploy_client.get_checking_block()
    assert not contract_proxy.estimate_gas(check_block, "fail")
def test_call_throws(deploy_client: JSONRPCClient) -> None:
    """ A JSON RPC call to a function that throws/gets reverted returns the empty string. """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.address
    assert len(deploy_client.web3.eth.getCode(address)) > 0

    call = contract_proxy.functions.fail_assert().call
    assert call() == []

    call = contract_proxy.functions.fail_require().call
    assert call() == []
def test_estimate_gas_fail(deploy_client: JSONRPCClient) -> None:
    """ A JSON RPC estimate gas call for a throwing transaction returns None"""
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.address
    assert len(deploy_client.web3.eth.getCode(address)) > 0

    msg = "Estimate gas should return None if the transaction hit an assert"
    assert deploy_client.estimate_gas(contract_proxy, "fail_assert", {}) is None, msg

    msg = "Estimate gas should return None if the transaction hit a revert."
    assert deploy_client.estimate_gas(contract_proxy, "fail_require", {}) is None, msg
Esempio n. 21
0
def test_call_works_with_blockhash(deploy_client):
    """ A JSON RPC call works with a block number or blockhash. """
    contract_proxy, receipt = deploy_rpc_test_contract(deploy_client,
                                                       "RpcTest")

    deploy_blockhash = receipt["blockHash"]
    assert contract_proxy.contract.functions.ret().call(
        block_identifier=deploy_blockhash) == 1

    deploy_block = receipt["blockNumber"]
    assert contract_proxy.contract.functions.ret().call(
        block_identifier=deploy_block) == 1
def test_call_with_a_block_number_before_smart_contract_deployed(
    deploy_client: JSONRPCClient, ) -> None:
    """ A JSON RPC call using a block number where the smart contract was not
    yet deployed should raise.
    """
    contract_proxy, receipt = deploy_rpc_test_contract(deploy_client,
                                                       "RpcTest")

    deploy_block = receipt["blockNumber"]
    assert contract_proxy.functions.ret().call(
        block_identifier=deploy_block) == 1

    with pytest.raises(BadFunctionCallOutput):
        contract_proxy.functions.ret().call(block_identifier=deploy_block - 1)
Esempio n. 23
0
def test_estimate_gas_fail(deploy_client):
    """ A JSON RPC estimate gas call for a throwing transaction returns None"""
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(to_checksum_address(address))) > 0

    check_block = deploy_client.get_checking_block()

    msg = "Estimate gas should return None if the transaction hit an assert"
    assert contract_proxy.estimate_gas(check_block, "fail_assert") is None, msg

    msg = "Estimate gas should return None if the transaction hit a revert."
    assert contract_proxy.estimate_gas(check_block, "fail_require") is None, msg
def test_transact_opcode(deploy_client: JSONRPCClient) -> None:
    """ The receipt status field of a transaction that did not throw is 0x1 """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(
        to_checksum_address(address))) > 0

    check_block = deploy_client.get_checking_block()
    startgas = contract_proxy.estimate_gas(check_block, "ret") * 2

    transaction = contract_proxy.transact("ret", startgas)
    receipt = deploy_client.poll(transaction)

    assert check_transaction_threw(receipt=receipt) is None, "must be empty"
def test_transact_throws_opcode(deploy_client: JSONRPCClient) -> None:
    """ The receipt status field of a transaction that hit an assert or require is 0x0 """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.address
    assert len(deploy_client.web3.eth.getCode(address)) > 0

    # the method always fails, so the gas estimation returns 0 here, using a
    # hardcoded a value to circumvent gas estimation.
    estimated_gas = safe_gas_limit(22000)
    gas_price = gas_price_for_fast_transaction(deploy_client.web3)

    block = deploy_client.get_block(BLOCK_ID_LATEST)

    estimated_transaction_fail_assert = TransactionEstimated(
        from_address=address,
        data=SmartContractCall(contract_proxy, "fail_assert", (), {}, value=0),
        eth_node=deploy_client.eth_node,
        extra_log_details={},
        estimated_gas=estimated_gas,
        gas_price=gas_price,
        approximate_block=(block["hash"], block["number"]),
    )
    transaction_fail_assert_sent = deploy_client.transact(
        estimated_transaction_fail_assert)
    transaction_fail_assert_mined = deploy_client.poll_transaction(
        transaction_fail_assert_sent)
    msg = "Transaction must have failed"
    assert not was_transaction_successfully_mined(
        transaction_fail_assert_mined), msg

    estimated_transaction_fail_require = TransactionEstimated(
        from_address=address,
        data=SmartContractCall(contract_proxy, "fail_require", (), {},
                               value=0),
        eth_node=deploy_client.eth_node,
        extra_log_details={},
        estimated_gas=estimated_gas,
        gas_price=gas_price,
        approximate_block=(block["hash"], block["number"]),
    )
    transaction_fail_require_sent = deploy_client.transact(
        estimated_transaction_fail_require)
    transaction_fail_require_mined = deploy_client.poll_transaction(
        transaction_fail_require_sent)
    msg = "Transaction must have failed"
    assert not was_transaction_successfully_mined(
        transaction_fail_require_mined), msg
def test_transact_opcode(deploy_client: JSONRPCClient) -> None:
    """ The receipt status field of a transaction that did not throw is 0x1 """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.address
    assert len(deploy_client.web3.eth.getCode(address)) > 0

    estimated_transaction = deploy_client.estimate_gas(contract_proxy, "ret",
                                                       {})
    assert estimated_transaction
    estimated_transaction.estimated_gas *= 2

    transaction_sent = deploy_client.transact(estimated_transaction)
    transaction_mined = deploy_client.poll_transaction(transaction_sent)
    assert was_transaction_successfully_mined(
        transaction_mined), "Transaction must be succesfull"
def test_transact_fails_if_the_account_does_not_have_enough_eth_to_pay_for_the_gas(
    deploy_client: JSONRPCClient, ) -> None:
    """ The gas estimation does not fail if the transaction execution requires
    more gas then the account's eth balance. However sending the transaction
    will.
    """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    estimated_transaction = deploy_client.estimate_gas(contract_proxy, "loop",
                                                       {}, 1000)
    assert estimated_transaction, "The gas estimation should not have failed."

    burn_eth(deploy_client,
             amount_to_leave=estimated_transaction.estimated_gas // 2)
    with pytest.raises(InsufficientEth):
        deploy_client.transact(estimated_transaction)
def test_transact_throws_opcode(deploy_client):
    """ The receipt status field of a transaction that threw is 0x0 """
    contract_proxy = deploy_rpc_test_contract(deploy_client, "RpcTest")

    address = contract_proxy.contract_address
    assert len(deploy_client.web3.eth.getCode(
        to_checksum_address(address))) > 0

    # the gas estimation returns 0 here, so hardcode a value
    startgas = safe_gas_limit(22_000)

    transaction = contract_proxy.transact("fail", startgas)
    deploy_client.poll(transaction)

    assert check_transaction_threw(deploy_client,
                                   transaction), "must not be empty"
Esempio n. 29
0
def test_call_which_returns_a_string_before_smart_contract_deployed(
        deploy_client):
    """ A JSON RPC call using a block number where the smart contract was not
    yet deployed should raise, even if the ABI of the function returns an empty
    string.
    """
    contract_proxy, receipt = deploy_rpc_test_contract(deploy_client,
                                                       "RpcTest")

    deploy_block = receipt["blockNumber"]
    assert contract_proxy.contract.functions.ret_str().call(
        block_identifier=deploy_block) == ""

    with pytest.raises(BadFunctionCallOutput):
        contract_proxy.contract.functions.ret_str().call(
            block_identifier=deploy_block - 1)
def test_transact_fails_if_the_account_does_not_have_enough_eth_to_pay_for_the_gas(
        deploy_client: JSONRPCClient) -> None:
    """ The gas estimation does not fail if the transaction execution requires
    more gas then the account's eth balance. However sending the transaction
    will.
    """
    contract_proxy, _ = deploy_rpc_test_contract(deploy_client, "RpcTest")

    check_block = deploy_client.get_checking_block()

    startgas = contract_proxy.estimate_gas(check_block, "loop", 1000)
    assert startgas, "The gas estimation should not have failed."

    burn_eth(deploy_client, amount_to_leave=startgas // 2)
    with pytest.raises(InsufficientEth):
        contract_proxy.transact("loop", startgas, 1000)