@@ -279,10 +279,12 @@ impl DataAvailability {
279
279
tcp_server : & mut DaTcpServer ,
280
280
) {
281
281
// Iterative loop to avoid stack overflows
282
+ // SignedBlock are ordered by height, so the first one is either the next one
283
+ // or there might still be holes.
282
284
while let Some ( first_buffered) = self . buffered_signed_blocks . first ( ) {
283
285
if first_buffered. parent_hash ( ) != & last_block_hash {
284
- error ! (
285
- "Buffered block parent hash {} does not match last block hash {}" ,
286
+ debug ! (
287
+ "Not popping buffer, parent hash {} does not match last block hash {}" ,
286
288
first_buffered. parent_hash( ) ,
287
289
last_block_hash
288
290
) ;
@@ -386,9 +388,13 @@ impl DataAvailability {
386
388
. last ( )
387
389
. map ( |block| block. height ( ) + 1 )
388
390
. unwrap_or ( BlockHeight ( 0 ) ) ;
389
- let mut client = DataAvailabilityClient :: connect ( "block_catcher" . to_string ( ) , ip)
390
- . await
391
- . context ( "Error occured setting up the DA listener" ) ?;
391
+ let mut client = DataAvailabilityClient :: connect_with_opts (
392
+ "block_catcher" . to_string ( ) ,
393
+ Some ( self . config . da_max_frame_length ) ,
394
+ ip,
395
+ )
396
+ . await
397
+ . context ( "Error occured setting up the DA listener" ) ?;
392
398
client. send ( DataAvailabilityRequest ( start) ) . await ?;
393
399
self . catchup_task = Some ( tokio:: spawn ( async move {
394
400
loop {
@@ -803,4 +809,69 @@ pub mod tests {
803
809
assert_eq ! ( received_blocks[ 0 ] . height( ) , BlockHeight ( 15 ) ) ;
804
810
assert_eq ! ( received_blocks[ 4 ] . height( ) , BlockHeight ( 19 ) ) ;
805
811
}
812
+
813
+ #[ test_log:: test( tokio:: test) ]
814
+ async fn test_out_of_order_blocks ( ) {
815
+ let tmpdir = tempfile:: tempdir ( ) . unwrap ( ) . into_path ( ) ;
816
+ let blocks = Blocks :: new ( & tmpdir) . unwrap ( ) ;
817
+
818
+ let mut server = DataAvailabilityServer :: start ( 7899 , "DaServer" )
819
+ . await
820
+ . unwrap ( ) ;
821
+
822
+ let bus = super :: DABusClient :: new_from_bus ( crate :: bus:: SharedMessageBus :: new (
823
+ crate :: bus:: metrics:: BusMetrics :: global ( "global" . to_string ( ) ) ,
824
+ ) )
825
+ . await ;
826
+
827
+ let mut da = super :: DataAvailability {
828
+ config : Default :: default ( ) ,
829
+ bus,
830
+ blocks,
831
+ buffered_signed_blocks : Default :: default ( ) ,
832
+ need_catchup : false ,
833
+ catchup_task : None ,
834
+ catchup_height : None ,
835
+ } ;
836
+
837
+ let mut block0 = SignedBlock :: default ( ) ;
838
+ block0. consensus_proposal . slot = 0 ;
839
+ let block0_hash = block0. hashed ( ) ;
840
+
841
+ let mut block1 = SignedBlock :: default ( ) ;
842
+ block1. consensus_proposal . slot = 1 ;
843
+ block1. consensus_proposal . parent_hash = block0_hash. clone ( ) ;
844
+ let block1_hash = block1. hashed ( ) ;
845
+
846
+ let mut block2 = SignedBlock :: default ( ) ;
847
+ block2. consensus_proposal . slot = 2 ;
848
+ block2. consensus_proposal . parent_hash = block1_hash. clone ( ) ;
849
+ let block2_hash = block2. hashed ( ) ;
850
+
851
+ let mut block3 = SignedBlock :: default ( ) ;
852
+ block3. consensus_proposal . slot = 3 ;
853
+ block3. consensus_proposal . parent_hash = block2_hash. clone ( ) ;
854
+
855
+ da. handle_signed_block ( block0. clone ( ) , & mut server)
856
+ . await
857
+ . unwrap ( ) ;
858
+ assert_eq ! ( da. blocks. last( ) . unwrap( ) . height( ) , BlockHeight ( 0 ) ) ;
859
+ da. handle_signed_block ( block3. clone ( ) , & mut server)
860
+ . await
861
+ . unwrap ( ) ;
862
+ assert_eq ! ( da. blocks. last( ) . unwrap( ) . height( ) , BlockHeight ( 0 ) ) ;
863
+ da. handle_signed_block ( block1. clone ( ) , & mut server)
864
+ . await
865
+ . unwrap ( ) ;
866
+ assert_eq ! ( da. blocks. last( ) . unwrap( ) . height( ) , BlockHeight ( 1 ) ) ;
867
+ da. handle_signed_block ( block2. clone ( ) , & mut server)
868
+ . await
869
+ . unwrap ( ) ;
870
+
871
+ assert_eq ! ( da. blocks. last( ) . unwrap( ) . height( ) , BlockHeight ( 3 ) ) ;
872
+ assert ! ( da. blocks. get( & block0_hash) . unwrap( ) . is_some( ) , ) ;
873
+ assert ! ( da. blocks. get( & block1_hash) . unwrap( ) . is_some( ) , ) ;
874
+ assert ! ( da. blocks. get( & block2_hash) . unwrap( ) . is_some( ) , ) ;
875
+ assert ! ( da. blocks. get( & block3. hashed( ) ) . unwrap( ) . is_some( ) , ) ;
876
+ }
806
877
}
0 commit comments