9
9
10
10
//! The top-level network map tracking logic lives here.
11
11
12
+ use bitcoin:: secp256k1:: constants:: PUBLIC_KEY_SIZE ;
12
13
use bitcoin:: secp256k1:: key:: PublicKey ;
13
14
use bitcoin:: secp256k1:: Secp256k1 ;
14
15
use bitcoin:: secp256k1;
@@ -50,12 +51,75 @@ const MAX_EXCESS_BYTES_FOR_RELAY: usize = 1024;
50
51
/// This value ensures a reply fits within the 65k payload limit and is consistent with other implementations.
51
52
const MAX_SCIDS_PER_REPLY : usize = 8000 ;
52
53
54
+ /// Represents the compressed public key of a node
55
+ #[ derive( Clone , Copy ) ]
56
+ pub struct NodeId ( [ u8 ; PUBLIC_KEY_SIZE ] ) ;
57
+
58
+ impl NodeId {
59
+ /// Create a new NodeId from a public key
60
+ pub fn from_pubkey ( pubkey : & PublicKey ) -> Self {
61
+ NodeId ( pubkey. serialize ( ) )
62
+ }
63
+
64
+ /// Get the public key slice from this NodeId
65
+ pub fn as_slice ( & self ) -> & [ u8 ] {
66
+ & self . 0
67
+ }
68
+ }
69
+
70
+ impl fmt:: Debug for NodeId {
71
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
72
+ write ! ( f, "NodeId({})" , log_bytes!( self . 0 ) )
73
+ }
74
+ }
75
+
76
+ impl core:: hash:: Hash for NodeId {
77
+ fn hash < H : core:: hash:: Hasher > ( & self , hasher : & mut H ) {
78
+ self . 0 . hash ( hasher) ;
79
+ }
80
+ }
81
+
82
+ impl Eq for NodeId { }
83
+
84
+ impl PartialEq for NodeId {
85
+ fn eq ( & self , other : & Self ) -> bool {
86
+ self . 0 [ ..] == other. 0 [ ..]
87
+ }
88
+ }
89
+
90
+ impl cmp:: PartialOrd for NodeId {
91
+ fn partial_cmp ( & self , other : & Self ) -> Option < cmp:: Ordering > {
92
+ Some ( self . cmp ( other) )
93
+ }
94
+ }
95
+
96
+ impl Ord for NodeId {
97
+ fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
98
+ self . 0 [ ..] . cmp ( & other. 0 [ ..] )
99
+ }
100
+ }
101
+
102
+ impl Writeable for NodeId {
103
+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
104
+ writer. write_all ( & self . 0 ) ?;
105
+ Ok ( ( ) )
106
+ }
107
+ }
108
+
109
+ impl Readable for NodeId {
110
+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
111
+ let mut buf = [ 0 ; PUBLIC_KEY_SIZE ] ;
112
+ reader. read_exact ( & mut buf) ?;
113
+ Ok ( Self ( buf) )
114
+ }
115
+ }
116
+
53
117
/// Represents the network as nodes and channels between them
54
118
pub struct NetworkGraph {
55
119
genesis_hash : BlockHash ,
56
120
// Lock order: channels -> nodes
57
121
channels : RwLock < BTreeMap < u64 , ChannelInfo > > ,
58
- nodes : RwLock < BTreeMap < PublicKey , NodeInfo > > ,
122
+ nodes : RwLock < BTreeMap < NodeId , NodeInfo > > ,
59
123
}
60
124
61
125
impl Clone for NetworkGraph {
@@ -73,7 +137,7 @@ impl Clone for NetworkGraph {
73
137
/// A read-only view of [`NetworkGraph`].
74
138
pub struct ReadOnlyNetworkGraph < ' a > {
75
139
channels : RwLockReadGuard < ' a , BTreeMap < u64 , ChannelInfo > > ,
76
- nodes : RwLockReadGuard < ' a , BTreeMap < PublicKey , NodeInfo > > ,
140
+ nodes : RwLockReadGuard < ' a , BTreeMap < NodeId , NodeInfo > > ,
77
141
}
78
142
79
143
/// Update to the [`NetworkGraph`] based on payment failure information conveyed via the Onion
@@ -277,11 +341,11 @@ where C::Target: chain::Access, L::Target: Logger
277
341
let mut result = Vec :: with_capacity ( batch_amount as usize ) ;
278
342
let nodes = self . network_graph . nodes . read ( ) . unwrap ( ) ;
279
343
let mut iter = if let Some ( pubkey) = starting_point {
280
- let mut iter = nodes. range ( ( * pubkey) ..) ;
344
+ let mut iter = nodes. range ( NodeId :: from_pubkey ( pubkey) ..) ;
281
345
iter. next ( ) ;
282
346
iter
283
347
} else {
284
- nodes. range ( ..)
348
+ nodes. range :: < NodeId , _ > ( ..)
285
349
} ;
286
350
while result. len ( ) < batch_amount as usize {
287
351
if let Some ( ( _, ref node) ) = iter. next ( ) {
@@ -314,7 +378,7 @@ where C::Target: chain::Access, L::Target: Logger
314
378
}
315
379
316
380
// Check if we need to perform a full synchronization with this peer
317
- if !self . should_request_full_sync ( their_node_id) {
381
+ if !self . should_request_full_sync ( & their_node_id) {
318
382
return ( ) ;
319
383
}
320
384
@@ -551,11 +615,11 @@ pub struct ChannelInfo {
551
615
/// Protocol features of a channel communicated during its announcement
552
616
pub features : ChannelFeatures ,
553
617
/// Source node of the first direction of a channel
554
- pub node_one : PublicKey ,
618
+ pub node_one : NodeId ,
555
619
/// Details about the first direction of a channel
556
620
pub one_to_two : Option < DirectionalChannelInfo > ,
557
621
/// Source node of the second direction of a channel
558
- pub node_two : PublicKey ,
622
+ pub node_two : NodeId ,
559
623
/// Details about the second direction of a channel
560
624
pub two_to_one : Option < DirectionalChannelInfo > ,
561
625
/// The channel capacity as seen on-chain, if chain lookup is available.
@@ -570,7 +634,7 @@ pub struct ChannelInfo {
570
634
impl fmt:: Display for ChannelInfo {
571
635
fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
572
636
write ! ( f, "features: {}, node_one: {}, one_to_two: {:?}, node_two: {}, two_to_one: {:?}" ,
573
- log_bytes!( self . features. encode( ) ) , log_pubkey !( self . node_one) , self . one_to_two, log_pubkey !( self . node_two) , self . two_to_one) ?;
637
+ log_bytes!( self . features. encode( ) ) , log_bytes !( self . node_one. as_slice ( ) ) , self . one_to_two, log_bytes !( self . node_two. as_slice ( ) ) , self . two_to_one) ?;
574
638
Ok ( ( ) )
575
639
}
576
640
}
@@ -724,8 +788,8 @@ impl fmt::Display for NetworkGraph {
724
788
writeln ! ( f, " {}: {}" , key, val) ?;
725
789
}
726
790
writeln ! ( f, "[Nodes]" ) ?;
727
- for ( key , val) in self . nodes . read ( ) . unwrap ( ) . iter ( ) {
728
- writeln ! ( f, " {}: {}" , log_pubkey! ( key ) , val) ?;
791
+ for ( & node_id , val) in self . nodes . read ( ) . unwrap ( ) . iter ( ) {
792
+ writeln ! ( f, " {}: {}" , log_bytes! ( node_id . as_slice ( ) ) , val) ?;
729
793
}
730
794
Ok ( ( ) )
731
795
}
@@ -780,7 +844,7 @@ impl NetworkGraph {
780
844
}
781
845
782
846
fn update_node_from_announcement_intern ( & self , msg : & msgs:: UnsignedNodeAnnouncement , full_msg : Option < & msgs:: NodeAnnouncement > ) -> Result < ( ) , LightningError > {
783
- match self . nodes . write ( ) . unwrap ( ) . get_mut ( & msg. node_id ) {
847
+ match self . nodes . write ( ) . unwrap ( ) . get_mut ( & NodeId :: from_pubkey ( & msg. node_id ) ) {
784
848
None => Err ( LightningError { err : "No existing channels for node_announcement" . to_owned ( ) , action : ErrorAction :: IgnoreError } ) ,
785
849
Some ( node) => {
786
850
if let Some ( node_info) = node. announcement_info . as_ref ( ) {
@@ -886,9 +950,9 @@ impl NetworkGraph {
886
950
887
951
let chan_info = ChannelInfo {
888
952
features : msg. features . clone ( ) ,
889
- node_one : msg. node_id_1 . clone ( ) ,
953
+ node_one : NodeId :: from_pubkey ( & msg. node_id_1 ) ,
890
954
one_to_two : None ,
891
- node_two : msg. node_id_2 . clone ( ) ,
955
+ node_two : NodeId :: from_pubkey ( & msg. node_id_2 ) ,
892
956
two_to_one : None ,
893
957
capacity_sats : utxo_value,
894
958
announcement_message : if msg. excess_data . len ( ) <= MAX_EXCESS_BYTES_FOR_RELAY
@@ -939,8 +1003,8 @@ impl NetworkGraph {
939
1003
} ;
940
1004
}
941
1005
942
- add_channel_to_node ! ( msg. node_id_1) ;
943
- add_channel_to_node ! ( msg. node_id_2) ;
1006
+ add_channel_to_node ! ( NodeId :: from_pubkey ( & msg. node_id_1) ) ;
1007
+ add_channel_to_node ! ( NodeId :: from_pubkey ( & msg. node_id_2) ) ;
944
1008
945
1009
Ok ( ( ) )
946
1010
}
@@ -1050,13 +1114,19 @@ impl NetworkGraph {
1050
1114
if msg. flags & 1 == 1 {
1051
1115
dest_node_id = channel. node_one . clone ( ) ;
1052
1116
if let Some ( ( sig, ctx) ) = sig_info {
1053
- secp_verify_sig ! ( ctx, & msg_hash, & sig, & channel. node_two) ;
1117
+ secp_verify_sig ! ( ctx, & msg_hash, & sig, & PublicKey :: from_slice( channel. node_two. as_slice( ) ) . map_err( |_| LightningError {
1118
+ err: "Couldn't parse source node pubkey" . to_owned( ) ,
1119
+ action: ErrorAction :: IgnoreAndLog ( Level :: Debug )
1120
+ } ) ?) ;
1054
1121
}
1055
1122
maybe_update_channel_info ! ( channel. two_to_one, channel. node_two) ;
1056
1123
} else {
1057
1124
dest_node_id = channel. node_two . clone ( ) ;
1058
1125
if let Some ( ( sig, ctx) ) = sig_info {
1059
- secp_verify_sig ! ( ctx, & msg_hash, & sig, & channel. node_one) ;
1126
+ secp_verify_sig ! ( ctx, & msg_hash, & sig, & PublicKey :: from_slice( channel. node_one. as_slice( ) ) . map_err( |_| LightningError {
1127
+ err: "Couldn't parse destination node pubkey" . to_owned( ) ,
1128
+ action: ErrorAction :: IgnoreAndLog ( Level :: Debug )
1129
+ } ) ?) ;
1060
1130
}
1061
1131
maybe_update_channel_info ! ( channel. one_to_two, channel. node_one) ;
1062
1132
}
@@ -1104,7 +1174,7 @@ impl NetworkGraph {
1104
1174
Ok ( ( ) )
1105
1175
}
1106
1176
1107
- fn remove_channel_in_nodes ( nodes : & mut BTreeMap < PublicKey , NodeInfo > , chan : & ChannelInfo , short_channel_id : u64 ) {
1177
+ fn remove_channel_in_nodes ( nodes : & mut BTreeMap < NodeId , NodeInfo > , chan : & ChannelInfo , short_channel_id : u64 ) {
1108
1178
macro_rules! remove_from_node {
1109
1179
( $node_id: expr) => {
1110
1180
if let BtreeEntry :: Occupied ( mut entry) = nodes. entry( $node_id) {
@@ -1136,7 +1206,7 @@ impl ReadOnlyNetworkGraph<'_> {
1136
1206
/// Returns all known nodes' public keys along with announced node info.
1137
1207
///
1138
1208
/// (C-not exported) because we have no mapping for `BTreeMap`s
1139
- pub fn nodes ( & self ) -> & BTreeMap < PublicKey , NodeInfo > {
1209
+ pub fn nodes ( & self ) -> & BTreeMap < NodeId , NodeInfo > {
1140
1210
& * self . nodes
1141
1211
}
1142
1212
@@ -1146,7 +1216,7 @@ impl ReadOnlyNetworkGraph<'_> {
1146
1216
///
1147
1217
/// (C-not exported) as there is no practical way to track lifetimes of returned values.
1148
1218
pub fn get_addresses ( & self , pubkey : & PublicKey ) -> Option < & Vec < NetAddress > > {
1149
- if let Some ( node) = self . nodes . get ( pubkey) {
1219
+ if let Some ( node) = self . nodes . get ( & NodeId :: from_pubkey ( & pubkey) ) {
1150
1220
if let Some ( node_info) = node. announcement_info . as_ref ( ) {
1151
1221
return Some ( & node_info. addresses )
1152
1222
}
0 commit comments