mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-24 14:50:46 +01:00
Created new files for pages that were in the wiki, but not already in the docs directory. Also made following fixes to README.md and existing files in the docs directory: * update bolt links to avoid redirect * link to logging guide from logging section (README.md) * fixed typo in Backup section and capitalization of Bitcoin Core (README.md) * Alice does not need trampoline feature enabled (TrampolinePayments.md) * link to 2021 edition of Trampoline PR (TrampolinePayments.md) * fixed API examples and removed quotes from password (API.md) * use --nodeIds for sendtoroute examples (TrampolinePayments.md and MultipartPayments.md) * update CLI example 3 to use jq (Usage.md) * fix typo in docs/FAQ.md * updated Guide.md to point to all pages that are guides
233 lines
10 KiB
Markdown
233 lines
10 KiB
Markdown
# Architecture of the eclair codebase
|
|
|
|
Eclair is developed in [Scala](https://www.scala-lang.org/) and relies heavily on [Akka](https://akka.io/).
|
|
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.
|
|
|
|
The actor model provides a clean separation between components, allowing eclair to:
|
|
|
|
1. Isolate faults and ensure high availability
|
|
2. Scale across CPUs and machines efficiently
|
|
3. Simplify development and testing
|
|
|
|
At a high-level, almost every entity is a separate, sandboxed actor:
|
|
|
|
- Every peer connection is an actor instance
|
|
- Every lightning channel is an actor instance
|
|
- Every payment attempt is an actor instance
|
|
|
|
Some actors are long-lived (e.g. lightning channels) while others are very short-lived (e.g. payment attempts).
|
|
|
|
## Top-level projects
|
|
|
|
Eclair is split into three top-level projects:
|
|
|
|
- `eclair-core`: core library implementing lightning
|
|
- `eclair-node`: server daemon built upon `eclair-core` (exposes a Json RPC and WebSocket endpoint)
|
|
- `eclair-front`: when using cluster mode, front-end server daemons handling peer connections
|
|
|
|
The entry point for `eclair-core` is in `Setup.scala`, where we start the actor system, connect to `bitcoind` and create top-level actors.
|
|
|
|
## Actor system overview
|
|
|
|
Here is a high-level view of the hierarchy of some of the main actors in the system:
|
|
|
|
```ascii
|
|
+---------+
|
|
+-------->| Channel |
|
|
| +---------+
|
|
+------+ +---------+
|
|
+---------------->| Peer |----->| Channel |
|
|
| +------+ +---------+
|
|
| | +---------+
|
|
| +-------->| Channel |
|
|
| +---------+
|
|
+-------------+
|
|
| Switchboard |
|
|
+-------------+
|
|
| +---------+
|
|
| +-------->| Channel |
|
|
| | +---------+
|
|
| +------+ +---------+
|
|
+---------------->| Peer |----->| Channel |
|
|
+------+ +---------+
|
|
| +---------+
|
|
+-------->| Channel |
|
|
+---------+
|
|
|
|
+----------------+
|
|
+---------------->| ChannelRelayer |
|
|
| +----------------+
|
|
+---------+
|
|
| Relayer |
|
|
+---------+
|
|
| +-------------+
|
|
+---------------->| NodeRelayer |
|
|
+-------------+
|
|
|
|
+------------------+
|
|
+----------->| PaymentLifecycle |
|
|
| +------------------+
|
|
+---------------------------+ +------------------+
|
|
+---------------->| MultiPartPaymentLifecycle |----->| PaymentLifecycle |
|
|
| +---------------------------+ +------------------+
|
|
| | +------------------+
|
|
| +----------->| PaymentLifecycle |
|
|
+------------------+ +------------------+
|
|
| PaymentInitiator |
|
|
+------------------+ +------------------+
|
|
| +----------->| PaymentLifecycle |
|
|
| | +------------------+
|
|
| +---------------------------+ +------------------+
|
|
+---------------->| MultiPartPaymentLifecycle |----->| PaymentLifecycle |
|
|
+---------------------------+ +------------------+
|
|
| +------------------+
|
|
+----------->| PaymentLifecycle |
|
|
+------------------+
|
|
|
|
+---------------------+
|
|
+---------------->| MultiPartPaymentFSM |
|
|
| +---------------------+
|
|
+----------------+
|
|
| PaymentHandler |
|
|
+----------------+
|
|
| +---------------------+
|
|
+---------------->| MultiPartPaymentFSM |
|
|
+---------------------+
|
|
|
|
+----------+
|
|
| Register |
|
|
+----------+
|
|
|
|
+--------+
|
|
| Router |
|
|
+--------+
|
|
```
|
|
|
|
And a short description of each actor's role:
|
|
|
|
- Switchboard: creates and deletes peers
|
|
- Peer: p2p connection to another lightning node (standard lightning messages described in [Bolt 1](https://github.com/lightning/bolts/blob/master/01-messaging.md))
|
|
- Channel: channel with another lightning node ([Bolt 2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md))
|
|
- Register: maps channel IDs to actors (provides a clean boundary between channel and payment components)
|
|
- PaymentInitiator: entry point for sending payments
|
|
- Relayer: entry point for relaying payments
|
|
- PaymentHandler: entry point for receiving payments
|
|
- Router: p2p gossip and the network graph ([Bolt 7](https://github.com/lightning/bolts/blob/master/07-routing-gossip.md))
|
|
|
|
Actors have two ways of communicating:
|
|
|
|
- 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)
|
|
- 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
|
|
|
|
## Payment scenarios
|
|
|
|
Let's dive into a few payment scenarios to show which actors are involved.
|
|
|
|
### Sending a payment
|
|
|
|
When we send a payment:
|
|
|
|
- we run a path-finding algorithm (`Router`)
|
|
- we split the payment into smaller chunks if [MPP](https://github.com/lightning/bolts/blob/master/04-onion-routing.md#basic-multi-part-payments) is used (`MultiPartPaymentLifecycle`)
|
|
- we retry with alternative routes in some failure cases and record failing channels/payments (`PaymentLifecycle`)
|
|
- we add HTLCs to some of our channels
|
|
|
|
```ascii
|
|
+------------------+ +---------+
|
|
+----->| PaymentLifecycle |-----+ +----->| Channel |
|
|
| +------------------+ | | +---------+
|
|
+------------------+ +---------------------------+ | +------------------+ | +----------+ | +---------+
|
|
| PaymentInitiator |-------->| MultiPartPaymentLifecycle |----+----->| PaymentLifecycle |-----+----->| Register |-----+----->| Channel |
|
|
+------------------+ +---------------------------+ | +------------------+ | +----------+ | +---------+
|
|
| | +------------------+ | | +---------+
|
|
| +----->| PaymentLifecycle |-----+ +----->| Channel |
|
|
| +------------------+ +---------+
|
|
| |
|
|
| |
|
|
| +--------+ |
|
|
+----->| Router |<-----------+
|
|
+--------+
|
|
```
|
|
|
|
### Receiving a payment
|
|
|
|
When we receive a payment:
|
|
|
|
- htlcs are forwarded by channels to the relayer
|
|
- a payment handler compares these htlcs to our payments database
|
|
- and decides to fail or fulfill them
|
|
|
|
```ascii
|
|
+---------+
|
|
| Channel |-----+
|
|
+---------+ |
|
|
+---------+ | +---------+ +----------------+ +----------+
|
|
| Channel |-----+----->| Relayer |----->| PaymentHandler |----->| Register |
|
|
+---------+ | +---------+ +----------------+ +----------+
|
|
+---------+ |
|
|
| Channel |-----+
|
|
+---------+
|
|
```
|
|
|
|
### Relaying a payment
|
|
|
|
When we relay a payment:
|
|
|
|
- htlcs are forwarded by channels to the relayer
|
|
- the relayer identifies the type of relay requested and delegates work to a channel relayer or a node relayer
|
|
- if a node relayer is used ([trampoline payments](https://github.com/lightning/bolts/pull/829)):
|
|
- incoming htlcs are validated by a payment handler (similar to the flow to receive payments)
|
|
- outgoing htlcs are sent out (similar to the flow to send payments)
|
|
|
|
```ascii
|
|
+----------------+ +----------+ +---------+
|
|
+--------->| ChannelRelayer |----->| Register |----->| Channel |
|
|
| +----------------+ +----------+ +---------+
|
|
+---------+ +---------+
|
|
| Channel |----->| Relayer |
|
|
+---------+ +---------+
|
|
| +-------------+ +---------------------------+
|
|
+--------->| NodeRelayer |----->| MultiPartPaymentLifecycle |
|
|
+-------------+ +---------------------------+
|
|
^
|
|
|
|
|
v
|
|
+----------------+
|
|
| PaymentHandler |
|
|
+----------------+
|
|
```
|
|
|
|
## Channel scenarios
|
|
|
|
Let's describe some channel operations and see which actors are involved.
|
|
|
|
### Opening a channel
|
|
|
|
When we open a channel:
|
|
|
|
- we exchange messages with our peer
|
|
- we use funds from our on-chain bitcoin wallet
|
|
- we start watching on-chain transactions to ensure our peer doesn't cheat us
|
|
|
|
```ascii
|
|
+------+ +---------+ +--------+
|
|
| Peer |----->| Channel |-----+----->| Wallet |
|
|
+------+ +---------+ | +--------+
|
|
^ | | +---------+
|
|
| | +----->| Watcher |
|
|
+--------------+ +---------+
|
|
```
|
|
|
|
### Closing a channel
|
|
|
|
When our peer tries to cheat:
|
|
|
|
- the blockchain watcher notices it and notifies the channel
|
|
- the channel publishes on-chain transactions
|
|
- and we notify our peer by sending an error message
|
|
|
|
```ascii
|
|
+---------+ +---------+ +------+
|
|
| Watcher |<----->| Channel |----->| Peer |
|
|
+---------+ +---------+ +------+
|
|
```
|