1
1
use core:: ops:: Deref ;
2
2
use std:: io;
3
3
use std:: io:: Read ;
4
- use lightning:: chain;
5
4
5
+ use lightning:: chain;
6
6
use lightning:: ln:: msgs;
7
7
use lightning:: ln:: wire:: encode:: Encode ;
8
8
use lightning:: routing:: network_graph;
9
- use lightning:: util:: ser:: { BigSize , FixedLengthReader , Readable } ;
9
+ use lightning:: util:: ser:: { BigSize , Readable } ;
10
10
11
11
use crate :: error:: GraphSyncError ;
12
12
13
- pub fn update_network_graph < CS : Deref > ( network_graph : & network_graph:: NetworkGraph , update_data : & [ u8 ] , chain_source : & Option < CS > ) -> Result < ( ) , GraphSyncError > where CS :: Target : chain:: Access {
14
- let total_input_length = update_data. len ( ) as u64 ;
13
+ pub fn update_network_graph < CS : Deref > (
14
+ network_graph : & network_graph:: NetworkGraph ,
15
+ update_data : & [ u8 ] ,
16
+ chain_source : & Option < CS > ,
17
+ ) -> Result < ( ) , GraphSyncError >
18
+ where
19
+ CS :: Target : chain:: Access ,
20
+ {
15
21
let mut read_cursor = io:: Cursor :: new ( update_data) ;
22
+ read_network_graph ( & network_graph, & mut read_cursor, & chain_source)
23
+ }
16
24
25
+ pub ( crate ) fn read_network_graph < R : Read , CS : Deref > (
26
+ network_graph : & network_graph:: NetworkGraph ,
27
+ read_cursor : & mut R ,
28
+ chain_source : & Option < CS > ,
29
+ ) -> Result < ( ) , GraphSyncError >
30
+ where
31
+ CS :: Target : chain:: Access ,
32
+ {
17
33
let mut prefix = Vec :: with_capacity ( 4 ) ;
18
34
prefix. resize ( 4 , 0 ) ;
19
35
read_cursor. read_exact ( & mut prefix) ?;
20
36
21
37
let _deserialize_unsigned = match & prefix[ ..] {
22
38
& [ 71 , 83 , 80 , 1 ] => {
23
- return Err ( GraphSyncError :: ProcessingError ( "Signed deserialization not supported" . to_string ( ) ) ) ;
39
+ return Err ( GraphSyncError :: ProcessingError (
40
+ "Signed deserialization not supported" . to_string ( ) ,
41
+ ) ) ;
24
42
}
25
43
& [ 76 , 68 , 75 , 2 ] => true ,
26
44
_ => {
27
- return Err ( GraphSyncError :: ProcessingError ( "Prefix must equal 'LDK' and the byte 2" . to_string ( ) ) ) ;
45
+ return Err ( GraphSyncError :: ProcessingError (
46
+ "Prefix must equal 'LDK' and the byte 2" . to_string ( ) ,
47
+ ) ) ;
28
48
}
29
49
} ;
30
50
51
+ // shadow variable for ownership release after length-restricted reads
52
+ let mut read_cursor = read_cursor;
31
53
loop {
32
- let message_length: BigSize = Readable :: read ( & mut read_cursor) ?;
33
- let mut restricted_cursor = FixedLengthReader :: new ( & mut read_cursor, message_length. 0 ) ;
54
+ let message_length_result = Readable :: read ( read_cursor) ;
55
+ let message_length: BigSize = if let Ok ( message_length) = message_length_result {
56
+ message_length
57
+ } else if let Err ( msgs:: DecodeError :: ShortRead ) = message_length_result {
58
+ break ;
59
+ } else {
60
+ return Err ( message_length_result. err ( ) . unwrap ( ) . into ( ) ) ;
61
+ } ;
62
+ // let mut restricted_cursor = FixedLengthReader::new(&read_cursor, message_length.0);
63
+ let mut restricted_cursor = read_cursor. take ( message_length. 0 ) ;
34
64
35
65
let message_type: u16 = Readable :: read ( & mut restricted_cursor) ?;
36
66
@@ -60,10 +90,62 @@ pub fn update_network_graph<CS: Deref>(network_graph: &network_graph::NetworkGra
60
90
// propagate the error
61
91
let _update = update_result?;
62
92
63
- if read_cursor. position ( ) == total_input_length {
64
- break ;
65
- }
93
+ read_cursor = restricted_cursor. into_inner ( ) ;
66
94
}
67
95
68
96
Ok ( ( ) )
69
- }
97
+ }
98
+
99
+ #[ cfg( test) ]
100
+ mod tests {
101
+ use bitcoin:: blockdata:: constants:: genesis_block;
102
+ use bitcoin:: Network ;
103
+
104
+ use lightning:: routing:: network_graph:: NetworkGraph ;
105
+
106
+ use crate :: processing:: update_network_graph;
107
+
108
+ #[ test]
109
+ fn network_graph_updates_from_example_binary_input ( ) {
110
+ let block_hash = genesis_block ( Network :: Bitcoin ) . block_hash ( ) ;
111
+ let network_graph = NetworkGraph :: new ( block_hash) ;
112
+
113
+ let before = network_graph. to_string ( ) ;
114
+ assert_eq ! ( before. len( ) , 31 ) ;
115
+
116
+ let chain_source: Option < Box < dyn lightning:: chain:: Access > > = None ;
117
+
118
+ let example_input = vec ! [
119
+ 76 , 68 , 75 , 2 , 176 , 1 , 0 , 0 , 0 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 ,
120
+ 70 , 174 , 99 , 247 , 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 ,
121
+ 10 , 209 , 73 , 0 , 2 , 144 , 0 , 0 , 2 , 96 , 250 , 182 , 51 , 6 , 110 , 215 , 177 , 217 , 185 , 184 ,
122
+ 160 , 250 , 200 , 126 , 21 , 121 , 209 , 112 , 158 , 135 , 77 , 40 , 160 , 209 , 113 , 161 , 245 , 196 ,
123
+ 59 , 184 , 119 , 2 , 180 , 101 , 113 , 124 , 204 , 150 , 157 , 103 , 192 , 42 , 110 , 145 , 224 , 176 ,
124
+ 14 , 26 , 197 , 136 , 6 , 143 , 13 , 46 , 3 , 200 , 220 , 34 , 228 , 191 , 104 , 238 , 134 , 80 , 3 , 167 ,
125
+ 152 , 93 , 150 , 15 , 179 , 70 , 61 , 160 , 42 , 198 , 253 , 53 , 249 , 37 , 29 , 21 , 176 , 28 , 136 ,
126
+ 240 , 237 , 138 , 165 , 218 , 254 , 14 , 245 , 123 , 228 , 145 , 150 , 2 , 25 , 120 , 160 , 148 , 15 ,
127
+ 56 , 179 , 42 , 198 , 99 , 96 , 81 , 85 , 53 , 227 , 51 , 62 , 134 , 4 , 175 , 0 , 151 , 217 , 104 , 180 ,
128
+ 201 , 249 , 117 , 196 , 87 , 94 , 150 , 74 , 1 , 2 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 ,
129
+ 166 , 162 , 70 , 174 , 99 , 247 , 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 ,
130
+ 0 , 0 , 0 , 10 , 209 , 73 , 0 , 2 , 144 , 0 , 0 , 97 , 139 , 55 , 91 , 1 , 2 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 ,
131
+ 3 , 232 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 100 , 0 , 0 , 0 , 0 , 123 , 235 , 5 , 192 , 74 , 1 , 2 , 111 , 226 ,
132
+ 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 , 174 , 99 , 247 , 79 , 147 , 30 , 131 , 101 ,
133
+ 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 10 , 209 , 73 , 0 , 2 , 144 , 0 , 0 , 97 , 138 ,
134
+ 144 , 189 , 1 , 1 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 0 , 0 , 0 , 0 , 5 , 220 , 0 , 0 , 0 , 0 ,
135
+ 123 , 235 , 5 , 192 ,
136
+ ] ;
137
+ let update_result = update_network_graph ( & network_graph, & example_input[ ..] , & chain_source) ;
138
+ assert ! ( update_result. is_ok( ) ) ;
139
+
140
+ let after = network_graph. to_string ( ) ;
141
+ assert_eq ! ( after. len( ) , 1132 ) ;
142
+ assert ! ( after. contains( "779484474903625728: features: 0000" ) ) ;
143
+ assert ! ( after. contains(
144
+ "node_one: 0260fab633066ed7b1d9b9b8a0fac87e1579d1709e874d28a0d171a1f5c43bb877"
145
+ ) ) ;
146
+ assert ! ( after. contains(
147
+ "node_two: 02b465717ccc969d67c02a6e91e0b00e1ac588068f0d2e03c8dc22e4bf68ee8650"
148
+ ) ) ;
149
+ assert ! ( after. contains( "channels: [779484474903625728]" ) ) ;
150
+ }
151
+ }
0 commit comments