#rollup #tezos #smart

no-std mavryk-smart-rollup

SDK for Mavryk Smart Rollup kernel development

1 unstable release

0.2.2 Jul 30, 2024

#7 in #tezos

MIT license

370KB
7.5K SLoC

SDK for Mavryk Smart Rollups.

To learn more about how Smart Rollups work in Mavryk, see the Smart Rollup Documentation.

The purpose of this SDK is to make writing Smart Rollup kernels in Rust simpler.

To learn about the changes in the current version of the SDK, see the CHANGELOG.

Smart Rollup Kernels

A kernel is a 32bit WebAssembly program that runs on a Smart Rollup. It decides how the Rollup handles input messages, updates the Rollup state, and when to output messages targetting Layer 1.

While any programming-language with WebAssembly-compilation support could be used for writing a Rollup kernel, Rust is an excellent fit due to first-class WASM support, deterministic runtime, and safe memory management.

Setting-up Rust

rustup is the standard way to get Rust. Once rustup is installed, enable WASM as a compilation target with:

rustup target add wasm32-unknown-unknown

Rust also has a wasm64-unknown-unknown compilation target. This target is not compatible with Mavryk Smart Rollups, which only provide a 32bit address space.

Installing Clang

In order to build the Rust SDK, clang >= 11 is required in addition to Rust. This can be installed through your favourite package manager.

On MacOS, LLVM and the WebAssembly Binary Toolkit (WABT) can be installed through homebrew:

brew install llvm
brew install wabt
LLVM_PATH=$(brew --prefix llvm)
export AR="${LLVM_PATH}/bin/llvm-ar"
export CC="${LLVM_PATH}/bin/clang"

On Linux, often the default CC is gcc, which is not supported for kernel builds. Ensure clang is being used:

export CC=clang

Features

Feature Default? Enables About
std alloc Disable for #![no_std] integration
alloc Enables methods/types requiring alloc crate
panic-hook Print panics to debug log and abort
dlmalloc Enables dlmalloc as default allocator
crypto mavryk_crypto_rs Integration with mavryk_crypto_rs types
bls mavryk_crypto_rs/bls Dac Certificate signature verification
data-encoding mavryk_data_encoding Integration with mavryk_data_encoding traits
testing crypto, mavryk_smart_rollup_mock Enables MockHost for writing tests

Usage

The following Cargo.toml file can be used to set up development with the Kernel SDK:

[package]
name = "kernel"
version = "0.1.0"
edition = "2021"
rust-version = "1.71.1"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
mavryk-smart-rollup = "0.2.2"
mavryk_data_encoding = "0.5"
mavryk_crypto_rs = { version = "0.5", default-features = false }
nom = "7.1"

[dev-dependencies]
mavryk-smart-rollup = { version = "0.2.0", features = ["testing"] }

Note that the cdylib crate type is required to enable compilation to wasm.

The following lib.rs file could then be used to get started with a 'hello kernel'. This kernel will run once per inbox level.

use mavryk_smart_rollup::prelude::*;
use mavryk_smart_rollup::kernel_entry;

kernel_entry!(hello_kernel);

fn hello_kernel(host: &mut impl Runtime) {
  debug_msg!(host, "Hello, kernel!\n");
}

With those two files saved to Cargo.toml & src/lib.rs, you can compile the kernel:

cargo build --release --target wasm32-unknown-unknown
cp target/wasm32-unknown-unknown/release/kernel.wasm .

Often, large .wasm files are produced. The size of these can be significantly reduced using wasm-strip, which will remove items such as debugging symbols & metadata from the binary, not required for execution on Smart Rollups:

wasm-strip kernel.wasm

You can test this kernel by using the mavkit-smart-rollup-wasm-debugger.

# Create an empty inputs.json file - the 'hello world' kernel does not read inputs.
echo '[[], []]' > inputs.json

# Run the kernel:
mavkit-smart-rollup-wasm-debugger --kernel kernel.wasm --inputs inputs.json

Once in the debugger, you can run the following commands to test the kernel:

> load inputs
Loaded 0 inputs at level 0
> step kernel_run
Hello, kernel!
Evaluation took 11000000000 ticks so far
Status: Waiting for input
Internal_status: Collect
> load inputs
Loaded 0 inputs at level 1
> step kernel_run
Hello, kernel!
Evaluation took 11000000000 ticks so far
Status: Waiting for input
Internal_status: Collect

As you can see, on each level, the kernel prints Hello, kernel! to the debug log.

Unit-testing

To learn about writing unit tests against a kernel, see MockHost.

Dependencies

~0.8–12MB
~132K SLoC