@@ -3,7 +3,9 @@ use ssz_types::VariableList;
3
3
use std:: { collections:: VecDeque , sync:: Arc } ;
4
4
use types:: { BlobSidecar , EthSpec , SignedBeaconBlock } ;
5
5
6
- #[ derive( Debug , Default ) ]
6
+ use super :: range_sync:: ByRangeRequestType ;
7
+
8
+ #[ derive( Debug ) ]
7
9
pub struct BlocksAndBlobsRequestInfo < E : EthSpec > {
8
10
/// Blocks we have received awaiting for their corresponding sidecar.
9
11
accumulated_blocks : VecDeque < Arc < SignedBeaconBlock < E > > > ,
@@ -13,9 +15,25 @@ pub struct BlocksAndBlobsRequestInfo<E: EthSpec> {
13
15
is_blocks_stream_terminated : bool ,
14
16
/// Whether the individual RPC request for sidecars is finished or not.
15
17
is_sidecars_stream_terminated : bool ,
18
+ /// Used to determine if this accumulator should wait for a sidecars stream termination
19
+ request_type : ByRangeRequestType ,
16
20
}
17
21
18
22
impl < E : EthSpec > BlocksAndBlobsRequestInfo < E > {
23
+ pub fn new ( request_type : ByRangeRequestType ) -> Self {
24
+ Self {
25
+ accumulated_blocks : <_ >:: default ( ) ,
26
+ accumulated_sidecars : <_ >:: default ( ) ,
27
+ is_blocks_stream_terminated : <_ >:: default ( ) ,
28
+ is_sidecars_stream_terminated : <_ >:: default ( ) ,
29
+ request_type,
30
+ }
31
+ }
32
+
33
+ pub fn get_request_type ( & self ) -> ByRangeRequestType {
34
+ self . request_type
35
+ }
36
+
19
37
pub fn add_block_response ( & mut self , block_opt : Option < Arc < SignedBeaconBlock < E > > > ) {
20
38
match block_opt {
21
39
Some ( block) => self . accumulated_blocks . push_back ( block) ,
@@ -78,6 +96,38 @@ impl<E: EthSpec> BlocksAndBlobsRequestInfo<E> {
78
96
}
79
97
80
98
pub fn is_finished ( & self ) -> bool {
81
- self . is_blocks_stream_terminated && self . is_sidecars_stream_terminated
99
+ let blobs_requested = match self . request_type {
100
+ ByRangeRequestType :: Blocks => false ,
101
+ ByRangeRequestType :: BlocksAndBlobs => true ,
102
+ } ;
103
+ self . is_blocks_stream_terminated && ( !blobs_requested || self . is_sidecars_stream_terminated )
104
+ }
105
+ }
106
+
107
+ #[ cfg( test) ]
108
+ mod tests {
109
+ use super :: BlocksAndBlobsRequestInfo ;
110
+ use crate :: sync:: range_sync:: ByRangeRequestType ;
111
+ use beacon_chain:: test_utils:: { generate_rand_block_and_blobs, NumBlobs } ;
112
+ use rand:: SeedableRng ;
113
+ use types:: { test_utils:: XorShiftRng , ForkName , MinimalEthSpec as E } ;
114
+
115
+ #[ test]
116
+ fn no_blobs_into_responses ( ) {
117
+ let mut info = BlocksAndBlobsRequestInfo :: < E > :: new ( ByRangeRequestType :: Blocks ) ;
118
+ let mut rng = XorShiftRng :: from_seed ( [ 42 ; 16 ] ) ;
119
+ let blocks = ( 0 ..4 )
120
+ . map ( |_| generate_rand_block_and_blobs :: < E > ( ForkName :: Base , NumBlobs :: None , & mut rng) . 0 )
121
+ . collect :: < Vec < _ > > ( ) ;
122
+
123
+ // Send blocks and complete terminate response
124
+ for block in blocks {
125
+ info. add_block_response ( Some ( block. into ( ) ) ) ;
126
+ }
127
+ info. add_block_response ( None ) ;
128
+
129
+ // Assert response is finished and RpcBlocks can be constructed
130
+ assert ! ( info. is_finished( ) ) ;
131
+ info. into_responses ( ) . unwrap ( ) ;
82
132
}
83
133
}
0 commit comments