Skip to content

Commit f39718a

Browse files
authored
Add high-level architecture diagrams (#1733)
It can be useful for newcomers to have a high-level view of the main components in eclair. This will help them quickly find where they should start digging into actual code to achieve what they want. We're leaving a lot of details out to ensure this document stays up-to-date and doesn't need to completely change every time we slightly rework internal details of our architecture.
1 parent 3d3766e commit f39718a

File tree

1 file changed

+234
-0
lines changed

1 file changed

+234
-0
lines changed

docs/Architecture.md

+234
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# Architecture of the eclair codebase
2+
3+
Eclair is developed in [Scala](https://www.scala-lang.org/) and relies heavily on [Akka](https://akka.io/).
4+
Akka is an [actor programming](https://doc.akka.io/docs/akka/current/typed/guide/actors-intro.html?language=scala) framework similar to [Erlang](https://www.erlang.org/) for the JVM.
5+
6+
The actor model provides a clean separation between components, allowing eclair to:
7+
8+
1. Isolate faults and ensure high availability
9+
2. Scale across CPUs and machines efficiently
10+
3. Simplify development and testing
11+
12+
At a high-level, almost every entity is a separate, sandboxed actor:
13+
14+
- Every peer connection is an actor instance
15+
- Every lightning channel is an actor instance
16+
- Every payment attempt is an actor instance
17+
18+
Some actors are long-lived (e.g. lightning channels) while others are very short-lived (e.g. payment attempts).
19+
20+
## Top-level projects
21+
22+
Eclair is split into four top-level projects:
23+
24+
- `eclair-core`: core library implementing lightning
25+
- `eclair-node`: server daemon built upon `eclair-core` (exposes a Json RPC and WebSocket endpoint)
26+
- `eclair-front`: when using cluster mode, front-end server daemons handling peer connections
27+
- `eclair-node-gui` (deprecated): sample JavaFX user interface to demo eclair (should not be used in production)
28+
29+
The entry point for `eclair-core` is in `Setup.scala`, where we start the actor system, connect to `bitcoind` and create top-level actors.
30+
31+
## Actor system overview
32+
33+
Here is a high-level view of the hierarchy of some of the main actors in the system:
34+
35+
```ascii
36+
+---------+
37+
+-------->| Channel |
38+
| +---------+
39+
+------+ +---------+
40+
+---------------->| Peer |----->| Channel |
41+
| +------+ +---------+
42+
| | +---------+
43+
| +-------->| Channel |
44+
| +---------+
45+
+-------------+
46+
| Switchboard |
47+
+-------------+
48+
| +---------+
49+
| +-------->| Channel |
50+
| | +---------+
51+
| +------+ +---------+
52+
+---------------->| Peer |----->| Channel |
53+
+------+ +---------+
54+
| +---------+
55+
+-------->| Channel |
56+
+---------+
57+
58+
+----------------+
59+
+---------------->| ChannelRelayer |
60+
| +----------------+
61+
+---------+
62+
| Relayer |
63+
+---------+
64+
| +-------------+
65+
+---------------->| NodeRelayer |
66+
+-------------+
67+
68+
+------------------+
69+
+----------->| PaymentLifecycle |
70+
| +------------------+
71+
+---------------------------+ +------------------+
72+
+---------------->| MultiPartPaymentLifecycle |----->| PaymentLifecycle |
73+
| +---------------------------+ +------------------+
74+
| | +------------------+
75+
| +----------->| PaymentLifecycle |
76+
+------------------+ +------------------+
77+
| PaymentInitiator |
78+
+------------------+ +------------------+
79+
| +----------->| PaymentLifecycle |
80+
| | +------------------+
81+
| +---------------------------+ +------------------+
82+
+---------------->| MultiPartPaymentLifecycle |----->| PaymentLifecycle |
83+
+---------------------------+ +------------------+
84+
| +------------------+
85+
+----------->| PaymentLifecycle |
86+
+------------------+
87+
88+
+---------------------+
89+
+---------------->| MultiPartPaymentFSM |
90+
| +---------------------+
91+
+----------------+
92+
| PaymentHandler |
93+
+----------------+
94+
| +---------------------+
95+
+---------------->| MultiPartPaymentFSM |
96+
+---------------------+
97+
98+
+----------+
99+
| Register |
100+
+----------+
101+
102+
+--------+
103+
| Router |
104+
+--------+
105+
```
106+
107+
And a short description of each actor's role:
108+
109+
- Switchboard: creates and deletes peers
110+
- Peer: p2p connection to another lightning node (standard lightning messages described in [Bolt 1](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md))
111+
- Channel: channel with another lightning node ([Bolt 2](https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md))
112+
- Register: maps channel IDs to actors (provides a clean boundary between channel and payment components)
113+
- PaymentInitiator: entry point for sending payments
114+
- Relayer: entry point for relaying payments
115+
- PaymentHandler: entry point for receiving payments
116+
- Router: p2p gossip and the network graph ([Bolt 7](https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md))
117+
118+
Actors have two ways of communicating:
119+
120+
- direct messages: when actors have a reference to other actors, they can exchange [direct messages](https://doc.akka.io/docs/akka/current/typed/interaction-patterns.html)
121+
- events: actors can emit events to a shared [event stream](https://doc.akka.io/docs/akka/current/event-bus.html), and other actors can register to these events
122+
123+
## Payment scenarios
124+
125+
Let's dive into a few payment scenarios to show which actors are involved.
126+
127+
### Sending a payment
128+
129+
When we send a payment:
130+
131+
- we run a path-finding algorithm (`Router`)
132+
- we split the payment into smaller chunks if [MPP](https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#basic-multi-part-payments) is used (`MultiPartPaymentLifecycle`)
133+
- we retry with alternative routes in some failure cases and record failing channels/payments (`PaymentLifecycle`)
134+
- we add HTLCs to some of our channels
135+
136+
```ascii
137+
+------------------+ +---------+
138+
+----->| PaymentLifecycle |-----+ +----->| Channel |
139+
| +------------------+ | | +---------+
140+
+------------------+ +---------------------------+ | +------------------+ | +----------+ | +---------+
141+
| PaymentInitiator |-------->| MultiPartPaymentLifecycle |----+----->| PaymentLifecycle |-----+----->| Register |-----+----->| Channel |
142+
+------------------+ +---------------------------+ | +------------------+ | +----------+ | +---------+
143+
| | +------------------+ | | +---------+
144+
| +----->| PaymentLifecycle |-----+ +----->| Channel |
145+
| +------------------+ +---------+
146+
| |
147+
| |
148+
| +--------+ |
149+
+----->| Router |<-----------+
150+
+--------+
151+
```
152+
153+
### Receiving a payment
154+
155+
When we receive a payment:
156+
157+
- htlcs are forwarded by channels to the relayer
158+
- a payment handler compares these htlcs to our payments database
159+
- and decides to fail or fulfill them
160+
161+
```ascii
162+
+---------+
163+
| Channel |-----+
164+
+---------+ |
165+
+---------+ | +---------+ +----------------+ +----------+
166+
| Channel |-----+----->| Relayer |----->| PaymentHandler |----->| Register |
167+
+---------+ | +---------+ +----------------+ +----------+
168+
+---------+ |
169+
| Channel |-----+
170+
+---------+
171+
```
172+
173+
### Relaying a payment
174+
175+
When we relay a payment:
176+
177+
- htlcs are forwarded by channels to the relayer
178+
- the relayer identifies the type of relay requested and delegates work to a channel relayer or a node relayer
179+
- if a node relayer is used ([trampoline payments](https://github.com/lightningnetwork/lightning-rfc/pull/829)):
180+
- incoming htlcs are validated by a payment handler (similar to the flow to receive payments)
181+
- outgoing htlcs are sent out (similar to the flow to send payments)
182+
183+
```ascii
184+
+----------------+ +----------+ +---------+
185+
+--------->| ChannelRelayer |----->| Register |----->| Channel |
186+
| +----------------+ +----------+ +---------+
187+
+---------+ +---------+
188+
| Channel |----->| Relayer |
189+
+---------+ +---------+
190+
| +-------------+ +---------------------------+
191+
+--------->| NodeRelayer |----->| MultiPartPaymentLifecycle |
192+
+-------------+ +---------------------------+
193+
^
194+
|
195+
v
196+
+----------------+
197+
| PaymentHandler |
198+
+----------------+
199+
```
200+
201+
## Channel scenarios
202+
203+
Let's describe some channel operations and see which actors are involved.
204+
205+
### Opening a channel
206+
207+
When we open a channel:
208+
209+
- we exchange messages with our peer
210+
- we use funds from our on-chain bitcoin wallet
211+
- we start watching on-chain transactions to ensure our peer doesn't cheat us
212+
213+
```ascii
214+
+------+ +---------+ +--------+
215+
| Peer |----->| Channel |-----+----->| Wallet |
216+
+------+ +---------+ | +--------+
217+
^ | | +---------+
218+
| | +----->| Watcher |
219+
+--------------+ +---------+
220+
```
221+
222+
### Closing a channel
223+
224+
When our peer tries to cheat:
225+
226+
- the blockchain watcher notices it and notifies the channel
227+
- the channel publishes on-chain transactions
228+
- and we notify our peer by sending an error message
229+
230+
```ascii
231+
+---------+ +---------+ +------+
232+
| Watcher |<----->| Channel |----->| Peer |
233+
+---------+ +---------+ +------+
234+
```

0 commit comments

Comments
 (0)