Skip to content

Commit 11d07c6

Browse files
committed
Add a channels section to ChannelManager docs
1 parent f3db184 commit 11d07c6

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

0 commit comments

Comments
 (0)