@@ -25,10 +25,10 @@ use core::convert::TryFrom;
2525use core:: fmt;
2626#[ cfg( feature = "std" ) ]
2727use std:: collections:: HashSet ;
28- use sha2:: { Sha256 , Digest } ;
2928
3029mod bytes;
3130mod hex;
31+ mod sha256;
3232
3333pub use self :: bytes:: Bytes ;
3434
@@ -70,6 +70,13 @@ pub enum Error {
7070 InvalidProtocolVersion ,
7171 /// Unsupported protocol version
7272 UnsupportedProtocolVersion ,
73+ /// Unexpected output
74+ UnexpectedOutput {
75+ /// Expected output
76+ expected : String ,
77+ /// Found output
78+ found : String ,
79+ } ,
7380}
7481
7582impl fmt:: Display for Error {
@@ -89,7 +96,14 @@ impl fmt::Display for Error {
8996 Self :: ParseEndsPrematurely => write ! ( f, "parse ends prematurely" ) ,
9097 Self :: DuplicateItemAdded => write ! ( f, "duplicate item added" ) ,
9198 Self :: InvalidProtocolVersion => write ! ( f, "invalid negentropy protocol version byte" ) ,
92- Self :: UnsupportedProtocolVersion => write ! ( f, "server does not support our negentropy protocol version" ) ,
99+ Self :: UnsupportedProtocolVersion => {
100+ write ! ( f, "server does not support our negentropy protocol version" )
101+ }
102+ Self :: UnexpectedOutput { expected, found } => write ! (
103+ f,
104+ "Unexpected output: expected={}, found={}" ,
105+ expected, found
106+ ) ,
93107 }
94108 }
95109}
@@ -221,7 +235,7 @@ impl Negentropy {
221235 }
222236
223237 Ok ( Self {
224- id_size : id_size ,
238+ id_size,
225239 frame_size_limit,
226240 added_items : Vec :: new ( ) ,
227241 item_timestamps : Vec :: new ( ) ,
@@ -270,15 +284,14 @@ impl Negentropy {
270284 & self . item_ids [ offset..( offset + self . id_size ) ]
271285 }
272286
273- fn get_item ( & self , i : usize ) -> Item {
274- Item :: with_timestamp_and_id ( self . item_timestamps [ i] , self . get_item_id ( i) ) . unwrap ( )
287+ fn get_item ( & self , i : usize ) -> Result < Item , Error > {
288+ Item :: with_timestamp_and_id ( self . item_timestamps [ i] , self . get_item_id ( i) )
275289 }
276290
277291 fn compute_fingerprint ( & self , lower : usize , num : usize ) -> Vec < u8 > {
278- let mut hasher = Sha256 :: new ( ) ;
279292 let offset = lower * self . id_size ;
280- hasher . update ( & self . item_ids [ offset..( offset + ( num * self . id_size ) ) ] ) ;
281- hasher . finalize ( ) . as_slice ( ) [ 0 .. self . id_size ] . to_vec ( )
293+ sha256 :: hash ( & self . item_ids [ offset..( offset + ( num * self . id_size ) ) ] ) [ 0 .. self . id_size ]
294+ . to_vec ( )
282295 }
283296
284297 /// Seal
@@ -336,38 +349,47 @@ impl Negentropy {
336349
337350 self . pending_outputs = outputs;
338351
339- Ok ( self . build_output ( true ) . unwrap ( ) . unwrap ( ) )
352+ self . build_output ( true ) ?. ok_or ( Error :: UnexpectedOutput {
353+ expected : String :: from ( "Initiate bytes" ) ,
354+ found : String :: from ( "None" ) ,
355+ } )
340356 }
341357
342358 /// Reconcile (server method)
343359 pub fn reconcile ( & mut self , query : & Bytes ) -> Result < Bytes , Error > {
344- let mut query: & [ u8 ] = query. as_ref ( ) ;
345-
346360 if self . is_initiator {
347361 return Err ( Error :: Initiator ) ;
348362 }
349363
364+ let mut query: & [ u8 ] = query. as_ref ( ) ;
365+
350366 if !self . did_handshake {
351367 let protocol_version = self . get_bytes ( & mut query, 1 ) ?[ 0 ] as u64 ;
352368
353- if protocol_version < 0x60 || protocol_version > 0x6F {
369+ if ! ( 0x60 ..= 0x6F ) . contains ( & protocol_version ) {
354370 return Err ( Error :: InvalidProtocolVersion ) ;
355371 }
356372
357373 if protocol_version != PROTOCOL_VERSION_0 {
358374 let mut o: Vec < u8 > = Vec :: new ( ) ;
359375 let mut last_timestamp_out: u64 = 0 ;
360- o. extend ( self . encode_bound ( & Item :: with_timestamp ( PROTOCOL_VERSION_0 ) , & mut last_timestamp_out) ) ;
376+ o. extend ( self . encode_bound (
377+ & Item :: with_timestamp ( PROTOCOL_VERSION_0 ) ,
378+ & mut last_timestamp_out,
379+ ) ) ;
361380 o. extend ( self . encode_mode ( Mode :: UnsupportedProtocolVersion ) ) ;
362381 return Ok ( Bytes :: from ( o) ) ;
363382 }
364383
365384 self . did_handshake = true ;
366385 }
367386
368- self . reconcile_aux ( & mut query, & mut Vec :: new ( ) , & mut Vec :: new ( ) ) ?;
387+ self . reconcile_aux ( query, & mut Vec :: new ( ) , & mut Vec :: new ( ) ) ?;
369388
370- Ok ( self . build_output ( false ) . unwrap ( ) . unwrap ( ) )
389+ self . build_output ( false ) ?. ok_or ( Error :: UnexpectedOutput {
390+ expected : String :: from ( "Reconcilie bytes" ) ,
391+ found : String :: from ( "None" ) ,
392+ } )
371393 }
372394
373395 /// Reconcile (client method)
@@ -377,14 +399,12 @@ impl Negentropy {
377399 have_ids : & mut Vec < Bytes > ,
378400 need_ids : & mut Vec < Bytes > ,
379401 ) -> Result < Option < Bytes > , Error > {
380- let mut query: & [ u8 ] = query. as_ref ( ) ;
381-
382402 if !self . is_initiator {
383403 return Err ( Error :: NonInitiator ) ;
384404 }
385405
386- self . reconcile_aux ( & mut query, have_ids , need_ids ) ? ;
387-
406+ let query: & [ u8 ] = query . as_ref ( ) ;
407+ self . reconcile_aux ( query , have_ids , need_ids ) ? ;
388408 self . build_output ( false )
389409 }
390410
@@ -415,17 +435,11 @@ impl Negentropy {
415435 match mode {
416436 Mode :: Skip => ( ) ,
417437 Mode :: Fingerprint => {
418- let their_fingerprint = self . get_bytes ( & mut query, self . id_size ) ?;
419- let our_fingerprint = self . compute_fingerprint ( lower, upper - lower) ;
438+ let their_fingerprint: Vec < u8 > = self . get_bytes ( & mut query, self . id_size ) ?;
439+ let our_fingerprint: Vec < u8 > = self . compute_fingerprint ( lower, upper - lower) ;
420440
421441 if their_fingerprint != our_fingerprint {
422- self . split_range (
423- lower,
424- upper,
425- prev_bound,
426- curr_bound,
427- & mut outputs,
428- ) ?;
442+ self . split_range ( lower, upper, prev_bound, curr_bound, & mut outputs) ?;
429443 }
430444 }
431445 Mode :: IdList => {
@@ -534,7 +548,7 @@ impl Negentropy {
534548 let next_split_bound: Item = if * it + 1 >= upper {
535549 * curr_bound
536550 } else {
537- self . get_minimal_bound ( & self . get_item ( * it) , & self . get_item ( * it + 1 ) ) ?
551+ self . get_minimal_bound ( & self . get_item ( * it) ? , & self . get_item ( * it + 1 ) ? ) ?
538552 } ;
539553
540554 outputs. push_back ( OutputRange {
@@ -579,10 +593,11 @@ impl Negentropy {
579593 let items_per_bucket: usize = num_elems / BUCKETS ;
580594 let buckets_with_extra: usize = num_elems % BUCKETS ;
581595 let mut curr: usize = lower;
582- let mut prev_bound = self . get_item ( lower) ;
596+ let mut prev_bound: Item = self . get_item ( lower) ? ;
583597
584598 for i in 0 ..BUCKETS {
585- let bucket_size: usize = items_per_bucket + ( if i < buckets_with_extra { 1 } else { 0 } ) ;
599+ let bucket_size: usize =
600+ items_per_bucket + ( if i < buckets_with_extra { 1 } else { 0 } ) ;
586601 let our_fingerprint = self . compute_fingerprint ( curr, bucket_size) ;
587602 curr += bucket_size;
588603
@@ -595,7 +610,7 @@ impl Negentropy {
595610 end : if curr == upper {
596611 upper_bound
597612 } else {
598- self . get_minimal_bound ( & self . get_item ( curr - 1 ) , & self . get_item ( curr) ) ?
613+ self . get_minimal_bound ( & self . get_item ( curr - 1 ) ? , & self . get_item ( curr) ? ) ?
599614 } ,
600615 payload,
601616 } ) ;
@@ -690,7 +705,7 @@ impl Negentropy {
690705 if cond {
691706 count = step;
692707 } else {
693- it = it + 1 ;
708+ it += 1 ;
694709 first = it;
695710 count -= step + 1 ;
696711 }
@@ -805,7 +820,7 @@ impl Negentropy {
805820 } else {
806821 let mut shared_prefix_bytes: usize = 0 ;
807822 for i in 0 ..prev. id_size ( ) . min ( curr. id_size ( ) ) {
808- if curr. id [ i as usize ] != prev. id [ i as usize ] {
823+ if curr. id [ i] != prev. id [ i] {
809824 break ;
810825 }
811826 shared_prefix_bytes += 1 ;
@@ -922,7 +937,7 @@ mod benches {
922937
923938 use super :: { Bytes , Negentropy } ;
924939
925- const ID_SIZE : u8 = 16 ;
940+ const ID_SIZE : usize = 16 ;
926941 const FRAME_SIZE_LIMIT : Option < u64 > = None ;
927942 const ITEMS_LEN : usize = 100_000 ;
928943
@@ -938,51 +953,6 @@ mod benches {
938953 } ) ;
939954 }
940955
941- #[ bench]
942- pub fn initiate_100_000_items ( bh : & mut Bencher ) {
943- let mut client = Negentropy :: new ( ID_SIZE , FRAME_SIZE_LIMIT ) . unwrap ( ) ;
944- for ( index, item) in generate_combinations ( "abc" , 32 , ITEMS_LEN )
945- . into_iter ( )
946- . enumerate ( )
947- {
948- client
949- . add_item ( index as u64 , Bytes :: from_hex ( item) . unwrap ( ) )
950- . unwrap ( ) ;
951- }
952- client. seal ( ) . unwrap ( ) ;
953- bh. iter ( || {
954- black_box ( client. initiate ( ) ) . unwrap ( ) ;
955- } ) ;
956- }
957-
958- #[ bench]
959- pub fn reconcile_100_000_items ( bh : & mut Bencher ) {
960- // Client
961- let mut client = Negentropy :: new ( ID_SIZE , FRAME_SIZE_LIMIT ) . unwrap ( ) ;
962- for ( index, item) in generate_combinations ( "abc" , 32 , 2 ) . into_iter ( ) . enumerate ( ) {
963- client
964- . add_item ( index as u64 , Bytes :: from_hex ( item) . unwrap ( ) )
965- . unwrap ( ) ;
966- }
967- client. seal ( ) . unwrap ( ) ;
968- let init_output = client. initiate ( ) . unwrap ( ) ;
969-
970- let mut relay = Negentropy :: new ( ID_SIZE , FRAME_SIZE_LIMIT ) . unwrap ( ) ;
971- for ( index, item) in generate_combinations ( "abc" , 32 , ITEMS_LEN )
972- . into_iter ( )
973- . enumerate ( )
974- {
975- relay
976- . add_item ( index as u64 , Bytes :: from_hex ( item) . unwrap ( ) )
977- . unwrap ( ) ;
978- }
979- relay. seal ( ) . unwrap ( ) ;
980-
981- bh. iter ( || {
982- black_box ( relay. reconcile ( & init_output) ) . unwrap ( ) ;
983- } ) ;
984- }
985-
986956 #[ bench]
987957 pub fn final_reconciliation_100_000_items ( bh : & mut Bencher ) {
988958 // Client
0 commit comments