@@ -422,11 +422,14 @@ struct RelayData<ParaHash, ParaNumber, RelayNumber> {
422422 pub para_header_at_source : Option < HeaderId < ParaHash , ParaNumber > > ,
423423 /// Parachain header, that is available at the source relay chain at `relay_header_at_target`
424424 /// block.
425+ ///
426+ /// May be `None` if there's no `relay_header_at_target` yet, or if the
427+ /// `relay_header_at_target` is too old and we think its state has been pruned.
425428 pub para_header_at_relay_header_at_target : Option < HeaderId < ParaHash , ParaNumber > > ,
426429 /// Relay header number at the source chain.
427430 pub relay_header_at_source : RelayNumber ,
428431 /// Relay header number at the target chain.
429- pub relay_header_at_target : RelayNumber ,
432+ pub relay_header_at_target : Option < RelayNumber > ,
430433}
431434
432435/// Read required data from source and target clients.
@@ -477,9 +480,8 @@ where
477480 // submit at least one. Otherwise the pallet will be treated as uninitialized and messages
478481 // sync will stall.
479482 let para_header_at_target = match para_header_at_target {
480- Ok ( para_header_at_target) => Some ( para_header_at_target. 0 ) ,
481- Err ( SubstrateError :: BridgePalletIsNotInitialized ) |
482- Err ( SubstrateError :: NoParachainHeadAtTarget ( _, _) ) => None ,
483+ Ok ( Some ( para_header_at_target) ) => Some ( para_header_at_target. 0 ) ,
484+ Ok ( None ) => None ,
483485 Err ( e) => return Err ( map_target_err ( e) ) ,
484486 } ;
485487
@@ -502,51 +504,70 @@ where
502504 . await
503505 . map_err ( map_target_err) ?;
504506
505- // if relay header at target is too old, then its state may already be discarded at the source
507+ // if relay header at target is too old then its state may already be discarded at the source
506508 // => just use `None` in this case
507- let is_relay_header_at_target_ancient =
508- is_ancient_block ( relay_header_at_target. number ( ) , relay_header_at_source) ;
509- let para_header_at_relay_header_at_target = if is_relay_header_at_target_ancient {
510- None
511- } else {
512- source
513- . on_chain_para_head_id ( relay_header_at_target, P :: SourceParachain :: PARACHAIN_ID . into ( ) )
514- . await
515- . map_err ( map_source_err) ?
516- } ;
509+ //
510+ // the same is for case when there's no relay header at target at all
511+ let available_relay_header_at_target =
512+ relay_header_at_target. filter ( |relay_header_at_target| {
513+ !is_ancient_block ( relay_header_at_target. number ( ) , relay_header_at_source)
514+ } ) ;
515+ let para_header_at_relay_header_at_target =
516+ if let Some ( available_relay_header_at_target) = available_relay_header_at_target {
517+ source
518+ . on_chain_para_head_id (
519+ available_relay_header_at_target,
520+ P :: SourceParachain :: PARACHAIN_ID . into ( ) ,
521+ )
522+ . await
523+ . map_err ( map_source_err) ?
524+ } else {
525+ None
526+ } ;
517527
518528 Ok ( RelayData {
519529 required_para_header : required_header_number,
520530 para_header_at_target,
521531 para_header_at_source,
522532 relay_header_at_source,
523- relay_header_at_target : relay_header_at_target. 0 ,
533+ relay_header_at_target : relay_header_at_target
534+ . map ( |relay_header_at_target| relay_header_at_target. 0 ) ,
524535 para_header_at_relay_header_at_target,
525536 } )
526537}
527538
528539/// Select relay and parachain headers that need to be relayed.
529540fn select_headers_to_relay < ParaHash , ParaNumber , RelayNumber > (
530541 data : & RelayData < ParaHash , ParaNumber , RelayNumber > ,
531- mut state : RelayState < ParaHash , ParaNumber , RelayNumber > ,
542+ state : RelayState < ParaHash , ParaNumber , RelayNumber > ,
532543) -> RelayState < ParaHash , ParaNumber , RelayNumber >
533544where
534545 ParaHash : Clone ,
535546 ParaNumber : Copy + PartialOrd + Zero ,
536547 RelayNumber : Copy + Debug + Ord ,
537548{
549+ // we can't do anything until **relay chain** bridge GRANDPA pallet is not initialized at the
550+ // target chain
551+ let relay_header_at_target = match data. relay_header_at_target {
552+ Some ( relay_header_at_target) => relay_header_at_target,
553+ None => return RelayState :: Idle ,
554+ } ;
555+
538556 // Process the `RelayingRelayHeader` state.
539557 if let & RelayState :: RelayingRelayHeader ( relay_header_number) = & state {
540- if data . relay_header_at_target < relay_header_number {
558+ if relay_header_at_target < relay_header_number {
541559 // The required relay header hasn't yet been relayed. Ask / wait for it.
542560 return state
543561 }
544562
545563 // We may switch to `RelayingParaHeader` if parachain head is available.
546- state = data
547- . para_header_at_relay_header_at_target
548- . clone ( )
549- . map_or ( RelayState :: Idle , RelayState :: RelayingParaHeader ) ;
564+ if let Some ( para_header_at_relay_header_at_target) =
565+ data. para_header_at_relay_header_at_target . as_ref ( )
566+ {
567+ return RelayState :: RelayingParaHeader ( para_header_at_relay_header_at_target. clone ( ) )
568+ }
569+
570+ // else use the regular process - e.g. we may require to deliver new relay header first
550571 }
551572
552573 // Process the `RelayingParaHeader` state.
@@ -585,7 +606,7 @@ where
585606 // its ancestor
586607
587608 // we need relay chain header first
588- if data . relay_header_at_target < data. relay_header_at_source {
609+ if relay_header_at_target < data. relay_header_at_source {
589610 return RelayState :: RelayingRelayHeader ( data. relay_header_at_source )
590611 }
591612
@@ -640,7 +661,8 @@ impl<'a, P: SubstrateParachainsPipeline>
640661 None ,
641662 )
642663 . await ?
643- . best_finalized_peer_at_best_self )
664+ . best_finalized_peer_at_best_self
665+ . ok_or ( SubstrateError :: BridgePalletIsNotInitialized ) ?)
644666 }
645667
646668 async fn best_finalized_para_block_at_source (
@@ -726,7 +748,7 @@ mod tests {
726748 para_header_at_target: Some ( 50 ) ,
727749 para_header_at_source: Some ( HeaderId ( 110 , 110 ) ) ,
728750 relay_header_at_source: 800 ,
729- relay_header_at_target: 700 ,
751+ relay_header_at_target: Some ( 700 ) ,
730752 para_header_at_relay_header_at_target: Some ( HeaderId ( 100 , 100 ) ) ,
731753 } ,
732754 RelayState :: RelayingRelayHeader ( 750 ) ,
@@ -744,7 +766,7 @@ mod tests {
744766 para_header_at_target: Some ( 50 ) ,
745767 para_header_at_source: Some ( HeaderId ( 110 , 110 ) ) ,
746768 relay_header_at_source: 800 ,
747- relay_header_at_target: 750 ,
769+ relay_header_at_target: Some ( 750 ) ,
748770 para_header_at_relay_header_at_target: Some ( HeaderId ( 100 , 100 ) ) ,
749771 } ,
750772 RelayState :: RelayingRelayHeader ( 750 ) ,
@@ -762,7 +784,7 @@ mod tests {
762784 para_header_at_target: Some ( 50 ) ,
763785 para_header_at_source: Some ( HeaderId ( 110 , 110 ) ) ,
764786 relay_header_at_source: 800 ,
765- relay_header_at_target: 780 ,
787+ relay_header_at_target: Some ( 780 ) ,
766788 para_header_at_relay_header_at_target: Some ( HeaderId ( 105 , 105 ) ) ,
767789 } ,
768790 RelayState :: RelayingRelayHeader ( 750 ) ,
@@ -779,7 +801,7 @@ mod tests {
779801 para_header_at_target: Some ( 50 ) ,
780802 para_header_at_source: Some ( HeaderId ( 110 , 110 ) ) ,
781803 relay_header_at_source: 800 ,
782- relay_header_at_target: 780 ,
804+ relay_header_at_target: Some ( 780 ) ,
783805 para_header_at_relay_header_at_target: Some ( HeaderId ( 105 , 105 ) ) ,
784806 } ,
785807 RelayState :: RelayingParaHeader ( HeaderId ( 105 , 105 ) ) ,
@@ -797,7 +819,7 @@ mod tests {
797819 para_header_at_target: Some ( 105 ) ,
798820 para_header_at_source: Some ( HeaderId ( 110 , 110 ) ) ,
799821 relay_header_at_source: 800 ,
800- relay_header_at_target: 780 ,
822+ relay_header_at_target: Some ( 780 ) ,
801823 para_header_at_relay_header_at_target: Some ( HeaderId ( 105 , 105 ) ) ,
802824 } ,
803825 RelayState :: Idle ,
@@ -815,7 +837,7 @@ mod tests {
815837 para_header_at_target: Some ( 105 ) ,
816838 para_header_at_source: None ,
817839 relay_header_at_source: 800 ,
818- relay_header_at_target: 780 ,
840+ relay_header_at_target: Some ( 780 ) ,
819841 para_header_at_relay_header_at_target: Some ( HeaderId ( 105 , 105 ) ) ,
820842 } ,
821843 RelayState :: Idle ,
@@ -833,7 +855,7 @@ mod tests {
833855 para_header_at_target: Some ( 105 ) ,
834856 para_header_at_source: Some ( HeaderId ( 110 , 110 ) ) ,
835857 relay_header_at_source: 800 ,
836- relay_header_at_target: 780 ,
858+ relay_header_at_target: Some ( 780 ) ,
837859 para_header_at_relay_header_at_target: Some ( HeaderId ( 105 , 105 ) ) ,
838860 } ,
839861 RelayState :: Idle ,
@@ -851,7 +873,7 @@ mod tests {
851873 para_header_at_target: Some ( 105 ) ,
852874 para_header_at_source: Some ( HeaderId ( 125 , 125 ) ) ,
853875 relay_header_at_source: 800 ,
854- relay_header_at_target: 780 ,
876+ relay_header_at_target: Some ( 780 ) ,
855877 para_header_at_relay_header_at_target: Some ( HeaderId ( 105 , 105 ) ) ,
856878 } ,
857879 RelayState :: Idle ,
@@ -869,7 +891,7 @@ mod tests {
869891 para_header_at_target: Some ( 105 ) ,
870892 para_header_at_source: Some ( HeaderId ( 125 , 125 ) ) ,
871893 relay_header_at_source: 800 ,
872- relay_header_at_target: 800 ,
894+ relay_header_at_target: Some ( 800 ) ,
873895 para_header_at_relay_header_at_target: Some ( HeaderId ( 125 , 125 ) ) ,
874896 } ,
875897 RelayState :: Idle ,
@@ -887,7 +909,7 @@ mod tests {
887909 para_header_at_target: Some ( 105 ) ,
888910 para_header_at_source: None ,
889911 relay_header_at_source: 800 ,
890- relay_header_at_target: 800 ,
912+ relay_header_at_target: Some ( 800 ) ,
891913 para_header_at_relay_header_at_target: None ,
892914 } ,
893915 RelayState :: RelayingRelayHeader ( 800 ) ,
@@ -905,7 +927,7 @@ mod tests {
905927 para_header_at_target: None ,
906928 para_header_at_source: Some ( HeaderId ( 125 , 125 ) ) ,
907929 relay_header_at_source: 800 ,
908- relay_header_at_target: 800 ,
930+ relay_header_at_target: Some ( 800 ) ,
909931 para_header_at_relay_header_at_target: Some ( HeaderId ( 125 , 125 ) ) ,
910932 } ,
911933 RelayState :: Idle ,
@@ -923,7 +945,7 @@ mod tests {
923945 para_header_at_target: None ,
924946 para_header_at_source: Some ( HeaderId ( 125 , 125 ) ) ,
925947 relay_header_at_source: 800 ,
926- relay_header_at_target: 700 ,
948+ relay_header_at_target: Some ( 700 ) ,
927949 para_header_at_relay_header_at_target: Some ( HeaderId ( 125 , 125 ) ) ,
928950 } ,
929951 RelayState :: Idle ,
0 commit comments