Skip to content

Commit 45a68ad

Browse files
authored
Fix on demand parachains relay when no parachain head at target (#1834)
* `best_finalized_peer_at_best_self` in messages relay is now Option<> - before it was an error, which effectively blocked the lane * unnecessary mut * clone on return
1 parent 6dbce72 commit 45a68ad

File tree

6 files changed

+150
-98
lines changed

6 files changed

+150
-98
lines changed

relays/lib-substrate-relay/src/finality/target.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ where
102102
None,
103103
)
104104
.await?
105-
.best_finalized_peer_at_best_self)
105+
.best_finalized_peer_at_best_self
106+
.ok_or(Error::BridgePalletIsNotInitialized)?)
106107
}
107108

108109
async fn submit_finality_proof(

relays/lib-substrate-relay/src/messages_source.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,15 @@ where
421421
.await?;
422422

423423
// read actual header, matching the `peer_on_self_best_finalized_id` from the peer chain
424-
let actual_peer_on_self_best_finalized_id = match peer_client {
425-
Some(peer_client) => {
426-
let actual_peer_on_self_best_finalized =
427-
peer_client.header_by_number(peer_on_self_best_finalized_id.number()).await?;
428-
actual_peer_on_self_best_finalized.id()
429-
},
430-
None => peer_on_self_best_finalized_id,
431-
};
424+
let actual_peer_on_self_best_finalized_id =
425+
match (peer_client, peer_on_self_best_finalized_id.as_ref()) {
426+
(Some(peer_client), Some(peer_on_self_best_finalized_id)) => {
427+
let actual_peer_on_self_best_finalized =
428+
peer_client.header_by_number(peer_on_self_best_finalized_id.number()).await?;
429+
Some(actual_peer_on_self_best_finalized.id())
430+
},
431+
_ => peer_on_self_best_finalized_id,
432+
};
432433

433434
Ok(ClientState {
434435
best_self: self_best_id,
@@ -444,7 +445,7 @@ where
444445
pub async fn best_finalized_peer_header_at_self<SelfChain, PeerChain>(
445446
self_client: &Client<SelfChain>,
446447
at_self_hash: HashOf<SelfChain>,
447-
) -> Result<HeaderIdOf<PeerChain>, SubstrateError>
448+
) -> Result<Option<HeaderIdOf<PeerChain>>, SubstrateError>
448449
where
449450
SelfChain: Chain,
450451
PeerChain: Chain,
@@ -456,8 +457,7 @@ where
456457
(),
457458
Some(at_self_hash),
458459
)
459-
.await?
460-
.ok_or(SubstrateError::BridgePalletIsNotInitialized)
460+
.await
461461
}
462462

463463
fn validate_out_msgs_details<C: Chain>(

relays/lib-substrate-relay/src/on_demand/parachains.rs

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
529540
fn 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>
533544
where
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

Comments
 (0)