NethermindEth / blockifier

Blockifier is a Rust implementation for the transaction-executing component in the StarkNet sequencer, in charge of creating state diffs and blocks.
Apache License 2.0
1 stars 4 forks source link

Moving Native Compilation outside of the Blockifier #112

Closed rodrigo-pino closed 1 month ago

rodrigo-pino commented 1 month ago

General Idea

The Native Blockifier is capable of executing Starknet Contracts compiled ahead of time using the Cairo Native compiler. The way it works currently is:

  1. The Blockifier receives a Starknet Contract in Sierra.
  2. It compiles it down to Machine Code.
  3. Executes it.
  4. Returns the Execution Trace.

This setup, although initially good enough for testing, won't be good in Production. The main reason is that it creates a bottleneck during execution where it will stop just to compile a file something that could have already been done by this point. It also raises other issue such as what to do with the compile file, store it somewhere (and how long) or delete it.

This two problems are not for the Blockifier to take care of but by the Sequencer/Nodes. We need to update the workflow, removing the compilation step, to:

  1. The Blockifier receives a Starknet Contract compiled with Cairo Native.
  2. Executes it.
  3. Returns the transaction trace

More technical

We currently have a SierraContractClass representing a Contract Definition written in Sierra. We should swap it for a NativeContractClass representing a Contract Definition compiled with Native.

This will break the general flow of the program since everything is based on getting this Sierra and compiling it. Also, I don't know how difficult it could be to represent a Natively Compiled Contract as a Rust object (maybe it's very easy).

Finally, you should take into account testing. Testing uses Sierra files which are compiled with Native during the test execution. Since now we won't have anymore compilation, those should be compiled (by having them pre-compiled) or compiling them directly in execution. We can discuss the best solution for this.

Juno

The problem of solving this issue alone is that we are going to end up with something un-usable since there isn't any Node prepared to work with the Native compiler.

The solution for this is that we are going to prep Juno in a patchy way to perform the compilation on it's side. Juno communicates with the Blockifier using CGo (an FFI). This communication layer is written partly in Go and partly in Rust.

The Patchy solution comes when the Juno sends the Sierra to the Blockifier, being able to "capture" it in the Rust side of the translation, compiling it with Native, and sending that instead. Maybe we can improve over this idea.

Now, this won't fix any of the problems mentioned, but for the scope of our tests we don't care about them. We only care about Native Blockifier performing the same as Base Blockifier. What this will do is to make our current Native Blockifier prototype achieve its final form, making it ready (or almost-ready) for production.