Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow block identifier for Contract.estimateGas #1639

Merged
merged 7 commits into from
Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/contracts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ Methods
# You can check the state after your pending transactions (if supported by your node):
>>> token_contract.functions.myBalance().call(block_identifier='pending')

.. py:method:: ContractFunction.estimateGas(transaction)
.. py:method:: ContractFunction.estimateGas(transaction, block_identifier=None)

Call a contract function, executing the transaction locally using the
``eth_call`` API. This will not create a new public transaction.
Expand All @@ -845,6 +845,11 @@ Methods
>>> my_contract.functions.multiply7(3).estimateGas()
42650

.. note::
The parameter ``block_identifier`` is not enabled in geth nodes,
hence passing a value of ``block_identifier`` when connected to a geth
nodes would result in an error like: ``ValueError: {'code': -32602, 'message': 'too many arguments, want at most 1'}``

.. py:method:: ContractFunction.buildTransaction(transaction)

Builds a transaction dictionary based on the contract function call specified.
Expand Down
1 change: 1 addition & 0 deletions newsfragments/1639.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Accept a block identifier in the ``Contract.estimateGas`` method. Includes a related upgrade of eth-tester to v0.5.0-beta.1.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

extras_require = {
'tester': [
"eth-tester[py-evm]==v0.4.0-beta.2",
"eth-tester[py-evm]==v0.5.0-beta.1",
"py-geth>=2.2.0,<3",
],
'linter': [
Expand Down
27 changes: 27 additions & 0 deletions tests/core/contracts/test_contract_estimateGas.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,30 @@ def test_estimateGas_sending_ether_to_nonpayable_function(
estimateGas(contract=payable_tester_contract,
contract_function='doNoValueCall',
tx_params={'value': 1})


def test_estimateGas_accepts_latest_block(web3, math_contract, transact):
gas_estimate = math_contract.functions.counter().estimateGas(block_identifier='latest')

txn_hash = transact(
contract=math_contract,
contract_function='increment')

txn_receipt = web3.eth.waitForTransactionReceipt(txn_hash)
gas_used = txn_receipt.get('gasUsed')

assert abs(gas_estimate - gas_used) < 21000


def test_estimateGas_block_identifier_unique_estimates(web3, math_contract, transact):
txn_hash = transact(contract=math_contract, contract_function="increment")
web3.eth.waitForTransactionReceipt(txn_hash)

latest_gas_estimate = math_contract.functions.counter().estimateGas(
block_identifier="latest"
)
earliest_gas_estimate = math_contract.functions.counter().estimateGas(
block_identifier="earliest"
)

assert latest_gas_estimate != earliest_gas_estimate
1 change: 0 additions & 1 deletion tests/integration/test_ethereum_tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,6 @@ def test_eth_call_old_contract_state(self, eth_tester, web3, math_contract, unlo
def test_eth_getStorageAt(self, web3, emitter_contract_address):
super().test_eth_getStorageAt(web3, emitter_contract_address)

@pytest.mark.xfail(reason='Block identifier has not been implemented in eth-tester')
def test_eth_estimateGas_with_block(self,
web3,
unlocked_account_dual_type):
Expand Down
9 changes: 6 additions & 3 deletions web3/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,9 @@ def transact(self, transaction: TxParams=None) -> HexBytes:
**self.kwargs
)

def estimateGas(self, transaction: TxParams=None) -> int:
def estimateGas(
self, transaction: TxParams=None, block_identifier: BlockIdentifier=None
) -> int:
if transaction is None:
estimate_gas_transaction: TxParams = {}
else:
Expand Down Expand Up @@ -1031,6 +1033,7 @@ def estimateGas(self, transaction: TxParams=None) -> int:
estimate_gas_transaction,
self.contract_abi,
self.abi,
block_identifier,
*self.args,
**self.kwargs
)
Expand Down Expand Up @@ -1588,6 +1591,7 @@ def estimate_gas_for_function(
transaction: TxParams=None,
contract_abi: ABI=None,
fn_abi: ABIFunction=None,
block_identifier: BlockIdentifier=None,
*args: Any,
**kwargs: Any) -> int:
"""Estimates gas cost a function call would take.
Expand All @@ -1606,8 +1610,7 @@ def estimate_gas_for_function(
fn_kwargs=kwargs,
)

gas_estimate = web3.eth.estimateGas(estimate_transaction)
return gas_estimate
return web3.eth.estimateGas(estimate_transaction, block_identifier)


def build_transaction_for_function(
Expand Down