populus icon indicating copy to clipboard operation
populus copied to clipboard

Populus cannot deploy contract related to estimated gas is not enough error.

Open avatar-lavventura opened this issue 9 years ago • 7 comments

  • platform darwin -- Python 2.7.12, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
  • plugins: populus-1.1.0
  • OS: Mac OS X

My contract is: Array.sol. All the following library and contracts are related to each other so I put all into same file. This approach is ugly (maybe the cause of the problem) but please note that I was not able to do import my .sol files in my contract file so one library and additional three contract is embedded into the same Array.sol file.

library LinkedList {
   struct data {...}
   struct Node {...}
   ...<some_code>...
}
library MappedList {
   struct Status{...}
   ...<some_code>...
}
contract owned {
   ...<some_code>...
}
contract Array is owned { #This is the main contract and calls other contracts and library as well.
  using LinkedList for LinkedList.data;
  using LinkedList for LinkedList.Node;
   LinkedList.data list;
  DateTime my_bank = `DateTime();`
  using MappedList for MappedList.Status;
   ...<some_code>...   
}
//Date and Time utilities for ethereum contracts written by pipermerriam.
contract DateTime {
   ...<some_code>...
}

I do face with following error: for the following line on my test.py file: my_contract = unmigrated_chain.get_contract('Array'); I assume this problem is related to there is not enough gas to deploy the contract.

def test_token_contract_1(web3, accounts, unmigrated_chain):
>   my_contract       = unmigrated_chain.get_contract('Array');
    tests/test.py:7:

/usr/local/lib/python2.7/site-packages/populus/chain.py:614: in get_contract
    kwargs=deploy_kwargs,
/usr/local/lib/python2.7/site-packages/web3/contract.py:194: in deploy
    txn_hash = cls.web3.eth.sendTransaction(deploy_transaction)
/usr/local/lib/python2.7/site-packages/web3/eth.py:216: in sendTransaction
    transaction=formatted_transaction,
/usr/local/lib/python2.7/site-packages/web3/utils/transactions.py:25: in get_buffered_gas_estimate
    gas_estimate = web3.eth.estimateGas(gas_estimate_transaction)
/usr/local/lib/python2.7/site-packages/web3/utils/functional.py:22: in inner
    value = fn(*args, **kwargs)
/usr/local/lib/python2.7/site-packages/web3/eth.py:247: in estimateGas
    return self.request_manager.request_blocking("eth_estimateGas", [transaction])
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ _ _ _ _ _ _ _ _ _ _ _ _
self = <web3.providers.manager.RequestManager object at 0x109d45590>, method = 'eth_estimateGas'
params = [{'data': '0x60606040526040516104ec80610243833901809050604051809103906000f08015610002576101fc8054600160a060020a0319169...ff0000000019169190911765ff000000000019169190911790555050505056', 'from': '0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1'}]

    def request_blocking(self, method, params):
        """
            Make a synchronous request using the provider
            """
        response_raw = self.provider.make_request(method, params)

        response = json.loads(force_text(response_raw))

        if "error" in response:
>           raise ValueError(response["error"])
E           ValueError: {u'message': u'Server error', u'code': -32000, u'data': {u'message': u'', u'args': [], u'type': u'TransactionFailed'}}

/usr/local/lib/python2.7/site-packages/web3/providers/manager.py:25: ValueError
====================================================== 1 failed in 5.44 seconds =======================================================
Exception AttributeError: "'NoneType' object has no attribute 'rmtree'" in <bound method state.__del__ of <ethereum.tester.state object at 0x109ef1290>> ignored

For example when I remove a line from my contract my code works perfectly fine. But when I add a new line that does some computation, which leads my contract to exceed the estimated gas and gives the error I mentioned.

[Q] Due to out of gas problem I can't deploy my contract inside Populus. How can I over come this problem?

Thank you for your valuable time and help.

screen shot 2017-01-16 at 18 51 01

avatar-lavventura avatar Jan 16 '17 17:01 avatar-lavventura

Can you provide the following info:

  • Populus version
  • Python version
  • PyEthereum version

pipermerriam avatar Jan 16 '17 17:01 pipermerriam

My guess is that deployment of the Array contract exceeds the block gas limit but I can't confirm this with the information above. You could confirm by doing some or all of the following.

  • Remove all constructor code from the Array contract. Does it deploy?
  • Start trimming out internals from the Array contract. Specifically any embedded statements that deploy other contracts as these will embed the entire bytecode for the other contract in the Array contract which will be the biggest contributor to size.

pipermerriam avatar Jan 16 '17 17:01 pipermerriam

How could I learn version for Populus (installed via pip install populus) and PyEthereum? Sorry I was not able to figure out to learn their versions.

  • platform darwin -- Python 2.7.12, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
  • plugins: populus-1.1.0
  • Inside pyethereum when I did: python setup.py the last line is: Finished processing dependencies for ethereum==1.6.0.

=> Yes when I remove all constructor code from the Array contract, it deploys. => Even if I remove a function from the Array contract, or a line that does some computation, it deploys as well. => For example, I was using your DateTime() contract to retrieve the year information and this contract was embedded inside the Array contract. So when I completely remove that contract inside the Array file, it deploys without any problem now. But when my Array contract extends with more functions, data storage; will there be similar problem? => Does embedded statements that call other libraries instead of contacts will embed the entire byte-code as well?

avatar-lavventura avatar Jan 17 '17 01:01 avatar-lavventura

You can get the installed versions with pip freeze

Does embedded statements that call other libraries instead of contacts will embed the entire byte-code as well?

No, library calls don't embed bytecode. However, if you are doing new DateTime() then you are embedding the bytecode because it is actually deploying a new version of that library. FYI, my ethereum-datetime repository is a contract, not a library.

This really looks like an out-of-gas issue with your Array contact just being too large. If you can provide me with the source code I can confirm this but otherwise I'm just postulating.

pipermerriam avatar Jan 17 '17 18:01 pipermerriam

I am sorry I cannot provide you the original source code, but I will do my best to trim it and provide you.

[Q] I think per transaction there is a gas limit and my contract exceeds that gas limit. When you were implementing Ethereum Alarm Clock code did you faced with similar error since it has 10 libraries and 4 contracts which have a complex linking hierarchy? so is there any way to increase transaction's gas_limit?

avatar-lavventura avatar Jan 24 '17 07:01 avatar-lavventura

I have the similar problem with my contract (although exception is different now), and it is definetely caused by out-of-gas error.


        try:
            (success, output) = processblock.apply_transaction(self.block, transaction)

            if not success:
>               raise TransactionFailed()
E               ethereum.tester.TransactionFailed

.venv/lib/python3.5/site-packages/ethereum/tester.py:296: TransactionFailed

May be it is worth to add some warning note to the documentation, because this error is hard to debug.

xuhcc avatar Nov 26 '17 10:11 xuhcc

@xuhcc one of the reasons for the unhelpful error is that pyethereum doesn't give any explanation of what went wrong when transactions fail.

py-evm was built with this in mind, so while it doesn't help you today, in the near term future when you can use the py-evm backend for testing the errors that it gives should be way more helpful.

pipermerriam avatar Nov 28 '17 22:11 pipermerriam