@@ -18,12 +18,24 @@ impl EventScannerBuilder<LatestEvents> {
1818 self
1919 }
2020
21+ /// Sets the starting block for the historic scan.
22+ ///
23+ /// # Note
24+ ///
25+ /// Although passing `BlockNumberOrTag::Pending` will compile, the subsequent call to
26+ /// `connect` will fail at runtime. See issue <https://github.com/OpenZeppelin/Event-Scanner/issues/244>
2127 #[ must_use]
2228 pub fn from_block ( mut self , block_id : impl Into < BlockId > ) -> Self {
2329 self . config . from_block = block_id. into ( ) ;
2430 self
2531 }
2632
33+ /// Sets the starting block for the historic scan.
34+ ///
35+ /// # Note
36+ ///
37+ /// Although passing `BlockNumberOrTag::Pending` will compile, the subsequent call to
38+ /// `connect` will fail at runtime. See issue <https://github.com/OpenZeppelin/Event-Scanner/issues/244>
2739 #[ must_use]
2840 pub fn to_block ( mut self , block_id : impl Into < BlockId > ) -> Self {
2941 self . config . to_block = block_id. into ( ) ;
@@ -52,7 +64,17 @@ impl EventScannerBuilder<LatestEvents> {
5264 let latest_block = provider. get_block_number ( ) . await ?;
5365
5466 let from_num = match scanner. config . from_block {
55- BlockId :: Number ( from_block) => from_block. as_number ( ) . unwrap_or ( 0 ) ,
67+ BlockId :: Number ( from_block) => {
68+ if from_block. is_pending ( ) {
69+ return Err ( ScannerError :: BlockExceedsLatest (
70+ "from_block" ,
71+ latest_block + 1 ,
72+ latest_block,
73+ ) ) ;
74+ }
75+ // can safely unwrap to 0 because any other tag < latest block
76+ from_block. as_number ( ) . unwrap_or ( 0 )
77+ }
5678 BlockId :: Hash ( from_hash) => {
5779 provider. get_block_by_hash ( from_hash. into ( ) ) . await ?. header ( ) . number ( )
5880 }
@@ -63,7 +85,17 @@ impl EventScannerBuilder<LatestEvents> {
6385 }
6486
6587 let to_num = match scanner. config . to_block {
66- BlockId :: Number ( to_block) => to_block. as_number ( ) . unwrap_or ( 0 ) ,
88+ BlockId :: Number ( to_block) => {
89+ if to_block. is_pending ( ) {
90+ return Err ( ScannerError :: BlockExceedsLatest (
91+ "to_block" ,
92+ latest_block + 1 ,
93+ latest_block,
94+ ) ) ;
95+ }
96+ // can safely unwrap to 0 because any other tag < latest block
97+ to_block. as_number ( ) . unwrap_or ( 0 )
98+ }
6799 BlockId :: Hash ( to_hash) => {
68100 provider. get_block_by_hash ( to_hash. into ( ) ) . await ?. header ( ) . number ( )
69101 }
@@ -366,4 +398,71 @@ mod tests {
366398 _ => panic ! ( "Expected BlockExceedsLatest error for 'from_block'" ) ,
367399 }
368400 }
401+
402+ #[ tokio:: test]
403+ async fn test_from_block_pending_returns_error ( ) {
404+ let anvil = Anvil :: new ( ) . try_spawn ( ) . unwrap ( ) ;
405+ let provider = ProviderBuilder :: new ( ) . connect_http ( anvil. endpoint_url ( ) ) ;
406+
407+ let latest_block = provider. get_block_number ( ) . await . unwrap ( ) ;
408+
409+ let result = EventScannerBuilder :: latest ( 1 )
410+ . from_block ( BlockNumberOrTag :: Pending )
411+ . to_block ( latest_block)
412+ . connect ( provider)
413+ . await ;
414+
415+ match result {
416+ Err ( ScannerError :: BlockExceedsLatest ( "from_block" , max, latest) ) => {
417+ assert_eq ! ( max, latest_block + 1 ) ;
418+ assert_eq ! ( latest, latest_block) ;
419+ }
420+ _ => panic ! ( "Expected BlockExceedsLatest error for 'from_block'" ) ,
421+ }
422+ }
423+
424+ #[ tokio:: test]
425+ async fn test_to_block_pending_returns_error ( ) {
426+ let anvil = Anvil :: new ( ) . try_spawn ( ) . unwrap ( ) ;
427+ let provider = ProviderBuilder :: new ( ) . connect_http ( anvil. endpoint_url ( ) ) ;
428+
429+ let latest_block = provider. get_block_number ( ) . await . unwrap ( ) ;
430+
431+ let result = EventScannerBuilder :: latest ( 1 )
432+ . from_block ( 0 )
433+ . to_block ( BlockNumberOrTag :: Pending )
434+ . connect ( provider)
435+ . await ;
436+
437+ match result {
438+ Err ( ScannerError :: BlockExceedsLatest ( "to_block" , max, latest) ) => {
439+ assert_eq ! ( max, latest_block + 1 ) ;
440+ assert_eq ! ( latest, latest_block) ;
441+ }
442+ _ => panic ! ( "Expected BlockExceedsLatest error for 'to_block'" ) ,
443+ }
444+ }
445+
446+ #[ tokio:: test]
447+ async fn test_from_and_to_block_pending_returns_error ( ) {
448+ let anvil = Anvil :: new ( ) . try_spawn ( ) . unwrap ( ) ;
449+ let provider = ProviderBuilder :: new ( ) . connect_http ( anvil. endpoint_url ( ) ) ;
450+
451+ let latest_block = provider. get_block_number ( ) . await . unwrap ( ) ;
452+
453+ let result = EventScannerBuilder :: latest ( 1 )
454+ . from_block ( BlockNumberOrTag :: Pending )
455+ . to_block ( BlockNumberOrTag :: Pending )
456+ . connect ( provider)
457+ . await ;
458+
459+ // from_block is checked first
460+ match result {
461+ Err ( ScannerError :: BlockExceedsLatest ( "from_block" , max, latest) ) => {
462+ assert_eq ! ( max, latest_block + 1 ) ;
463+ assert_eq ! ( latest, latest_block) ;
464+ }
465+ _ => panic ! ( "Expected BlockExceedsLatest error for 'from_block'" ) ,
466+ }
467+ }
369468}
0 commit comments