Repository: paritytech/substrate
File: frame/message-queue/src/lib.rs (Rust)

Code before:
	/// * `message_count` > 0
	/// * `size` > 0
	/// * `end` > begin
	/// * Some(ready_neighbours)
	/// * If `ready_neighbours.next` == self.origin, then `ready_neighbours.prev` == self.origin
	///   (only queue in ring)
	///
	/// For Pages(begin to end-1) in BookState:
	///
	/// * `remaining` > 0
	/// * `remaining_size` > 0
	/// * `first` <= `last`
	/// * Every page can be decoded into peek_* functions

	pub fn do_try_state() -> Result<(), &'static str> {
		// No state to check
		if ServiceHead::<T>::get().is_none() {
			return Ok(())
		}

		//loop around this origin
		let starting_origin = ServiceHead::<T>::get().unwrap();

		let mut service_head = ServiceHead::<T>::get();

		loop {
			if let Some(head) = service_head {
				let head_book_state = BookStateFor::<T>::get(&head);
				assert!(
					head_book_state.message_count > 0,
					"There must be some messages if in ReadyRing"
				);
				assert!(head_book_state.size > 0, "There must be some messages if in ReadyRing");
				assert!(
					head_book_state.end > head_book_state.begin,
					"End > Begin if unprocessed messages exists"
				);
				assert!(
					head_book_state.ready_neighbours.is_some(),
					"There must be neighbours if in ReadyRing"
				);

				if head_book_state.ready_neighbours.as_ref().unwrap().next == head {
					assert_eq!(
						head_book_state.ready_neighbours.as_ref().unwrap().prev,
						head,
						"Can only happen if only queue in ReadyRing"
					);
				}

				for page_index in head_book_state.begin..head_book_state.end {

Review comment (suggestion):
I dont really get the logic here. There is no `else`.  
```suggestion
		while let Some(head) = Self::bump_service_head(&mut WeightMeter::max_limit()) {
```
Now you just need to check if it is at `starting_origin` again. Note that the bump function returns the current one.

Code after:
			InsufficientWeight => return ItemExecutionStatus::Bailed,
			Unprocessable { permanent: false } => return ItemExecutionStatus::NoProgress,
			Processed | Unprocessable { permanent: true } => true,
			Overweight => false,
		};

		if is_processed {
			book_state.message_count.saturating_dec();
			book_state.size.saturating_reduce(payload.len() as u64);
		}
		page.skip_first(is_processed);
		ItemExecutionStatus::Executed(is_processed)
	}

	/// Ensure the correctness of state of this pallet.
	///
	/// # Assumptions-
	///
	/// If `serviceHead` points to a ready Queue, then BookState of that Queue has:
	///
	/// * `message_count` > 0
	/// * `size` > 0
	/// * `end` > `begin`
	/// * Some(ready_neighbours)
	/// * If `ready_neighbours.next` == self.origin, then `ready_neighbours.prev` == self.origin
	///   (only queue in ring)
	///
	/// For Pages(begin to end-1) in BookState:
	///
	/// * `remaining` > 0
	/// * `remaining_size` > 0
	/// * `first` <= `last`
	/// * Every page can be decoded into peek_* functions
	#[cfg(any(test, feature = "try-runtime"))]
	pub fn do_try_state() -> Result<(), sp_runtime::TryRuntimeError> {
		// Checking memory corruption for BookStateFor
		ensure!(
			BookStateFor::<T>::iter_keys().count() == BookStateFor::<T>::iter_values().count(),
			"Memory Corruption in BookStateFor"
		);
		// Checking memory corruption for Pages
		ensure!(
			Pages::<T>::iter_keys().count() == Pages::<T>::iter_values().count(),
			"Memory Corruption in Pages"
		);

		// No state to check
		if ServiceHead::<T>::get().is_none() {
			return Ok(())
		}