2

Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully: Due to the block gas limit, transactions can only consume a certain amount of gas. Either explicitly or just due to normal operation, the number of iterations in a loop can grow beyond the block gas limit which can cause the complete contract to be stalled at a certain point.

What happens if a scenario occurs where a loop grows beyond the block gas limit? particularly; for how long will the contract be stalled?
To extend, If only 50 out of 500 (a random number) values of an array were effected by the loop iteration, would the function which started the loop then be callable another 9 times and effect the remaining 450 values of the array or would it just continuously effect only the same first 50 out of the 500?
Finally, How does one mitigate against this properly when looping through storage values and not function parameter input arguments?

2

Whether the contract is stalled or not depends on your exact implementation.

If you have some function in your contract which iterates over the entire array every time it is called, then the contract will be stalled permanently when the array grows to a size that looping over it exceeds the block gas limit (unless you have another function that allows you to delete entries from the array arbitrarily).

If, on the other hand, you have a function which accepts an array of indexes, and only iterates over a storage array using those indices directly (i.e. you loop over your input array, not the storage array), then you could avoid the stalling situation by simply passing in as many indices as allowed under the block gas limit.

Mitigating it comes down to code structure. It is possible to have an array that is too large to iterate all at once, but you can easily build functions that will directly access indices without looping.

For instance, if you wish to modify an array entry where the value is 4839, and your array has 10000 entries, a naive way would be to just loop over it, check every entry, and modify if when you find one that equals 4839. This is susceptible to hitting the block gas limit as the array size grows.

A better implementation would be to read your array, loop over it off chain, and then have a function which accepts a list of indices that you want to modify, and their new values. Now, instead of looping over the entire array within the contract, you can loop over the index list and just update those entries.

  • Hi Raghav, If I'm iterating through a function with the purpose of releasing a certain stake % of tokens to all stakers, would iterating through a storage array of stakers (which could grow to thousands) then be a bad idea and should I instead iterate through e.g. 50 addresses per transaction through a function in memory argument array of addresses (to ultimately avoid breaking block limit)? – NowsyMe Aug 12 '18 at 23:17

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.