Zilliqa / zq2

Zilliqa 2.0 code base
Apache License 2.0
6 stars 0 forks source link

Correctly track block gas usage during block building #1105

Open theo-zil opened 1 week ago

theo-zil commented 1 week ago

Currently, block building happens in two steps:

  1. A transaction list is drained from the mempool, until the sum of the gas limits for every transaction exceeds the block's gas limit.
  2. This list of transactions is executed; a second check - wholly redundant, as far as I can tell - ensures the actual gas usage is below the block gas limit (and returns an error if this fails)

This causes blocks to be under-filled, assuming the transaction gas limit is overestimated as a rule.

Here's what should happen instead:

  1. Transactions are drained one by one from the mempool and executed, until the actual gas usage exceeds the block's gas limit; the list of transactions before that point is the total transactions included in the block

For the last transaction, a potentially easy way to detect it would be to always pass min(transaction.gas_limit, block_gas_remaining) as the actual gas limit to the EVM for execution; then on out-of-gas errors, iff block_gas_remaining < transaction.gas_limit then re-insert that last transaction into the mempool (instead of discarding it as failed) and cease iteration.

DrZoltanFazekas commented 4 days ago

I was submitting a transaction with a manually set gas limit. If I set the gas limit to 10_000_000, the transaction fails. If I set it to 12_000_000, it succeeds, but only consumes only 2_767_052 gas. Just as an example of why we can't rely on the transaction gas limit to judge whether a transaction would fit into the block or not.