# [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:

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).
```