Currently, the gas used in the EVM matches (more or less) the cpu time
being used by the OPCODEs executed. However, with the limitation of the PoV size
required by the relaychain, it is not enough to just rely on the cpu time.
- How do we account for the Proof Size when executing an EVM transaction ?
- How do we restrict the Proof Size of an EVM Transaction ?
The solution we are proposing is to change the EVM Gasometer to add another dimension to the execution, counting every read to the storage and comparing to a given limit (see 2.).
In the case the limit of the Proof Size is reached, a revert message with “out-of-proof-size” (probably converted to “out-of-gas” for compatibility) will be triggered.
At the difference of the gasLimit, which can be provided in a subcall, the Proof Size limit will be independant and will always be to the remaining proof size when executing the subcall.
Once the PR for using a dedicated storage for the Smart Contract code size is merged, it will be possible to check and charge directly the amount of Proof Size needed to perform a sub-call
- Smart Contract A calls Smart contract B (5kB)
- Gasometer: checks proof size > 5kB, reduces proof size remaining by 5kB
- Smart Contract B accesses 10 storages of 32 bytes
- Gasometer: checks proof size > 32 bytes (for each access), reduces total proof size remaining by 320B
- Smart Contract B calls Smart Contract C (9kB) with 10_000 gasLimit
- Gasometer: checks proof size > 9k (doesn’t matter the gasLimit value), reduces proof size remaining by 9kB
In order to succeed, the proof size limit should be at least
5kB + 320B + 9kB=> ~15kB
In order to avoid Ethereum Transactions from abusing the Proof Size,
each transaction needs to have an associated limit for the proof size.
When being executed from XCM, this will be taken directly from the BuyExecution.
However, when coming from an Ethereum Transaction, we need a way to convert the gas limit into a proof size limit.
Currently, blocks are limited to 5Mb PoV (This limit applied to the compressed Pov, but for simplicity I’ll consider only the uncompressed Proof Size), so a simple solution is to use a ratio of Maximum amount of Proof Size (5M) by the Maximum amount of Gas (15M currently in Moonbeam) allowed for a block.
We could then apply this ratio to the gasLimit that is provided with the Ethereum Transaction to obtain a Proof Size limit to use with the gasometer.
Transfer(Alith, Bob, 2 ETH), GasLimit: 21000: would allow
21000 * 5M / 15M => 7000 bytes of Proof Size.