9

I have a contract storing rdf data in various mappings. It is all working lovely except for large array returns. I have functions to return arrays of hashes matching certain criteria. I have found, through testing, that a function call to the contract that returns an array of 36,000 bytes32 hashes works fine. However, a function call to the contract that should return an array of 100,000 records fails. An example function I am calling is:

// return a bytes32 array of hashes matching a subject search hash
function getSubjectArray(bytes32 which) public constant returns (bytes32[]) {
    return subjectindex[which];
}

I was originally testing using web3 function calls to the contract, then I decided to test using direct curl commands to see if it was a web3 issue. But it behaves the same using curl. A result array of 36,000 hashes returns from the curl call successfully, but a result array of 100,000 returns just '0x'.

curl --data '{"id":1,"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x0a0bdad3a719adacf6ef29299b25f4799c3961ba","data":"0xd6cf19ffa6ccec97d46345da54fa1ac0a269b860a855d19895705920f2fdfb4eb786817a"},"latest"]}' -H "Content-Type: application/json" -X POST 127.0.0.1:55200

{"jsonrpc":"2.0","result":"0x","id":1}

I have stepped though this large results array using a separate function passing an index, so I know all the 100,000 records are there to be returned. So it seems to be a limit on the size that an array returned from a function call to a contract can be.

Can anyone confirm if there is a limit that an array being returned from a function can be?

9
  • 4
    The limit is how much gas is provided, which is needed even for constant functions, so try increasing the gas: ethereum.stackexchange.com/questions/9824/…
    – eth
    Aug 8, 2017 at 15:48
  • Apparently my colleague said he was able to get an array of 60,000 hashes from a function call to our RDF storage contract, but not an array of 63,000 hashes. Aug 9, 2017 at 8:49
  • 1
    There is no gas cost in getting the data. We are not adding any gas. It is just a read. But I can of course try adding some gas I guess. But it pulls 60,000 without any gas just fine. So maybe there is a limit to what is free and at what point it needs gas. I will test adding gas. Aug 9, 2017 at 8:49
  • 1
    OK I tried adding gas of 4700000 which is the most I can use on our parity network. It made no difference. I still just get back a result of 0x, and no error about being out of gas. I really don't think gas is the issue. It should not cost gas. Aug 9, 2017 at 9:05
  • It would be certainly interesting to reproduce this on our side. Could you join the Parity Gitter or create a new issue on GitHub to discuss this with @tomusdrw and me? Thanks.
    – q9f
    Aug 10, 2017 at 8:51

1 Answer 1

5

The limit is how much gas is provided: gas is needed even for eth_call / constant functions: Can Solidity constant functions be arbitrarily complex?

The gas needed to be increased, example in bold:

curl -H "Content-Type: application/json" -X POST 127.0.0.1:55200 \
--data '{"id":1,"jsonrpc":"2.0","method":"eth_call","params": [{"to":"0x0a0bdad3a719adacf6ef29299b25f4799c3961ba","data":"0xd6cf19ffa6ccec97d46345da54fa1ac 0a269b860a855d19895705920f2fdfb4eb786817a", "gas":"0x4000000000000"},"latest"]}'


@tomusdrw from Parity also had a good explanation of eth_call:

Yes, reads are indeed free, but eth_call is just creating a "virtual" transaction that gets executed in the context of the blockchain. It's not subject to block gas limit that you tried (4.7M), but still gas calculation is being done for anything that eth_call does (for instance to prevent infinite loop). Our default gas limit was 50M and taking out ~64k of bytes32 was hitting the limit, you should try specifying something much larger like 2**50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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