Skip to content
lib.rs 69.5 KiB
Newer Older
				REGULAR_PAYLOAD,
			));
			assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof(
				RuntimeOrigin::signed(1),
				TestMessagesDeliveryProof(Ok((
					TEST_LANE_ID_2,
					InboundLaneData {
						last_confirmed_nonce: 1,
						relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)]
							.into_iter()
							.collect(),
					},
				))),
				UnrewardedRelayersState {
					unrewarded_relayer_entries: 1,
					messages_in_oldest_entry: 1,
					total_messages: 1,
					last_delivered_nonce: 1,
				},
			));

			// nothing is pruned yet
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().latest_received_nonce,
				1
			);
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce,
				1
			);
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().latest_received_nonce,
				1
			);
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce,
				1
			);

			// in block#2.on_idle lane messages of lane 1 are pruned
			let dbw = DbWeight::get();
			System::<TestRuntime>::set_block_number(2);
			assert_eq!(
				Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)),
				dbw.reads_writes(1, 2),
			);
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce,
				2
			);
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce,
				1
			);

			// in block#3.on_idle lane messages of lane 2 are pruned
			System::<TestRuntime>::set_block_number(3);

			assert_eq!(
				Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)),
				dbw.reads_writes(1, 2),
			);
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce,
				2
			);
			assert_eq!(
				outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce,
				2
			);
		});
	}

	#[test]
	fn outbound_message_from_unconfigured_lane_is_rejected() {
		run_test(|| {
			assert_noop!(
				send_message::<TestRuntime, ()>(
					RuntimeOrigin::signed(1),
					TEST_LANE_ID_3,
					REGULAR_PAYLOAD,
				),
				Error::<TestRuntime, ()>::InactiveOutboundLane,
			);
		});
	}

	#[test]
	fn test_bridge_messages_call_is_correctly_defined() {
		let account_id = 1;
		let message_proof: TestMessagesProof = Ok(vec![message(1, REGULAR_PAYLOAD)]).into();
		let message_delivery_proof = TestMessagesDeliveryProof(Ok((
			TEST_LANE_ID,
			InboundLaneData {
				last_confirmed_nonce: 1,
				relayers: vec![UnrewardedRelayer {
					relayer: 0,
					messages: DeliveredMessages::new(1, true),
				}]
				.into_iter()
				.collect(),
			},
		)));
		let unrewarded_relayer_state = UnrewardedRelayersState {
			unrewarded_relayer_entries: 1,
			total_messages: 1,
			last_delivered_nonce: 1,
			..Default::default()
		};

		let direct_receive_messages_proof_call = Call::<TestRuntime>::receive_messages_proof {
			relayer_id_at_bridged_chain: account_id,
			proof: message_proof.clone(),
			messages_count: 1,
			dispatch_weight: REGULAR_PAYLOAD.declared_weight,
		};
		let indirect_receive_messages_proof_call = BridgeMessagesCall::<
			AccountId,
			TestMessagesProof,
			TestMessagesDeliveryProof,
		>::receive_messages_proof {
			relayer_id_at_bridged_chain: account_id,
			proof: message_proof,
			messages_count: 1,
			dispatch_weight: REGULAR_PAYLOAD.declared_weight,
		};
		assert_eq!(
			direct_receive_messages_proof_call.encode(),
			indirect_receive_messages_proof_call.encode()
		);

		let direct_receive_messages_delivery_proof_call =
			Call::<TestRuntime>::receive_messages_delivery_proof {
				proof: message_delivery_proof.clone(),
				relayers_state: unrewarded_relayer_state.clone(),
			};
		let indirect_receive_messages_delivery_proof_call = BridgeMessagesCall::<
			AccountId,
			TestMessagesProof,
			TestMessagesDeliveryProof,
		>::receive_messages_delivery_proof {
			proof: message_delivery_proof,
			relayers_state: unrewarded_relayer_state,
		};
		assert_eq!(
			direct_receive_messages_delivery_proof_call.encode(),
			indirect_receive_messages_delivery_proof_call.encode()
		);
	}

	generate_owned_bridge_module_tests!(
		MessagesOperatingMode::Basic(BasicOperatingMode::Normal),
		MessagesOperatingMode::Basic(BasicOperatingMode::Halted)
	);
	#[test]
	fn inbound_storage_extra_proof_size_bytes_works() {
		let max_entries = crate::mock::MaxUnrewardedRelayerEntriesAtInboundLane::get() as usize;
		let max_msgs = crate::mock::MaxUnconfirmedMessagesAtInboundLane::get() as usize;
		fn storage(
			entry_count: usize,
			msg_count: usize,
		) -> RuntimeInboundLaneStorage<TestRuntime, ()> {
			RuntimeInboundLaneStorage {
				lane_id: Default::default(),
				cached_data: RefCell::new(Some(InboundLaneData {
					relayers: unrewarded_relayers_vec(entry_count, msg_count),
					last_confirmed_nonce: 0,
				})),
				_phantom: Default::default(),
			}
		}

		// when we have exactly `MaxUnrewardedRelayerEntriesAtInboundLane` unrewarded relayers
		assert_eq!(storage(max_entries, max_msgs).extra_proof_size_bytes(), 0);

		// when we have less than `MaxUnrewardedRelayerEntriesAtInboundLane` unrewarded relayers
		assert_eq!(
			storage(max_entries - 1, max_msgs).extra_proof_size_bytes(),
			unrewarded_relayer_entry(1).encoded_size() as u64
			storage(max_entries - 2, max_msgs).extra_proof_size_bytes(),
			2 * unrewarded_relayer_entry(1).encoded_size() as u64
		);

		// when we have more than `MaxUnrewardedRelayerEntriesAtInboundLane` unrewarded relayers
		// (shall not happen in practice)
		assert_eq!(storage(max_entries + 1, max_msgs).extra_proof_size_bytes(), 0);
	#[test]
	fn maybe_outbound_lanes_count_returns_correct_value() {
		assert_eq!(
			MaybeOutboundLanesCount::<TestRuntime, ()>::get(),
			Some(mock::ActiveOutboundLanes::get().len() as u32)
		);
	}