From 7f744d15a912be1aefc576a923f870fc3680dfaa Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 23 Sep 2024 09:19:34 -0400 Subject: [PATCH] feat(book): Custom backend, `kona-executor` extensions, and FPVM backend (#552) * feat(book): Custom backend, `kona-executor` extensions, and FPVM backend * updates * README rm telegram ref --- README.md | 11 + book/book.toml | 5 + book/custom.css | 141 +++++++++++++ book/src/CONTRIBUTING.md | 2 +- book/src/SUMMARY.md | 4 + book/src/fpp-dev/env.md | 2 +- book/src/fpp-dev/targets.md | 103 ++-------- book/src/intro.md | 2 +- book/src/links.md | 2 + book/src/sdk/custom-backend.md | 120 +++++++++++ book/src/sdk/exec-ext.md | 55 +++++ book/src/sdk/fpvm-backend.md | 139 +++++++++++++ book/src/sdk/intro.md | 36 ++++ book/theme/index.hbs | 364 +++++++++++++++++++++++++++++++++ 14 files changed, 895 insertions(+), 91 deletions(-) create mode 100644 book/custom.css create mode 100644 book/src/sdk/custom-backend.md create mode 100644 book/src/sdk/exec-ext.md create mode 100644 book/src/sdk/fpvm-backend.md create mode 100644 book/src/sdk/intro.md create mode 100644 book/theme/index.hbs diff --git a/README.md b/README.md index 3639fa43..d6dba04a 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,16 @@ the block execution logic. Built on top of these libraries, this repository also features a [fault proof program][fpp-specs] designed to deterministically execute the rollup state transition in order to verify an [L2 output root][g-output-root] from the L1 inputs it was [derived from][g-derivation-pipeline]. +### Alternative Backends + +Kona's libraries were built with alternative backend support and extensibility in mind - it is not just a fault proof +program! Kona is also used by: + +- [`op-succinct`][op-succinct] + +To build your own backend for kona, or build a new application on top of its libraries, +see the [SDK section of the book](https://anton-rs.github.io/kona/sdk/intro.html). + ### Development Status `kona` is currently in active development, and is not yet ready for use in production. @@ -70,6 +80,7 @@ The [book][book] contains a more in-depth overview of the project, contributor g [asterisc]: https://github.com/etheruem-optimism/asterisc [fpp-specs]: https://specs.optimism.io/experimental/fault-proof/index.html [book]: https://anton-rs.github.io/kona/ +[op-succinct]: https://github.com/succinctlabs/op-succinct [op-labs]: https://github.com/ethereum-optimism [bad-boi-labs]: https://github.com/BadBoiLabs [g-output-root]: https://specs.optimism.io/glossary.html#l2-output-root diff --git a/book/book.toml b/book/book.toml index c2002cc2..c6541b76 100644 --- a/book/book.toml +++ b/book/book.toml @@ -11,4 +11,9 @@ command = "mdbook-mermaid" [preprocessor.template] [output.html] +default-theme = "ferra" +preferred-dark-theme = "ferra" +git-repository-url = "https://github.com/anton-rs/kona" +edit-url-template = "https://github.com/anton-rs/kona/edit/main/book/{path}" +additional-css = ["custom.css"] additional-js = ["mermaid.min.js", "mermaid-init.js"] diff --git a/book/custom.css b/book/custom.css new file mode 100644 index 00000000..a5fdb46d --- /dev/null +++ b/book/custom.css @@ -0,0 +1,141 @@ +table { + width: 100%; +} + +table thead th { + padding: .75rem; + text-align: left; + font-weight: 500; + line-height: 1.5; + width: auto; +} + +table td { + padding: .75rem; + border: none; +} + +table thead tr { + border: none; + border-bottom: 2px var(--table-border-color) solid; +} + +table tbody tr { + border-bottom: 1px var(--table-border-line) solid; +} + +table tbody tr:nth-child(2n) { + background: unset; +} + +.content h1, +.content h2, +.content h3, +.content h4 { + font-weight: 600; + margin-top: 1.275em; + margin-bottom: .875em; +} + +.ferra { + --bg: #2b292d; + --fg: #fecdb2; + --heading-fg: #fff; + + --sidebar-bg: #383539; + --sidebar-fg: #fecdb2; + --sidebar-non-existant: #feceb454; + --sidebar-active: #ffa07a; + --scrollbar: var(--sidebar-fg); + + --icons: #f6b6c9ba; + --icons-hover: #b7b9cc; + + --links: #ffa07a; + + --inline-code-color: #f6b6c9ba; + + --theme-popup-bg: #383539; + --theme-popup-border: #5f5a60; + --theme-hover: rgba(0, 0, 0, .2); + + --quote-bg: #222124; + --quote-border: #2b292d; + + --table-border-color: #383539; + --table-header-bg: hsla(226, 23%, 31%, 0); + --table-alternate-bg: hsl(226, 23%, 14%); + --table-border-line: #383539; + + --searchbar-border-color: #222124; + --searchbar-bg: #222124; + --searchbar-fg: #fecdb2; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #fce2d4; + --searchresults-border-color: #feceb454; + --search-mark-bg: #f6b6c9ba; + +} + +.ferra .content .header { + color: #fce2d4; +} + +/* highlight.js theme, :where() is used to avoid increasing specificity */ + +:where(.ferra) .hljs { + background: #222124; + color: #feceb4e1; +} + +:where(.ferra) .hljs-comment, +:where(.ferra) .hljs-quote { + color: #6F5D63; +} + +:where(.ferra) .hljs-link, +:where(.ferra) .hljs-meta, +:where(.ferra) .hljs-name, +:where(.ferra) .hljs-regexp, +:where(.ferra) .hljs-selector-class, +:where(.ferra) .hljs-selector-id, +:where(.ferra) .hljs-tag, +:where(.ferra) .hljs-template-variable, +:where(.ferra) .hljs-variable { + color: #fecdb2; +} + +:where(.ferra) .hljs-built_in, +:where(.ferra) .hljs-deletion, +:where(.ferra) .hljs-literal, +:where(.ferra) .hljs-number, +:where(.ferra) .hljs-params, +:where(.ferra) .hljs-type { + color: #f6b6c9; +} + +:where(.ferra) .hljs-attribute, +:where(.ferra) .hljs-section, +:where(.ferra) .hljs-title { + color: #ffa07a; +} + +:where(.ferra) .hljs-addition, +:where(.ferra) .hljs-bullet, +:where(.ferra) .hljs-string, +:where(.ferra) .hljs-symbol { + color: #b1b695; +} + +:where(.ferra) .hljs-keyword, +:where(.ferra) .hljs-selector-tag { + color: #d1d1e0; +} + +:where(.ferra) .hljs-emphasis { + font-style: italic; +} + +:where(.ferra) .hljs-strong { + font-weight: 700; +} diff --git a/book/src/CONTRIBUTING.md b/book/src/CONTRIBUTING.md index 1a6437fe..563d511a 100644 --- a/book/src/CONTRIBUTING.md +++ b/book/src/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contributing Thank you for wanting to contribute! Before contributing to this repository, please read through this document and -discuss the change you wish to make via issue or in the development telegram. +discuss the change you wish to make via issue. ## Dependencies diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 7d0960e6..a9e81e06 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -7,5 +7,9 @@ - [Prologue](./fpp-dev/prologue.md) - [Execution](./fpp-dev/execution.md) - [Epilogue](./fpp-dev/epilogue.md) +- [Kona SDK](./sdk/intro.md) + - [FPVM Backend](./sdk/fpvm-backend.md) + - [Custom Backend](./sdk/custom-backend.md) + - [`kona-executor` Extensions](./sdk/exec-ext.md) - [Glossary](./glossary.md) - [Contributing](./CONTRIBUTING.md) diff --git a/book/src/fpp-dev/env.md b/book/src/fpp-dev/env.md index 3de69023..3d4c1db1 100644 --- a/book/src/fpp-dev/env.md +++ b/book/src/fpp-dev/env.md @@ -28,9 +28,9 @@ when the `host` is the native implementation of the FPVM. ```mermaid sequenceDiagram Client->>+Host: Hint preimage (no-op on-chain / read-only mode) - Host-->>Host: Prepare Preimage Host-->>-Client: Hint acknowledgement Client-->>+Host: Preimage Request + Host-->>Host: Prepare Preimage Host-->>-Client: Preimage Data ``` diff --git a/book/src/fpp-dev/targets.md b/book/src/fpp-dev/targets.md index 51ef9609..f1237a35 100644 --- a/book/src/fpp-dev/targets.md +++ b/book/src/fpp-dev/targets.md @@ -3,95 +3,13 @@ Kona seeks to support all FPVM targets that LLVM and `rustc` can offer introductory support for. Below is a matrix of features that Kona offers for each FPVM target: -| Target | Build Pipeline | IO | malloc | Program Stages | -| ---------------------- | -------------- | --- | ------ | -------------- | -| `cannon` & `cannon-rs` | ✅ | ✅ | ✅ | ❌ | -| `asterisc` | ✅ | ✅ | ✅ | ❌ | +| Target | Build Pipeline | IO | malloc | +| ---------------------- | -------------- | --- | ------ | +| `cannon` & `cannon-rs` | ✅ | ✅ | ✅ | +| `asterisc` | ✅ | ✅ | ✅ | If there is a feature that you would like to see supported, please [open an issue][new-issue] or [consider contributing][contributing]! -## Cannon (MIPS32r2) - -Cannon is based off of the `mips32r2` target architecture, supporting 55 instructions: - -| Category | Instruction | Description | -| -------------------- | ----------- | ----------------------------------------- | -| `Arithmetic` | `addi` | Add immediate (with sign-extension). | -| `Arithmetic` | `addiu` | Add immediate unsigned (no overflow). | -| `Arithmetic` | `addu` | Add unsigned (no overflow). | -| `Logical` | `and` | Bitwise AND. | -| `Logical` | `andi` | Bitwise AND immediate. | -| `Branch` | `b` | Unconditional branch. | -| `Conditional Branch` | `beq` | Branch on equal. | -| `Conditional Branch` | `beqz` | Branch if equal to zero. | -| `Conditional Branch` | `bgez` | Branch on greater than or equal to zero. | -| `Conditional Branch` | `bgtz` | Branch on greater than zero. | -| `Conditional Branch` | `blez` | Branch on less than or equal to zero. | -| `Conditional Branch` | `bltz` | Branch on less than zero. | -| `Conditional Branch` | `bne` | Branch on not equal. | -| `Conditional Branch` | `bnez` | Branch if not equal to zero. | -| `Logical` | `clz` | Count leading zeros. | -| `Arithmetic` | `divu` | Divide unsigned. | -| `Unconditional Jump` | `j` | Jump. | -| `Unconditional Jump` | `jal` | Jump and link. | -| `Unconditional Jump` | `jalr` | Jump and link register. | -| `Unconditional Jump` | `jr` | Jump register. | -| `Data Transfer` | `lb` | Load byte. | -| `Data Transfer` | `lbu` | Load byte unsigned. | -| `Data Transfer` | `lui` | Load upper immediate. | -| `Data Transfer` | `lw` | Load word. | -| `Data Transfer` | `lwr` | Load word right. | -| `Data Transfer` | `mfhi` | Move from HI register. | -| `Data Transfer` | `mflo` | Move from LO register. | -| `Data Transfer` | `move` | Move between registers. | -| `Data Transfer` | `movn` | Move conditional on not zero. | -| `Data Transfer` | `movz` | Move conditional on zero. | -| `Data Transfer` | `mtlo` | Move to LO register. | -| `Arithmetic` | `mul` | Multiply (to produce a word result). | -| `Arithmetic` | `multu` | Multiply unsigned. | -| `Arithmetic` | `negu` | Negate unsigned. | -| `No Op` | `nop` | No operation. | -| `Logical` | `not` | Bitwise NOT (pseudo-instruction in MIPS). | -| `Logical` | `or` | Bitwise OR. | -| `Logical` | `ori` | Bitwise OR immediate. | -| `Data Transfer` | `sb` | Store byte. | -| `Logical` | `sll` | Shift left logical. | -| `Logical` | `sllv` | Shift left logical variable. | -| `Comparison` | `slt` | Set on less than (signed). | -| `Comparison` | `slti` | Set on less than immediate. | -| `Comparison` | `sltiu` | Set on less than immediate unsigned. | -| `Comparison` | `sltu` | Set on less than unsigned. | -| `Logical` | `sra` | Shift right arithmetic. | -| `Logical` | `srl` | Shift right logical. | -| `Logical` | `srlv` | Shift right logical variable. | -| `Arithmetic` | `subu` | Subtract unsigned. | -| `Data Transfer` | `sw` | Store word. | -| `Data Transfer` | `swr` | Store word right. | -| `Serialization` | `sync` | Synchronize shared memory. | -| `System Calls` | `syscall` | System call. | -| `Logical` | `xor` | Bitwise XOR. | -| `Logical` | `xori` | Bitwise XOR immediate. | - -### Syscalls - -| \$v0 | system call | \$a0 | \$a1 | \$a2 | Effect | -| ---- | ----------- | --------------- | ---------- | ------------ | -------------------------------------------------------------------------------------------------------------------- | -| 4090 | mmap | uint32 addr | uint32 len | 🚫 | Allocates a page from the heap. See [heap](#heap) for details. | -| 4045 | brk | 🚫 | 🚫 | 🚫 | Returns a fixed address for the program break at `0x40000000` | -| 4120 | clone | 🚫 | 🚫 | 🚫 | Returns 1 | -| 4246 | exit_group | uint8 exit_code | 🚫 | 🚫 | Sets the Exited and ExitCode states to `true` and `$a0` respectively. | -| 4003 | read | uint32 fd | char \*buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned reads. See [I/O](#io) for more details. | -| 4004 | write | uint32 fd | char \*buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. | -| 4055 | fcntl | uint32 fd | int32 cmd | 🚫 | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands | - -For all of the above syscalls, an error is indicated by setting the return -register (`$v0`) to `0xFFFFFFFF` (-1) and `errno` (`$a3`) is set accordingly. -The VM must not modify any register other than `$v0` and `$a3` during syscall handling. -For unsupported syscalls, the VM must do nothing except to zero out the syscall return (`$v0`) -and errno (`$a3`) registers. - -Note that the above syscalls have identical syscall numbers and ABIs as Linux/MIPS. - ## Asterisc (RISC-V) Asterisc is based off of the `rv64gc` target architecture, which defines the following extensions: @@ -100,7 +18,6 @@ Asterisc is based off of the `rv64gc` target architecture, which defines the fol - `FENCE`, `ECALL`, `EBREAK` are hardwired to implement a minimal subset of systemcalls of the linux kernel - Work in progress. All syscalls used by the Golang `risc64` runtime. - `RV64I` support -- `RV64C`: Compressed instructions - `RV32M`+`RV64M`: Multiplication support - `RV32A`+`RV64A`: Atomics support - `RV{32,64}{D,F,Q}`: no-op: No floating points support (since no IEEE754 determinism with rounding modes etc., nor worth the complexity) @@ -116,6 +33,16 @@ programs to directly invoke a select few syscalls: 1. `WRITE` - Write the passed buffer to the passed file descriptor. 1. `READ` - Read the specified number of bytes from the passed file descriptor. -[asterisc-syscalls]: https://github.com/ethereum-optimism/asterisc +[asterisc-syscalls]: https://github.com/ethereum-optimism/asterisc/blob/master/docs/golang.md#linux-syscalls-used-by-go + +## Cannon (MIPS32r2) + +Cannon is based off of the `mips32r2` target architecture, specified in [_MIPS32™ Architecture For Programmers Volume III: The MIPS32™ Privileged Resource Architecture_](https://www.cs.cornell.edu/courses/cs3410/2013sp/MIPS_Vol3.pdf) + +### Syscalls + +Syscalls supported by `cannon` can be found within the `cannon` specification [here][cannon-syscalls]. + +[cannon-syscalls]: https://specs.optimism.io/fault-proof/cannon-fault-proof-vm.html#syscalls {{#include ../links.md}} diff --git a/book/src/intro.md b/book/src/intro.md index 83844cbc..294637bc 100644 --- a/book/src/intro.md +++ b/book/src/intro.md @@ -2,7 +2,7 @@ _Documentation for the Kona project._ - + > 📖 `kona` is in active development, and is not yet ready for use in production. During development, this book will evolve quickly and may contain inaccuracies. > diff --git a/book/src/links.md b/book/src/links.md index da5a5a7f..9d68ad14 100644 --- a/book/src/links.md +++ b/book/src/links.md @@ -10,6 +10,8 @@ [preimage-specs]: https://specs.optimism.io/experimental/fault-proof/index.html#pre-image-oracle [cannon-specs]: https://specs.optimism.io/experimental/fault-proof/cannon-fault-proof-vm.html#cannon-fault-proof-virtual-machine [l2-output-root]: https://specs.optimism.io/protocol/proposals.html#l2-output-commitment-construction +[op-succinct]: https://github.com/succinctlabs/op-succinct +[revm]: https://github.com/bluealloy/revm diff --git a/book/src/sdk/custom-backend.md b/book/src/sdk/custom-backend.md new file mode 100644 index 00000000..f008f8c8 --- /dev/null +++ b/book/src/sdk/custom-backend.md @@ -0,0 +1,120 @@ +# Custom Backends + +## Understanding the OP Stack STF + +The OP Stack state transition is comprised of two primary components: + +- **The [derivation pipeline](https://specs.optimism.io/protocol/derivation.html)** (`kona-derive`) + - Responsible for deriving L2 chain state from the DA layer. +- **The [execution engine](https://specs.optimism.io/protocol/exec-engine.html#l2-execution-engine)** (`kona-executor`) + - Responsible for the execution of transactions and state commitments. + - Ensures correct application of derived L2 state. + +To prove the correctness of the state transition, Kona composes these two components: + +- It combines the derivation of the L2 chain with its execution in the same process. +- It pulls in necessary data from sources to complete the STF, verifiably unrolling the input commitments along the way. + +`kona-client` serves as an implementation of this process, capable of deriving and executing a single L2 block in a +verifiable manner. + +> 📖 Why just a single block by default? +> +> On the OP Stack, we employ an interactive bisection game that narrows in on the disagreed upon block -> block state +> transition before requiring a fault proof to be ran. Because of this, the default implementation only serves +> to derive and execute the single block that the participants of the bisection game landed on. + +## Backend Traits + +Covered in the [FPVM Backend](./fpvm-backend.md) section of the book, `kona-client` ships with an implementation of +`kona-derive` and `kona-executor`'s data source traits which pull in data over the [PreimageOracle ABI][preimage-specs]. + +However, running `kona-client` on top of a different verifiable environment, i.e. a zkVM or TEE, is also possible +through custom implementations of these data source traits. + +[`op-succinct`](https://github.com/succinctlabs/op-succinct) is an excellent example of both a custom backend and a custom +program, implementing both `kona-derive` and `kona-executor`'s data source traits backed by [sp1_lib::io](https://docs.rs/sp1-lib/latest/sp1_lib/io/index.html) +in order to: + +1. Execute `kona-client` verbatim, proving a single block's derivation and execution on SP-1. +1. Derive and execute an entire [Span Batch](https://specs.optimism.io/protocol/delta/span-batches.html#span-batches) + worth of L2 blocks, using `kona-derive` and `kona-executor`. + +This section of the book outlines how you can do the same for a different platform. + +### Custom `kona-derive` sources + +Before getting started, we need to create custom implementations of the following traits: + +| Trait | Description | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [`ChainProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.ChainProvider.html) | The `ChainProvider` trait describes the minimal interface for fetching data from L1 during L2 chain derivation. | +| [`L2ChainProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.L2ChainProvider.html) | The `ChainProvider` trait describes the minimal interface for fetching data from the safe L2 chain during L2 chain derivation. | +| [`BlobProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.BlobProvider.html) | The `BlobProvider` trait describes an interface for fetching EIP-4844 blobs from the L1 consensus layer during L2 chain derivation. | + +Once these are implemented, constructing the pipeline is as simple as passing in the data sources to the `PipelineBuilder`. Keep in mind the requirements for validation of incoming data, depending on your platform. For example, programs +targeting zkVMs must constrain that the incoming data is indeed valid, whereas fault proof programs can offload this validation to the on-chain implementation of the host. + +```rs +let chain_provider = ...; +let l2_chain_provider = ...; +let blob_provider = ...; +let l1_origin = ...; + +let cfg = Arc::new(RollupConfig::default()); +let attributes = StatefulAttributesBuilder::new( + cfg.clone(), + l2_chain_provider.clone(), + chain_provider.clone(), +); +let dap = EthereumDataSource::new( + chain_provider.clone(), + blob_provider, + cfg.as_ref() +); + +// Construct a new derivation pipeline. +let pipeline = PipelineBuilder::new() + .rollup_config(cfg) + .dap_source(dap) + .l2_chain_provider(l2_chain_provider) + .chain_provider(chain_provider) + .builder(attributes) + .origin(l1_origin) + .build(); +``` + +From here, a custom derivation driver is needed to produce the desired execution payload(s). An example of this for +`kona-client` can be found in the [DerivationDriver](https://github.com/anton-rs/kona/blob/main/bin/client/src/l1/driver.rs#L77). + +### `kona-mpt` / `kona-executor` sources + +Before getting started, we need to create custom implementations of the following traits: + +| Trait | Description | +| ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`TrieDBFetcher`](https://docs.rs/kona-mpt/latest/kona_mpt/trait.TrieDBFetcher.html) | The `TrieDBFetcher` trait describes the interface for fetching trie node preimages and chain information while executing a payload on the L2 chain. | +| [`TrieDBHinter`](https://docs.rs/kona-mpt/latest/kona_mpt/trait.TrieDBHinter.html) | The `TrieDBHinter` trait describes the interface for requesting the host program to prepare trie proof preimages for the client's consumption. For targets with upfront witness generation, i.e. zkVMs, a no-op hinter is exported as [`NoopTrieDBHinter`](https://docs.rs/kona-mpt/latest/kona_mpt/struct.NoopTrieDBHinter.html). | + +Once we have those, the `StatelessL2BlockExecutor` can be constructed like so: + +```rust +let cfg = RollupConfig::default(); +let provider = ...; +let hinter = ...; + +let executor = StatelessL2BlcokExecutor::builder(&cfg, provider, hinter) + .with_parent_header(...) + .build(); + +let header = executor.execute_payload(...).expect("Failed execution"); +``` + +### Bringing it Together + +Once your custom backend traits for both `kona-derive` and `kona-executor` have been implemented, +your final binary may look something like [that of `kona-client`'s](https://github.com/anton-rs/kona/blob/main/bin/client/src/kona.rs). +Alternatively, if you're looking to prove a wider range of blocks, [`op-succinct`'s `range` program](https://github.com/succinctlabs/op-succinct/tree/main/programs/range) +offers a good example of running the pipeline and executor across a string of contiguous blocks. + +{{ #include ../links.md }} diff --git a/book/src/sdk/exec-ext.md b/book/src/sdk/exec-ext.md new file mode 100644 index 00000000..fef15caa --- /dev/null +++ b/book/src/sdk/exec-ext.md @@ -0,0 +1,55 @@ +# `kona-executor` Extensions + +The `kona-executor` crate offers a to-spec, stateless implementation of the OP Stack STF. However, due to the +power of [`revm`][revm]'s Handler abstractions, the logic of the STF can be easily modified. + +To register a custom handler, for example to add a custom precompile, modify the behavior of an EVM opcode, +or change the fee handling, `StatelessL2BlockExecutorBuilder::with_handle_register` is your friend. It accepts a +[`KonaHandleRegister`](https://docs.rs/kona-executor/latest/kona_executor/type.KonaHandleRegister.html), which +can be used to take full advantage of [`revm`'s Handler API](https://github.com/bluealloy/revm/blob/f57e3e639ee157c7e659e740bd175a7357003570/documentation/src/crates/revm/handler.md#handler). + +## Example - Custom Precompile + +```rs +const MY_PRECOMPILE_ADDRESS: Address = u64_to_address(0xFF); + +fn my_precompile(input: &Bytes, gas_limit: u64) -> PrecompileResult { + Ok(PrecompileOutput::new(50, "hello, world!".as_bytes().into())) +} + +fn custom_handle_register( + handler: &mut EvmHandler<'_, (), &mut State<&mut TrieDB>>, +) where + F: TrieProvider, + H: TrieHinter, +{ + let spec_id = handler.cfg.spec_id; + + handler.pre_execution.load_precompiles = Arc::new(move || { + let mut ctx_precompiles = spec_to_generic!(spec_id, { + revm::optimism::load_precompiles::>>() + }); + + let precompile = PrecompileWithAddress( + MY_PRECOMPILE_ADDRESS, + Precompile::Standard(my_precompile) + ); + ctx_precompiles.extend([precompile]); + + ctx_precompiles + }); +} + +// - snip - + +let cfg = RollupConfig::default(); +let provider = ...; +let hinter = ...; + +let executor = StatelessL2BlcokExecutor::builder(&cfg, provider, hinter) + .with_parent_header(...) + .with_handle_register(custom_handle_register) + .build(); +``` + +{{ #include ../links.md }} diff --git a/book/src/sdk/fpvm-backend.md b/book/src/sdk/fpvm-backend.md new file mode 100644 index 00000000..80f7d7fc --- /dev/null +++ b/book/src/sdk/fpvm-backend.md @@ -0,0 +1,139 @@ +# FPVM Backend + +> 📖 Before reading this section of the book, it is advised to read the [Fault Proof Program Environment](../fpp-dev/env.md) +> section to familiarize yourself with the PreimageOracle IO pattern. + +Kona is effectively split into two parts: + +- OP Stack state transition logic & types (`kona-derive`, `kona-executor`, `kona-mpt`, `kona-primitives`) +- {{#template ../../templates/glossary-link.md root=./ ref=fault-proof-vm text=Fault Proof VM}} IO and utilities + (`kona-common`, `kona-common-proc`, `kona-preimage`) + +This section of the book focuses on the usage of `kona-common` and `kona-preimage` to facilitate host<->client +communication for programs running on top of the [FPVM targets](../fpp-dev/env.md). + +## Host <-> Client Communication API + +The FPVM system API is built on several layers. In this document, we'll cover these layers, from lowest-level to +highest-level API. + +### `kona-common` + +`kona-common` implements raw syscall dispatch, a default global memory allocator, and a blocking async runtime. +`kona-common` relies on a minimal linux backend to function, supporting only the syscalls required to implement the +[PreimageOracle ABI][preimage-specs] (`read`, `write`, `exit_group`). + +These syscalls are exposed to the user through the `io` module directly, with each supported platform implementing the +[`BasicKernelInterface`](https://docs.rs/kona-common/latest/kona_common/trait.BasicKernelInterface.html) trait. + +To directly dispatch these syscalls, the [`io`](https://docs.rs/kona-common/latest/kona_common/io/index.html) module +exposes a safe API: + +```rs +use kona_common::{io, FileDescriptor}; + +// Print to `stdout`. Infalliable, will panic if dispatch fails. +io::print("Hello, world!"); + +// Print to `stderr`. Infalliable, will panic if dispatch fails. +io::print_err("Goodbye, world!"); + +// Read from or write to a specified file descriptor. Returns a result with the +// return value or syscall errno. +let _ = io::write(FileDescriptor::StdOut, "Hello, world!".as_bytes()); +let mut buf = Vec::with_capacity(8); +let _ = io::read(FileDescriptor::StdIn, buf.as_mut_slice()); + +// Exit the program with a specified exit code. +io::exit(0); +``` + +With this library, you can implement a custom host<->client communication protocol, or extend the existing +[PreimageOracle ABI][preimage-specs]. However, for most developers, we recommend sticking with `kona-preimage` +when developing programs that target the [FPVMs](../fpp-dev/env.md), barring needs like printing directly to +`stdout`. + +### `kona-preimage` + +`kona-preimage` is an implementation of the [PreimageOracle ABI][preimage-specs], built on top of `kona-common`. This +crate enables synchronous communication between the host and client program, described in +[Host <-> Client Communication](../fpp-dev/env.md#host---client-communication) in the FPP Dev environment section of the +book. + +The crate is built around the [`PipeHandle`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.PipeHandle.html), +which serves as a single end of a bidirectional pipe (see: [`pipe` manpage](https://man7.org/linux/man-pages/man2/pipe.2.html)). + +Through this handle, the higher-level constructs can read and write data to the counterparty holding on to the other end +of the pipe, following the protocol below: + +
+ +```mermaid +sequenceDiagram + Client->>+Host: Hint preimage (no-op on-chain / read-only mode) + Host-->>-Client: Hint acknowledgement + Client-->>+Host: Preimage Request + Host-->>Host: Prepare Preimage + Host-->>-Client: Preimage Data +``` + +
+ +The interfaces of each part of the above protocol are described by the following traits: + +- [`PreimageOracleClient`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.PreimageOracleClient.html) + - To-spec implementation: [`OracleReader`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.OracleReader.html) +- [`HintWriterClient`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.HintWriterClient.html) + - To-spec implementation: [`HintWriter`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.HintWriter.html) +- [`PreimageOracleServer`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.PreimageOracleServer.html) + - To-spec implementation: [`OracleServer`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.OracleServer.html) +- [`HintReaderServer`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.HintReaderServer.html) + - To-spec implementation: [`HintReader`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.HintReader.html) + +Each of these traits, however, can be re-implemented to redefine the host<->client communication protocol if the needs +of the consumer are not covered by the to-[spec][preimage-specs] implementations. + +### `kona-client` - Oracle-backed sources (example) + +Finally, in `kona-client`, implementations of data source traits from `kona-derive` and `kona-executor` are implemented +to pull in untyped data from the host by `PreimageKey`. These data source traits are covered in more detail within +the [Custom Backend](./custom-backend.md) section, but we'll quickly gloss over them here to build intuition. + +Let's take, for example, [`OracleL1ChainProvider`](https://github.com/anton-rs/kona/blob/40a8d7ec3def4a1eeb26492a1e4338d8b032e428/bin/client/src/l1/chain_provider.rs#L16-L23). +The [`ChainProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.ChainProvider.html) trait in `kona-derive` +defines a simple interface for fetching information about the L1 chain. In the `OracleL1ChainProvider`, this information +is pulled in over the [PreimageOracle ABI][preimage-specs]. There are many other examples of these data source traits, +namely the `L2ChainProvider`, `BlobProvider`, `TrieProvider`, and `TrieHinter`, which enable the creation of different +data-source backends. + +As an example, let's look at `OracleL1ChainProvider::header_by_hash`, built on top of the `CommsClient` trait, which +is a composition trait of the `PreimageOracleClient + HintReaderServer` traits outlined above. + +```rs +#[async_trait] +impl ChainProvider for OracleL1ChainProvider { + type Error = anyhow::Error; + + async fn header_by_hash(&mut self, hash: B256) -> Result
{ + // Send a hint for the block header. + self.oracle.write(&HintType::L1BlockHeader.encode_with(&[hash.as_ref()])).await?; + + // Fetch the header RLP from the oracle. + let header_rlp = + self.oracle.get(PreimageKey::new(*hash, PreimageKeyType::Keccak256)).await?; + + // Decode the header RLP into a Header. + Header::decode(&mut header_rlp.as_slice()) + .map_err(|e| anyhow!("Failed to decode header RLP: {e}")) + } + + // - snip - +} +``` + +In `header_by_hash`, we use the inner `HintWriter` to send a hint to the host to prepare the block hash preimage. +Then, once we've received an acknowledgement from the host that the preimage has been prepared, we reach out for +the RLP (which is the preimage of the hash). After the RLP is received, we decode the `Header` type, and return +it to the user. + +{{ #include ../links.md }} diff --git a/book/src/sdk/intro.md b/book/src/sdk/intro.md new file mode 100644 index 00000000..24df6f58 --- /dev/null +++ b/book/src/sdk/intro.md @@ -0,0 +1,36 @@ +# Kona SDK + +Welcome to the Kona SDK, a powerful set of libraries designed to revolutionize the way developers build proofs for the +OP Stack STF on top of the OP Stack's FPVMs and other verifiable backends like [SP-1][sp-1], [Risc0][rzero], +[Intel TDX][tdx], and [AMD SEV-SNP][sev-snp]. At its core, Kona is built on the principles of modularity, extensibility, +and developer empowerment. + +## A Foundation of Flexibility + +The kona repository is more than a fault proof program for the OP Stack — it's an ecosystem of interoperable components, +each crafted with reusability and extensibility as primary goals. While we provide +{{#template ../../templates/glossary-link.md root=./ ref=fault-proof-vm text=Fault Proof VM}} and "online" backends +for key components like `kona-derive` and `kona-executor`, the true power of `kona` lies in its adaptability. + +## Extend Without Forking + +One of Kona's standout features is its ability to support custom features and data sources without requiring you to fork +the entire project. Through careful use of Rust's powerful trait system and abstract interfaces, we've created a +framework that allows you to plug in your own features and ideas seamlessly. + +## What You'll Learn + +In this section of the developer book, we'll dive deep into the Kona SDK, covering: +* **Building on the FPVM Backend**: Learn how to leverage the Fault Proof VM tooling to create your own fault proof programs. +* **Creating Custom Backends**: Discover the process of designing and implementing your own backend to run `kona-client` or a variation of it on different targets. +* **Extending Core Components**: Explore techniques for creating new constructs that integrate smoothly with crates like `kona-derive` and `kona-executor`. + +Whether you're looking to use Kona as-is, extend its functionality, or create entirely new programs based on its libraries, +this guide is intended to provide you with the knowledge and tools you need to succeed. + +[sp-1]: https://github.com/succinct-labs/sp-1 +[rzero]: https://github.com/risc0/risc0 +[tdx]: https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html +[sev-snp]: https://www.amd.com/en/developer/sev.html + +{{#include ../links.md}} diff --git a/book/theme/index.hbs b/book/theme/index.hbs new file mode 100644 index 00000000..c4fd6f23 --- /dev/null +++ b/book/theme/index.hbs @@ -0,0 +1,364 @@ + + + + + + + {{ title }} + {{#if is_print }} + + {{/if}} + {{#if base_url}} + + {{/if}} + + + + {{> head}} + + + + + + {{#if favicon_svg}} + + {{/if}} + {{#if favicon_png}} + + {{/if}} + + + + {{#if print_enable}} + + {{/if}} + + + + {{#if copy_fonts}} + + {{/if}} + + + + + + + + {{#each additional_css}} + + {{/each}} + + {{#if mathjax_support}} + + + {{/if}} + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ {{> header}} + + + + {{#if search_enabled}} + + {{/if}} + + + + +
+
+ {{{ content }}} +
+ + +
+
+ + + +
+ + {{#if live_reload_endpoint}} + + + {{/if}} + + {{#if google_analytics}} + + + {{/if}} + + {{#if playground_line_numbers}} + + {{/if}} + + {{#if playground_copyable}} + + {{/if}} + + {{#if playground_js}} + + + + + + {{/if}} + + {{#if search_js}} + + + + {{/if}} + + + + + + + {{#each additional_js}} + + {{/each}} + + {{#if is_print}} + {{#if mathjax_support}} + + {{else}} + + {{/if}} + {{/if}} + +
+ + +