@@ -34,7 +34,7 @@ use lightning::{impl_writeable_tlv_based, impl_writeable_tlv_based_enum};
3434use lightning_liquidity:: lsps2:: utils:: compute_opening_fee;
3535use lightning_types:: payment:: { PaymentHash , PaymentPreimage } ;
3636
37- use crate :: closed_channel:: ClosedChannelDetails ;
37+ use crate :: closed_channel:: { ClosedChannelDetails , PendingChannelInfo } ;
3838use crate :: config:: { may_announce_channel, Config } ;
3939use crate :: connection:: ConnectionManager ;
4040use crate :: data_store:: DataStoreUpdateResult ;
@@ -56,7 +56,7 @@ use crate::payment::PaymentMetadata;
5656use crate :: runtime:: Runtime ;
5757use crate :: types:: {
5858 ClosedChannelStore , CustomTlvRecord , DynStore , KeysManager , OnionMessenger , PaymentStore ,
59- Sweeper , Wallet ,
59+ PendingChannelStore , Sweeper , Wallet ,
6060} ;
6161use crate :: {
6262 hex_utils, BumpTransactionEventHandler , ChannelManager , Error , Graph , PeerInfo , PeerStore ,
@@ -551,6 +551,7 @@ where
551551 payment_store : Arc < PaymentStore > ,
552552 peer_store : Arc < PeerStore < L > > ,
553553 closed_channel_store : Arc < ClosedChannelStore > ,
554+ pending_channel_store : Arc < PendingChannelStore > ,
554555 // Tracks which user_channel_ids correspond to outbound channels. Populated at startup from
555556 // list_channels() and updated on ChannelPending events. Consumed on ChannelClosed events.
556557 outbound_channel_ids : Mutex < HashSet < UserChannelId > > ,
@@ -577,9 +578,10 @@ where
577578 output_sweeper : Arc < Sweeper > , network_graph : Arc < Graph > ,
578579 liquidity_source : Arc < LiquiditySource < Arc < Logger > > > , payment_store : Arc < PaymentStore > ,
579580 peer_store : Arc < PeerStore < L > > , closed_channel_store : Arc < ClosedChannelStore > ,
580- keys_manager : Arc < KeysManager > , static_invoice_store : Option < StaticInvoiceStore > ,
581- onion_messenger : Arc < OnionMessenger > , om_mailbox : Option < Arc < OnionMessageMailbox > > ,
582- runtime : Arc < Runtime > , logger : L , config : Arc < Config > ,
581+ pending_channel_store : Arc < PendingChannelStore > , keys_manager : Arc < KeysManager > ,
582+ static_invoice_store : Option < StaticInvoiceStore > , onion_messenger : Arc < OnionMessenger > ,
583+ om_mailbox : Option < Arc < OnionMessageMailbox > > , runtime : Arc < Runtime > , logger : L ,
584+ config : Arc < Config > ,
583585 ) -> Self {
584586 // Seed outbound_channel_ids and announced_channel_ids from currently open channels so we
585587 // correctly classify channels that were already open when this node started.
@@ -609,6 +611,7 @@ where
609611 payment_store,
610612 peer_store,
611613 closed_channel_store,
614+ pending_channel_store,
612615 outbound_channel_ids,
613616 announced_channel_ids,
614617 keys_manager,
@@ -1386,12 +1389,23 @@ where
13861389 100
13871390 ) ;
13881391 }
1392+ // For LSPS2 JIT channels (channel_override_config is Some iff the counterparty
1393+ // is our configured LSP), accept with ZeroConfZeroReserve so the LSP is not
1394+ // forced to keep 1000 sats locked as reserve. Without this, the hard
1395+ // MIN_THEIR_CHAN_RESERVE_SATOSHIS = 1000 floor in LDK reduces the usable
1396+ // outbound capacity enough that the initial HTLC forward fails on small channels.
1397+ let is_lsps2_channel = channel_override_config. is_some ( ) ;
13891398 let res = if allow_0conf {
1399+ let trusted_features = if is_lsps2_channel {
1400+ TrustedChannelFeatures :: ZeroConfZeroReserve
1401+ } else {
1402+ TrustedChannelFeatures :: ZeroConf
1403+ } ;
13901404 self . channel_manager . accept_inbound_channel_from_trusted_peer (
13911405 & temporary_channel_id,
13921406 & counterparty_node_id,
13931407 user_channel_id,
1394- TrustedChannelFeatures :: ZeroConf ,
1408+ trusted_features ,
13951409 channel_override_config,
13961410 )
13971411 } else {
@@ -1567,13 +1581,13 @@ where
15671581 } ,
15681582 } ;
15691583
1570- let peer_to_store = {
1584+ let ( pending_info_opt , peer_to_store) = {
15711585 let network_graph = self . network_graph . read_only ( ) ;
15721586 let channels =
15731587 self . channel_manager . list_channels_with_counterparty ( & counterparty_node_id) ;
15741588 let pending_channel = channels. into_iter ( ) . find ( |c| c. channel_id == channel_id) ;
15751589
1576- if let Some ( ref ch) = pending_channel {
1590+ let pending_info_opt = if let Some ( ref ch) = pending_channel {
15771591 if ch. is_outbound {
15781592 self . outbound_channel_ids
15791593 . lock ( )
@@ -1586,9 +1600,16 @@ where
15861600 . expect ( "Lock poisoned" )
15871601 . insert ( UserChannelId ( user_channel_id) ) ;
15881602 }
1589- }
1603+ Some ( PendingChannelInfo {
1604+ user_channel_id : UserChannelId ( user_channel_id) ,
1605+ is_outbound : ch. is_outbound ,
1606+ is_announced : ch. is_announced ,
1607+ } )
1608+ } else {
1609+ None
1610+ } ;
15901611
1591- pending_channel
1612+ let peer_to_store = pending_channel
15921613 . filter ( |ch| {
15931614 !ch. is_outbound
15941615 && self . peer_store . get_peer ( & counterparty_node_id) . is_none ( )
@@ -1603,8 +1624,23 @@ where
16031624 node_id : counterparty_node_id,
16041625 address : address. clone ( ) ,
16051626 } )
1606- } )
1607- } ;
1627+ } ) ;
1628+
1629+ ( pending_info_opt, peer_to_store)
1630+ } ; // network_graph is dropped here, before any await
1631+
1632+ if let Some ( pending_info) = pending_info_opt {
1633+ if let Err ( e) = self . pending_channel_store . insert_or_update ( pending_info) . await
1634+ {
1635+ log_error ! (
1636+ self . logger,
1637+ "Failed to persist pending channel info {}: {}" ,
1638+ channel_id,
1639+ e
1640+ ) ;
1641+ return Err ( ReplayEvent ( ) ) ;
1642+ }
1643+ }
16081644 if let Some ( peer) = peer_to_store {
16091645 self . peer_store . add_peer ( peer) . await . unwrap_or_else ( |e| {
16101646 log_error ! (
@@ -1682,14 +1718,20 @@ where
16821718 . expect ( "Lock poisoned" )
16831719 . remove ( & user_channel_id) ;
16841720
1685- // On replay (after a restart or after handle_event returns ReplayEvent),
1686- // the channel is no longer in list_channels() and the in-memory sets are
1687- // not repopulated for it, so .remove() returns false. Fall back to any
1688- // already-persisted record so we don't overwrite correct values with false.
1721+ // Primary: use the durably-persisted PendingChannelInfo written at
1722+ // ChannelPending time. Falls back to in-memory sets (populated at startup
1723+ // or on ChannelPending), then to any already-persisted ClosedChannelDetails
1724+ // record (for the replay case where insert_or_update already succeeded but
1725+ // add_event failed and PendingChannelInfo was already cleaned up).
16891726 let ( is_outbound, is_announced) = self
1690- . closed_channel_store
1727+ . pending_channel_store
16911728 . get ( & user_channel_id)
1692- . map ( |existing| ( existing. is_outbound , existing. is_announced ) )
1729+ . map ( |info| ( info. is_outbound , info. is_announced ) )
1730+ . or_else ( || {
1731+ self . closed_channel_store
1732+ . get ( & user_channel_id)
1733+ . map ( |existing| ( existing. is_outbound , existing. is_announced ) )
1734+ } )
16931735 . unwrap_or ( ( is_outbound_from_set, is_announced_from_set) ) ;
16941736
16951737 let closed_at = SystemTime :: now ( )
@@ -1737,7 +1779,16 @@ where
17371779 } ;
17381780
17391781 match self . event_queue . add_event ( event) . await {
1740- Ok ( _) => { } ,
1782+ Ok ( _) => {
1783+ if let Err ( e) = self . pending_channel_store . remove ( & user_channel_id) . await {
1784+ log_error ! (
1785+ self . logger,
1786+ "Failed to remove pending channel info for {}: {}" ,
1787+ channel_id,
1788+ e
1789+ ) ;
1790+ }
1791+ } ,
17411792 Err ( e) => {
17421793 log_error ! ( self . logger, "Failed to push to event queue: {}" , e) ;
17431794 return Err ( ReplayEvent ( ) ) ;
0 commit comments