Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas limits for calls #117

Open
xermicus opened this issue Nov 21, 2024 · 4 comments
Open

Gas limits for calls #117

xermicus opened this issue Nov 21, 2024 · 4 comments
Assignees

Comments

@xermicus
Copy link
Member

xermicus commented Nov 21, 2024

Gas does not correspond to ref_time exactly as semantically equivalent code can exhibit totally different gas usage on EVM vs. ref_time usage on PVM.

Right now we ignore it, making all calls unconstrained. But those gas limits are a security feature (DOS and re-entrancy).
Without gas limits in place, we essentially force people to not use existing libraries and write their contracts such that any calls or transfers are made at the end of the execution or when 1/64 of the available gas is enough to complete after the call or transfer.

Possible solutions:

  1. Scale the supplied gas limit with a fixed factor. We can benchmark a variety of contract calls and compare their gas vs. ref_time usage to distill such a factor.
  2. Treat the supplied gas as relative value relative to the EVM block gas limit and convert it to the corresponding relative ref_time limit with respect to our ref_time block limit (the portion that's allocated for contracts). Drawback is that the compiler (i.e. the user) needs to know the absolute ref_time limit of the target blockchain. It also largely disconnects the semantic meaning of the value should the block limits in either chain change (Solved if the pallet takes care of this). However we can implement it in the pallet to reflect that. Also note that on Ethereum, for transfers a gas stipend of 2300 is hard-coded in the compiler, so realistically they can never make any change breaking this.

Note: By default, when no explicit gas limit is specified, solc compiles down to supplying what the gas() opcode returns.

@xermicus
Copy link
Member Author

xermicus commented Dec 12, 2024

Limiting the ref_time seems do-able via an approximation, we could benchmark a bunch contracts and approximate a ref_time X EVM gas factor. This solves the problem of too much arbitrary code execution in sub-calls, most importantly transfers.

However, it doesn't solve the DOS vector as malicious contracts can potentially still use up a lot of gas via proof_size.
We'd need to approximate by looking at the gas costs in EVM related to everything that causes proof_size costs and then translate it. However we need to see if this is accurate enough.

So with either solution, we'd have an API for calls with EVM gas instead of our traditional weights. The pallet does then take care of translating the supplied gas stipend into sensible weight limits, either via a fixed factor (1.), via a relative approach (2.) or somehow else. The pallet should do it because if it is a compile time constant we can never change it (in case we have to bump it).

@xermicus
Copy link
Member Author

xermicus commented Dec 12, 2024

Also note that zkSync is passing gas as-is to the eravm. I don't see anything in the docs how eravm gas relates to evm gas, however are hardly exactly equivalent to the EVM, but it seems fine for them too?

Related issue is to cap nested stack frames at 63/64.

@athei
Copy link
Member

athei commented Dec 12, 2024

We discussed the following:

  1. Normal CALL opcode is always uncapped because any thing we can do will hamper compatibility too much. No matter which scaling we use it can always lead to a situation where code cannot be executed or too much will be executed.

  2. We detect a Solidity transfer via a heuristic in resolc (2300 gas + empty call data) and enable re-entrancy protection for such calls.

  3. For use cases where sub call resources need to be capped we provide a custom API via pre-compile.

@athei athei moved this to Minimal Feature Launch in Smart Contracts Dec 12, 2024
@xermicus xermicus added this to the Initial release milestone Dec 18, 2024
@xermicus
Copy link
Member Author

Tasks:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Minimal Feature Launch
Development

No branches or pull requests

2 participants