parachains_loop.rs 36.1 KiB
Newer Older
			target_submit_result: Ok(()),

			submitted_proof_at_source_relay_block: None,
			exit_signal_sender: Some(Box::new(exit_signal_sender)),
		};

		let source_client = TestClient::from(clients_data.clone());
		let target_client = TestClient::from(clients_data);
		assert_eq!(
			run_until_connection_lost(
				source_client,
				target_client.clone(),
				None,
				true,
				exit_signal.into_future().map(|(_, _)| ()),
			)
			.await,
			Ok(()),
		);

		assert_eq!(
			target_client
				.data
				.lock()
				.await
				.submitted_proof_at_source_relay_block
				.map(|id| id.0),
			Some(95)
		);

		// now source relay block chain 104 is mined with parachain head #84
		// => since 104 - 95 < 10, there are no free headers
		// => nothing is submitted
		let mut clients_data: TestClientData = target_client.data.lock().await.clone();
		clients_data
			.source_head
			.insert(104, Ok(AvailableHeader::Available(HeaderId(84, [84u8; 32].into()))));
		clients_data.target_best_finalized_source_block = Ok(HeaderId(104, [104u8; 32].into()));
		clients_data.target_head =
			Ok(Some((HeaderId(95, [95u8; 32].into()), HeaderId(42, [42u8; 32].into()))));
		clients_data.target_best_block = Ok(HeaderId(255, [255u8; 32].into()));
		clients_data.exit_signal_sender = None;

		let source_client = TestClient::from(clients_data.clone());
		let target_client = TestClient::from(clients_data);
		assert_eq!(
			run_until_connection_lost(
				source_client,
				target_client.clone(),
				None,
				true,
				async_std::task::sleep(std::time::Duration::from_millis(100)),
			)
			.await,
			Ok(()),
		);

		assert_eq!(
			target_client
				.data
				.lock()
				.await
				.submitted_proof_at_source_relay_block
				.map(|id| id.0),
			Some(95)
		);
	}

	fn test_tx_tracker() -> SubmittedHeadsTracker<TestParachainsPipeline> {
		SubmittedHeadsTracker::new(
			AvailableHeader::Available(HeaderId(20, PARA_20_HASH)),
	impl From<SubmittedHeadStatus<TestParachainsPipeline>> for Option<()> {
		fn from(status: SubmittedHeadStatus<TestParachainsPipeline>) -> Option<()> {
				SubmittedHeadStatus::Waiting(_) => Some(()),
	async fn tx_tracker_update_when_head_at_target_has_none_value() {
				.update(&HeaderId(0, Default::default()), &Some(HeaderId(10, PARA_10_HASH)))
	async fn tx_tracker_update_when_head_at_target_has_old_value() {
			test_tx_tracker()
				.update(&HeaderId(0, Default::default()), &Some(HeaderId(10, PARA_10_HASH)))
	async fn tx_tracker_update_when_head_at_target_has_same_value() {
		assert!(matches!(
			test_tx_tracker()
				.update(&HeaderId(0, Default::default()), &Some(HeaderId(20, PARA_20_HASH)))
				.await,
			SubmittedHeadStatus::Final(TrackedTransactionStatus::Finalized(_)),
		));
	async fn tx_tracker_update_when_head_at_target_has_better_value() {
		assert!(matches!(
			test_tx_tracker()
				.update(&HeaderId(0, Default::default()), &Some(HeaderId(30, PARA_20_HASH)))
				.await,
			SubmittedHeadStatus::Final(TrackedTransactionStatus::Finalized(_)),
		));
	async fn tx_tracker_update_when_tx_is_lost() {
		let mut tx_tracker = test_tx_tracker();
		tx_tracker.transaction_tracker =
			futures::future::ready(TrackedTransactionStatus::Lost).boxed().shared();
				.update(&HeaderId(0, Default::default()), &Some(HeaderId(10, PARA_10_HASH)))
			SubmittedHeadStatus::Final(TrackedTransactionStatus::Lost),
		));
	}

	#[async_std::test]
	async fn tx_tracker_update_when_tx_is_finalized_but_heads_are_not_updated() {
		let mut tx_tracker = test_tx_tracker();
		tx_tracker.transaction_tracker =
			futures::future::ready(TrackedTransactionStatus::Finalized(Default::default()))
				.boxed()
				.shared();
		assert!(matches!(
			tx_tracker
				.update(&HeaderId(0, Default::default()), &Some(HeaderId(10, PARA_10_HASH)))
			SubmittedHeadStatus::Final(TrackedTransactionStatus::Lost),
	#[test]
	fn parachain_is_not_updated_if_it_is_unavailable() {
		assert!(!is_update_required::<TestParachainsPipeline>(
			AvailableHeader::Unavailable,
			None,
			Default::default(),
			Default::default(),
		));
		assert!(!is_update_required::<TestParachainsPipeline>(
			AvailableHeader::Unavailable,
			Some(HeaderId(10, PARA_10_HASH)),
			Default::default(),
			Default::default(),
	#[test]
	fn parachain_is_not_updated_if_it_is_unknown_to_both_clients() {
		assert!(!is_update_required::<TestParachainsPipeline>(
			AvailableHeader::Missing,
			None,
			Default::default(),
			Default::default(),
		),);
	fn parachain_is_not_updated_if_target_has_better_head() {
		assert!(!is_update_required::<TestParachainsPipeline>(
			AvailableHeader::Available(HeaderId(10, Default::default())),
			Some(HeaderId(20, Default::default())),
	}

	#[test]
	fn parachain_is_updated_after_offboarding() {
		assert!(is_update_required::<TestParachainsPipeline>(
			AvailableHeader::Missing,
			Some(HeaderId(20, Default::default())),
	}

	#[test]
	fn parachain_is_updated_after_onboarding() {
		assert!(is_update_required::<TestParachainsPipeline>(
			AvailableHeader::Available(HeaderId(30, Default::default())),
			None,
	}

	#[test]
	fn parachain_is_updated_if_newer_head_is_known() {
		assert!(is_update_required::<TestParachainsPipeline>(
			AvailableHeader::Available(HeaderId(40, Default::default())),
			Some(HeaderId(30, Default::default())),