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

I believe I face with this error due to Solidity compiler's default gas limit that is 3,000,000.

[Q] How could I increase my solidity compiler's gas limit due to this error, or another gas limit that populus reads from?

in estimate_gas -> does it exceed gas limit? When I remove some function inside my contract the error gets fixed. I guess there is a gas limit for populus to deploy the contract, is it possible to extend it? If yes how?

Error:

========================================== FAILURES ==========================================
________________________________________ test_receipt ________________________________________

web3 = <web3.main.Web3 object at 0x1061af2d0>
accounts = ['0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1', '0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e', '0xDCEceAF3fc5C0a63d195d6...1d7585Bd0577402861E5', '0x13cBB8D99C6C4e0f2728C7d72606e78A29C4E224', '0x77dB2BEBBA79Db42a978F896968f4afCE746ea1F', ...]
chain = <populus.chain.tester.TesterChain object at 0x105489b50>

    def test_receipt(web3, accounts, chain): #{
        web3._requestManager = web3.manager
        global blkArrayIndex;
        global runTime;
>       my_contract, _   = chain.provider.get_or_deploy_contract('eBlocBroker');

tests/test.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/Library/Python/2.7/site-packages/populus/contracts/provider.py:143: in get_or_deploy_contract
    deploy_kwargs=deploy_kwargs,
/Library/Python/2.7/site-packages/populus/contracts/provider.py:121: in deploy_contract
    kwargs=deploy_kwargs,
/Library/Python/2.7/site-packages/web3/contract.py:311: in deploy
    txn_hash = cls.web3.eth.sendTransaction(deploy_transaction)
/Library/Python/2.7/site-packages/web3/eth.py:216: in sendTransaction
    get_buffered_gas_estimate(self.web3, transaction),
/Library/Python/2.7/site-packages/web3/utils/transactions.py:28: in get_buffered_gas_estimate
    gas_estimate = web3.eth.estimateGas(gas_estimate_transaction)
/Library/Python/2.7/site-packages/web3/eth.py:263: in estimateGas
    [transaction],
/Library/Python/2.7/site-packages/web3/manager.py:93: in request_blocking
    response = self._make_request(method, params)
/Library/Python/2.7/site-packages/web3/manager.py:76: in _make_request
    return request_func(method, params)
/Library/Python/2.7/site-packages/web3/middleware/attrdict.py:20: in middleware
    response = make_request(method, params)
/Library/Python/2.7/site-packages/web3/middleware/formatting.py:23: in middleware
    response = make_request(method, formatted_params)
/Library/Python/2.7/site-packages/web3/middleware/formatting.py:25: in middleware
    response = make_request(method, params)
/Library/Python/2.7/site-packages/web3/middleware/exception_handling.py:20: in middleware
    return make_request(method, params)
/Library/Python/2.7/site-packages/web3/providers/tester.py:86: in middleware
    return make_request(method, params)
/Library/Python/2.7/site-packages/web3/providers/tester.py:115: in make_request
    response = rpc_fn(*params)
/Library/Python/2.7/site-packages/testrpc/rpc.py:138: in eth_estimateGas
    return self.client.estimate_gas(**formatted_transaction)
/Library/Python/2.7/site-packages/testrpc/client/client.py:253: in estimate_gas
    txn_hash = self.send_transaction(*args, **kwargs)
/Library/Python/2.7/site-packages/testrpc/client/client.py:263: in send_transaction
    self._send_transaction(*args, **kwargs)
/Library/Python/2.7/site-packages/testrpc/client/client.py:58: in inner
    return client_method(self, *args, **kwargs)
/Library/Python/2.7/site-packages/testrpc/client/utils.py:104: in inner
    return fn(*bytes_args, **bytes_kwargs)
/Library/Python/2.7/site-packages/testrpc/client/client.py:225: in _send_transaction
    output = self.evm.send(sender=sender, to=to, value=value, evmdata=data)
/Library/Python/2.7/site-packages/ethereum/tester.py:338: in send
    return self._send(*args, **kwargs)["output"]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <ethereum.tester.state object at 0x1061af590>
