Skip to content

Commit 65b381c

Browse files
committed
Add a channels section to ChannelManager docs
1 parent a90efee commit 65b381c

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,169 @@ where
12441244
/// respectively. The remaining requirements can be met using the [`lightning-background-processor`]
12451245
/// crate. For languages other than Rust, the availability of similar utilities may vary.
12461246
///
1247+
/// # Channels
1248+
///
1249+
/// [`ChannelManager`]'s primary function involves managing a channel state. Without channels,
1250+
/// payments can't be sent. Use [`list_channels`] or [`list_usable_channels`] for a snapshot of the
1251+
/// currently open channels.
1252+
///
1253+
/// ```
1254+
/// # use lightning::ln::channelmanager::AChannelManager;
1255+
/// #
1256+
/// # fn example<T: AChannelManager>(channel_manager: T) {
1257+
/// # let channel_manager = channel_manager.get_cm();
1258+
/// let channels = channel_manager.list_usable_channels();
1259+
/// for details in channels {
1260+
/// println!("{:?}", details);
1261+
/// }
1262+
/// # }
1263+
/// ```
1264+
///
1265+
/// Each channel is identified using a [`ChannelId`], which will change throughout the channel's
1266+
/// life cycle. Additionally, channels are assigned a `user_channel_id`, which is given in
1267+
/// [`Event`]s associated with the channel and serves as a fixed identifier but is otherwise unused
1268+
/// by [`ChannelManager`].
1269+
///
1270+
/// ## Opening Channels
1271+
///
1272+
/// To an open a channel with a peer, call [`create_channel`]. This will initiate the process of
1273+
/// opening an outbound channel, which requires self-funding when handling
1274+
/// [`Event::FundingGenerationReady`].
1275+
///
1276+
/// ```
1277+
/// # use bitcoin::{ScriptBuf, Transaction};
1278+
/// # use bitcoin::secp256k1::PublicKey;
1279+
/// # use lightning::ln::channelmanager::AChannelManager;
1280+
/// # use lightning::events::{Event, EventsProvider};
1281+
/// #
1282+
/// # trait Wallet {
1283+
/// # fn create_funding_transaction(
1284+
/// # &self, _amount_sats: u64, _output_script: ScriptBuf
1285+
/// # ) -> Transaction;
1286+
/// # }
1287+
/// #
1288+
/// # fn example<T: AChannelManager, W: Wallet>(channel_manager: T, wallet: W, peer_id: PublicKey) {
1289+
/// # let channel_manager = channel_manager.get_cm();
1290+
/// let value_sats = 1_000_000;
1291+
/// let push_msats = 10_000_000;
1292+
/// match channel_manager.create_channel(peer_id, value_sats, push_msats, 42, None, None) {
1293+
/// Ok(channel_id) => println!("Opening channel {}", channel_id),
1294+
/// Err(e) => println!("Error opening channel: {:?}", e),
1295+
/// }
1296+
///
1297+
/// // On the event processing thread once the peer has responded
1298+
/// channel_manager.process_pending_events(&|event| match event {
1299+
/// Event::FundingGenerationReady {
1300+
/// temporary_channel_id, counterparty_node_id, channel_value_satoshis, output_script,
1301+
/// user_channel_id, ..
1302+
/// } => {
1303+
/// assert_eq!(user_channel_id, 42);
1304+
/// let funding_transaction = wallet.create_funding_transaction(
1305+
/// channel_value_satoshis, output_script
1306+
/// );
1307+
/// match channel_manager.funding_transaction_generated(
1308+
/// &temporary_channel_id, &counterparty_node_id, funding_transaction
1309+
/// ) {
1310+
/// Ok(()) => println!("Funding channel {}", temporary_channel_id),
1311+
/// Err(e) => println!("Error funding channel {}: {:?}", temporary_channel_id, e),
1312+
/// }
1313+
/// },
1314+
/// Event::ChannelPending { channel_id, user_channel_id, former_temporary_channel_id, .. } => {
1315+
/// assert_eq!(user_channel_id, 42);
1316+
/// println!(
1317+
/// "Channel {} now {} pending (funding transaction has been broadcasted)", channel_id,
1318+
/// former_temporary_channel_id.unwrap()
1319+
/// );
1320+
/// },
1321+
/// Event::ChannelReady { channel_id, user_channel_id, .. } => {
1322+
/// assert_eq!(user_channel_id, 42);
1323+
/// println!("Channel {} ready", channel_id);
1324+
/// },
1325+
/// // ...
1326+
/// # _ => {},
1327+
/// });
1328+
/// # }
1329+
/// ```
1330+
///
1331+
/// ## Accepting Channels
1332+
///
1333+
/// Inbound channels are initiated by peers and are automatically accepted unless [`ChannelManager`]
1334+
/// has [`UserConfig::manually_accept_inbound_channels`] set. In that case, the channel may be
1335+
/// either accepted or rejected when handling [`Event::OpenChannelRequest`].
1336+
///
1337+
/// ```
1338+
/// # use bitcoin::secp256k1::PublicKey;
1339+
/// # use lightning::ln::channelmanager::AChannelManager;
1340+
/// # use lightning::events::{Event, EventsProvider};
1341+
/// #
1342+
/// # fn is_trusted(counterparty_node_id: PublicKey) -> bool {
1343+
/// # // ...
1344+
/// # unimplemented!()
1345+
/// # }
1346+
/// #
1347+
/// # fn example<T: AChannelManager>(channel_manager: T) {
1348+
/// # let channel_manager = channel_manager.get_cm();
1349+
/// channel_manager.process_pending_events(&|event| match event {
1350+
/// Event::OpenChannelRequest { temporary_channel_id, counterparty_node_id, .. } => {
1351+
/// if !is_trusted(counterparty_node_id) {
1352+
/// match channel_manager.force_close_without_broadcasting_txn(
1353+
/// &temporary_channel_id, &counterparty_node_id
1354+
/// ) {
1355+
/// Ok(()) => println!("Rejecting channel {}", temporary_channel_id),
1356+
/// Err(e) => println!("Error rejecting channel {}: {:?}", temporary_channel_id, e),
1357+
/// }
1358+
/// return;
1359+
/// }
1360+
///
1361+
/// let user_channel_id = 43;
1362+
/// match channel_manager.accept_inbound_channel(
1363+
/// &temporary_channel_id, &counterparty_node_id, user_channel_id
1364+
/// ) {
1365+
/// Ok(()) => println!("Accepting channel {}", temporary_channel_id),
1366+
/// Err(e) => println!("Error accepting channel {}: {:?}", temporary_channel_id, e),
1367+
/// }
1368+
/// },
1369+
/// // ...
1370+
/// # _ => {},
1371+
/// });
1372+
/// # }
1373+
/// ```
1374+
///
1375+
/// ## Closing Channels
1376+
///
1377+
/// There are two ways to close a channel: either cooperatively using [`close_channel`] or
1378+
/// unilaterally using [`force_close_broadcasting_latest_txn`]. The former is ideal as it makes for
1379+
/// lower fees and immediate access to funds. However, the latter may be necessary if the
1380+
/// counterparty isn't behaving properly or has gone offline. [`Event::ChannelClosed`] is generated
1381+
/// once the channel has been closed successfully.
1382+
///
1383+
/// ```
1384+
/// # use bitcoin::secp256k1::PublicKey;
1385+
/// # use lightning::ln::ChannelId;
1386+
/// # use lightning::ln::channelmanager::AChannelManager;
1387+
/// # use lightning::events::{Event, EventsProvider};
1388+
/// #
1389+
/// # fn example<T: AChannelManager>(
1390+
/// # channel_manager: T, channel_id: ChannelId, counterparty_node_id: PublicKey
1391+
/// # ) {
1392+
/// # let channel_manager = channel_manager.get_cm();
1393+
/// match channel_manager.close_channel(&channel_id, &counterparty_node_id) {
1394+
/// Ok(()) => println!("Closing channel {}", channel_id),
1395+
/// Err(e) => println!("Error closing channel {}: {:?}", channel_id, e),
1396+
/// }
1397+
///
1398+
/// // On the event processing thread
1399+
/// channel_manager.process_pending_events(&|event| match event {
1400+
/// Event::ChannelClosed { channel_id, user_channel_id, .. } => {
1401+
/// assert_eq!(user_channel_id, 42);
1402+
/// println!("Channel {} closed", channel_id);
1403+
/// },
1404+
/// // ...
1405+
/// # _ => {},
1406+
/// });
1407+
/// # }
1408+
/// ```
1409+
///
12471410
/// # Persistence
12481411
///
12491412
/// Implements [`Writeable`] to write out all channel state to disk. Implies [`peer_disconnected`] for
@@ -1305,6 +1468,11 @@ where
13051468
/// [`lightning-block-sync`]: https://docs.rs/lightning_block_sync/latest/lightning_block_sync
13061469
/// [`lightning-transaction-sync`]: https://docs.rs/lightning_transaction_sync/latest/lightning_transaction_sync
13071470
/// [`lightning-background-processor`]: https://docs.rs/lightning_background_processor/lightning_background_processor
1471+
/// [`list_channels`]: Self::list_channels
1472+
/// [`list_usable_channels`]: Self::list_usable_channels
1473+
/// [`create_channel`]: Self::create_channel
1474+
/// [`close_channel`]: Self::force_close_broadcasting_latest_txn
1475+
/// [`force_close_broadcasting_latest_txn`]: Self::force_close_broadcasting_latest_txn
13081476
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
13091477
/// [`funding_created`]: msgs::FundingCreated
13101478
/// [`funding_transaction_generated`]: Self::funding_transaction_generated

0 commit comments

Comments
 (0)