notary-server
An implementation of the notary server in Rust.
⚠️ Notice
This project is currently under active development and should not be used in production. Expect bugs and regular major breaking changes.
Running the server
- Configure the server setting in this file — refer here for more information on the definition of the setting parameters.
- Start the server by running following in a terminal at the top level of this project.
cargo run
- To use a config file from a different location, run the following command to override the default config file location.
cargo run -- --config-file <path-to-new-config-file>
API
All APIs are TLS-protected, hence please use https:// or wss://.
HTTP APIs
Defined in the OpenAPI specification.
WebSocket APIs
/notarize
Description
To perform notarization using the session id (unique id returned upon calling the /session endpoint successfully) submitted as a custom header.
Custom Header
X-Session-Id
Custom Header Type
String
Architecture
Objective
The main objective of a notary server is to perform notarization together with a prover. In this case, the prover can either be
- TCP client — which has access and control over the transport layer, i.e. TCP
- WebSocket client — which has no access over TCP and instead uses WebSocket for notarization
Design Choices
Web Framework
Axum is chosen as the framework to serve HTTP and WebSocket requests from the prover clients due to its rich and well supported features, e.g. native integration with Tokio/Hyper/Tower, customizable middleware, ability to support lower level integration of TLS (example). To simplify the notary server setup, a single Axum router is used to support both HTTP and WebSocket connections, i.e. all requests can be made to the same port of the notary server.
Notarization Configuration
To perform notarization, some parameters need to be configured by the prover and notary server (more details in the OpenAPI specification), i.e.
- maximum transcript size
- unique session id
To streamline this process, a single HTTP endpoint (/session) is used by both TCP and WebSocket clients.
WebSocket
Axum's internal implementation of WebSocket uses tokio_tungstenite, which provides a WebSocket struct that doesn't implement AsyncRead and AsyncWrite. Both these traits are required by TLSN core libraries for prover and notary. To overcome this, a slight modification of Axum's implementation of WebSocket is used, where async_tungstenite is used instead so that ws_stream_tungstenite can be used to wrap on top of the WebSocket struct to get AsyncRead and AsyncWrite implemented.