@@ -22,6 +22,7 @@ use linera_base::{
2222} ;
2323use linera_chain:: {
2424 data_types:: { BlockProposal , LiteVote } ,
25+ manager:: LockingBlock ,
2526 types:: { ConfirmedBlock , GenericCertificate , ValidatedBlock , ValidatedBlockCertificate } ,
2627} ;
2728use linera_execution:: { committee:: Committee , system:: EPOCH_STREAM_NAME } ;
@@ -451,6 +452,7 @@ where
451452 } else {
452453 tracing:: warn!( "NOPE 0" ) ;
453454 }
455+ // TODO: Deduplicate!!
454456 return Ok ( ( ) ) ;
455457 } ;
456458 // Figure out which certificates this validator is missing. In many cases, it's just the
@@ -517,7 +519,8 @@ where
517519 }
518520 }
519521 // If the remote node is missing a timeout certificate, send it as well.
520- let local_info = self . local_node . chain_info ( chain_id) . await ?;
522+ let query = ChainInfoQuery :: new ( chain_id) . with_manager_values ( ) ;
523+ let local_info = self . local_node . handle_chain_info_query ( query) . await ?. info ;
521524 if let Some ( cert) = local_info. manager . timeout {
522525 if ( local_info. next_block_height , cert. round ) >= ( remote_height, remote_round) {
523526 tracing:: debug!( "send_chain_information --> {:?}" , cert) ;
@@ -528,6 +531,36 @@ where
528531 } else {
529532 tracing:: debug!( "send_chain_information NOPE 2" ) ;
530533 }
534+ if let Some ( proposal) = local_info. manager . requested_proposed {
535+ tracing:: info!( "send_chain_information prop --> {:?}" , proposal) ;
536+ if let Err ( err) = Box :: pin ( self . send_block_proposal ( proposal, vec ! [ ] ) ) . await {
537+ tracing:: info!( "Failed to propose: {err}" ) ;
538+ }
539+ }
540+ if let Some ( proposal) = local_info. manager . requested_signed_proposal {
541+ tracing:: info!( "send_chain_information sig --> {:?}" , proposal) ;
542+ if let Err ( err) = Box :: pin ( self . send_block_proposal ( proposal, vec ! [ ] ) ) . await {
543+ tracing:: info!( "Failed to propose: {err}" ) ;
544+ }
545+ }
546+ match local_info. manager . requested_locking . map ( |b| * b) {
547+ Some ( LockingBlock :: Regular ( validated) ) => {
548+ if let Err ( err) = self
549+ . remote_node
550+ . handle_optimized_validated_certificate (
551+ & validated,
552+ CrossChainMessageDelivery :: NonBlocking ,
553+ )
554+ . await
555+ {
556+ tracing:: info!( "Failed to send locking block: {err}" ) ;
557+ }
558+ }
559+ Some ( LockingBlock :: Fast ( _) ) => {
560+ tracing:: error!( "TODO: FAST" )
561+ }
562+ None => { }
563+ }
531564 Ok ( ( ) )
532565 }
533566
@@ -605,7 +638,50 @@ where
605638 }
606639 CommunicateAction :: RequestTimeout { round, height, .. } => {
607640 let query = ChainInfoQuery :: new ( chain_id) . with_timeout ( height, round) ;
608- let info = self . remote_node . handle_chain_info_query ( query) . await ?;
641+ let info = match self
642+ . remote_node
643+ . handle_chain_info_query ( query. clone ( ) )
644+ . await
645+ {
646+ Ok ( info) => info,
647+ Err ( NodeError :: WrongRound ( validator_round) ) => {
648+ tracing:: info!(
649+ "Failed to request timeout from validator {} because it sees \
650+ chain {} at round {} instead of {}.",
651+ self . remote_node. public_key,
652+ chain_id,
653+ validator_round,
654+ round
655+ ) ;
656+ // The timeout is for a different round, so we need to update the validator.
657+ // TODO: this should probably be more specific as to which rounds are retried.
658+ self . send_chain_information (
659+ chain_id,
660+ height,
661+ CrossChainMessageDelivery :: NonBlocking ,
662+ )
663+ . await ?;
664+ self . remote_node
665+ . handle_chain_info_query ( query. clone ( ) )
666+ . await ?
667+ }
668+ Err ( NodeError :: UnexpectedBlockHeight {
669+ expected_block_height,
670+ found_block_height,
671+ } ) if expected_block_height < found_block_height => {
672+ // The proposal is for a later block height, so we need to update the validator.
673+ self . send_chain_information (
674+ chain_id,
675+ found_block_height,
676+ CrossChainMessageDelivery :: NonBlocking ,
677+ )
678+ . await ?;
679+ self . remote_node
680+ . handle_chain_info_query ( query. clone ( ) )
681+ . await ?
682+ }
683+ Err ( err) => Err ( err) ?,
684+ } ;
609685 info. manager . timeout_vote . ok_or_else ( || {
610686 NodeError :: MissingVoteInValidatorResponse ( "request a timeout" . into ( ) )
611687 } ) ?
0 commit comments