lnp2p/bifrost/mod.rs
1// LNP P2P library, plmeneting both bolt (BOLT) and Bifrost P2P messaging
2// system for Lightning network protocol (LNP)
3//
4// Written in 2020-2022 by
5// Dr. Maxim Orlovsky <orlovsky@pandoracore.com>
6//
7// To the extent possible under law, the author(s) have dedicated all
8// copyright and related and neighboring rights to this software to
9// the public domain worldwide. This software is distributed without
10// any warranty.
11//
12// You should have received a copy of the MIT License
13// along with this software.
14// If not, see <https://opensource.org/licenses/MIT>.
15
16//! # Bifrost transaction requirements
17//!
18//! Bifrost requires all off-chain transactions always have v2 and use
19//! v1 witness P2TR outputs (or later witness versions). Transaction inputs,
20//! aside from funding transaction, also must be v1 witness inputs spending
21//! P2TR outputs (or above).
22//!
23//! For funding onchain transactions and funding outputs of channel level 1
24//! this requirement is released to witness v0 or above. The reason for lower
25//! requirement is the interoperability with the bolt lightning network,
26//! allowing migration of existing channels opened in bolt network to
27//! Bifrost.
28//!
29//!
30//! # Channel coordination
31//!
32//! For channel operations we assume that any channel may be a multi-peer
33//! channel. Thus, for channel updates it is required that all parties
34//! cooperate and sign the latest version of updated channel transactions.
35//! This is achieved by introducing concept of *channel coordinator*. Channel
36//! coordinator is the lightning node that has originally proposed channel.
37//! It is responsible for orchestrating message flow between all nodes which
38//! are the parts of the channel and keeping them up-to-date. Also, the
39//! channel coordinator is the only party required to have direct connections
40//! with other channel participants – and each of channel participants is
41//! required to be connected at least to the channel coordinator.
42//!
43//! If a multiple nested channels are present, for all higher-level channels
44//! channel coordinator MUST be the same as channel coordinator for the base
45//! (level 1) channel; the list of participants for the nested channels MUST be
46//! a subset of the participants of the topmost level 1 channel.
47//!
48//!
49//! # Channel workflows
50//!
51//! There are following workflows affecting channel status / existence. Each
52//! of these workflows represent a set of P2P messages exchanged by channel
53//! peers.
54//!
55//! - Channel creation
56//! - Moving channel from bolt to Bifrost LN
57//! - Removing channel from Bifrost to bolt LN
58//! - Changing channel status (pausing etc)
59//! - Upgrading channel to support more protocols
60//! - Downgrading channel by removing specific protocol
61//! - Cooperatively closing channel
62//!
63//! Workflow can be initiated only by a *channel coordinator*, and specific
64//! P2P messages inside the workflow can be sent either from the *channel
65//! coordinator* to a peer – or, in response, from a peer to the *channel
66//! coordinator*.
67//!
68//! Normal channel operations are covered by application-specific business logic
69//! and messages and are not part of any listed channel workflow. Unlike
70//! workflows, they may be initiated by any of the channel peers sending message
71//! to the channel coordinator, however whenever they involve other peers or
72//! external channels, after being initiated they must be coordinated by the
73//! channel coordinator.
74//!
75//! ## Channel creation workflow
76//!
77//! Considering generic case of multi-peer channel setup channel creation
78//! workflow is organized with the following algorithm:
79//!
80//! 1. First, all parties agree on the structure of the *funding transaction*
81//! and overall transaction graph within the channel – simultaneously signing
82//! *refund transaction* (which, upon channel creation, will become first
83//! version of the channel *commitment transaction*). This is done using
84//! [`ProposeChannel`] requests sent by the *channel coordinator* to each of
85//! the peers, replying with either [`AcceptChannel`] (containing updated
86//! transaction graph with signed refund transaction) or [`Error`].
87//! peers must wait for `CHANNEL_CREATION_TIMEOUT` period and discard all
88//! provisional channel data from their memory.
89//!
90//! 2. Once the refund transaction is fully signed – implying that the
91//! transaction graph if agreed between participants – channel coordinator
92//! starts next phase, where the funding transaction gets fully signed.
93//! Coordinator sends [`FinalizeChannel`] message to each of the peers and
94//! collects signatures, publishing the final transaction either to bitcoin
95//! blockchain (for level 1 channels) or updating the state of the top-level
96//! channel (for nested channels above level 1). Peers track upper level
97//! channel or blockchain to detect funding transaction, and upon transaction
98//! mining starts operate channel in active mode, not requiring any other
99//! messages from the channel coordinator (NB: this differs from the bolt
100//! LN channel creation workflow).
101//!
102//! 3. Replacing funding by fee (RBF): channel coordinator SHOULD initiate RBF
103//! subworkflow for level 1 channels if the funding transaction was not mined
104//! after reasonable amount of time, which should be less than
105//! [`ChannelParams::funding_timeout`]. With RGB subworkflow coordinator
106//! updates funding transaction – and propagates it with [`FinalizeChannel`]
107//! request, collecting new signatures (peers MUST reset their funding
108//! timeout counters).
109//!
110//! 4. Cancelling channel creation: if any of the peer nodes replied with
111//! [`Error`] on any of the channel construction requests within the channel
112//! creation workflow – or if the coordinator detected incorrect reply,
113//! channel coordinator MUST abandon channel creation – and MUST forward
114//! [`Error`] message to all other peers. A peer posting [`Error`] MUST
115//! provide a valid error code and a message explaining the cause of the
116//! error. The coordinator SHOULD also send [`Error`] message to peers if
117//! any of the stages of transaction construction workflow has stuck
118//! without a reply from a peer for over [`ChannelParams::peer_timeout`]
119//! time.
120//!
121//! 5. Timeouts: the coordinator SHOULD send [`Error`] message to peers if any
122//! of the peers at any stage of transaction construction workflow has stuck
123//! without a reply for over [`ChannelParams::peer_timeout`] time.
124//! The peers should abandon channel and clear all information about it from
125//! the memory regardless whether they have received [`Error`] message from
126//! the coordinator after [`ChannelParams::peer_timeout`]` * 2` time before
127//! `ChannelFinalized` – and if they has not received new
128//! [`FinalizeChannel`] request from the coordinator after
129//! [`ChannelParams::funding_timeout`] time (see pt 3 for RBF subworkflow).
130//!
131//! ```ignore
132//! Channel coordinator Peer 1 Peer 2
133//! | | |
134//! (enters ChannelProposed state) | |
135//! | | |
136//! | --(1)- ProposeChannel ------> | |
137//! | | |
138//! | --(1)------------ ProposeChannel --------------> |
139//! | | |
140//! | (enter ChannelProposed state)
141//! | | |
142//! | <-(2)------------- AcceptChannel --------------- |
143//! | | |
144//! | <-(2)-- AcceptChannel ------- | |
145//! | | |
146//! (enters ChannelAccepted state) (enter ChannelAccepted state)
147//! | | |
148//! | --(3)- FinalizeChannel -----> | |
149//! | | |
150//! | --(3)------------ FinalizeChannel -------------> |
151//! | | |
152//! | <-(4)-- FinalizeChannel ----- | |
153//! | | |
154//! | <-(4)------------- FinalizeChannel ------------- |
155//! | | |
156//! (enters ChannelFinalized state) (enter ChannelFinalized state)
157//! | | |
158//! (await funding transaction mining or entering the valid super-channel state)
159//! | | |
160//! (enters ChannelActive state) (enter ChannelActive state)
161//! | | |
162//! ```
163//!
164//! During channel construction workflow channels are identified by
165//! [`ChannelId`], which is constructed as a tagged SHA-256 hash
166//! (using `bifrost:channel-proposal` as tag) of the strict-serialized
167//! [`ChannelParams`] data and coordinator node public key.
168//!
169//! [`Error`]: [struct@Error]
170
171mod app;
172mod channel;
173mod ctrl;
174mod msg;
175mod proposals;
176mod types;
177
178use std::io;
179use std::ops::Deref;
180
181pub use app::{BifrostApp, BIFROST_APP_STORM, BIFROST_APP_VENDOR_MASK};
182pub use channel::*;
183pub use ctrl::*;
184use internet2::{CreateUnmarshaller, Payload, Unmarshall, Unmarshaller};
185use lnpbp::bech32::Blob;
186pub use msg::Msg;
187use once_cell::sync::Lazy;
188pub use proposals::*;
189use strict_encoding::{self, StrictDecode, StrictEncode};
190pub use types::{
191 AddressList, AnnouncedNodeAddr, ChannelId, ProtocolList, ProtocolName,
192 ProtocolNameError,
193};
194
195/// Default bolt Lightning port number
196pub const LNP2P_BIFROST_PORT: u16 = 9999;
197
198pub static LNP2P_BIFROST_UNMARSHALLER: Lazy<Unmarshaller<Messages>> =
199 Lazy::new(Messages::create_unmarshaller);
200
201#[derive(Clone, Debug, Display, Api)]
202#[api(encoding = "strict")]
203#[non_exhaustive]
204#[display(inner)]
205pub enum Messages {
206 // Part I: Generic messages outside of channel operations (BOLT-1)
207 // ===============================================================
208 /// Once authentication is complete, the first message reveals the features
209 /// supported or required by this node, even if this is a reconnection.
210 #[api(type = 0x0010)]
211 Init(Init),
212
213 /// For simplicity of diagnosis, it's often useful to tell a peer that
214 /// something is incorrect.
215 #[api(type = 0x0011)]
216 Error(Error),
217
218 /// In order to allow for the existence of long-lived TCP connections, at
219 /// times it may be required that both ends keep alive the TCP connection
220 /// at the application level. Such messages also allow obfuscation of
221 /// traffic patterns.
222 #[api(type = 0x0012)]
223 Ping(Ping),
224
225 /// The pong message is to be sent whenever a ping message is received. It
226 /// serves as a reply and also serves to keep the connection alive, while
227 /// explicitly notifying the other end that the receiver is still active.
228 /// Within the received ping message, the sender will specify the number of
229 /// bytes to be included within the data payload of the pong message.
230 #[api(type = 0x0013)]
231 #[display("pong(...)")]
232 Pong(Blob),
233
234 #[api(type = 0x0014)]
235 #[display(inner)]
236 Message(Msg),
237
238 #[api(type = 0x0020)]
239 ProposeChannel(ProposeChannel),
240 #[api(type = 0x0021)]
241 AcceptChannel(AcceptChannel),
242 #[api(type = 0x0022)]
243 FinalizeChannel(FinalizeChannel),
244
245 #[api(type = 0x0023)]
246 MoveChannel(MoveChannel),
247 #[api(type = 0x0024)]
248 RemoveChannel(RemoveChannel),
249
250 #[api(type = 0x0025)]
251 UpdateChannelStatus(UpdateChannelStatus),
252
253 #[api(type = 0x0026)]
254 UpgradeChannel(UpgradeChannel),
255 #[api(type = 0x0027)]
256 DowngradeChannel(DowngradeChannel),
257
258 #[api(type = 0x0028)]
259 CloseChannel(CloseChannel),
260}
261
262impl StrictEncode for Messages {
263 fn strict_encode<E: io::Write>(
264 &self,
265 e: E,
266 ) -> Result<usize, strict_encoding::Error> {
267 Payload::from(self.clone()).strict_encode(e)
268 }
269}
270
271impl StrictDecode for Messages {
272 fn strict_decode<D: io::Read>(
273 d: D,
274 ) -> Result<Self, strict_encoding::Error> {
275 let message =
276 LNP2P_BIFROST_UNMARSHALLER.unmarshall(d).map_err(|err| {
277 strict_encoding::Error::DataIntegrityError(format!(
278 "can't unmarshall Bifrost LNP2P message. Details: {}",
279 err
280 ))
281 })?;
282 Ok(message.deref().clone())
283 }
284}