@@ -649,6 +649,48 @@ pub struct ChannelInfo {
649
649
announcement_received_time : u64 ,
650
650
}
651
651
652
+ impl ChannelInfo {
653
+ /// Returns a [`DirectedChannelInfo`] for the channel from `source` to `target`.
654
+ ///
655
+ /// # Panics
656
+ ///
657
+ /// Panics if `source` and `target` are not the channel's counterparties.
658
+ pub fn as_directed ( & self , source : & NodeId , target : & NodeId ) -> DirectedChannelInfo {
659
+ let ( direction, source, target) = {
660
+ if source == & self . node_one && target == & self . node_two {
661
+ ( self . one_to_two . as_ref ( ) , & self . node_one , & self . node_two )
662
+ } else if source == & self . node_two && target == & self . node_one {
663
+ ( self . two_to_one . as_ref ( ) , & self . node_two , & self . node_one )
664
+ } else if source != & self . node_one && source != & self . node_two {
665
+ panic ! ( "Unknown source node: {:?}" , source)
666
+ } else if target != & self . node_one && target != & self . node_two {
667
+ panic ! ( "Unknown target node: {:?}" , target)
668
+ } else {
669
+ unreachable ! ( )
670
+ }
671
+ } ;
672
+ DirectedChannelInfo { channel : self , direction, source, target }
673
+ }
674
+
675
+ /// Returns a [`DirectedChannelInfo`] for the channel directed to the given `target`.
676
+ ///
677
+ /// # Panics
678
+ ///
679
+ /// Panics if `target` is not one of the channel's counterparties.
680
+ pub fn directed_to ( & self , target : & NodeId ) -> DirectedChannelInfo {
681
+ let ( direction, source, target) = {
682
+ if target == & self . node_one {
683
+ ( self . two_to_one . as_ref ( ) , & self . node_two , & self . node_one )
684
+ } else if target == & self . node_two {
685
+ ( self . one_to_two . as_ref ( ) , & self . node_one , & self . node_two )
686
+ } else {
687
+ panic ! ( "Unknown target node: {:?}" , target)
688
+ }
689
+ } ;
690
+ DirectedChannelInfo { channel : self , direction, source, target }
691
+ }
692
+ }
693
+
652
694
impl fmt:: Display for ChannelInfo {
653
695
fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
654
696
write ! ( f, "features: {}, node_one: {}, one_to_two: {:?}, node_two: {}, two_to_one: {:?}" ,
@@ -668,6 +710,105 @@ impl_writeable_tlv_based!(ChannelInfo, {
668
710
( 12 , announcement_message, required) ,
669
711
} ) ;
670
712
713
+ /// A wrapper around [`ChannelInfo`] representing information about the channel as directed from a
714
+ /// source node to a target node.
715
+ pub struct DirectedChannelInfo < ' a : ' b , ' b > {
716
+ channel : & ' a ChannelInfo ,
717
+ direction : Option < & ' b DirectionalChannelInfo > ,
718
+ source : & ' b NodeId ,
719
+ target : & ' b NodeId ,
720
+ }
721
+
722
+ impl < ' a : ' b , ' b > DirectedChannelInfo < ' a , ' b > {
723
+ /// Returns the node id for the source.
724
+ pub fn source ( & self ) -> & ' b NodeId { self . source }
725
+
726
+ /// Returns the node id for the target.
727
+ pub fn target ( & self ) -> & ' b NodeId { self . target }
728
+
729
+ /// Consumes the [`DirectedChannelInfo`], returning the wrapped parts.
730
+ pub fn into_parts ( self ) -> ( & ' a ChannelInfo , Option < & ' b DirectionalChannelInfo > ) {
731
+ ( self . channel , self . direction )
732
+ }
733
+
734
+ /// Returns the [`EffectiveCapacity`] of the channel in a specific direction.
735
+ ///
736
+ /// This is either the total capacity from the funding transaction, if known, or the
737
+ /// `htlc_maximum_msat` for the direction as advertised by the gossip network, if known,
738
+ /// whichever is smaller.
739
+ pub fn effective_capacity ( & self ) -> EffectiveCapacity {
740
+ Self :: effective_capacity_from_parts ( self . channel , self . direction )
741
+ }
742
+
743
+ /// Returns the [`EffectiveCapacity`] of the channel in the given direction.
744
+ ///
745
+ /// See [`Self::effective_capacity`] for details.
746
+ pub fn effective_capacity_from_parts (
747
+ channel : & ChannelInfo , direction : Option < & DirectionalChannelInfo >
748
+ ) -> EffectiveCapacity {
749
+ let capacity_msat = channel. capacity_sats . map ( |capacity_sats| capacity_sats * 1000 ) ;
750
+ direction
751
+ . and_then ( |direction| direction. htlc_maximum_msat )
752
+ . map ( |max_htlc_msat| {
753
+ let capacity_msat = capacity_msat. unwrap_or ( u64:: max_value ( ) ) ;
754
+ if max_htlc_msat < capacity_msat {
755
+ EffectiveCapacity :: MaximumHTLC { amount_msat : max_htlc_msat }
756
+ } else {
757
+ EffectiveCapacity :: Total { capacity_msat }
758
+ }
759
+ } )
760
+ . or_else ( || capacity_msat. map ( |capacity_msat|
761
+ EffectiveCapacity :: Total { capacity_msat } ) )
762
+ . unwrap_or ( EffectiveCapacity :: Unknown )
763
+ }
764
+ }
765
+
766
+ /// The effective capacity of a channel for routing purposes.
767
+ ///
768
+ /// While this may be smaller than the actual channel capacity, amounts greater than
769
+ /// [`Self::as_msat`] should not be routed through the channel.
770
+ pub enum EffectiveCapacity {
771
+ /// The available liquidity in the channel known from being a channel counterparty, and thus a
772
+ /// direct hop.
773
+ ExactLiquidity {
774
+ /// Either the inbound or outbound liquidity depending on the direction, denominated in
775
+ /// millisatoshi.
776
+ liquidity_msast : u64 ,
777
+ } ,
778
+ /// The maximum HTLC amount in one direction as advertised on the gossip network.
779
+ MaximumHTLC {
780
+ /// The maximum HTLC amount denominated in millisatoshi.
781
+ amount_msat : u64 ,
782
+ } ,
783
+ /// The total capacity of the channel as determined by the funding transaction.
784
+ Total {
785
+ /// The funding amount denominated in millisatoshi.
786
+ capacity_msat : u64 ,
787
+ } ,
788
+ /// A capacity sufficient to route any payment, typically used for private channels provided by
789
+ /// an invoice, though may not be the case for zero-amount invoices.
790
+ Infinite ,
791
+ /// A capacity that is unknown possibly because either the chain state is unavailable to know
792
+ /// the total capacity or the `htlc_maximum_msat` was not advertised on the gossip network.
793
+ Unknown ,
794
+ }
795
+
796
+ /// The presumed channel capacity denominated in millisatoshi for [`EffectiveCapacity::Unknown`] to
797
+ /// use when making routing decisions.
798
+ pub const UNKNOWN_CHANNEL_CAPACITY_MSAT : u64 = 250_000 * 1000 ;
799
+
800
+ impl EffectiveCapacity {
801
+ /// Returns the effective capacity denominated in millisatoshi.
802
+ pub fn as_msat ( & self ) -> u64 {
803
+ match self {
804
+ EffectiveCapacity :: ExactLiquidity { liquidity_msast } => * liquidity_msast,
805
+ EffectiveCapacity :: MaximumHTLC { amount_msat } => * amount_msat,
806
+ EffectiveCapacity :: Total { capacity_msat } => * capacity_msat,
807
+ EffectiveCapacity :: Infinite => u64:: max_value ( ) ,
808
+ EffectiveCapacity :: Unknown => UNKNOWN_CHANNEL_CAPACITY_MSAT ,
809
+ }
810
+ }
811
+ }
671
812
672
813
/// Fees for routing via a given channel or a node
673
814
#[ derive( Eq , PartialEq , Copy , Clone , Debug , Hash ) ]
0 commit comments