sender = '\x04HR\xb2\xa6p\xad\xe5@~x\xfb(c\xc5\x1d\xe9\xfc\xb9eB\xa0q\x86\xfe:\xed\xa6\xbb\x8a\x11m'
to = '', value = 0
evmdata = "```@R4\x15a\x00\x0fW`\x00\x80\xfd[C`\x00\x81\x90UP3`\x01`\x00a\x01\x00\n\x81T\x81s\xff\xff\xff\xff\xff\xff\xff\xff\xf...c3V[P\x90V[\x90V\x00\xa1ebzzr0X Ks\x04pt'-\x02$\\\xbf\x86\x9c\x0f\xf8\xfa\xbf\x97\xda\xb8/\xd6X\xc8|\xadp\xc6JQpC\x00)"
funid = None, abi = None, profiling = 0

    def _send(self, sender, to, value, evmdata='', funid=None, abi=None,  # pylint: disable=too-many-arguments
              profiling=0):
        # pylint: disable=too-many-locals

        if funid is not None or abi is not None:
            raise Exception(
                'Send with funid+abi is deprecated. Please use the abi_contract mechanism'
            )

        start_time = time.time()
        gas_used = self.block.gas_used

        sendnonce = self.block.get_nonce(privtoaddr(sender))
        transaction = transactions.Transaction(sendnonce, gas_price, gas_limit, to, value, evmdata)
        self.last_tx = transaction
        transaction.sign(sender)
        recorder = None

        if profiling > 1:
            recorder = LogRecorder(
                disable_other_handlers=True,
                log_config=TRACE_LVL_MAP[3],
            )

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

            if not success:
>               raise TransactionFailed()
E               TransactionFailed

/Library/Python/2.7/site-packages/ethereum/tester.py:296: TransactionFailed
------------------------------------- Captured log call --------------------------------------
rpc.py                     129 INFO     eth_blockNumber
============================ 1 failed, 4 warnings in 1.41 seconds ============================

Update:

The way I use Populus:

$ mkdir populus_workspace && cd populus_workspace
$ [~/populus_workspace] populus init
Created Directory: ./contracts
Created Example Contract: ./contracts/Greeter.sol
Created Directory: ./tests
Created Example Tests: ./tests/test_greeter.py
$ py.test --capture=fd tests/test_greeter.py -s --disable-pytest-warnings
==================================== test session starts =====================================
platform darwin -- Python 2.7.10, pytest-3.5.0, py-1.5.3, pluggy-0.6.0
rootdir: /Users/alper/mu, inifile:
plugins: populus-2.0.1
collected 2 items

tests/test_greeter.py ..

============================ 2 passed, 6 warnings in 0.82 seconds ============================

Based on @mafrasi2 answer when I tried:

 my_contract, _   = chain.provider.get_or_deploy_contract('eBlocBroker', deploy_transaction={"gas": 4000001})

I get following error message:

