Skip to content
parachains_loop.rs 36 KiB
Newer Older
		fn from(status: SubmittedHeadsStatus<TestParachainsPipeline>) -> Option<BTreeSet<ParaId>> {
			match status {
				SubmittedHeadsStatus::Waiting(tracker) => Some(tracker.awaiting_update),
				_ => None,
			}
		}
	}

	#[async_std::test]
	async fn tx_tracker_update_when_nothing_is_updated() {
		assert_eq!(
			Some(test_tx_tracker().awaiting_update),
			test_tx_tracker()
				.update(&HeaderId(0, Default::default()), &vec![].into_iter().collect())
				.await
				.into(),
	#[async_std::test]
	async fn tx_tracker_update_when_one_of_heads_is_updated_to_previous_value() {
			Some(test_tx_tracker().awaiting_update),
			test_tx_tracker()
				.update(
					&HeaderId(0, Default::default()),
					&vec![(
						ParaId(PARA_ID),
						Some(BestParaHeadHash {
							at_relay_block_number: SOURCE_BLOCK_NUMBER - 1,
							head_hash: PARA_0_HASH,
						})
					)]
					.into_iter()
					.collect()
				)
	#[async_std::test]
	async fn tx_tracker_update_when_one_of_heads_is_updated() {
			Some(vec![ParaId(PARA_1_ID)].into_iter().collect::<BTreeSet<_>>()),
			test_tx_tracker()
				.update(
					&HeaderId(0, Default::default()),
					&vec![(
						ParaId(PARA_ID),
						Some(BestParaHeadHash {
							at_relay_block_number: SOURCE_BLOCK_NUMBER,
							head_hash: PARA_0_HASH,
						})
					)]
					.into_iter()
					.collect()
				)
	#[async_std::test]
	async fn tx_tracker_update_when_all_heads_are_updated() {
			Option::<BTreeSet<_>>::None,
			test_tx_tracker()
				.update(&HeaderId(0, Default::default()), &all_expected_tracker_heads())
	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();
		assert!(matches!(
			tx_tracker
				.update(&HeaderId(0, Default::default()), &vec![].into_iter().collect())
				.await,
			SubmittedHeadsStatus::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()), &vec![].into_iter().collect())
				.await,
			SubmittedHeadsStatus::Final(TrackedTransactionStatus::Lost),
		));
	async fn tx_tracker_update_when_tx_is_finalized_and_heads_are_updated() {
		let mut tx_tracker = test_tx_tracker();
		tx_tracker.transaction_tracker =
			futures::future::ready(TrackedTransactionStatus::Finalized(Default::default()))
				.boxed()
				.shared();
			tx_tracker
				.update(&HeaderId(0, Default::default()), &all_expected_tracker_heads())
				.await,
			SubmittedHeadsStatus::Final(TrackedTransactionStatus::Finalized(_)),
	#[test]
	fn parachain_is_not_updated_if_it_is_unknown_to_both_clients() {
		assert_eq!(
			select_parachains_to_update::<TestParachainsPipeline>(
Serban Iorga's avatar
Serban Iorga committed
				vec![(ParaId(PARA_ID), AvailableHeader::Missing)].into_iter().collect(),
				vec![(ParaId(PARA_ID), None)].into_iter().collect(),
				HeaderId(10, Default::default()),
			),
			Vec::<ParaId>::new(),
		);
	}

	#[test]
	fn parachain_is_not_updated_if_it_has_been_updated_at_better_relay_block() {
		assert_eq!(
			select_parachains_to_update::<TestParachainsPipeline>(
Serban Iorga's avatar
Serban Iorga committed
				vec![(ParaId(PARA_ID), AvailableHeader::Available(PARA_0_HASH))]
				vec![(
					ParaId(PARA_ID),
					Some(BestParaHeadHash { at_relay_block_number: 20, head_hash: PARA_1_HASH })
				)]
				.into_iter()
				.collect(),
				HeaderId(10, Default::default()),
			),
			Vec::<ParaId>::new(),
		);
	}

	#[test]
	fn parachain_is_not_updated_if_hash_is_the_same_at_next_relay_block() {
		assert_eq!(
			select_parachains_to_update::<TestParachainsPipeline>(
Serban Iorga's avatar
Serban Iorga committed
				vec![(ParaId(PARA_ID), AvailableHeader::Available(PARA_0_HASH))]
				vec![(
					ParaId(PARA_ID),
					Some(BestParaHeadHash { at_relay_block_number: 0, head_hash: PARA_0_HASH })
				)]
				.into_iter()
				.collect(),
				HeaderId(10, Default::default()),
			),
			Vec::<ParaId>::new(),
		);
	}

	#[test]
	fn parachain_is_updated_after_offboarding() {
		assert_eq!(
			select_parachains_to_update::<TestParachainsPipeline>(
Serban Iorga's avatar
Serban Iorga committed
				vec![(ParaId(PARA_ID), AvailableHeader::Missing)].into_iter().collect(),
				vec![(
					ParaId(PARA_ID),
					Some(BestParaHeadHash {
						at_relay_block_number: 0,
						head_hash: Default::default(),
					})
				)]
				.into_iter()
				.collect(),
				HeaderId(10, Default::default()),
			),
			vec![ParaId(PARA_ID)],
		);
	}

	#[test]
	fn parachain_is_updated_after_onboarding() {
		assert_eq!(
			select_parachains_to_update::<TestParachainsPipeline>(
Serban Iorga's avatar
Serban Iorga committed
				vec![(ParaId(PARA_ID), AvailableHeader::Available(PARA_0_HASH))]
				vec![(ParaId(PARA_ID), None)].into_iter().collect(),
				HeaderId(10, Default::default()),
			),
			vec![ParaId(PARA_ID)],
		);
	}

	#[test]
	fn parachain_is_updated_if_newer_head_is_known() {
		assert_eq!(
			select_parachains_to_update::<TestParachainsPipeline>(
Serban Iorga's avatar
Serban Iorga committed
				vec![(ParaId(PARA_ID), AvailableHeader::Available(PARA_1_HASH))]
				vec![(
					ParaId(PARA_ID),
					Some(BestParaHeadHash { at_relay_block_number: 0, head_hash: PARA_0_HASH })
				)]
				.into_iter()
				.collect(),
				HeaderId(10, Default::default()),
			),
			vec![ParaId(PARA_ID)],
		);
	}

	#[test]
	fn parachain_is_not_updated_if_source_head_is_unavailable() {
		assert_eq!(
			select_parachains_to_update::<TestParachainsPipeline>(
Serban Iorga's avatar
Serban Iorga committed
				vec![(ParaId(PARA_ID), AvailableHeader::Unavailable)].into_iter().collect(),
				vec![(
					ParaId(PARA_ID),
					Some(BestParaHeadHash { at_relay_block_number: 0, head_hash: PARA_0_HASH })
				)]
				.into_iter()
				.collect(),
				HeaderId(10, Default::default()),
			),
			vec![],
		);
	}

	#[test]
	fn is_update_required_works() {
		let mut sync_params = ParachainSyncParams {
			parachains: vec![ParaId(PARA_ID), ParaId(PARA_1_ID)],
			strategy: ParachainSyncStrategy::Any,
			stall_timeout: Duration::from_secs(60),
		};

		assert!(!is_update_required(&sync_params, &[]));
		assert!(is_update_required(&sync_params, &[ParaId(PARA_ID)]));
		assert!(is_update_required(&sync_params, &[ParaId(PARA_ID), ParaId(PARA_1_ID)]));

		sync_params.strategy = ParachainSyncStrategy::All;
		assert!(!is_update_required(&sync_params, &[]));
		assert!(!is_update_required(&sync_params, &[ParaId(PARA_ID)]));
		assert!(is_update_required(&sync_params, &[ParaId(PARA_ID), ParaId(PARA_1_ID)]));