original eth-tester estimate_gas:
421 def estimate_gas (self , transaction ):
1 # TODO: move this to the VM level (and use binary search approach)
2 signed_evm_transaction = self ._get_normalized_and_signed_evm_transaction (
3 dict (transaction , gas = self ._max_available_gas ()),
4 )
5
6 computation = _execute_and_revert_transaction (self .chain , signed_evm_transaction , 'pending' )
7 if computation .is_error :
8 raise TransactionFailed (str (computation ._error ))
9
10 gas_used = computation .gas_meter .start_gas - computation .gas_meter .gas_remaining
11
12 return int (max (gas_used * GAS_ESTIMATE_BUFFER , MINIMUM_GAS_ESTIMATE ))
replacing with py-evm chain.estimate_gas().
def estimate_gas (self , transaction ):
signed_evm_transaction = self ._get_normalized_and_signed_evm_transaction (
dict (transaction , gas = self ._max_available_gas ()),
block_number = 'pending' ,
)
return self .chain .estimate_gas (signed_evm_transaction )
results in gas limit exceeded
tests/backends/test_pyevm.py::TestPyEVMBackendDirect::test_estimate_gas <- eth_tester/utils/backend_testing.py FAILED
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
self = <test_pyevm.TestPyEVMBackendDirect object at 0x7f653139c278>, eth_tester = <eth_tester.main.EthereumTester object at 0x7f65313992b0>
def test_estimate_gas(self, eth_tester):
self.skip_if_no_evm_execution()
math_address = _deploy_math(eth_tester)
estimate_call_math_transaction = _make_call_math_transaction(
eth_tester,
math_address,
'increment',
)
> gas_estimation = eth_tester.estimate_gas(estimate_call_math_transaction)
estimate_call_math_transaction = {'data': '0xd09de08a', 'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', 'gas': 500000, 'to': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b'}
eth_tester = <eth_tester.main.EthereumTester object at 0x7f65313992b0>
math_address = '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b'
self = <test_pyevm.TestPyEVMBackendDirect object at 0x7f653139c278>
eth_tester/utils/backend_testing.py:645:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
eth_tester/main.py:445: in estimate_gas
raw_gas_estimate = self.backend.estimate_gas(raw_transaction)
eth_tester/backends/pyevm/main.py:425: in estimate_gas
return self.chain.estimate_gas(signed_evm_transaction)
venv/lib/python3.6/site-packages/evm/chains/chain.py:277: in estimate_gas
return self.gas_estimator(state, transaction)
cytoolz/functoolz.pyx:232: in cytoolz.functoolz.curry.__call__
???
venv/lib/python3.6/site-packages/evm/estimators/gas.py:59: in binary_gas_search
error = _get_computation_error(state, maximum_transaction)
venv/lib/python3.6/site-packages/evm/estimators/gas.py:29: in _get_computation_error
computation = state.execute_transaction(transaction)
venv/lib/python3.6/site-packages/evm/vm/forks/spurious_dragon/vm_state.py:22: in execute_transaction
computation = _execute_frontier_transaction(self, transaction)
venv/lib/python3.6/site-packages/evm/vm/forks/frontier/vm_state.py:56: in _execute_frontier_transaction
vm_state.validate_transaction(transaction)
venv/lib/python3.6/site-packages/evm/vm/forks/homestead/vm_state.py:13: in validate_transaction
validate_homestead_transaction(self, transaction)
venv/lib/python3.6/site-packages/evm/vm/forks/homestead/validation.py:17: in validate_homestead_transaction
validate_frontier_transaction(evm, transaction)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
vm_state = <evm.vm.forks.spurious_dragon.vm_state.SpuriousDragonVMState object at 0x7f6531396208>, transaction = <evm.utils.spoof.SpoofTransaction object at 0x7f65313b3be0>
def validate_frontier_transaction(vm_state, transaction):
gas_cost = transaction.gas * transaction.gas_price
with vm_state.state_db(read_only=True) as state_db:
sender_balance = state_db.get_balance(transaction.sender)
if sender_balance < gas_cost:
raise ValidationError(
"Sender account balance cannot afford txn gas: `{0}`".format(transaction.sender)
)
total_cost = transaction.value + gas_cost
if sender_balance < total_cost:
raise ValidationError("Sender account balance cannot afford txn")
if vm_state.gas_used + transaction.gas > vm_state.gas_limit:
> raise ValidationError("Transaction exceeds gas limit")
E evm.exceptions.ValidationError: Transaction exceeds gas limit
gas_cost = 3144659
sender_balance = 999999999999999999799489
state_db = <evm.db.state.AccountStateDB object at 0x7f653138e0b8>
total_cost = 3144659
transaction = <evm.utils.spoof.SpoofTransaction object at 0x7f65313b3be0>
vm_state = <evm.vm.forks.spurious_dragon.vm_state.SpuriousDragonVMState object at 0x7f6531396208>
venv/lib/python3.6/site-packages/evm/vm/forks/frontier/validation.py:22: ValidationError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> /home/dwilson/Develop/Projects/ethereum/eth-tester/venv/lib/python3.6/site-packages/evm/vm/forks/frontier/validation.py(22)validate_frontier_transaction()
-> raise ValidationError("Transaction exceeds gas limit")
(Pdb) vm_state.gas_used()
*** TypeError: 'int' object is not callable
(Pdb) vm_state.gas_used
200511
(Pdb) transaction.gas
3144659
(Pdb) vm_state.gas_limit
3144659
(Pdb)
Navigating up the stack to where the temp block context manager is created, and see 200511 gas_used
[28] > /home/dwilson/Develop/Projects/ethereum/eth-tester/venv/lib/python3.6/site-packages/evm/chains/chain.py(277)estimate_gas()
-> return self.gas_estimator(state, transaction)
(Pdb++) list
272
273 def estimate_gas(self, transaction, at_header=None):
274 if at_header is None:
275 at_header = self.get_canonical_head()
276 with self.get_vm(at_header).state_in_temp_block() as state:
277 -> return self.gas_estimator(state, transaction)
278
279 def import_block(self, block, perform_validation=True):
280 """
281 Imports a complete block.
282 """
(Pdb++) state.gas_used
200511
set breakpoint in estimate_gas() and start with 200511 gas_used
421 def estimate_gas(self, transaction):
422 import pdb; pdb.set_trace()
423 -> signed_evm_transaction = self._get_normalized_and_signed_evm_transaction(
424 dict(transaction, gas=self._max_available_gas()),
425 )
426 return self.chain.estimate_gas(signed_evm_transaction)
427
428 def call(self, transaction, block_number="latest"):
(Pdb++) self.chain.get_vm(self.chain.get_canonical_head()).state.gas_used
200511
Set breakpoint at top of test_estimate_gas() and run py-evm backend test, step through and check gas_used
>>>>>>>>>>>>>>>>>>>>>>> PDB set_trace (IO-capturing turned off) >>>>>>>>>>>>>>>>>>>>>>>
[50] > /home/dwilson/Develop/Projects/ethereum/eth-tester/eth_tester/utils/backend_testing.py(638)test_estimate_gas()
-> self.skip_if_no_evm_execution()
(Pdb++) eth_tester.backend.chain.get_vm(eth_tester.backend.chain.get_canonical_head()).state.gas_used
0
(Pdb++) list
633 assert result == (0,)
634 assert result_new == (1,)
635
636 def test_estimate_gas(self, eth_tester):
637 import pdb; pdb.set_trace()
638 -> self.skip_if_no_evm_execution()
639
640 math_address = _deploy_math(eth_tester)
641 estimate_call_math_transaction = _make_call_math_transaction(
642 eth_tester,
643 math_address,
(Pdb++) n
[50] > /home/dwilson/Develop/Projects/ethereum/eth-tester/eth_tester/utils/backend_testing.py(640)test_estimate_gas()
-> math_address = _deploy_math(eth_tester)
(Pdb++) n
[50] > /home/dwilson/Develop/Projects/ethereum/eth-tester/eth_tester/utils/backend_testing.py(641)test_estimate_gas()
-> estimate_call_math_transaction = _make_call_math_transaction(
(Pdb++) eth_tester.backend.chain.get_vm(eth_tester.backend.chain.get_canonical_head()).state.gas_used
200511
(Pdb++) list
636 def test_estimate_gas(self, eth_tester):
637 import pdb; pdb.set_trace()
638 self.skip_if_no_evm_execution()
639
640 math_address = _deploy_math(eth_tester)
641 -> estimate_call_math_transaction = _make_call_math_transaction(
642 eth_tester,
643 math_address,
644 'increment',
645 )
646 gas_estimation = eth_tester.estimate_gas(estimate_call_math_transaction)
(Pdb++)