block = <Block(#1 2bb28319)>, tx = <Transaction(751d)>

    def validate_transaction(block, tx):

        def rp(what, actual, target):
            return '%r: %r actual:%r target:%r' % (tx, what, actual, target)

        # (1) The transaction signature is valid;
        if not tx.sender:  # sender is set and validated on Transaction initialization
            if block.number >= config.default_config["METROPOLIS_FORK_BLKNUM"]:
                tx._sender = normalize_address(config.default_config["METROPOLIS_ENTRY_POINT"])
            else:
                raise UnsignedTransaction(tx)
        if block.number >= config.default_config["HOMESTEAD_FORK_BLKNUM"]:
                tx.check_low_s()

        # (2) the transaction nonce is valid (equivalent to the
        #     sender account's current nonce);
        acctnonce = block.get_nonce(tx.sender)
        if acctnonce != tx.nonce:
            raise InvalidNonce(rp('nonce', tx.nonce, acctnonce))

        # (3) the gas limit is no smaller than the intrinsic gas,
        # g0, used by the transaction;
        if tx.startgas < tx.intrinsic_gas_used:
            raise InsufficientStartGas(rp('startgas', tx.startgas, tx.intrinsic_gas_used))

        # (4) the sender account balance contains at least the
        # cost, v0, required in up-front payment.
        total_cost = tx.value + tx.gasprice * tx.startgas
        if block.get_balance(tx.sender) < total_cost:
            raise InsufficientBalance(rp('balance', block.get_balance(tx.sender), total_cost))

        # check block gas limit
        if block.gas_used + tx.startgas > block.gas_limit:
>           raise BlockGasLimitReached(rp('gaslimit', block.gas_used + tx.startgas, block.gas_limit))
E           BlockGasLimitReached: <Transaction(751d)>: 'gaslimit' actual:4000001 target:4000000

/Library/Python/2.7/site-packages/ethereum/processblock.py:112: BlockGasLimitReached
0
+50

Unfortuately, you can't do this on the command line right now. However, Populus also allows you to use a script to deploy your contract which gives you a ton of customization.

The example in the documentation uses the default gas amount:

txhash = Crowdsale.deploy(
    transaction={"from": beneficiary},
    args=[beneficiary, multisig_address, 1]
)

You can simply change this by adding "gas": x to the transaction parameter:

txhash = Crowdsale.deploy(
    transaction={"from": beneficiary, "gas": 4000000},
    args=[beneficiary, multisig_address, 1]
)

In general, you can use all the functionality from web3py in Populus. There even is functionality to automatically estimate the amount of gas needed beforehand:

gas_needed = Crowdsale.constructor(beneficiary, multisig_address, 1).estimateGas()

Edit:

I think your problem occurs when you call get_or_deploy_contract()? In that case, you can use:

chain.provider.get_or_deploy_contract('eBlocBroker', deploy_transaction={"gas": 4000000})

Edit 2:

After going through lots of code, I have some new information. Populus uses its tester chain by default. The tester chain represents EthereumTesterProvider from web3py. Now, there are two versions of EthereumTesterProvider: one uses eth-tester and the other uses eth-testrpc. The second one is deprecated, but it's the one that Populus uses. Now, there are two ways to set the block gas limit in eth-testrpc:

  • either, set the environment variable TESTRPC_GAS_LIMIT to something very high like 8000000 before you call py.test ...
  • or, put this snippet into your test_*.py file:

    import pytest
    
    @pytest.fixture(scope="session", autouse=True)
    def adjust_block_gas_limit():
        import testrpc.client
        testrpc.client.client.DEFAULT_GAS_LIMIT = 8000000
    
  • I tried your approach I received this error: E BlockGasLimitReached: <Transaction(751d)>: 'gaslimit' actual:4000001 target:4000000 /Library/Python/2.7/site-packages/ethereum/processblock.py:112: BlockGasLimitReached and when I tried for 4000000 it still gives the same initial error. @mafrasi2 – alper May 27 '18 at 18:33
  • Your block gas limit is too small then. What chain are you using for testing? – mafrasi2 May 27 '18 at 21:05
  • Populus uses its own simualtion chain. I dont know how it increaee block gas limit, its linked to solidity compiler’s gas limit. – alper May 27 '18 at 21:09
  • @alper I'm fairly confident that my new solution will work for you :) – mafrasi2 May 27 '18 at 23:27
  • Well yeah, obviously you were supposed to put it outside the test function. I can't hold your hand at each line of code you write.... – mafrasi2 May 28 '18 at 11:15
0

Based on @mafrasi2 answer changing the value inside test_*.py file did not help.


By default DEFAULT_GAS_LIMIT is assigned with 4000000.

Please see eth-testrpc/testrpc/client/client.py :

DEFAULT_GAS_LIMIT = t.gas_limit = t.GAS_LIMIT = int(os.environ.get('TESTRPC_GAS_LIMIT', 4000000))

We need to increase DEFAULT_GAS_LIMIT value.

$ pip show eth-testrpc | grep 'Location'
Location: /Library/Python/2.7/site-packages
$ cd /Library/Python/2.7/site-packages
$ grep -r 'TESTRPC_GAS_LIMIT' .
./testrpc/client/client.py:DEFAULT_GAS_LIMIT = t.gas_limit = t.GAS_LIMIT = int(os.environ.get('TESTRPC_GAS_LIMIT', 4000000))

Then open ./testrpc/client/client.py with your editor and update 4000000 with a larger value.


Example test.py: (To run: py.test --capture=fd test.py -s --disable-pytest-warnings)

import pytest
def test_receipt(web3, accounts, chain): #{    
    my_contract, _   = chain.provider.get_or_deploy_contract('myContractName');
    ...
#}
  • You can do that. It's really really bad practice though... – mafrasi2 May 28 '18 at 11:12
  • Because you are not supposed to just edit installed python packages. What happens when you upgrade the package? What happens when other installed programs expect the original package? I – mafrasi2 May 28 '18 at 11:18
  • My second solution definitely works when you do what I said. Did you even try using the first one? Just run export TESTRPC_GAS_LIMIT=8000000 before you run pytest. You can also put this into your ~/.bash_profile to set the environment variable automatically each time you start the terminal. – mafrasi2 May 28 '18 at 11:29
  • export TESTRPC_GAS_LIMIT=8000000 works, but second approach didn't not work in my case, it keeps giving: BlockGasLimitReached error. – alper May 28 '18 at 11:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.