---
# System prepended metadata

title: Notes on Trin Architecture
tags: [trin, notes, epf, portal-network, ethereum]

---

# [Draft] Notes on Trin Architecture

> This document is a WIP. I expect to add more info as I learn more about trin.

In this document, I try to better document how trin is built. Focusing on the history network.

Let's start by learning what happens at startup. This is an outline of the functions called:

![](https://hackmd.io/_uploads/Bkhc7LNn3.jpg)

We start with the `main` function. This is called when the program is executed, or at `cargo run`. `main` reads the config of the program (the flags included in the launch command) and calls `run_trin`.

`run_trin` does a lot of things, but we'll focus on how it starts the sub-protocols. Each sub-protocol has an asociated function of the form `initialize_history_network`. This function starts some services (see the image above) but also returns four values. Those values are used as follows:



| Return variable name | Type               | Usage                                                                                          |
| -------------------- | ------------------ | ---------------------------------------------------------------------------------------------- |
| history_handler      | HistoryHandler     | spawns a thread where `handle_client_queries` is executed                                      |
| history_network_task | HistoryNetworkTask | spawns a thread with the task                                                                  |
| history_event_tx     | HistoryEventTx     | one of the arguments to spawn the main portal events handler by calling `PortalnetEvents::new` |
| history_jsonrpc_tx   | HistoryJsonRpcTx   | one of the arguments to launch the JSON-RPC server by calling `launch_jsonrpc_server`                                                                                               |



## Detailed Description

### [`main`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/main.rs#L10)

This is the entry point to Trin. It's the function executed when you run `cargo run`.

- start tracing logger
- parse config from cli
- call [`run_trin`](#run_trin) and handle errors
- listen for `Ctrl+c` shutdown signal

### [`run_trin`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L25)

- define trin version
- log info about trin version and confg being used
- setup temp trin data directory if in ephemeral mode
- configure node data dir based on the provided private key
- build instance of `PortalnetConfig` [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L39C1-L46C7)
- initialize base discovery protocol [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L48C1-L51C41)
    - build instance of `Discovery` by calling `Discovery::new`
    - get `talk_req_rx` by calling `Discovery::start`
    - wrap the discovery instance on an `Arc`
- initialize prometheus metrics
- initialize and spawn uTP socket [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L58C1-L62C43)
    - get `utp_talk_reqs_tx` and `utp_talk_reqs_rx` by starting a `mpsc::unbounded_channel()`
    - build instance of `Discv5UdpSocket` by calling `Discv5UdpSocket::new`
    - build instance of `UtpSocket` by calling `UtpSocket::with_socket(discv5_utp_socket)`
    - wrap the `UtpSocket` on an `Arc`
- build instance of `PortalStorageConfig` by calling `PortalStorageConfig::new` [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L64C1-L68C8)
- initialize validation oracle [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L70C1-L77C62)
    - build `MasterAccumulator` by calling `MasterAccumulator::try_from_file`
    - build `HeaderOracle` by calling `HeaderOracle::new`
    - wrap `HeaderOracle` on `RwLock` and that in `Arc`
- initialize portal sub-protocols
    - initialize state sub-network service and event handlers, if selected
    - initialize trin-beacon sub-network service and event handlers, if selected
    - initialize chain history sub-network service and event handlers, if selected, by calling [`initialize_history_network`](#initialize_history_network) [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L109C1-L126C11)
- launch JSON-RPC server [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L128C1-L138C13)
- spawn handler threads [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L140C1-L148C6)
- spawn main portal events handler [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L150C1-L161C8)
- spawn network threads [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/src/lib.rs#L163C1-L171C6)
- return RPC handle

### [`initialize_history_network`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/lib.rs#L36)

- get `history_jsonrpc_tx` and `history_jsonrpc_rx` by calling `mpsc::unbounded_channel::<HistoryJsonRpcRequest>()`
- assing `history_jsonrpc_tx` to its corresponding field in the `header_oracle`
- get `history_event_tx` and `history_event_rx` by calling `mpsc::unbounded_channel::<TalkRequest>()`
- build instance of `HistoryNetwork` [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/lib.rs#L53C1-L60C13)
    - call [`HistoryNetwork::new`](#HistoryNetwork::new)
    - wrap the new `HistoryNetwork` in an `Arc`
- build instance of `HistoryRequestHandler`
- get `history_network_task` by calling [`spawn_history_network`](#spawn_history_network)[↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/lib.rs#L66C1-L67C92)
- call [`spawn_history_heartbeat`](#spawn_history_heartbeat)
- return `history_handler`, `history_network_task`, `history_event_tx` and `history_jsonrpc_tx`


### [`HistoryNetwork::new`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/network.rs#L28)

- parse config
- build instance of `PortalStorage`
    - call `PortalStorage::new`
    - wrap in `PLRwLock` and that in `Arc`
- build instance of `ChainHistoryValidator` and wrap in `Arc`
- build instace of `OverlayProtocol` by calling [`OverlayProtocol::new`](#OverlayProtocol::new)
- return a new instance of `HistoryNetwork`, only field is the `OverlayProtocol` just built wrapped in `Arc`

### [`spawn_history_network`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/lib.rs#L77C1-L77C30)

- parse bootnode config and log info about them
- spawn a thread that handles history events [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/lib.rs#L88C1-L103C7)
    - build instance of `HistoryEvents` 
    - spawn history event handler by calling [`HistoryEvents::start`](#HistoryEvents::start)
    - make sure we establish a session with the boot node
    - listen for `Ctrl+c` shutdown signal

### [`OverlayProtocol::new`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/portalnet/src/overlay.rs#L128)

- get `kbuckets` [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/portalnet/src/overlay.rs#L136C1-L142C13)
- initialize metrics
- get `command_tx` by calling [`OverlayService::spawn`](#OverlayService::spawn)
- return a new instance of `OverlayProtocol` with values passed as arguments and the values gotten in the function

### [`HistoryEvents::start`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/events.rs#L14)

- loop listening for events (`TalkRequest`). when an event is found call [`HistoryEvents::handle_history_talk_request`](#HistoryEvents::handle_history_talk_request). also, error handling

### [`HistoryEvents::handle_history_talk_request`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/trin-history/src/events.rs#L28)

- calls [`OverlayProtocol::process_one_request`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/portalnet/src/overlay.rs#L195) and handles errors
 
### [`OverlayService::spawn`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/portalnet/src/overlay_service.rs#L332)

- get `command_tx` and `command_rx` by calling `mpsc::unbounded_channel`
- get peers to ping [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/portalnet/src/overlay_service.rs#L356C1-L360C11)
- get (`response_tx` and `response_rx` by calling `mpsc::unbounded_channel`
- spawn a service thread [↗️](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/portalnet/src/overlay_service.rs#L364C9-L393C12)
    - build instance of `OverlayService`
    - log
    - run `OverlayService::initialize_routing_table`
    - run [`OverlayService::start`](#OverlayService::start)

### [`OverlayService::start`](https://github.com/ethereum/trin/blob/4914f5a76ddaa80aa98ea8de75463f66d509c74a/portalnet/src/overlay_service.rs#L469)

``` rust
/// The main loop for the overlay service. The loop selects over different possible tasks to
/// perform.
///
/// Process request: Process an incoming or outgoing request through the overlay.
///
/// Process response: Process a response to an outgoing request from the local node. Try to
/// match this response to an active request, and send the response or error over the
/// associated response channel. Update node state based on result of response.
///
/// Ping queue: Ping a node in the routing table to perform a liveness check and to refresh
/// information relevant to the overlay network.
///
/// Bucket maintenance: Maintain the routing table (more info documented above function).
```
