Skip to content

Commit

Permalink
doc: add architecture overview
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-melnychuk committed Oct 23, 2024
1 parent c70dd36 commit e2f90a2
Showing 1 changed file with 114 additions and 0 deletions.
114 changes: 114 additions & 0 deletions doc/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
Beerus Architecture Overview
============================

## Components

* Beerus client library (`src/client.rs`)
* Beerus RPC server
- Based on `axum` HTTP server
- RPC impl (`src/rpc.rs`)
* JSON-RPC spec (generated code: `src/gen.rs`)
- Starknet spec 0.7.1 (`etc/spec/starknet/0.7.1`)
- Generated by `iamgroot` (Rust DTO codegen tool)
* Ethereum client (`src/eth.rs`)
- Based on `helios` Ethereum light client
* Merkle proof check (`src/proof.rs`)
* Stateless execution (`src/exe/mod.rs`)
- `blockifier`
- `cairo-vm`
- `cairo-lang-*`
* WebAssembly library (`web/beerus-web`)

## Execution

### Get current state

```mermaid
sequenceDiagram
Beerus->>Helios: Start
loop Sync
Helios->>(Beacon Chain): Query Beacon Chain
(Beacon Chain)->>Helios: Beacon Chain data
end
Note right of Helios: Helios is ready
Helios->>Beerus: Synced
Note right of Beerus: Beerus is ready
Beerus->>Helios: Query State
Beerus->>Helios: Get Latest Block
Helios->>(Ethereum RPC): Get Latest Block
(Ethereum RPC)->>Helios: Latest Block Number
Helios->>Beerus: Latest Block Number
Beerus->>Helios: Call stateBlockNumber()
Helios->>(Ethereum RPC): Call Starknet Core Contract
(Ethereum RPC)->>Helios: Get Result
Helios->>Beerus: Get Result
Beerus->>Helios: Call stateBlockHash()
Helios->>(Ethereum RPC): Call Starknet Core Contract
(Ethereum RPC)->>Helios: Get Result
Helios->>Beerus: Get Result
Beerus->>Helios: Call stateRoot()
Helios->>(Ethereum RPC): Call Starknet Core Contract
(Ethereum RPC)->>Helios: Get Result
Helios->>Beerus: Get Result
Beerus->>Beerus: Store Current State
```

### Stateless call (RPC)

```mermaid
sequenceDiagram
(RPC Server)->>Beerus: starknet_call
Beerus->>Beerus: Check current state
Beerus->>Blockifier: Prepare execution context
Blockifier->>Blockifier: Create Starknet client
Blockifier->>Blockifier: Create State reader & write
loop Stateless Execution
Blockifier->>State Reader: State Request
State Reader->>(Starknet RPC): Query State
(Starknet RPC)->>State Reader: State Result
State Reader->>(Starknet RPC): Query State Proof
(Starknet RPC)->>State Reader: State Proof
State Reader->>State Reader: Verify State Proof
State Reader->>Blockifier: State Result
end
Note right of (RPC Server): Other methods are proxied
(RPC Server)->>Beerus: starknet_*
Beerus->>(Starknet RPC): (proxy the request)
(Starknet RPC)->>Beerus: (proxy the response)
Beerus->>(RPC Server): response
```

### Stateless call (WASM)

```mermaid
sequenceDiagram
(Browser)->>(Browser): Check Proxy
(Browser)->>Beerus: Init
Note right of Beerus: Beerus is set up to run in a WebWorker
Beerus->>(Browser): Ready
(Browser)->>Beerus: Call
Beerus->>Client: Inject post() function
Client->>Client: create blocking StateReader
Note right of Client: Blocking StateReader is required by Blockifier
Client->>Client: create async StateReader
Client->>Beerus: Ready
Beerus->>Blockifier: Execute call
loop Stateless Execution
Blockifier->>Client: State Request
Client->>(Starknet RPC): State Request
(Starknet RPC)->>Client: State Result
Client->>(Starknet RPC): Get State Proof
(Starknet RPC)->>Client: State Proof
Client->>Client: Verify State Proof
Client->>Blockifier: State Result
end
Blockifier->>Beerus: Call Result
```

Beerus allows Blockifier to execute calls in a stateless manner by providing implementation of a `StateReader`. The `StateReader` implementation fetches necessary state (the value for the provided key to be exact) directly from Starknet RPC (and then pulls merkle proof for the value and verifies that it is valid). Thus during call execution Beerus has no control over which specific RPC methods are being called and how often - it depends on Blockifier and specific execution context of the call (contract & method that are being executed).

Beerus workload is purely IO bound, as the only computation being performed is the verification of a merkle proof for a received key-value pairs. Thus performance of the stateless call execution depends on latency and frequency of RPC calls performed by Blockifier.

0 comments on commit e2f90a2

Please sign in to comment.