evm-v1.0.0 #383
sorpaas
announced in
Announcements
evm-v1.0.0
#383
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
The v1.0 branch is finally released! This is a completely revamped version compared with v0.x.
Notable features
Generalized design
The v1.0 branch kept many of the good features in v0.x. For example, we keep to maintain a clear separation between the EVM gasometer and EVM opcode interpretation. This allow chains with a different cost map to reuse Rust EVM as is, while rolling out a totally new gas metering strategy. (In v1.0, this actually becomes even easier -- simply write your own
eval_gasometer
.)v1.0 brings a few new important generalizations that allow certain customization to be possible.
Etable
trait. Custom opcodes can be added "on the fly", and you can switch between different interpretation strategies (match
clause vs. evaluation table). You can also add pre- or post-hooks (commonly known as "inspectors" or "tracers"), which we explain further below.HeapTransact
, custom interrupts can now be returned (for example, via a custom opcode). For operations that must be done async (for example, a cross-chain call), the EVM execution can be paused any time in the middle until the return data becomes available.evm
crate. This is made possible by Rust'sAsRef
/AsMut
traits (which we used extensively).New call stack
v1.0 introduces a new call stack implementation (in other EVM libraries this is commonly called a "call frame").
The call stack can now be both heap-based or stack-based. For "common" EVM smart contracts, a stack-based call stack is more efficient (simply due to the fact that it doesn't need the additional heap allocations). However, EVM calls can be really nested (up to a depth of 1024). Therefore, other EVM libraries usually have to implement heap-based call stack to avoid possible stack overflow. The new call stack implementation combines the best of both worlds -- in the default config in
evm-mainnet
, the call stack would first be stack based up to a depth of 4 (so that it runs faster), and then automatically switch to heap based for higher depth.Stepping and tracing
For debugging, two strategies are possible:
Rust EVM v0.x only supports tracing. Stepping is generally difficult to implement as it requires nested call stack stepping as well. v1.0 finally adds supports for both stepping and tracing. This is made possible by the new call stack design. The call stack can immediately pause at any moment and still maintain its valid state. An interpreter with depth more than one can be stepped just as normal -- it will only advance the PC by one in the deepest call frame. The entire chain of interpreter calls can then be inspected.
In v1.0, tracing is also improved. It can now be done without any specialized hooks. This can simply be implemented as a chained Etable (
evm::interpreter::etable::Chained
).Custom interpreter
The invocation logic
evm::standard::Resolver
can now accommodate the requirements of custom interpreters. For example, we may need to support calling an RISC-V contract inside an EVM contract while inside an EVM call stack and maintaining the usual EVM execution context.evm::standard::Invoker
can now support a custom interpreter implementation (which will usually be anenum
wrapper with an extra variant around the normal EVM interpreter).Compliance and testing updates
We now pass the entire Ethereum test suites from Frontier hard fork to Cancun hard fork, which is production-ready.
Migration
We don't have a migration path from v0.x to v1.0 yet, but this will change soon. The plan is a
evm-compat
crate that mimics the API interface of v0.x which should make migrations easier.This discussion was created from the release evm-v1.0.0.
Beta Was this translation helpful? Give feedback.
All reactions