1
1
extern crate bitcoin;
2
+ extern crate crypto;
2
3
extern crate lightning;
3
4
extern crate secp256k1;
4
5
5
- use bitcoin:: blockdata:: transaction:: Transaction ;
6
+ use bitcoin:: blockdata:: block:: BlockHeader ;
7
+ use bitcoin:: blockdata:: transaction:: { Transaction , TxOut } ;
8
+ use bitcoin:: blockdata:: script:: Script ;
6
9
use bitcoin:: network:: constants:: Network ;
10
+ use bitcoin:: network:: serialize:: { serialize, BitcoinHash } ;
7
11
use bitcoin:: util:: hash:: Sha256dHash ;
12
+ use bitcoin:: util:: uint:: Uint256 ;
8
13
9
- use lightning:: chain:: chaininterface:: { BroadcasterInterface , ConfirmationTarget , FeeEstimator , ChainWatchInterfaceUtil } ;
14
+ use crypto:: sha2:: Sha256 ;
15
+ use crypto:: digest:: Digest ;
16
+
17
+ use lightning:: chain:: chaininterface:: { BroadcasterInterface , ConfirmationTarget , ChainListener , FeeEstimator , ChainWatchInterfaceUtil } ;
10
18
use lightning:: ln:: { channelmonitor, msgs} ;
11
19
use lightning:: ln:: channelmanager:: ChannelManager ;
12
20
use lightning:: ln:: peer_handler:: { MessageHandler , PeerManager , SocketDescriptor } ;
13
21
use lightning:: ln:: router:: Router ;
22
+ use lightning:: util:: events:: { EventsProvider , Event } ;
23
+ use lightning:: util:: reset_rng_state;
14
24
15
25
use secp256k1:: key:: { PublicKey , SecretKey } ;
16
26
use secp256k1:: Secp256k1 ;
17
27
28
+ use std:: collections:: HashMap ;
18
29
use std:: sync:: Arc ;
19
30
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
20
31
@@ -24,6 +35,13 @@ pub fn slice_to_be16(v: &[u8]) -> u16 {
24
35
( ( v[ 1 ] as u16 ) << 8 * 0 )
25
36
}
26
37
38
+ #[ inline]
39
+ pub fn slice_to_be24 ( v : & [ u8 ] ) -> u32 {
40
+ ( ( v[ 0 ] as u32 ) << 8 * 2 ) |
41
+ ( ( v[ 1 ] as u32 ) << 8 * 1 ) |
42
+ ( ( v[ 2 ] as u32 ) << 8 * 0 )
43
+ }
44
+
27
45
#[ inline]
28
46
pub fn slice_to_be32 ( v : & [ u8 ] ) -> u32 {
29
47
( ( v[ 0 ] as u32 ) << 8 * 3 ) |
@@ -32,6 +50,20 @@ pub fn slice_to_be32(v: &[u8]) -> u32 {
32
50
( ( v[ 3 ] as u32 ) << 8 * 0 )
33
51
}
34
52
53
+ #[ inline]
54
+ pub fn be64_to_array ( u : u64 ) -> [ u8 ; 8 ] {
55
+ let mut v = [ 0 ; 8 ] ;
56
+ v[ 0 ] = ( ( u >> 8 * 7 ) & 0xff ) as u8 ;
57
+ v[ 1 ] = ( ( u >> 8 * 6 ) & 0xff ) as u8 ;
58
+ v[ 2 ] = ( ( u >> 8 * 5 ) & 0xff ) as u8 ;
59
+ v[ 3 ] = ( ( u >> 8 * 4 ) & 0xff ) as u8 ;
60
+ v[ 4 ] = ( ( u >> 8 * 3 ) & 0xff ) as u8 ;
61
+ v[ 5 ] = ( ( u >> 8 * 2 ) & 0xff ) as u8 ;
62
+ v[ 6 ] = ( ( u >> 8 * 1 ) & 0xff ) as u8 ;
63
+ v[ 7 ] = ( ( u >> 8 * 0 ) & 0xff ) as u8 ;
64
+ v
65
+ }
66
+
35
67
struct InputData {
36
68
data : Vec < u8 > ,
37
69
read_pos : AtomicUsize ,
@@ -44,13 +76,6 @@ impl InputData {
44
76
}
45
77
Some ( & self . data [ old_pos..old_pos + len] )
46
78
}
47
- fn get_slice_nonadvancing ( & self , len : usize ) -> Option < & [ u8 ] > {
48
- let old_pos = self . read_pos . load ( Ordering :: Acquire ) ;
49
- if self . data . len ( ) < old_pos + len {
50
- return None ;
51
- }
52
- Some ( & self . data [ old_pos..old_pos + len] )
53
- }
54
79
}
55
80
56
81
struct FuzzEstimator {
@@ -92,6 +117,8 @@ impl SocketDescriptor for Peer {
92
117
93
118
#[ inline]
94
119
pub fn do_test ( data : & [ u8 ] ) {
120
+ reset_rng_state ( ) ;
121
+
95
122
let input = Arc :: new ( InputData {
96
123
data : data. to_vec ( ) ,
97
124
read_pos : AtomicUsize :: new ( 0 ) ,
@@ -137,6 +164,12 @@ pub fn do_test(data: &[u8]) {
137
164
} , our_network_key) ;
138
165
139
166
let mut peers = [ false ; 256 ] ;
167
+ let mut should_forward = false ;
168
+ let mut payments_received = Vec :: new ( ) ;
169
+ let mut payments_sent = 0 ;
170
+ let mut pending_funding_generation: Vec < ( Uint256 , u64 , Script ) > = Vec :: new ( ) ;
171
+ let mut pending_funding_signatures = HashMap :: new ( ) ;
172
+ let mut pending_funding_relay = Vec :: new ( ) ;
140
173
141
174
loop {
142
175
match get_slice ! ( 1 ) [ 0 ] {
@@ -178,8 +211,122 @@ pub fn do_test(data: &[u8]) {
178
211
Err ( _) => { peers[ peer_id as usize ] = false ; }
179
212
}
180
213
} ,
214
+ 4 => {
215
+ let value = slice_to_be24 ( get_slice ! ( 3 ) ) as u64 ;
216
+ let route = match router. get_route ( & get_pubkey ! ( ) , & Vec :: new ( ) , value, 42 ) {
217
+ Ok ( route) => route,
218
+ Err ( _) => return ,
219
+ } ;
220
+ let mut payment_hash = [ 0 ; 32 ] ;
221
+ payment_hash[ 0 ..8 ] . copy_from_slice ( & be64_to_array ( payments_sent) ) ;
222
+ let mut sha = Sha256 :: new ( ) ;
223
+ sha. input ( & payment_hash) ;
224
+ sha. result ( & mut payment_hash) ;
225
+ for i in 1 ..32 { payment_hash[ i] = 0 ; }
226
+ payments_sent += 1 ;
227
+ match channelmanager. send_payment ( route, payment_hash) {
228
+ Ok ( _) => { } ,
229
+ Err ( _) => return ,
230
+ }
231
+ } ,
232
+ 5 => {
233
+ let peer_id = get_slice ! ( 1 ) [ 0 ] ;
234
+ if !peers[ peer_id as usize ] { return ; }
235
+ let their_key = get_pubkey ! ( ) ;
236
+ let chan_value = slice_to_be24 ( get_slice ! ( 3 ) ) as u64 ;
237
+ if channelmanager. create_channel ( their_key, chan_value, 0 ) . is_err ( ) { return ; }
238
+ } ,
239
+ 6 => {
240
+ let mut channels = channelmanager. list_channels ( ) ;
241
+ let channel_id = get_slice ! ( 1 ) [ 0 ] as usize ;
242
+ if channel_id >= channels. len ( ) { return ; }
243
+ channels. sort_by ( |a, b| { a. channel_id . cmp ( & b. channel_id ) } ) ;
244
+ if channelmanager. close_channel ( & channels[ channel_id] . channel_id ) . is_err ( ) { return ; }
245
+ } ,
246
+ 7 => {
247
+ if should_forward {
248
+ channelmanager. process_pending_htlc_forward ( ) ;
249
+ handler. process_events ( ) ;
250
+ should_forward = false ;
251
+ }
252
+ } ,
253
+ 8 => {
254
+ for payment in payments_received. drain ( ..) {
255
+ let mut payment_preimage = None ;
256
+ for i in 0 ..payments_sent {
257
+ let mut payment_hash = [ 0 ; 32 ] ;
258
+ payment_hash[ 0 ..8 ] . copy_from_slice ( & be64_to_array ( i) ) ;
259
+ let mut sha = Sha256 :: new ( ) ;
260
+ sha. input ( & payment_hash) ;
261
+ sha. result ( & mut payment_hash) ;
262
+ for i in 1 ..32 { payment_hash[ i] = 0 ; }
263
+ if payment_hash == payment {
264
+ payment_hash = [ 0 ; 32 ] ;
265
+ payment_hash[ 0 ..8 ] . copy_from_slice ( & be64_to_array ( i) ) ;
266
+ payment_preimage = Some ( payment_hash) ;
267
+ break ;
268
+ }
269
+ }
270
+ channelmanager. claim_funds ( payment_preimage. unwrap ( ) ) ;
271
+ }
272
+ } ,
273
+ 9 => {
274
+ for payment in payments_received. drain ( ..) {
275
+ channelmanager. fail_htlc_backwards ( & payment) ;
276
+ }
277
+ } ,
278
+ 10 => {
279
+ for funding_generation in pending_funding_generation. drain ( ..) {
280
+ let mut tx = Transaction { version : 0 , lock_time : 0 , input : Vec :: new ( ) , output : vec ! [ TxOut {
281
+ value: funding_generation. 1 , script_pubkey: funding_generation. 2 ,
282
+ } ] } ;
283
+ let funding_output = ( Sha256dHash :: from_data ( & serialize ( & tx) . unwrap ( ) [ ..] ) , 0 ) ;
284
+ channelmanager. funding_transaction_generated ( & funding_generation. 0 , funding_output. clone ( ) ) ;
285
+ pending_funding_signatures. insert ( funding_output, tx) ;
286
+ }
287
+ } ,
288
+ 11 => {
289
+ if !pending_funding_relay. is_empty ( ) {
290
+ let mut txn = Vec :: with_capacity ( pending_funding_relay. len ( ) ) ;
291
+ let mut txn_idxs = Vec :: with_capacity ( pending_funding_relay. len ( ) ) ;
292
+ for ( idx, tx) in pending_funding_relay. iter ( ) . enumerate ( ) {
293
+ txn. push ( tx) ;
294
+ txn_idxs. push ( idx as u32 + 1 ) ;
295
+ }
296
+
297
+ let mut header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
298
+ channelmanager. block_connected ( & header, 1 , & txn[ ..] , & txn_idxs[ ..] ) ;
299
+ txn. clear ( ) ;
300
+ txn_idxs. clear ( ) ;
301
+ for i in 2 ..100 {
302
+ header = BlockHeader { version : 0x20000000 , prev_blockhash : header. bitcoin_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
303
+ channelmanager. block_connected ( & header, i, & txn[ ..] , & txn_idxs[ ..] ) ;
304
+ }
305
+ }
306
+ pending_funding_relay. clear ( ) ;
307
+ } ,
181
308
_ => return ,
182
309
}
310
+ for event in handler. get_and_clear_pending_events ( ) {
311
+ match event {
312
+ Event :: FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => {
313
+ pending_funding_generation. push ( ( temporary_channel_id, channel_value_satoshis, output_script) ) ;
314
+ } ,
315
+ Event :: FundingBroadcastSafe { funding_txo, .. } => {
316
+ pending_funding_relay. push ( pending_funding_signatures. remove ( & funding_txo) . unwrap ( ) ) ;
317
+ } ,
318
+ Event :: PaymentReceived { payment_hash, .. } => {
319
+ payments_received. push ( payment_hash) ;
320
+ } ,
321
+ Event :: PaymentSent { ..} => { } ,
322
+ Event :: PaymentFailed { ..} => { } ,
323
+
324
+ Event :: PendingHTLCsForwardable { ..} => {
325
+ should_forward = true ;
326
+ } ,
327
+ _ => panic ! ( "Unknown event" ) ,
328
+ }
329
+ }
183
330
}
184
331
}
185
332
0 commit comments