@@ -1156,63 +1156,40 @@ impl<Env: Environment> Client<Env> {
11561156 . get ( & sender_chain_id)
11571157 . copied ( )
11581158 . unwrap_or ( BlockHeight :: ZERO ) ;
1159- let ( max_epoch, committees) = self . admin_committees ( ) . await ?;
1160-
1161- // Recursively collect all certificates we need, following
1162- // the chain of previous_message_blocks back to next_outbox_height.
1163- let mut certificates = BTreeMap :: new ( ) ;
1164- let mut current_height = height;
11651159
1166- // Stop if we've reached the height we've already processed.
1167- while current_height >= next_outbox_height {
1168- // Download the certificate for this height.
1169- let downloaded = self
1170- . requests_scheduler
1171- . download_certificates_by_heights (
1172- remote_node,
1173- sender_chain_id,
1174- vec ! [ current_height] ,
1175- )
1176- . await ?;
1177- let Some ( certificate) = downloaded. into_iter ( ) . next ( ) else {
1178- return Err ( chain_client:: Error :: CannotDownloadMissingSenderBlock {
1179- chain_id : sender_chain_id,
1180- height : current_height,
1181- } ) ;
1182- } ;
1160+ // Skip if we already have all certificates up to this height.
1161+ if height < next_outbox_height {
1162+ return Ok ( ( ) ) ;
1163+ }
11831164
1184- // Validate the certificate.
1185- Client :: < Env > :: check_certificate ( max_epoch, & committees, & certificate) ?
1186- . into_result ( ) ?;
1165+ let ( max_epoch, committees) = self . admin_committees ( ) . await ?;
11871166
1188- // Check if there's a previous message block to our chain.
1189- let block = certificate. block ( ) ;
1190- let next_height = block
1191- . body
1192- . previous_message_blocks
1193- . get ( & receiver_chain_id)
1194- . map ( |( _prev_hash, prev_height) | * prev_height) ;
1195-
1196- // Store this certificate.
1197- certificates. insert ( current_height, certificate) ;
1198-
1199- if let Some ( prev_height) = next_height {
1200- // Continue with the previous block.
1201- current_height = prev_height;
1202- } else {
1203- // No more dependencies.
1204- break ;
1205- }
1206- }
1167+ // Request the proxy to do the traversal and return the certificates
1168+ // in ascending height order, ready for processing.
1169+ let certificates = self
1170+ . requests_scheduler
1171+ . download_sender_certificates_for_receiver (
1172+ remote_node,
1173+ sender_chain_id,
1174+ receiver_chain_id,
1175+ height,
1176+ next_outbox_height,
1177+ )
1178+ . await ?;
12071179
12081180 if certificates. is_empty ( ) {
12091181 self . local_node
12101182 . retry_pending_cross_chain_requests ( sender_chain_id)
12111183 . await ?;
1184+ return Ok ( ( ) ) ;
12121185 }
12131186
1214- // Process certificates in ascending block height order (BTreeMap keeps them sorted).
1215- for certificate in certificates. into_values ( ) {
1187+ // Process certificates in ascending block height order (already sorted by proxy).
1188+ for certificate in certificates {
1189+ // Validate the certificate.
1190+ Client :: < Env > :: check_certificate ( max_epoch, & committees, & certificate) ?
1191+ . into_result ( ) ?;
1192+
12161193 self . receive_sender_certificate (
12171194 certificate,
12181195 ReceiveCertificateMode :: AlreadyChecked ,
0 commit comments