diff --git a/docs/book.toml b/docs/book.toml new file mode 100644 index 0000000..a7b2016 --- /dev/null +++ b/docs/book.toml @@ -0,0 +1,16 @@ +[book] +authors = ["Miden contributors"] +description = "Manual for the Miden Transport Layer node software which is responsible for exchanging private notes in the Miden ecosystem." +language = "en" +multilingual = false +title = "The Miden Transport Layer Node Operator and Developer Guide" + +[output.html] +git-repository-url = "https://github.com/0xMiden/miden-private-transport" + +[preprocessor.katex] +after = ["links"] + +[preprocessor.alerts] + +[output.linkcheck] diff --git a/docs/src/EXPORTED.md b/docs/src/EXPORTED.md new file mode 100644 index 0000000..0015e12 --- /dev/null +++ b/docs/src/EXPORTED.md @@ -0,0 +1,12 @@ + + +# Summary + +- [Node](./index.md) + - [Node Operator Guide](./operator/index.md) + - [Architecture](./operator/architecture.md) + - [Installation](./operator/installation.md) + - [Configuration and Usage](./operator/usage.md) + - [Monitoring](./operator/monitoring.md) + - [Versioning](./operator/versioning.md) + - [Node gRPC Reference](./user/rpc.md) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md new file mode 100644 index 0000000..2f5073a --- /dev/null +++ b/docs/src/SUMMARY.md @@ -0,0 +1,30 @@ + + +# Summary + +[Introduction](./index.md) + +--- + +# Operator Guide + +- [Overview](./operator/index.md) +- [Architecture](./operator/architecture.md) +- [Installation](./operator/installation.md) +- [Configuration and Usage](./operator/usage.md) +- [Monitoring](./operator/monitoring.md) +- [Versioning](./operator/versioning.md) + +--- + +# Developer Guide + +- [Overview](./developer/index.md) +- [Navigating the codebase](./developer/codebase.md) +- [Components](./developer/components.md) + +--- + +# gRPC Reference + +- [RPC Reference](./user/rpc.md) diff --git a/docs/src/developer/codebase.md b/docs/src/developer/codebase.md new file mode 100644 index 0000000..727cc3b --- /dev/null +++ b/docs/src/developer/codebase.md @@ -0,0 +1,13 @@ +# Navigating the codebase + +The code is organised using a Rust workspace with two crates (`miden-private-transport-node` and `miden-private-transport-proto`) and a binary (`miden-private-transport-node-bin`): + +- `miden-private-transport-node` (at `crates/node`): Primary node library. Contains all of the node logic; +- `miden-private-transport-proto` (at `crates/proto`): gRPC protobuf definitions and associated auto-generated Rust code. Both clients and node use this crate to establish communications; +- `miden-private-transport-node-bin` (at `bin/node`): Running node binary. Instantiation and wrapper of the node library. + +------- + +> [!NOTE] +> [`miden-base`](https://github.com/0xMiden/miden-base) is an important dependency which +> contains the core Miden protocol definitions e.g. accounts, notes, transactions etc. diff --git a/docs/src/developer/components.md b/docs/src/developer/components.md new file mode 100644 index 0000000..44efa55 --- /dev/null +++ b/docs/src/developer/components.md @@ -0,0 +1,33 @@ +# Node components + +The node is split into two main components: RPC and database. + +The following sections will describe the inner architecture of each component. + +## RPC + +The RPC component provides a public interface to user requests. +Essentially this is a thin gRPC server that proxies all requests to the database. + +A running task is spawned with this gRPC server. The library `tonic` is used to provide gRPC support. + +### Streaming + +Note streaming is employed based on gRPC streams. A `NoteStreamer` task manages subscribed connections, feeding them newly received notes. + +Focusing on performance, notes are not forwarded to subscribers as soon as they are received. +For subscribed tags, the `NoteStreamer` task periodically (every 500 ms) queries the database for new notes, akin to a fetch notes operation, and sends these to subscribed users. + +## Database + +This component persists the private notes in a SQLite database. Currently, there is only one table (named `notes`). + +### Migrations + +Migration support is provided but not in use yet, given that the node is under heavy development. + +### Database maintenance + +Database maintenance is provided by a separate task. Currently this is only a periodic cleanup of older notes -- notes which have exceeded the defined retention period. + +A running task is spawned dedicated to this maintenance service. diff --git a/docs/src/developer/index.md b/docs/src/developer/index.md new file mode 100644 index 0000000..04a62e1 --- /dev/null +++ b/docs/src/developer/index.md @@ -0,0 +1,21 @@ +# Developer Guide + +Welcome to the developer guide for the `miden` transport layer node :) + +This is intended to serve as a basic introduction to the codebase as well as covering relevant concepts and recording +architectural decisions. + +This is _not_ intended for dApp developers or users of the node, but for development of the node itself. + +It is also a good idea to familiarize yourself with the [operator manual](../operator/index.md). + +
+ +Living documents go stale - the code is the final arbitrator of truth. + +If you encounter any outdated, incorrect or misleading information, please +[open an issue](https://github.com/0xMiden/miden-private-transport/issues/new/choose). + +
+ +Please also see the `miden-node` contribution [guidelines](https://0xmiden.github.io/miden-node/developer/contributing.html) and monitoring [guide](https://0xmiden.github.io/miden-node/developer/monitoring.html) as these also apply here. diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 0000000..713f0b7 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,36 @@ +# Introduction + +> [!IMPORTANT] +> The Miden Transport Layer is under heavy development. The protocol and interface may face large changes. + +Welcome to the Miden Transport Layer node documentation. + +This book provides two separate guides aimed at node operators and developers looking to contribute to the node +respectively. Each guide is standalone, but developers should also read through the operator guide as it provides some +additional context. + +At present, the Miden Transport Layer node is the central hub responsible for exchanging private notes in the Miden ecosystem. +As Miden decentralizes, the node will morph into the official reference implementation(s) of +the various components required by a fully p2p network. + +The node provides a gRPC interface for users, dApps, wallets and other entities to send and receive private notes in a secure way. +A client implementation is provided as a module in the [`miden-client`](https://github.com/0xMiden/miden-client). + +## The Transport Layer + +The architecture of the Transport Layer is simple. +It is based on a client-node (or, client-server) architecture, where clients exchange notes by pushing them and fetching them from the node. + +The flow is as follows, +1. User sends a note to the node; +2. The note is stored for a retention period (default at 30 days). The node also labels the note with an increasing-monotonic integer cursor (currently a timestamp); +3. The recipient fetches notes by note tag. To reduce the number of fetched notes (pagination), the user may employ the cursor (only notes after this value will be provided). + +The node itself may also be referred to as the transport layer. + +## Feedback + +Please report any issues, ask questions or leave feedback in the node repository +[here](https://github.com/0xMiden/miden-private-transport/issues/new/choose). + +This includes outdated, misleading, incorrect or just plain confusing information :) diff --git a/docs/src/operator/architecture.md b/docs/src/operator/architecture.md new file mode 100644 index 0000000..829227d --- /dev/null +++ b/docs/src/operator/architecture.md @@ -0,0 +1,24 @@ +# Node architecture + +The node consists of two main components: RPC and database. Combined, a simple system supports the core mechanism of the transport layer: the node serves public RPC requests, while using the database to store the notes associated with the requests. + +While currently only supporting a centralized architecture, it is expected to evolve into a more distributed approach in order to increase the resilience of the transport layer. + +## RPC + +The RPC component provides a public gRPC API with which users can send and fetch notes. +Requests are processed and then proxied to the database. + +Note streaming is also supported through gRPC. + +This is the _only_ externally facing component. + +## Database + +The database is responsible for storing the private notes. +As the transport layer was built with a focus on user privacy, no user data is stored. + +Notes are stored for a predefined duration (default at 30 days). +An internal sub-component running in the node is responsible for the database maintenance, performing the removal of expired notes. + +Currently, SQLite is the only database implementation provided. diff --git a/docs/src/operator/index.md b/docs/src/operator/index.md new file mode 100644 index 0000000..38165c2 --- /dev/null +++ b/docs/src/operator/index.md @@ -0,0 +1,7 @@ +# Operator Guide + +Welcome to the `Miden` Transport Layer node operator guide which should cover everything you need to successfully run and maintain a +Miden Transport Layer node. + +You can report any issues, ask questions or leave feedback at our project repo +[here](https://github.com/0xMiden/miden-private-transport/issues/new/choose). diff --git a/docs/src/operator/installation.md b/docs/src/operator/installation.md new file mode 100644 index 0000000..5983a29 --- /dev/null +++ b/docs/src/operator/installation.md @@ -0,0 +1,59 @@ +# Installation + +The Miden Transport Layer currently can only be installed from source using the Rust package manager `cargo`, or by using the Docker setup provided in the repository. + +## Install using `cargo` + +Install Rust version **1.89** or greater using the official Rust installation +[instructions](https://www.rust-lang.org/tools/install). + +Depending on the platform, you may need to install additional libraries. For example, on Ubuntu 22.04 the following +command ensures that all required libraries are installed. + +```sh +sudo apt install llvm clang bindgen pkg-config libssl-dev libsqlite3-dev +``` + +Then use `cargo` to compile the node from the source code: + +```sh +# Install latest version +cargo install --locked --git https://github.com/0xMiden/miden-private-transport miden-private-transport-node-bin + +# Install from a specific branch +cargo install --locked --git https://github.com/0xMiden/miden-private-transport miden-private-transport-node-bin --branch + +# Install a specific tag +cargo install --locked --git https://github.com/0xMiden/miden-private-transport miden-private-transport-node-bin --tag + +# Install a specific git revision +cargo install --locked --git https://github.com/0xMiden/miden-private-transport miden-private-transport-node-bin --rev +``` + +More information on the various `cargo install` options can be found +[here](https://doc.rust-lang.org/cargo/commands/cargo-install.html#install-options). + +## Docker setup + +With Docker installed on your system, a Docker setup is provided that also includes a monitoring stack with: OpenTelemetry exporter, Grafana (visualization), Prometheus (metrics), and Tempo (traces). + +Clone the repository: + +```sh +git clone https://github.com/0xMiden/miden-private-transport +``` + +Then, move into the directory, `cd miden-private-transport`, and run `make docker-node-up` to start the node and monitoring stack. +To stop the stack, run `make docker-node-down`. + +Grafana will be accessible at `localhost:3000`. + + +## Updating + +> [!WARNING] +> We currently have no backwards compatibility guarantees. This means updating your node is destructive - your +> existing chain will not work with the new version. This will change as our protocol and database schema mature and +> settle. + +Updating the node to a new version is as simple as re-running the install process and repeating the [bootstrapping](./usage.md#bootstrapping) instructions. diff --git a/docs/src/operator/monitoring.md b/docs/src/operator/monitoring.md new file mode 100644 index 0000000..cb6a98f --- /dev/null +++ b/docs/src/operator/monitoring.md @@ -0,0 +1,90 @@ +# Monitoring & telemetry + +We provide logging to `stdout` and an optional [OpenTelemetry](https://opentelemetry.io/) exporter for our metrics and traces. + +OpenTelemetry exporting can be enabled by specifying `--enable-otel` via the command-line or the +`MIDEN_TLNODE_ENABLE_OTEL` environment variable when operating the node. + +## Metrics + +Various metrics associated with the RPC requests and database operations are provided: + +### RPC metrics + +| name | type | description | +|------------------------------------|---------------------|---------------------------------------------------| +| `send_note_count` | Counter | number of `send_note` requests | +| `send_note_duration` | Histogram (seconds) | duration of `send_note` requests | +| `send_note_size` | Histogram (bytes) | size of received notes in `send_note` requests | +| `fetch_notes_count` | Counter | number of `fetch_notes` requests | +| `fetch_notes_duration` | Histogram (seconds) | duration of `fetch_notes` requests | +| `fetch_notes_replied_notes_number` | Counter | number of replied notes in `fetch_notes` requests | +| `fetch_notes_replied_notes_size` | Histogram (bytes) | size of replied notes in `fetch_notes` requests | + +### Database metrics + +| name | type | description | +|--------------------------------------|---------------------|--------------------------------------------| +| `store_note_count` | Counter | number of `store_note` operations | +| `store_note_duration` | Histogram (seconds) | duration of `store_note` operations | +| `fetch_notes_count` | Counter | number of `fetch_notes` operations | +| `fetch_notes_duration` | Histogram (seconds) | duration of `fetch_notes` operations | +| `maintenance_cleanup_notes_count` | Counter | number of `cleanup_old_notes` operations | +| `maintenance_cleanup_notes_duration` | Histogram (seconds) | duration of `cleanup_old_notes` operations | +} + +## Traces + +We assign a unique trace (aka root span) to each RPC request. + +
+ +Span and attribute naming is unstable and should not be relied upon. This also means changes here will not be considered +breaking, however we will do our best to document them. + +
+ +### RPC traces + +
+ Span tree + +```sh +grpc.send_note.request +┕━ db.store_note + +grpc.fetch_notes.request +┕━ db.fetch_notes +``` + +
+ + +## Verbosity + +We log important spans and events at `info` level or higher, which is also the default log level. + +Changing this level should rarely be required - let us know if you're missing information that should be at `info`. + +The available log levels are `trace`, `debug`, `info` (default), `warn`, `error` which can be configured using the +`RUST_LOG` environment variable e.g. + +```sh +export RUST_LOG=debug +``` + +## Configuration + +The OpenTelemetry trace exporter is enabled by adding the `--enable-otel` flag to the node's start command: + +```sh +miden-private-transport-node-bin --enable-otel +``` + +The exporter can be configured using environment variables as specified in the official +[documents](https://opentelemetry.io/docs/specs/otel/protocol/exporter/). + +
+Not all options are fully supported. We are limited to what the Rust OpenTelemetry implementation supports. If you have any problems please open an issue and we'll do our best to resolve it. + +
diff --git a/docs/src/operator/usage.md b/docs/src/operator/usage.md new file mode 100644 index 0000000..a69115f --- /dev/null +++ b/docs/src/operator/usage.md @@ -0,0 +1,23 @@ +# Configuration and Usage + +Configuration and operation of the Miden Transport Layer node is simple. + + +## Operation + +Start the node with the desired public gRPC server address. +For example, + +```sh +miden-private-transport-node-bin \ + --host 0.0.0.0 \ + --port 9730 \ + --database-url mtln.db +``` + +> [!NOTE] +> `miden-private-transport-node-bin` provides default arguments aimed at development. + +Configuration is purely made using command line arguments. Run `miden-private-transport-node-bin --help` for available options. + +If using the provided Docker setup, see the [setup page](installation.md#docker-setup). Configure the node binary launch arguments accordingly before starting Docker containers. diff --git a/docs/src/operator/versioning.md b/docs/src/operator/versioning.md new file mode 100644 index 0000000..39afca4 --- /dev/null +++ b/docs/src/operator/versioning.md @@ -0,0 +1,5 @@ +# Versioning + +The Transport Layer is under heavy development and was not yet released. + +We defer to the [`git` history](https://github.com/0xMiden/miden-private-transport/commits/main/) in the meanwhile. diff --git a/docs/src/user/rpc.md b/docs/src/user/rpc.md new file mode 100644 index 0000000..06d4c1a --- /dev/null +++ b/docs/src/user/rpc.md @@ -0,0 +1,35 @@ +# gRPC Reference + +This is a reference of the Node's public RPC interface. It consists of a gRPC API which may be used to exchange notes with the Transport Layer. + +The gRPC service definition can be found in the Miden Transport Layer's `proto` crate +[directory](https://github.com/0xMiden/miden-private-transport/tree/main/crates/proto) in the `miden-private-transport.proto` file. + + + +- [SendNote](#sendnote) +- [FetchNotes](#fetchnotes) +- [StreamNotes](#streamnotes) +- [Stats](#stats) + + + +## SendNote + +Pushes a note to the node. +The note is split into its header and details. The details can be encrypted. + +## FetchNotes + +Fetches notes from the node. +Notes with the provided tag are supplied as response. +Pagination is employed through an increasing-monotonic cursor. + +## StreamNotes + +Stream notes from the node to a subscribed client. +Similarly to `FetchNotes` but the node continuously provides newly received notes which have the subscribed tag. + +## Stats + +Gets generic statistics from the node database. Total stored notes and total (unique) tags are provided.