# Link protocol

The link protocol controls every node-node link in the Earendil network, both relay-relay links and relay-client links.

The basic outline is such:

* Every link is a `picomux` session
* Each end of a link can call "LinkRPC" methods on the other end, by using JSON-RPC over `picomux` streams. These streams have label `"!rpc"`
* Onion-routed messages are passed through a stream with label `""`.

## LinkRPC

Each end of a link separately establishes one or more `sosistab2` streams labelled `"n2n_control"`. Over these streams, JSON-RPC requests are sent in a newline-delimitated manner analogous to JSON-RPC over TCP. For example, here is an example of the send and receive ends of a LinkRPC stream, while one end pings the other:

```json
--> {"jsonrpc":"2.0","method":"ping","params":[123],"id":1}
<-- {"jsonrpc":"2.0","result":123,"id":1}
```

LinkRPC methods are used for actions such as:

* Checking the liveness and performance of a link by "pinging" it
* Gossipping the relay graph
* Negotiating prices and keeping track of debt

We now discuss some of these functions in more detail.

## Relay graph gossip

The purpose of the relay graph gossip is to ensure that between two connected nodes Alice and Bob, they eventually agree on the shape of the relay graph. Since we assume that the network is ultimately globally connected, this means that *everyone*'s view is eventually consistent.

We use a simple pull-based approach. Both ends of every link expose this LinkRPC endpoint:

```
get_adjacencies(fingerprints: string[]) -> AdjacencyDescriptor[]
```

which takes a list of relay fingerprints, and returns all the adjacency descriptors where one end is one of the provided relay fingerprints.

Each side continually calls `get_adjacencies` on the other side, passing in a random subset of fingerprints they know about. The responses are then added to the local relay graph.

This ensures that relay graphs of both of the sides eventually stay in sync.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.earendil.network/wiki/protocols/link-protocol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
