11
11
use std:: fs:: File ;
12
12
13
13
use lightning:: routing:: network_graph;
14
- use lightning_block_sync:: http:: * ;
15
14
16
15
use crate :: error:: GraphSyncError ;
17
16
18
17
pub mod error;
19
18
pub mod processing;
20
19
21
- pub async fn sync_network_graph_with_url (
22
- network_graph : & network_graph:: NetworkGraph ,
23
- sync_host : & str ,
24
- sync_port : u16 ,
25
- sync_path : & str ,
26
- ) -> Result < ( ) , GraphSyncError > {
27
- // make sure there is precisely one leading slash
28
- let canonical_path = format ! ( "/{}" , sync_path. trim_start_matches( "/" ) ) ;
29
- let http_endpoint = HttpEndpoint :: for_host ( sync_host. into ( ) ) . with_port ( sync_port) ;
30
- let http_client_result = HttpClient :: connect ( & http_endpoint) ;
31
- let mut http_client = http_client_result?;
32
-
33
- let response_result = http_client
34
- . get :: < BinaryResponse > ( & canonical_path, sync_host)
35
- . await ;
36
-
37
- let response_bytes = response_result?. 0 ;
38
- processing:: update_network_graph ( & network_graph, & response_bytes[ ..] )
39
- }
40
-
41
20
pub fn sync_network_graph_with_file_path (
42
21
network_graph : & network_graph:: NetworkGraph ,
43
22
sync_path : & str ,
@@ -54,264 +33,8 @@ mod tests {
54
33
use bitcoin:: Network ;
55
34
56
35
use lightning:: routing:: network_graph:: NetworkGraph ;
57
- use lightning_block_sync:: http:: { BinaryResponse , HttpClient } ;
58
-
59
- use crate :: { sync_network_graph_with_file_path, sync_network_graph_with_url} ;
60
- use crate :: error:: GraphSyncError ;
61
- use crate :: tests:: http_server_test_duplication:: HttpServer ;
62
-
63
- mod http_server_test_duplication {
64
- use std:: io:: { BufRead , Write } ;
65
- use std:: time:: Duration ;
66
-
67
- use lightning_block_sync:: http:: HttpEndpoint ;
68
-
69
- /// Server for handling HTTP client requests with a stock response.
70
- pub struct HttpServer {
71
- address : std:: net:: SocketAddr ,
72
- handler : std:: thread:: JoinHandle < ( ) > ,
73
- shutdown : std:: sync:: Arc < std:: sync:: atomic:: AtomicBool > ,
74
- }
75
-
76
- /// Body of HTTP response messages.
77
- pub enum MessageBody < T : ToString > {
78
- Empty ,
79
- Content ( T ) ,
80
- ChunkedContent ( T ) ,
81
- }
82
-
83
- impl HttpServer {
84
- fn responding_with_data ( status : & str , data : & [ u8 ] ) -> Self {
85
- let mut response_bytes = format ! (
86
- "{}\r \n \
87
- Content-Length: {}\r \n \
88
- \r \n \
89
- ",
90
- status,
91
- data. len( )
92
- )
93
- . as_bytes ( )
94
- . to_vec ( ) ;
95
- response_bytes. extend_from_slice ( data) ;
96
- HttpServer :: responding_with ( response_bytes)
97
- }
98
-
99
- pub fn responding_with_ok ( data : & [ u8 ] ) -> Self {
100
- HttpServer :: responding_with_data ( "HTTP/1.1 200 OK" , data)
101
- }
102
-
103
- pub fn responding_with_server_error ( data : & [ u8 ] ) -> Self {
104
- HttpServer :: responding_with_data ( "HTTP/1.1 500 Internal Server Error" , data)
105
- }
106
-
107
- fn responding_with ( response_bytes : Vec < u8 > ) -> Self {
108
- let listener = std:: net:: TcpListener :: bind ( "127.0.0.1:0" ) . unwrap ( ) ;
109
- let address = listener. local_addr ( ) . unwrap ( ) ;
110
-
111
- let shutdown = std:: sync:: Arc :: new ( std:: sync:: atomic:: AtomicBool :: new ( false ) ) ;
112
- let shutdown_signaled = std:: sync:: Arc :: clone ( & shutdown) ;
113
- let handler = std:: thread:: spawn ( move || {
114
- for stream in listener. incoming ( ) {
115
- let mut stream = stream. unwrap ( ) ;
116
- stream
117
- . set_write_timeout ( Some ( Duration :: from_secs ( 5 ) ) )
118
- . unwrap ( ) ;
119
-
120
- let lines_read = std:: io:: BufReader :: new ( & stream)
121
- . lines ( )
122
- . take_while ( |line| !line. as_ref ( ) . unwrap ( ) . is_empty ( ) )
123
- . count ( ) ;
124
- if lines_read == 0 {
125
- continue ;
126
- }
127
-
128
- for chunk in response_bytes. chunks ( 16 ) {
129
- if shutdown_signaled. load ( std:: sync:: atomic:: Ordering :: SeqCst ) {
130
- return ;
131
- } else {
132
- if let Err ( _) = stream. write ( chunk) {
133
- break ;
134
- }
135
- if let Err ( _) = stream. flush ( ) {
136
- break ;
137
- }
138
- }
139
- }
140
- }
141
- } ) ;
142
-
143
- Self {
144
- address,
145
- handler,
146
- shutdown,
147
- }
148
- }
149
-
150
- fn shutdown ( self ) {
151
- self . shutdown
152
- . store ( true , std:: sync:: atomic:: Ordering :: SeqCst ) ;
153
- self . handler . join ( ) . unwrap ( ) ;
154
- }
155
-
156
- pub fn endpoint ( & self ) -> HttpEndpoint {
157
- HttpEndpoint :: for_host ( self . address . ip ( ) . to_string ( ) ) . with_port ( self . address . port ( ) )
158
- }
159
- }
160
- }
161
-
162
- #[ tokio:: test]
163
- async fn test_mock_endpoint_fidelity ( ) {
164
- let valid_response = vec ! [
165
- 76 , 68 , 75 , 2 , 2 , 174 , 0 , 0 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 ,
166
- 174 , 99 , 247 , 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 8 ,
167
- 153 , 192 , 0 , 2 , 27 , 0 , 0 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 , 231 , 230 , 231 , 56 , 102 , 61 ,
168
- 250 , 251 , 187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 , 238 , 252 , 53 , 192 , 6 , 67 ,
169
- 2 , 36 , 125 , 157 , 176 , 223 , 175 , 234 , 116 , 94 , 248 , 201 , 225 , 97 , 235 , 50 , 47 , 115 , 172 ,
170
- 63 , 136 , 88 , 216 , 115 , 11 , 111 , 217 , 114 , 84 , 116 , 124 , 231 , 107 , 2 , 163 , 216 , 116 ,
171
- 204 , 120 , 152 , 52 , 172 , 208 , 143 , 140 , 71 , 242 , 209 , 153 , 111 , 23 , 61 , 222 , 28 , 106 ,
172
- 198 , 149 , 87 , 166 , 201 , 180 , 51 , 64 , 252 , 143 , 166 , 2 , 57 , 240 , 15 , 230 , 190 , 255 , 224 ,
173
- 70 , 176 , 137 , 155 , 249 , 125 , 20 , 170 , 114 , 97 , 221 , 142 , 89 , 231 , 233 , 205 , 126 , 199 ,
174
- 216 , 149 , 155 , 0 , 210 , 45 , 67 , 174 , 0 , 0 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 ,
175
- 166 , 162 , 70 , 174 , 99 , 247 , 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 ,
176
- 0 , 0 , 0 , 10 , 222 , 162 , 0 , 8 , 38 , 0 , 1 , 2 , 158 , 1 , 242 , 121 , 152 , 106 , 204 , 131 , 186 ,
177
- 35 , 93 , 70 , 216 , 10 , 237 , 224 , 183 , 89 , 95 , 65 , 3 , 83 , 185 , 58 , 138 , 181 , 64 , 187 , 103 ,
178
- 127 , 68 , 50 , 2 , 201 , 19 , 17 , 138 , 136 , 149 , 185 , 226 , 156 , 137 , 175 , 110 , 32 , 237 , 0 ,
179
- 217 , 90 , 31 , 100 , 228 , 149 , 46 , 219 , 175 , 168 , 77 , 4 , 143 , 38 , 128 , 76 , 97 , 2 , 155 , 9 ,
180
- 173 , 229 , 75 , 82 , 137 , 57 , 21 , 112 , 207 , 99 , 92 , 145 , 58 , 48 , 229 , 10 , 228 , 163 , 3 ,
181
- 106 , 147 , 39 , 177 , 90 , 242 , 186 , 249 , 11 , 210 , 54 , 2 , 212 , 16 , 225 , 46 , 42 , 209 , 254 ,
182
- 11 , 28 , 254 , 196 , 167 , 139 , 164 , 241 , 7 , 176 , 120 , 192 , 199 , 148 , 152 , 38 , 17 , 118 , 41 ,
183
- 122 , 240 , 223 , 249 , 158 , 145 , 2 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 1 , 27 , 1 , 0 , 40 , 0 , 0 , 0 ,
184
- 0 , 0 , 0 , 3 , 232 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 125 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 10 , 222 , 162 ,
185
- 0 , 8 , 38 , 0 , 1 , 1 , 27 , 1 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 3 , 232 , 0 , 0 , 0 , 1 , 0 ,
186
- 0 , 0 , 0 , 29 , 129 , 25 , 192 ,
187
- ] ;
188
- let server = HttpServer :: responding_with_ok ( & valid_response[ ..] ) ;
189
-
190
- let mut client = HttpClient :: connect ( & server. endpoint ( ) ) . unwrap ( ) ;
191
- let binary_response = client
192
- . get :: < BinaryResponse > ( "/foo" , "foo.com" )
193
- . await
194
- . unwrap ( ) ;
195
- assert_eq ! ( binary_response. 0 , valid_response) ;
196
- }
197
-
198
- #[ tokio:: test]
199
- async fn http_sync_fails_on_server_error ( ) {
200
- let valid_response = vec ! [
201
- 76 , 68 , 75 , 2 , 2 , 174 , 0 , 0 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 ,
202
- 174 , 99 , 247 , 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 8 ,
203
- 153 , 192 , 0 , 2 , 27 , 0 , 0 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 , 231 , 230 , 231 , 56 , 102 , 61 ,
204
- 250 , 251 , 187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 , 238 , 252 , 53 , 192 , 6 , 67 ,
205
- 2 , 36 , 125 , 157 , 176 , 223 , 175 , 234 , 116 , 94 , 248 , 201 , 225 , 97 , 235 , 50 , 47 , 115 , 172 ,
206
- 63 , 136 , 88 , 216 , 115 , 11 , 111 , 217 , 114 , 84 , 116 , 124 , 231 , 107 , 2 , 163 , 216 , 116 ,
207
- 204 , 120 , 152 , 52 , 172 , 208 , 143 , 140 , 71 , 242 , 209 , 153 , 111 , 23 , 61 , 222 , 28 , 106 ,
208
- 198 , 149 , 87 , 166 , 201 , 180 , 51 , 64 , 252 , 143 , 166 , 2 , 57 , 240 , 15 , 230 , 190 , 255 , 224 ,
209
- 70 , 176 , 137 , 155 , 249 , 125 , 20 , 170 , 114 , 97 , 221 , 142 , 89 , 231 , 233 , 205 , 126 , 199 ,
210
- 216 , 149 , 155 , 0 , 210 , 45 , 67 , 174 , 0 , 0 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 ,
211
- 166 , 162 , 70 , 174 , 99 , 247 , 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 ,
212
- 0 , 0 , 0 , 10 , 222 , 162 , 0 , 8 , 38 , 0 , 1 , 2 , 158 , 1 , 242 , 121 , 152 , 106 , 204 , 131 , 186 ,
213
- 35 , 93 , 70 , 216 , 10 , 237 , 224 , 183 , 89 , 95 , 65 , 3 , 83 , 185 , 58 , 138 , 181 , 64 , 187 , 103 ,
214
- 127 , 68 , 50 , 2 , 201 , 19 , 17 , 138 , 136 , 149 , 185 , 226 , 156 , 137 , 175 , 110 , 32 , 237 , 0 ,
215
- 217 , 90 , 31 , 100 , 228 , 149 , 46 , 219 , 175 , 168 , 77 , 4 , 143 , 38 , 128 , 76 , 97 , 2 , 155 , 9 ,
216
- 173 , 229 , 75 , 82 , 137 , 57 , 21 , 112 , 207 , 99 , 92 , 145 , 58 , 48 , 229 , 10 , 228 , 163 , 3 ,
217
- 106 , 147 , 39 , 177 , 90 , 242 , 186 , 249 , 11 , 210 , 54 , 2 , 212 , 16 , 225 , 46 , 42 , 209 , 254 ,
218
- 11 , 28 , 254 , 196 , 167 , 139 , 164 , 241 , 7 , 176 , 120 , 192 , 199 , 148 , 152 , 38 , 17 , 118 , 41 ,
219
- 122 , 240 , 223 , 249 , 158 , 145 , 2 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 1 , 27 , 1 , 0 , 40 , 0 , 0 , 0 ,
220
- 0 , 0 , 0 , 3 , 232 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 125 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 10 , 222 , 162 ,
221
- 0 , 8 , 38 , 0 , 1 , 1 , 27 , 1 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 3 , 232 , 0 , 0 , 0 , 1 , 0 ,
222
- 0 , 0 , 0 , 29 , 129 , 25 , 192 ,
223
- ] ;
224
- let server = HttpServer :: responding_with_server_error ( & valid_response[ ..] ) ;
225
-
226
- let block_hash = genesis_block ( Network :: Bitcoin ) . block_hash ( ) ;
227
- let network_graph = NetworkGraph :: new ( block_hash) ;
228
-
229
- let before = network_graph. to_string ( ) ;
230
- assert_eq ! ( before. len( ) , 31 ) ;
231
-
232
- let endpoint = & server. endpoint ( ) ;
233
- let sync_result = sync_network_graph_with_url (
234
- & network_graph,
235
- endpoint. host ( ) ,
236
- endpoint. port ( ) ,
237
- endpoint. path ( ) ,
238
- )
239
- . await ;
240
-
241
- let error_string = if let Err ( GraphSyncError :: IOError ( error) ) = sync_result {
242
- error. to_string ( )
243
- } else {
244
- assert ! ( false ) ;
245
- "" . to_string ( )
246
- } ;
247
-
248
- assert ! ( error_string. contains( "status_code: 500," ) ) ;
249
36
250
- let after = network_graph. to_string ( ) ;
251
- assert_eq ! ( after. len( ) , 31 ) ;
252
- }
253
-
254
- #[ tokio:: test]
255
- async fn test_http_request ( ) {
256
- let valid_response = vec ! [
257
- 76 , 68 , 75 , 2 , 2 , 0 , 0 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 ,
258
- 231 , 230 , 231 , 56 , 102 , 61 , 250 , 251 , 187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 ,
259
- 238 , 252 , 53 , 192 , 6 , 67 , 2 , 36 , 125 , 157 , 176 , 223 , 175 , 234 , 116 , 94 , 248 , 201 , 225 ,
260
- 97 , 235 , 50 , 47 , 115 , 172 , 63 , 136 , 88 , 216 , 115 , 11 , 111 , 217 , 114 , 84 , 116 , 124 , 231 ,
261
- 107 , 0 , 0 , 10 , 222 , 162 , 0 , 8 , 38 , 0 , 1 , 2 , 158 , 1 , 242 , 121 , 152 , 106 , 204 , 131 , 186 ,
262
- 35 , 93 , 70 , 216 , 10 , 237 , 224 , 183 , 89 , 95 , 65 , 3 , 83 , 185 , 58 , 138 , 181 , 64 , 187 , 103 ,
263
- 127 , 68 , 50 , 2 , 201 , 19 , 17 , 138 , 136 , 149 , 185 , 226 , 156 , 137 , 175 , 110 , 32 , 237 , 0 ,
264
- 217 , 90 , 31 , 100 , 228 , 149 , 46 , 219 , 175 , 168 , 77 , 4 , 143 , 38 , 128 , 76 , 97 , 2 , 8 , 153 ,
265
- 192 , 0 , 2 , 27 , 0 , 0 , 1 , 27 , 1 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 0 , 1 , 0 , 0 , 0 ,
266
- 125 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 10 , 222 , 162 , 0 , 8 , 38 , 0 , 1 , 1 , 27 , 1 , 0 , 40 , 0 , 0 ,
267
- 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 3 , 232 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 29 , 129 , 25 , 192 ,
268
- ] ;
269
- let server = HttpServer :: responding_with_ok ( & valid_response[ ..] ) ;
270
-
271
- let block_hash = genesis_block ( Network :: Bitcoin ) . block_hash ( ) ;
272
- let network_graph = NetworkGraph :: new ( block_hash) ;
273
-
274
- let before = network_graph. to_string ( ) ;
275
- assert_eq ! ( before. len( ) , 31 ) ;
276
-
277
- let endpoint = & server. endpoint ( ) ;
278
- let sync_result = sync_network_graph_with_url (
279
- & network_graph,
280
- endpoint. host ( ) ,
281
- endpoint. port ( ) ,
282
- endpoint. path ( ) ,
283
- )
284
- . await ;
285
-
286
- if !sync_result. is_ok ( ) {
287
- let error_string = match sync_result. as_ref ( ) . unwrap_err ( ) {
288
- GraphSyncError :: IOError ( error) => error. to_string ( ) ,
289
- GraphSyncError :: DecodeError ( error) => error. to_string ( ) ,
290
- GraphSyncError :: LightningError ( error) => ( & error. err ) . to_string ( ) ,
291
- GraphSyncError :: ProcessingError ( error) => error. to_string ( ) ,
292
- } ;
293
- println ! ( "Error: {}" , error_string) ;
294
- }
295
-
296
- assert ! ( sync_result. is_ok( ) ) ;
297
-
298
- let after = network_graph. to_string ( ) ;
299
- assert_eq ! ( after. len( ) , 1737 ) ;
300
- assert ! (
301
- after. contains( "021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643:" )
302
- ) ;
303
- assert ! (
304
- after. contains( "02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b:" )
305
- ) ;
306
- assert ! (
307
- after. contains( "029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432:" )
308
- ) ;
309
- assert ! (
310
- after. contains( "02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61:" )
311
- ) ;
312
- assert ! ( after. contains( "channels: [619737530008010752]" ) ) ;
313
- assert ! ( after. contains( "channels: [783241506229452801]" ) ) ;
314
- }
37
+ use crate :: { sync_network_graph_with_file_path} ;
315
38
316
39
#[ test]
317
40
fn test_sync_from_file ( ) {
0 commit comments