@@ -103,7 +103,7 @@ struct IncomingDataState {
103
103
/// requested the blocks for.
104
104
pending_headers : Vec < SignedBlockHeader > ,
105
105
/// A list of blocks that we requested from this peer.
106
- requested_blocks : BTreeSet < Id < Block > > ,
106
+ requested_blocks : VecDeque < Id < Block > > ,
107
107
/// The id of the best block header that we've received from the peer and that we also have.
108
108
/// This includes headers received by any means, e.g. via HeaderList messages, as part
109
109
/// of a locator during peer's header requests, via block responses.
@@ -158,7 +158,7 @@ where
158
158
time_getter,
159
159
incoming : IncomingDataState {
160
160
pending_headers : Vec :: new ( ) ,
161
- requested_blocks : BTreeSet :: new ( ) ,
161
+ requested_blocks : VecDeque :: new ( ) ,
162
162
peers_best_block_that_we_have : None ,
163
163
singular_unconnected_headers_count : 0 ,
164
164
} ,
@@ -225,15 +225,15 @@ where
225
225
}
226
226
}
227
227
228
- fn send_message ( & mut self , message : SyncMessage ) -> Result < ( ) > {
229
- self . messaging_handle . send_message ( self . id ( ) , message)
228
+ async fn send_message ( & mut self , message : SyncMessage ) -> Result < ( ) > {
229
+ self . messaging_handle . send_message ( self . id ( ) , message) . await
230
230
}
231
231
232
- fn send_headers ( & mut self , headers : HeaderList ) -> Result < ( ) > {
232
+ async fn send_headers ( & mut self , headers : HeaderList ) -> Result < ( ) > {
233
233
if let Some ( last_header) = headers. headers ( ) . last ( ) {
234
234
self . outgoing . best_sent_block_header = Some ( last_header. block_id ( ) . into ( ) ) ;
235
235
}
236
- self . send_message ( SyncMessage :: HeaderList ( headers) )
236
+ self . send_message ( SyncMessage :: HeaderList ( headers) ) . await
237
237
}
238
238
239
239
async fn handle_new_tip ( & mut self , new_tip_id : & Id < Block > ) -> Result < ( ) > {
@@ -290,23 +290,17 @@ where
290
290
. await ?;
291
291
292
292
if headers. is_empty ( ) {
293
- log:: warn!(
294
- concat!(
295
- "[peer id = {}] Got new tip event with block id {}, " ,
296
- "but there is nothing to send"
297
- ) ,
293
+ log:: debug!(
294
+ "[peer id = {}] Got new tip event with block id {}, but there is nothing to send" ,
298
295
self . id( ) ,
299
296
new_tip_id,
300
297
) ;
301
298
} else if best_block_id != new_tip_id {
302
299
// If we got here, another "new tip" event should be generated soon,
303
300
// so we may ignore this one (and it makes sense to ignore it to avoid sending
304
301
// the same header list multiple times).
305
- log:: warn!(
306
- concat!(
307
- "[peer id = {}] Got new tip event with block id {}, " ,
308
- "but the tip has changed since then to {}"
309
- ) ,
302
+ log:: info!(
303
+ "[peer id = {}] Got new tip event with block id {}, but the tip has changed since then to {}" ,
310
304
self . id( ) ,
311
305
new_tip_id,
312
306
best_block_id
@@ -317,7 +311,7 @@ where
317
311
self . id( ) ,
318
312
headers. len( )
319
313
) ;
320
- return self . send_headers ( HeaderList :: new ( headers) ) ;
314
+ return self . send_headers ( HeaderList :: new ( headers) ) . await ;
321
315
}
322
316
} else {
323
317
// Note: if we got here, then we haven't received a single header request or
@@ -346,7 +340,7 @@ where
346
340
&& self . common_services . has_service ( Service :: Transactions )
347
341
{
348
342
self . add_known_transaction ( txid) ;
349
- self . send_message ( SyncMessage :: NewTransaction ( txid) )
343
+ self . send_message ( SyncMessage :: NewTransaction ( txid) ) . await
350
344
} else {
351
345
Ok ( ( ) )
352
346
}
@@ -357,9 +351,6 @@ where
357
351
async fn request_headers ( & mut self ) -> Result < ( ) > {
358
352
let locator = self . chainstate_handle . call ( |this| Ok ( this. get_locator ( ) ?) ) . await ?;
359
353
if locator. len ( ) > * self . p2p_config . protocol_config . msg_max_locator_count {
360
- // Note: msg_max_locator_count is not supposed to be configurable outside of tests,
361
- // so we should never get here in production code. Moreover, currently it's not
362
- // modified even in tests. TODO: make it a constant.
363
354
log:: warn!(
364
355
"[peer id = {}] Sending locator of the length {}, which exceeds the maximum length {:?}" ,
365
356
self . id( ) ,
@@ -371,7 +362,8 @@ where
371
362
log:: debug!( "[peer id = {}] Sending header list request" , self . id( ) ) ;
372
363
self . send_message ( SyncMessage :: HeaderListRequest ( HeaderListRequest :: new (
373
364
locator,
374
- ) ) ) ?;
365
+ ) ) )
366
+ . await ?;
375
367
376
368
self . peer_activity
377
369
. set_expecting_headers_since ( Some ( self . time_getter . get_time ( ) ) ) ;
@@ -445,7 +437,7 @@ where
445
437
// all headers that were available at the moment.
446
438
self . have_sent_all_headers = headers. len ( ) < header_count_limit;
447
439
448
- self . send_headers ( HeaderList :: new ( headers) )
440
+ self . send_headers ( HeaderList :: new ( headers) ) . await
449
441
}
450
442
451
443
/// Processes the blocks request.
@@ -719,7 +711,7 @@ where
719
711
. await ?;
720
712
}
721
713
722
- self . request_blocks ( new_block_headers)
714
+ self . request_blocks ( new_block_headers) . await
723
715
}
724
716
725
717
async fn handle_block_response ( & mut self , block : Block ) -> Result < ( ) > {
@@ -734,10 +726,28 @@ where
734
726
// The code below will set it again if needed.
735
727
self . peer_activity . set_expecting_blocks_since ( None ) ;
736
728
737
- if self . incoming . requested_blocks . take ( & block. get_id ( ) ) . is_none ( ) {
738
- return Err ( P2pError :: ProtocolError ( ProtocolError :: UnexpectedMessage (
739
- "block response" . to_owned ( ) ,
740
- ) ) ) ;
729
+ if self . incoming . requested_blocks . front ( ) . is_some_and ( |id| id == & block. get_id ( ) ) {
730
+ self . incoming . requested_blocks . pop_front ( ) ;
731
+ } else {
732
+ let idx = self . incoming . requested_blocks . iter ( ) . position ( |id| id == & block. get_id ( ) ) ;
733
+ // Note: we treat wrongly ordered blocks in the same way as unsolicited ones, i.e.
734
+ // we don't remove their ids from the list.
735
+ if idx. is_some ( ) {
736
+ return Err ( P2pError :: ProtocolError (
737
+ ProtocolError :: BlocksReceivedInWrongOrder {
738
+ expected_block_id : * self
739
+ . incoming
740
+ . requested_blocks
741
+ . front ( )
742
+ . expect ( "The deque is known to be non-empty" ) ,
743
+ actual_block_id : block. get_id ( ) ,
744
+ } ,
745
+ ) ) ;
746
+ } else {
747
+ return Err ( P2pError :: ProtocolError (
748
+ ProtocolError :: UnsolicitedBlockReceived ( block. get_id ( ) ) ,
749
+ ) ) ;
750
+ }
741
751
}
742
752
743
753
let block = self . chainstate_handle . call ( |c| Ok ( c. preliminary_block_check ( block) ?) ) . await ?;
@@ -798,7 +808,7 @@ where
798
808
self . request_headers ( ) . await ?;
799
809
} else {
800
810
// Download remaining blocks.
801
- self . request_blocks ( headers) ?;
811
+ self . request_blocks ( headers) . await ?;
802
812
}
803
813
} else {
804
814
// We expect additional blocks from the peer, update the timestamp.
@@ -821,7 +831,7 @@ where
821
831
None => TransactionResponse :: NotFound ( id) ,
822
832
} ;
823
833
824
- self . send_message ( SyncMessage :: TransactionResponse ( res) ) ?;
834
+ self . send_message ( SyncMessage :: TransactionResponse ( res) ) . await ?;
825
835
826
836
Ok ( ( ) )
827
837
}
@@ -905,7 +915,7 @@ where
905
915
}
906
916
907
917
if !( self . mempool_handle . call ( move |m| m. contains_transaction ( & tx) ) . await ?) {
908
- self . send_message ( SyncMessage :: TransactionRequest ( tx) ) ?;
918
+ self . send_message ( SyncMessage :: TransactionRequest ( tx) ) . await ?;
909
919
assert ! ( self . announced_transactions. insert( tx) ) ;
910
920
}
911
921
@@ -916,7 +926,7 @@ where
916
926
///
917
927
/// The number of blocks requested equals `P2pConfig::requested_blocks_limit`, the remaining
918
928
/// headers are stored in the peer context.
919
- fn request_blocks ( & mut self , mut headers : Vec < SignedBlockHeader > ) -> Result < ( ) > {
929
+ async fn request_blocks ( & mut self , mut headers : Vec < SignedBlockHeader > ) -> Result < ( ) > {
920
930
debug_assert ! ( self . incoming. pending_headers. is_empty( ) ) ;
921
931
debug_assert ! ( self . incoming. requested_blocks. is_empty( ) ) ;
922
932
debug_assert ! ( !headers. is_empty( ) ) ;
@@ -936,7 +946,8 @@ where
936
946
) ;
937
947
self . send_message ( SyncMessage :: BlockListRequest ( BlockListRequest :: new (
938
948
block_ids. clone ( ) ,
939
- ) ) ) ?;
949
+ ) ) )
950
+ . await ?;
940
951
self . incoming . requested_blocks . extend ( block_ids) ;
941
952
942
953
self . peer_activity . set_expecting_blocks_since ( Some ( self . time_getter . get_time ( ) ) ) ;
@@ -945,7 +956,7 @@ where
945
956
}
946
957
947
958
async fn send_block ( & mut self , id : Id < Block > ) -> Result < ( ) > {
948
- let ( block, index ) = self
959
+ let ( block, block_index ) = self
949
960
. chainstate_handle
950
961
. call ( move |c| {
951
962
let index = c. get_block_index ( & id) ;
@@ -960,14 +971,27 @@ where
960
971
// to delete block indices of missing blocks when resetting their failure flags).
961
972
// P2p should handle such situations correctly (see issue #1033 for more details).
962
973
let block = block?. unwrap_or_else ( || panic ! ( "Unknown block requested: {id}" ) ) ;
963
- self . outgoing . best_sent_block = index?;
974
+ let block_index = block_index?. expect ( "Block index must exist" ) ;
975
+
976
+ let old_best_sent_block_id = self . outgoing . best_sent_block . as_ref ( ) . map ( |idx| {
977
+ let id: Id < GenBlock > = ( * idx. block_id ( ) ) . into ( ) ;
978
+ id
979
+ } ) ;
980
+ let new_best_sent_block_id = self
981
+ . chainstate_handle
982
+ . call ( move |c| choose_peers_best_block ( c, old_best_sent_block_id, Some ( id. into ( ) ) ) )
983
+ . await ?;
984
+
985
+ if new_best_sent_block_id == Some ( id. into ( ) ) {
986
+ self . outgoing . best_sent_block = Some ( block_index) ;
987
+ }
964
988
965
989
log:: debug!(
966
990
"[peer id = {}] Sending block with id = {} to the peer" ,
967
991
self . id( ) ,
968
992
block. get_id( )
969
993
) ;
970
- self . send_message ( SyncMessage :: BlockResponse ( BlockResponse :: new ( block) ) )
994
+ self . send_message ( SyncMessage :: BlockResponse ( BlockResponse :: new ( block) ) ) . await
971
995
}
972
996
973
997
async fn disconnect_if_stalling ( & mut self ) -> Result < ( ) > {
0 commit comments