@@ -795,22 +795,32 @@ where
795795 }
796796}
797797
798+ // Fetching values from this struct is very performance sensitive during routefinding. Thus, we
799+ // want to ensure that all of the fields we care about (all of them except `last_update_message`)
800+ // sit on the same cache line.
801+ //
802+ // We do this by using `repr(C)`, which forces the struct to be laid out in memory the way we write
803+ // it (ensuring `last_update_message` hangs off the end and no fields are reordered after it), and
804+ // `align(32)`, ensuring the struct starts either at the start, or in the middle, of a 64b x86-64
805+ // cache line. This ensures the beginning fields (which are 31 bytes) all sit in the same cache
806+ // line.
807+ #[ repr( C , align( 32 ) ) ]
798808#[ derive( Clone , Debug , PartialEq , Eq ) ]
799809/// Details about one direction of a channel as received within a [`ChannelUpdate`].
800810pub struct ChannelUpdateInfo {
801- /// When the last update to the channel direction was issued.
802- /// Value is opaque, as set in the announcement.
803- pub last_update : u32 ,
804- /// Whether the channel can be currently used for payments (in this one direction).
805- pub enabled : bool ,
806- /// The difference in CLTV values that you must have when routing through this channel.
807- pub cltv_expiry_delta : u16 ,
808811 /// The minimum value, which must be relayed to the next hop via the channel
809812 pub htlc_minimum_msat : u64 ,
810813 /// The maximum value which may be relayed to the next hop via the channel.
811814 pub htlc_maximum_msat : u64 ,
812815 /// Fees charged when the channel is used for routing
813816 pub fees : RoutingFees ,
817+ /// When the last update to the channel direction was issued.
818+ /// Value is opaque, as set in the announcement.
819+ pub last_update : u32 ,
820+ /// The difference in CLTV values that you must have when routing through this channel.
821+ pub cltv_expiry_delta : u16 ,
822+ /// Whether the channel can be currently used for payments (in this one direction).
823+ pub enabled : bool ,
814824 /// Most recent update for the channel received from the network
815825 /// Mostly redundant with the data we store in fields explicitly.
816826 /// Everything else is useful only for sending out for initial routing sync.
@@ -878,22 +888,46 @@ impl Readable for ChannelUpdateInfo {
878888 }
879889}
880890
891+ // Fetching values from this struct is very performance sensitive during routefinding. Thus, we
892+ // want to ensure that all of the fields we care about (all of them except `last_update_message`
893+ // and `announcement_received_time`) sit on the same cache line.
894+ //
895+ // Sadly, this is not possible, however we can still do okay - all of the fields before
896+ // `one_to_two` and `two_to_one` are just under 128 bytes long, so we can ensure they sit on
897+ // adjacent cache lines (which are generally fetched together in x86_64 processors).
898+ //
899+ // This leaves only the two directional channel info structs on separate cache lines.
900+ //
901+ // We accomplish this using `repr(C)`, which forces the struct to be laid out in memory the way we
902+ // write it (ensuring the fields we care about are at the start of the struct) and `align(128)`,
903+ // ensuring the struct starts at the beginning of two adjacent 64b x86-64 cache lines.
904+ #[ repr( align( 128 ) , C ) ]
881905#[ derive( Clone , Debug , Eq ) ]
882906/// Details about a channel (both directions).
883907/// Received within a channel announcement.
884908pub struct ChannelInfo {
885909 /// Protocol features of a channel communicated during its announcement
886910 pub features : ChannelFeatures ,
911+
887912 /// Source node of the first direction of a channel
888913 pub node_one : NodeId ,
889- /// Details about the first direction of a channel
890- pub one_to_two : Option < ChannelUpdateInfo > ,
914+
891915 /// Source node of the second direction of a channel
892916 pub node_two : NodeId ,
893- /// Details about the second direction of a channel
894- pub two_to_one : Option < ChannelUpdateInfo > ,
917+
918+ /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_one`].
919+ pub ( crate ) node_one_counter : u32 ,
920+ /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_two`].
921+ pub ( crate ) node_two_counter : u32 ,
922+
895923 /// The channel capacity as seen on-chain, if chain lookup is available.
896924 pub capacity_sats : Option < u64 > ,
925+
926+ /// Details about the first direction of a channel
927+ pub one_to_two : Option < ChannelUpdateInfo > ,
928+ /// Details about the second direction of a channel
929+ pub two_to_one : Option < ChannelUpdateInfo > ,
930+
897931 /// An initial announcement of the channel
898932 /// Mostly redundant with the data we store in fields explicitly.
899933 /// Everything else is useful only for sending out for initial routing sync.
@@ -903,11 +937,6 @@ pub struct ChannelInfo {
903937 /// (which we can probably assume we are - no-std environments probably won't have a full
904938 /// network graph in memory!).
905939 announcement_received_time : u64 ,
906-
907- /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_one`].
908- pub ( crate ) node_one_counter : u32 ,
909- /// The [`NodeInfo::node_counter`] of the node pointed to by [`Self::node_two`].
910- pub ( crate ) node_two_counter : u32 ,
911940}
912941
913942impl PartialEq for ChannelInfo {
0 commit comments