Challenges
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 ?
1. Accounting for the Proof Size
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.
Subcall accounting
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
Example:
- 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
2. Computing the Proof Size limit
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.
Ex:
Transfer(Alith, Bob, 2 ETH), GasLimit: 21000
: would allow 21000 * 5M / 15M => 7000 bytes
of Proof Size.