Merge pull request #84 from pipermerriam/piper/auto-estimate-gas-for-all-transactions

Always estimate gas for transactions with data
This commit is contained in:
Piper Merriam 2016-09-06 14:13:52 -06:00 committed by GitHub
commit 577877de6b
5 changed files with 40 additions and 30 deletions

View File

@ -143,4 +143,4 @@ def test_auto_gas_computation_when_transacting(web3,
assert force_bytes(final_value) == force_bytes("ÄLÄMÖLÖ")
txn = web3.eth.getTransaction(txn_hash)
assert txn['gas'] == gas_estimate + string_contract.gas_buffer
assert txn['gas'] == gas_estimate + 100000

View File

@ -38,3 +38,17 @@ def test_eth_sendTransaction_with_data(web3, wait_for_transaction, MATH_CODE, MA
contract_address = txn_receipt['contractAddress']
assert force_bytes(web3.eth.getCode(contract_address)) == MATH_RUNTIME
def test_eth_sendTransaction_auto_estimates_gas_if_not_provided(web3, wait_for_transaction, MATH_CODE, MATH_RUNTIME):
txn_hash = web3.eth.sendTransaction({
"from": web3.eth.coinbase,
"data": MATH_CODE,
})
wait_for_transaction(web3, txn_hash)
txn_receipt = web3.eth.getTransactionReceipt(txn_hash)
contract_address = txn_receipt['contractAddress']
assert force_bytes(web3.eth.getCode(contract_address)) == MATH_RUNTIME

View File

@ -39,9 +39,6 @@ from web3.utils.abi import (
from web3.utils.decorators import (
combomethod,
)
from web3.utils.transactions import (
get_block_gas_limit,
)
from web3.utils.events import (
get_event_data,
)
@ -78,9 +75,6 @@ class Contract(object):
# instance level properties
address = None
# extra gas to include when auto-computing transaction gas.
gas_buffer = 100000
def __init__(self, abi=None, address=None, code=None, code_runtime=None, source=None):
"""Create a new smart contract proxy object.
@ -246,30 +240,10 @@ class Contract(object):
deploy_transaction['data'] = cls.encodeConstructorData(arguments)
if 'gas' not in deploy_transaction:
deploy_transaction['gas'] = cls.getBufferedGasEstimate(deploy_transaction)
# TODO: handle asynchronous contract creation
txn_hash = cls.web3.eth.sendTransaction(deploy_transaction)
return txn_hash
@classmethod
def getBufferedGasEstimate(cls, transaction):
gas_estimate_transaction = dict(**transaction)
gas_estimate = cls.web3.eth.estimateGas(gas_estimate_transaction)
gas_limit = get_block_gas_limit(cls.web3)
if gas_estimate > gas_limit:
raise ValueError(
"Contract does not appear to be delpoyable within the "
"current network gas limits. Estimated: {0}. Current gas "
"limit: {1}".format(gas_estimate, gas_limit)
)
return min(gas_limit, gas_estimate + cls.gas_buffer)
#
# ABI Helpers
#
@ -756,9 +730,6 @@ def transact_with_contract_function(contract=None,
data=function_selector,
)
if 'gas' not in transact_transaction:
transact_transaction['gas'] = contract.getBufferedGasEstimate(transact_transaction)
txn_hash = contract.web3.eth.sendTransaction(transact_transaction)
return txn_hash

View File

@ -12,6 +12,9 @@ from web3.utils.types import (
from web3.utils.functional import (
apply_formatters_to_return,
)
from web3.utils.transactions import (
get_buffered_gas_estimate,
)
from web3.utils.filters import (
BlockFilter,
TransactionFilter,
@ -204,6 +207,11 @@ class Eth(object):
def sendTransaction(self, transaction):
formatted_transaction = formatters.input_transaction_formatter(self, transaction)
if 'gas' not in formatted_transaction and 'data' in formatted_transaction:
formatted_transaction['gas'] = get_buffered_gas_estimate(
self.web3,
transaction=formatted_transaction,
)
return self.request_manager.request_blocking(
"eth_sendTransaction",

View File

@ -17,3 +17,20 @@ def get_block_gas_limit(web3, block_identifier=None):
block_identifier = web3.eth.blockNumber
block = web3.eth.getBlock(block_identifier)
return block['gasLimit']
def get_buffered_gas_estimate(web3, transaction, gas_buffer=100000):
gas_estimate_transaction = dict(**transaction)
gas_estimate = web3.eth.estimateGas(gas_estimate_transaction)
gas_limit = get_block_gas_limit(web3)
if gas_estimate > gas_limit:
raise ValueError(
"Contract does not appear to be delpoyable within the "
"current network gas limits. Estimated: {0}. Current gas "
"limit: {1}".format(gas_estimate, gas_limit)
)
return min(gas_limit, gas_estimate + gas_buffer)