1
- use std:: {
2
- collections:: { HashMap , HashSet } ,
3
- fs:: File ,
4
- io:: { BufReader , Error , ErrorKind } ,
5
- } ;
1
+ #![ allow( dead_code) ]
2
+ use std:: collections:: HashMap ;
3
+ use std:: fs:: File ;
4
+ use std:: io:: { BufReader , Error , ErrorKind } ;
6
5
7
- use fundamentals:: {
8
- bolt:: bolt7:: ChannelAnnouncement ,
9
- prelude:: bolt7:: { ChannelUpdate , NodeAnnouncement } ,
10
- } ;
11
- use fundamentals:: { core:: FromWire , types:: ShortChannelId } ;
6
+ use fundamentals:: core:: FromWire ;
7
+ use fundamentals:: prelude:: bolt7:: { ChannelAnnouncement , ChannelUpdate , NodeAnnouncement } ;
8
+ use fundamentals:: types:: ShortChannelId ;
12
9
13
10
mod flags;
14
11
mod gossip_store_msg;
@@ -20,27 +17,28 @@ use flags::{
20
17
WIRE_GOSSIP_STORE_PRIVATE_UPDATE ,
21
18
} ;
22
19
use gossip_store_msg:: * ;
23
- use types:: { GossipChannel , GossipNode , GossipNodeId } ;
20
+ use types:: { GossipChannel , GossipNode , GossipNodeId , GossipStoredHeader } ;
24
21
25
22
/// Gossip map implementation, that allow you to manage the gossip_store
26
23
/// written by core lightning.
27
- struct GossipMap < ' a > {
24
+ #[ derive( Debug ) ]
25
+ struct GossipMap {
28
26
version : u8 ,
29
27
stream : Option < BufReader < File > > ,
30
- nodes : HashMap < GossipNodeId , GossipNode < ' a > > ,
31
- channels : HashMap < ShortChannelId , GossipChannel < ' a > > ,
32
- orphan_channel_updates : HashSet < ChannelUpdate > ,
28
+ nodes : HashMap < GossipNodeId , GossipNode > ,
29
+ channels : HashMap < ShortChannelId , GossipChannel > ,
30
+ orphan_channel_updates : HashMap < ShortChannelId , ChannelUpdate > ,
33
31
}
34
32
35
- impl GossipMap < ' _ > {
33
+ impl GossipMap {
36
34
// Create a new instance of the gossip map.
37
35
pub fn new ( version : u8 ) -> Self {
38
36
GossipMap {
39
37
version,
40
38
stream : None ,
41
39
nodes : HashMap :: new ( ) ,
42
40
channels : HashMap :: new ( ) ,
43
- orphan_channel_updates : HashSet :: new ( ) ,
41
+ orphan_channel_updates : HashMap :: new ( ) ,
44
42
}
45
43
}
46
44
@@ -52,23 +50,27 @@ impl GossipMap<'_> {
52
50
stream : Some ( stream) ,
53
51
nodes : HashMap :: new ( ) ,
54
52
channels : HashMap :: new ( ) ,
55
- orphan_channel_updates : HashSet :: new ( ) ,
53
+ orphan_channel_updates : HashMap :: new ( ) ,
56
54
} ;
57
55
gossip_map. refresh ( ) ?;
58
56
Ok ( gossip_map)
59
57
}
60
58
61
- pub fn get_channel ( & self , short_chananel_id : & str ) -> Option < & ' static GossipChannel > {
59
+ pub fn get_channel ( & self , short_chananel_id : & str ) -> Option < & GossipChannel > {
62
60
self . channels . get ( short_chananel_id. as_bytes ( ) )
63
61
}
64
62
65
- pub fn get_node ( & self , node_id : & str ) -> Option < & ' static GossipNode > {
66
- // FIXME: store the node as String?
67
- self . nodes . get ( & GossipNodeId {
68
- node_id : node_id. to_owned ( ) ,
69
- } )
63
+ pub fn get_node ( & self , node_id : & str ) -> Option < & GossipNode > {
64
+ let node_id = GossipNodeId :: from ( node_id) ;
65
+ self . nodes . get ( & node_id)
70
66
}
71
67
68
+ /// add a node announcement message inside the gossip map
69
+ fn add_node_announcement ( & mut self , node_announce : NodeAnnouncement ) { }
70
+
71
+ /// add a channel announcement message inside the gossip map.
72
+ fn add_channel_announcement ( & mut self , channel_announce : ChannelAnnouncement ) { }
73
+
72
74
fn refresh ( & mut self ) -> std:: io:: Result < ( ) > {
73
75
let mut stream = self . stream . as_mut ( ) . unwrap ( ) ;
74
76
let version = u8:: from_wire ( & mut stream) ? as u16 ;
@@ -79,38 +81,146 @@ impl GossipMap<'_> {
79
81
) ) ;
80
82
}
81
83
self . version = version as u8 ;
84
+ println ! ( "version {version}" ) ;
82
85
83
- while let Ok ( chunk) = u8:: from_wire ( & mut stream) {
84
- match chunk as u16 {
86
+ let mut last_short_channel_id: Option < ShortChannelId > = None ;
87
+ loop {
88
+ let Ok ( header) = GossipStoredHeader :: from_wire ( & mut stream) else {
89
+ break ; // EOF?
90
+ } ;
91
+ match header. flag ( ) {
92
+ flags:: GOSSIP_STORE_LEN_DELETED_BIT | flags:: GOSSIP_STORE_LEN_RATELIMIT_BIT => {
93
+ continue
94
+ }
95
+ _ => { }
96
+ }
97
+
98
+ println ! ( "header {:?}" , header) ;
99
+ let chunk = u16:: from_wire ( & mut stream) ?;
100
+ println ! ( "chunk {chunk}" ) ;
101
+ match chunk {
85
102
// channel announcement!
86
103
256 => {
87
104
let channel_announcement = ChannelAnnouncement :: from_wire ( & mut stream) ?;
105
+ let node_one = GossipNodeId :: from_bytes ( & channel_announcement. node_id_1 ) ?;
106
+ let node_two = GossipNodeId :: from_bytes ( & channel_announcement. node_id_2 ) ?;
107
+ if !self . nodes . contains_key ( & node_one) {
108
+ let node = GossipNode :: new ( node_one. clone ( ) , None ) ;
109
+ self . nodes . insert ( node_one. clone ( ) , node) ;
110
+ }
111
+
112
+ if !self . nodes . contains_key ( & node_two) {
113
+ let node = GossipNode :: new ( node_two. clone ( ) , None ) ;
114
+ self . nodes . insert ( node_two. clone ( ) , node) ;
115
+ }
116
+ println ! ( "{:?}" , self . nodes) ;
117
+ last_short_channel_id = Some ( channel_announcement. short_channel_id ) ;
118
+ let channel = GossipChannel :: new ( channel_announcement, & node_one, & node_two) ;
119
+ // SAFETY: this is sage because the node is always present, due the
120
+ // previous checks.
121
+ let node_one = self . nodes . get_mut ( & node_one) . unwrap ( ) ;
122
+ node_one. add_channel ( & channel. clone ( ) ) ;
123
+ let node_two = self . nodes . get_mut ( & node_two) . unwrap ( ) ;
124
+ node_two. add_channel ( & channel. clone ( ) ) ;
125
+ self . channels
126
+ . insert ( last_short_channel_id. unwrap ( ) , channel) ;
88
127
}
89
128
WIRE_GOSSIP_STORE_PRIVATE_CHANNEL => {
90
- let private_channel = GossipStorePrivateChannel :: from_wire ( & mut stream) ?;
129
+ let _ = stream. seek_relative ( 2 + 8 + 2 ) ?;
130
+ let channel_announcement = ChannelAnnouncement :: from_wire ( & mut stream) ?;
131
+
132
+ let node_one = GossipNodeId :: from_bytes ( & channel_announcement. node_id_1 ) ?;
133
+ let node_two = GossipNodeId :: from_bytes ( & channel_announcement. node_id_2 ) ?;
134
+ if !self . nodes . contains_key ( & node_one) {
135
+ let node = GossipNode :: new ( node_one. clone ( ) , None ) ;
136
+ self . nodes . insert ( node_one. clone ( ) , node) ;
137
+ }
138
+
139
+ if !self . nodes . contains_key ( & node_two) {
140
+ let node = GossipNode :: new ( node_two. clone ( ) , None ) ;
141
+ self . nodes . insert ( node_two. clone ( ) , node) ;
142
+ }
143
+
144
+ last_short_channel_id = Some ( channel_announcement. short_channel_id ) ;
145
+ let mut channel =
146
+ GossipChannel :: new ( channel_announcement, & node_one, & node_two) ;
147
+ // SAFETY: this is sage because the node is always present, due the
148
+ // previous checks.
149
+ let node_one = self . nodes . get_mut ( & node_one) . unwrap ( ) ;
150
+ node_one. add_channel ( & channel. clone ( ) ) ;
151
+ let node_two = self . nodes . get_mut ( & node_two) . unwrap ( ) ;
152
+ node_two. add_channel ( & channel. clone ( ) ) ;
153
+ channel. set_private ( true ) ;
154
+ self . channels
155
+ . insert ( last_short_channel_id. unwrap ( ) , channel) ;
91
156
}
92
157
WIRE_GOSSIP_STORE_CHANNEL_AMOUNT => {
93
158
let channel_amount = GossipStoreChannelAmount :: from_wire ( & mut stream) ?;
159
+ //FIXME: remove the unwrap().
160
+ assert ! ( last_short_channel_id. is_some( ) ) ;
161
+ let channel = self
162
+ . channels
163
+ . get_mut ( & last_short_channel_id. unwrap ( ) )
164
+ . unwrap ( ) ;
165
+ channel. set_amount ( channel_amount) ;
94
166
}
95
167
WIRE_GOSSIP_STORE_PRIVATE_UPDATE => {
96
168
let private_update = GossipStorePrivateUpdate :: from_wire ( & mut stream) ?;
169
+ unimplemented ! ( )
97
170
}
98
171
WIRE_GOSSIP_STORE_DELETE_CHAN => {
99
172
let del_chan = GossipStoreDeleteChan :: from_wire ( & mut stream) ?;
173
+ unimplemented ! ( )
100
174
}
101
175
WIRE_GOSSIP_STORE_ENDED => {
102
- let eof = GossipStoreEnded :: from_wire ( & mut stream) ?;
176
+ let _ = GossipStoreEnded :: from_wire ( & mut stream) ?;
177
+ break ;
103
178
}
104
179
257 => {
105
180
let node_announcement = NodeAnnouncement :: from_wire ( & mut stream) ?;
181
+ let node_id = GossipNodeId :: from_bytes ( & node_announcement. node_id ) ?;
182
+ if !self . nodes . contains_key ( & node_id) {
183
+ let node = GossipNode :: new ( node_id. clone ( ) , Some ( node_announcement) ) ;
184
+ self . nodes . insert ( node_id, node) ;
185
+ }
106
186
}
107
187
258 => {
108
188
let channel_update = ChannelUpdate :: from_wire ( & mut stream) ?;
189
+ if self . channels . contains_key ( & channel_update. short_channel_id ) {
190
+ // SAFETY: we check the existence before!
191
+ let channel = self
192
+ . channels
193
+ . get_mut ( & channel_update. short_channel_id )
194
+ . unwrap ( ) ;
195
+ channel. channel_update ( & channel_update)
196
+ } else {
197
+ self . orphan_channel_updates
198
+ . insert ( channel_update. short_channel_id , channel_update) ;
199
+ }
109
200
}
110
- _ => continue ,
201
+ _ => assert ! ( false ) ,
111
202
}
203
+ println ! ( "----------------------------------------------------" ) ;
112
204
}
113
205
114
206
Ok ( ( ) )
115
207
}
116
208
}
209
+
210
+ #[ cfg( test) ]
211
+ mod tests {
212
+ use super :: * ;
213
+
214
+ #[ test]
215
+ fn read_gossipmap_from_file ( ) {
216
+ let path = "/run/media/vincent/VincentSSD/.lightning/testnet/gossip_store" ;
217
+ let pubkey = "03b39d1ddf13ce486de74e9e44e0538f960401a9ec75534ba9cfe4100d65426880" ;
218
+ let map = GossipMap :: from_file ( path) ;
219
+ assert ! ( map. is_ok( ) , "{:?}" , map) ;
220
+ let map = map. unwrap ( ) ;
221
+ assert ! (
222
+ map. get_node( pubkey) . is_some( ) ,
223
+ "node with id `{pubkey}` not found!"
224
+ ) ;
225
+ }
226
+ }
0 commit comments