@@ -593,9 +593,8 @@ where
593
593
}
594
594
595
595
#[ derive( Clone , Debug , PartialEq ) ]
596
- /// Details about one direction of a channel. Received
597
- /// within a channel update.
598
- pub struct DirectionalChannelInfo {
596
+ /// Details about one direction of a channel as received within a [`ChannelUpdate`].
597
+ pub struct ChannelUpdateInfo {
599
598
/// When the last update to the channel direction was issued.
600
599
/// Value is opaque, as set in the announcement.
601
600
pub last_update : u32 ,
@@ -616,14 +615,14 @@ pub struct DirectionalChannelInfo {
616
615
pub last_update_message : Option < ChannelUpdate > ,
617
616
}
618
617
619
- impl fmt:: Display for DirectionalChannelInfo {
618
+ impl fmt:: Display for ChannelUpdateInfo {
620
619
fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
621
620
write ! ( f, "last_update {}, enabled {}, cltv_expiry_delta {}, htlc_minimum_msat {}, fees {:?}" , self . last_update, self . enabled, self . cltv_expiry_delta, self . htlc_minimum_msat, self . fees) ?;
622
621
Ok ( ( ) )
623
622
}
624
623
}
625
624
626
- impl_writeable_tlv_based ! ( DirectionalChannelInfo , {
625
+ impl_writeable_tlv_based ! ( ChannelUpdateInfo , {
627
626
( 0 , last_update, required) ,
628
627
( 2 , enabled, required) ,
629
628
( 4 , cltv_expiry_delta, required) ,
@@ -642,11 +641,11 @@ pub struct ChannelInfo {
642
641
/// Source node of the first direction of a channel
643
642
pub node_one : NodeId ,
644
643
/// Details about the first direction of a channel
645
- pub one_to_two : Option < DirectionalChannelInfo > ,
644
+ pub one_to_two : Option < ChannelUpdateInfo > ,
646
645
/// Source node of the second direction of a channel
647
646
pub node_two : NodeId ,
648
647
/// Details about the second direction of a channel
649
- pub two_to_one : Option < DirectionalChannelInfo > ,
648
+ pub two_to_one : Option < ChannelUpdateInfo > ,
650
649
/// The channel capacity as seen on-chain, if chain lookup is available.
651
650
pub capacity_sats : Option < u64 > ,
652
651
/// An initial announcement of the channel
@@ -660,6 +659,23 @@ pub struct ChannelInfo {
660
659
announcement_received_time : u64 ,
661
660
}
662
661
662
+ impl ChannelInfo {
663
+ /// Returns a [`DirectedChannelInfo`] for the channel directed to the given `target` from a
664
+ /// returned `source`, or `None` if `target` is not one of the channel's counterparties.
665
+ pub fn as_directed_to ( & self , target : & NodeId ) -> Option < ( DirectedChannelInfo , & NodeId ) > {
666
+ let ( direction, source) = {
667
+ if target == & self . node_one {
668
+ ( self . two_to_one . as_ref ( ) , & self . node_two )
669
+ } else if target == & self . node_two {
670
+ ( self . one_to_two . as_ref ( ) , & self . node_one )
671
+ } else {
672
+ return None ;
673
+ }
674
+ } ;
675
+ Some ( ( DirectedChannelInfo { channel : self , direction } , source) )
676
+ }
677
+ }
678
+
663
679
impl fmt:: Display for ChannelInfo {
664
680
fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
665
681
write ! ( f, "features: {}, node_one: {}, one_to_two: {:?}, node_two: {}, two_to_one: {:?}" ,
@@ -679,6 +695,132 @@ impl_writeable_tlv_based!(ChannelInfo, {
679
695
( 12 , announcement_message, required) ,
680
696
} ) ;
681
697
698
+ /// A wrapper around [`ChannelInfo`] representing information about the channel as directed from a
699
+ /// source node to a target node.
700
+ #[ derive( Clone ) ]
701
+ pub struct DirectedChannelInfo < ' a > {
702
+ channel : & ' a ChannelInfo ,
703
+ direction : Option < & ' a ChannelUpdateInfo > ,
704
+ }
705
+
706
+ impl < ' a > DirectedChannelInfo < ' a > {
707
+ /// Returns information for the channel.
708
+ pub fn channel ( & self ) -> & ' a ChannelInfo { self . channel }
709
+
710
+ /// Returns information for the direction.
711
+ pub fn direction ( & self ) -> Option < & ' a ChannelUpdateInfo > { self . direction }
712
+
713
+ /// Returns the [`EffectiveCapacity`] of the channel in the direction.
714
+ ///
715
+ /// This is either the total capacity from the funding transaction, if known, or the
716
+ /// `htlc_maximum_msat` for the direction as advertised by the gossip network, if known,
717
+ /// whichever is smaller.
718
+ pub fn effective_capacity ( & self ) -> EffectiveCapacity {
719
+ let capacity_msat = self . channel . capacity_sats . map ( |capacity_sats| capacity_sats * 1000 ) ;
720
+ self . direction
721
+ . and_then ( |direction| direction. htlc_maximum_msat )
722
+ . map ( |max_htlc_msat| {
723
+ let capacity_msat = capacity_msat. unwrap_or ( u64:: max_value ( ) ) ;
724
+ if max_htlc_msat < capacity_msat {
725
+ EffectiveCapacity :: MaximumHTLC { amount_msat : max_htlc_msat }
726
+ } else {
727
+ EffectiveCapacity :: Total { capacity_msat }
728
+ }
729
+ } )
730
+ . or_else ( || capacity_msat. map ( |capacity_msat|
731
+ EffectiveCapacity :: Total { capacity_msat } ) )
732
+ . unwrap_or ( EffectiveCapacity :: Unknown )
733
+ }
734
+
735
+ /// Returns `Some` if [`ChannelUpdateInfo`] is available in the direction.
736
+ pub ( super ) fn with_update ( self ) -> Option < DirectedChannelInfoWithUpdate < ' a > > {
737
+ match self . direction {
738
+ Some ( _) => Some ( DirectedChannelInfoWithUpdate { inner : self } ) ,
739
+ None => None ,
740
+ }
741
+ }
742
+ }
743
+
744
+ impl < ' a > fmt:: Debug for DirectedChannelInfo < ' a > {
745
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
746
+ f. debug_struct ( "DirectedChannelInfo" )
747
+ . field ( "channel" , & self . channel )
748
+ . finish ( )
749
+ }
750
+ }
751
+
752
+ /// A [`DirectedChannelInfo`] with [`ChannelUpdateInfo`] available in its the direction.
753
+ #[ derive( Clone ) ]
754
+ pub ( super ) struct DirectedChannelInfoWithUpdate < ' a > {
755
+ inner : DirectedChannelInfo < ' a > ,
756
+ }
757
+
758
+ impl < ' a > DirectedChannelInfoWithUpdate < ' a > {
759
+ /// Returns information for the channel.
760
+ #[ inline]
761
+ pub ( super ) fn channel ( & self ) -> & ' a ChannelInfo { & self . inner . channel }
762
+
763
+ /// Returns information for the direction.
764
+ #[ inline]
765
+ pub ( super ) fn direction ( & self ) -> & ' a ChannelUpdateInfo { self . inner . direction . unwrap ( ) }
766
+
767
+ /// Returns the [`EffectiveCapacity`] of the channel in the direction.
768
+ #[ inline]
769
+ pub ( super ) fn effective_capacity ( & self ) -> EffectiveCapacity { self . inner . effective_capacity ( ) }
770
+ }
771
+
772
+ impl < ' a > fmt:: Debug for DirectedChannelInfoWithUpdate < ' a > {
773
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
774
+ self . inner . fmt ( f)
775
+ }
776
+ }
777
+
778
+ /// The effective capacity of a channel for routing purposes.
779
+ ///
780
+ /// While this may be smaller than the actual channel capacity, amounts greater than
781
+ /// [`Self::as_msat`] should not be routed through the channel.
782
+ pub enum EffectiveCapacity {
783
+ /// The available liquidity in the channel known from being a channel counterparty, and thus a
784
+ /// direct hop.
785
+ ExactLiquidity {
786
+ /// Either the inbound or outbound liquidity depending on the direction, denominated in
787
+ /// millisatoshi.
788
+ liquidity_msat : u64 ,
789
+ } ,
790
+ /// The maximum HTLC amount in one direction as advertised on the gossip network.
791
+ MaximumHTLC {
792
+ /// The maximum HTLC amount denominated in millisatoshi.
793
+ amount_msat : u64 ,
794
+ } ,
795
+ /// The total capacity of the channel as determined by the funding transaction.
796
+ Total {
797
+ /// The funding amount denominated in millisatoshi.
798
+ capacity_msat : u64 ,
799
+ } ,
800
+ /// A capacity sufficient to route any payment, typically used for private channels provided by
801
+ /// an invoice.
802
+ Infinite ,
803
+ /// A capacity that is unknown possibly because either the chain state is unavailable to know
804
+ /// the total capacity or the `htlc_maximum_msat` was not advertised on the gossip network.
805
+ Unknown ,
806
+ }
807
+
808
+ /// The presumed channel capacity denominated in millisatoshi for [`EffectiveCapacity::Unknown`] to
809
+ /// use when making routing decisions.
810
+ pub const UNKNOWN_CHANNEL_CAPACITY_MSAT : u64 = 250_000 * 1000 ;
811
+
812
+ impl EffectiveCapacity {
813
+ /// Returns the effective capacity denominated in millisatoshi.
814
+ pub fn as_msat ( & self ) -> u64 {
815
+ match self {
816
+ EffectiveCapacity :: ExactLiquidity { liquidity_msat } => * liquidity_msat,
817
+ EffectiveCapacity :: MaximumHTLC { amount_msat } => * amount_msat,
818
+ EffectiveCapacity :: Total { capacity_msat } => * capacity_msat,
819
+ EffectiveCapacity :: Infinite => u64:: max_value ( ) ,
820
+ EffectiveCapacity :: Unknown => UNKNOWN_CHANNEL_CAPACITY_MSAT ,
821
+ }
822
+ }
823
+ }
682
824
683
825
/// Fees for routing via a given channel or a node
684
826
#[ derive( Eq , PartialEq , Copy , Clone , Debug , Hash ) ]
@@ -1227,7 +1369,7 @@ impl NetworkGraph {
1227
1369
let last_update_message = if msg. excess_data. len( ) <= MAX_EXCESS_BYTES_FOR_RELAY
1228
1370
{ full_msg. cloned( ) } else { None } ;
1229
1371
1230
- let updated_channel_dir_info = DirectionalChannelInfo {
1372
+ let updated_channel_update_info = ChannelUpdateInfo {
1231
1373
enabled: chan_enabled,
1232
1374
last_update: msg. timestamp,
1233
1375
cltv_expiry_delta: msg. cltv_expiry_delta,
@@ -1239,7 +1381,7 @@ impl NetworkGraph {
1239
1381
} ,
1240
1382
last_update_message
1241
1383
} ;
1242
- $target = Some ( updated_channel_dir_info ) ;
1384
+ $target = Some ( updated_channel_update_info ) ;
1243
1385
}
1244
1386
}
1245
1387
0 commit comments