filecoin-project / ref-fvm

Reference implementation of the Filecoin Virtual Machine
https://fvm.filecoin.io/
Other
380 stars 137 forks source link

Precompiles & Wasm Modules #790

Open Stebalien opened 2 years ago

Stebalien commented 2 years ago

The EVM has two features to allow extension with native code, usually for performance:

  1. Custom opcodes: The EVM makes it relatively easy to add new opcodes. These are usually used for new crypto primitives, etc. They're more difficult to implement than precompiles, but get to skip the calling overhead.
  2. Precompiles: Special contracts with network-defined calling costs that are implemented in the client's native language instead of in the EVM. These are easy to implement, but introduce some overhead because they need to be called like any other contract.

In Wasm, we have two options:

  1. Runtime provided function calls (same as any other syscall).
  2. Precompiles (same as any other actor).

Given that we're planning on allowing deployed Wasm modules to import other deployed Wasm modules, option 1 likely makes the most sense.

However, we can take this even further. Given that LLVM can compile Wasm to native code, we can:

  1. Try out new user libraries and see what works and what doesn't.
  2. If we find that a specific library could benefit from running natively, the network can designate that library as a "precompile" and specify the gas cost.
  3. Implementations can then compile the Wasm contract down to native code. In practice, this may not help much as the Wasm VM will likely run at near native performance.
  4. Implementations can replace the native code with optimized assembly, if desired.

Importantly, this means promoting a library to "native" doesn't require a full network upgrade. At worst, some implementations may start syncing more slowly if they don't follow steps 3 & 4. However, even an implementation running 10x slower should be able to stay in sync.

nikkolasg commented 2 years ago

I am surely lacking some context so please bear with me :pray:

Stebalien commented 2 years ago

The goal here is to make it possible to validate the chain without having to "update" every client for every new precompile. For most clients (i.e., not miners) slightly slower chain verification is fine.

Isn't it a problem if you allow to have different implementations that can be 10x slower with respect to gas ? Like a tx should pay less gas with an optimized assembly operations (i'm thinking cryptographic operations here, like verifying a SNARK)

The network would specify the gas costs based on the optimized (assembly) "reference" implementation.

Some operations (again, cryptographic operations) may only make sense with optimized assembly operations, and will likely just be "too slow" to run on wasm.

For the lowest-level building blocks, yes, for now. But I also expect WASM extensions like SIMD and improved compilers to reduce the need for this over time.

Do i understand right that if that is the case, the whole network will agree on using those assembly implementations ?

No. The network would agree on a WASM module implementing the algorithm and on "standard" gas price for the operation based on some "reference" assembly implementation for some reference hardware.