From 5a06771eccb27e58f09189ea34ce20d947b1db4f Mon Sep 17 00:00:00 2001
From: Clara van Staden <claravanstaden64@gmail.com>
Date: Wed, 21 Feb 2024 16:48:40 +0200
Subject: [PATCH] Snowbridge - Test pallet order (#3381)

- Adds a test to check the correct digest for Snowbridge outbound
messages. For the correct digest to be in the block, the the
MessageQueue pallet should be configured after the EthereumOutbound
queue pallet. The added test fails if the EthereumOutbound is configured
after the MessageQueue pallet.
- Adds a helper method `run_to_block_with_finalize` to simulate the
block finalizing. The existing `run_to_block` method does not finalize
and so it cannot successfully test this condition.

Closes: https://github.com/paritytech/polkadot-sdk/issues/3208

---------

Co-authored-by: claravanstaden <Cats 4 life!>
---
 Cargo.lock                                    |   3 +
 bridges/snowbridge/README.md                  |  24 ++--
 bridges/snowbridge/pallets/system/src/lib.rs  |   4 +-
 .../snowbridge/runtime/test-common/src/lib.rs | 112 +++++++++++++++--
 .../snowbridge/scripts/contribute-upstream.sh |  80 ++++++++++++
 .../scripts/verify-pallets-build.sh           | 116 ------------------
 .../runtimes/assets/test-utils/Cargo.toml     |   2 +
 .../assets/test-utils/src/test_cases.rs       |  18 ++-
 .../test-utils/src/test_cases_over_bridge.rs  |   9 +-
 .../bridge-hubs/bridge-hub-rococo/src/lib.rs  |   2 +-
 .../bridge-hub-rococo/tests/snowbridge.rs     |  32 ++++-
 .../bridge-hubs/test-utils/Cargo.toml         |   2 +
 .../test-utils/src/test_cases/helpers.rs      |   4 +-
 .../parachains/runtimes/test-utils/Cargo.toml |   2 +
 .../parachains/runtimes/test-utils/src/lib.rs |  71 ++++++++++-
 .../runtimes/test-utils/src/test_cases.rs     |   6 +-
 16 files changed, 332 insertions(+), 155 deletions(-)
 create mode 100755 bridges/snowbridge/scripts/contribute-upstream.sh
 delete mode 100755 bridges/snowbridge/scripts/verify-pallets-build.sh

diff --git a/Cargo.lock b/Cargo.lock
index 9f2a1a06891..93ee9cc99c4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1054,6 +1054,7 @@ dependencies = [
  "pallet-balances",
  "pallet-collator-selection",
  "pallet-session",
+ "pallet-timestamp",
  "pallet-xcm",
  "pallet-xcm-bridge-hub-router",
  "parachains-common",
@@ -2099,6 +2100,7 @@ dependencies = [
  "pallet-bridge-messages",
  "pallet-bridge-parachains",
  "pallet-bridge-relayers",
+ "pallet-timestamp",
  "pallet-utility",
  "parachains-common",
  "parachains-runtimes-test-utils",
@@ -11430,6 +11432,7 @@ dependencies = [
  "pallet-balances",
  "pallet-collator-selection",
  "pallet-session",
+ "pallet-timestamp",
  "pallet-xcm",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
diff --git a/bridges/snowbridge/README.md b/bridges/snowbridge/README.md
index 49b9c2eaf55..6561df40112 100644
--- a/bridges/snowbridge/README.md
+++ b/bridges/snowbridge/README.md
@@ -1,32 +1,40 @@
-# Snowbridge
-[![codecov](https://codecov.io/gh/Snowfork/snowbridge/branch/main/graph/badge.svg?token=9hvgSws4rN)](https://codecov.io/gh/Snowfork/snowbridge)
+# Snowbridge &middot;
+[![codecov](https://codecov.io/gh/Snowfork/polkadot-sdk/branch/snowbridge/graph/badge.svg?token=9hvgSws4rN)](https://codecov.io/gh/Snowfork/polkadot-sdk)
 ![GitHub](https://img.shields.io/github/license/Snowfork/snowbridge)
 
 Snowbridge is a trustless bridge between Polkadot and Ethereum. For documentation, visit https://docs.snowbridge.network.
 
 ## Components
 
+The Snowbridge project lives in two repositories:
+
+- [Snowfork/Polkadot-sdk](https://github.com/Snowfork/polkadot-sdk): The Snowbridge parachain and pallets live in
+a fork of the Polkadot SDK. Changes are eventually contributed back to
+[paritytech/Polkadot-sdk](https://github.com/paritytech/polkadot-sdk)
+- [Snowfork/snowbridge](https://github.com/Snowfork/snowbridge): The rest of the Snowbridge components, like contracts,
+off-chain relayer, end-to-end tests and test-net setup code.
+
 ### Parachain
 
-Polkadot parachain and our pallets. See [parachain/README.md](https://github.com/Snowfork/snowbridge/blob/main/parachain/README.md).
+Polkadot parachain and our pallets. See [README.md](https://github.com/Snowfork/polkadot-sdk/blob/snowbridge/bridges/snowbridge/README.md).
 
 ### Contracts
 
-Ethereum contracts and unit tests. See [contracts/README.md](https://github.com/Snowfork/snowbridge/blob/main/contracts/README.md)
+Ethereum contracts and unit tests. See [Snowfork/snowbridge/contracts/README.md](https://github.com/Snowfork/snowbridge/blob/main/contracts/README.md)
 
 ### Relayer
 
 Off-chain relayer services for relaying messages between Polkadot and Ethereum. See
-[relayer/README.md](https://github.com/Snowfork/snowbridge/blob/main/relayer/README.md)
+[Snowfork/snowbridge/relayer/README.md](https://github.com/Snowfork/snowbridge/blob/main/relayer/README.md)
 
 ### Local Testnet
 
 Scripts to provision a local testnet, running the above services to bridge between local deployments of Polkadot and
-Ethereum. See [web/packages/test/README.md](https://github.com/Snowfork/snowbridge/blob/main/web/packages/test/README.md).
+Ethereum. See [Snowfork/snowbridge/web/packages/test/README.md](https://github.com/Snowfork/snowbridge/blob/main/web/packages/test/README.md).
 
 ### Smoke Tests
 
-Integration tests for our local testnet. See [smoketest/README.md](https://github.com/Snowfork/snowbridge/blob/main/smoketest/README.md).
+Integration tests for our local testnet. See [Snowfork/snowbridge/smoketest/README.md](https://github.com/Snowfork/snowbridge/blob/main/smoketest/README.md).
 
 ## Development
 
@@ -83,7 +91,7 @@ direnv allow
 
 ### Upgrading the Rust toolchain
 
-Sometimes we would like to upgrade rust toolchain. First update `parachain/rust-toolchain.toml` as required and then
+Sometimes we would like to upgrade rust toolchain. First update `rust-toolchain.toml` as required and then
 update `flake.lock` running
 ```sh
 nix flake lock --update-input rust-overlay
diff --git a/bridges/snowbridge/pallets/system/src/lib.rs b/bridges/snowbridge/pallets/system/src/lib.rs
index b7f38fb753d..6e5ceb5e9b1 100644
--- a/bridges/snowbridge/pallets/system/src/lib.rs
+++ b/bridges/snowbridge/pallets/system/src/lib.rs
@@ -37,8 +37,6 @@
 //! `force_update_channel` and extrinsics to manage agents and channels for system parachains.
 #![cfg_attr(not(feature = "std"), no_std)]
 
-pub use pallet::*;
-
 #[cfg(test)]
 mod mock;
 
@@ -79,6 +77,8 @@ use xcm_executor::traits::ConvertLocation;
 #[cfg(feature = "runtime-benchmarks")]
 use frame_support::traits::OriginTrait;
 
+pub use pallet::*;
+
 pub type BalanceOf<T> =
 	<<T as pallet::Config>::Token as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
 pub type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
diff --git a/bridges/snowbridge/runtime/test-common/src/lib.rs b/bridges/snowbridge/runtime/test-common/src/lib.rs
index c9bbce98e57..29b0e738c18 100644
--- a/bridges/snowbridge/runtime/test-common/src/lib.rs
+++ b/bridges/snowbridge/runtime/test-common/src/lib.rs
@@ -13,9 +13,9 @@ use parachains_runtimes_test_utils::{
 };
 use snowbridge_core::{ChannelId, ParaId};
 use snowbridge_pallet_ethereum_client_fixtures::*;
-use sp_core::H160;
+use sp_core::{H160, U256};
 use sp_keyring::AccountKeyring::*;
-use sp_runtime::{traits::Header, AccountId32, SaturatedConversion, Saturating};
+use sp_runtime::{traits::Header, AccountId32, DigestItem, SaturatedConversion, Saturating};
 use xcm::{
 	latest::prelude::*,
 	v3::Error::{self, Barrier},
@@ -53,7 +53,8 @@ where
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
-		+ snowbridge_pallet_outbound_queue::Config,
+		+ snowbridge_pallet_outbound_queue::Config
+		+ pallet_timestamp::Config,
 	XcmConfig: xcm_executor::Config,
 {
 	let assethub_parachain_location = Location::new(1, Parachain(assethub_parachain_id));
@@ -125,7 +126,8 @@ pub fn send_transfer_token_message_success<Runtime, XcmConfig>(
 		+ pallet_message_queue::Config
 		+ cumulus_pallet_parachain_system::Config
 		+ snowbridge_pallet_outbound_queue::Config
-		+ snowbridge_pallet_system::Config,
+		+ snowbridge_pallet_system::Config
+		+ pallet_timestamp::Config,
 	XcmConfig: xcm_executor::Config,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 	<Runtime as frame_system::Config>::AccountId: From<sp_runtime::AccountId32> + AsRef<[u8]>,
@@ -193,12 +195,100 @@ pub fn send_transfer_token_message_success<Runtime, XcmConfig>(
 
 			let digest = included_head.digest();
 
-			//let digest = frame_system::Pallet::<Runtime>::digest();
 			let digest_items = digest.logs();
 			assert!(digest_items.len() == 1 && digest_items[0].as_other().is_some());
 		});
 }
 
+pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works<
+	Runtime,
+	XcmConfig,
+	AllPalletsWithoutSystem,
+>(
+	collator_session_key: CollatorSessionKeys<Runtime>,
+	runtime_para_id: u32,
+	assethub_parachain_id: u32,
+	weth_contract_address: H160,
+	destination_address: H160,
+	fee_amount: u128,
+	snowbridge_pallet_outbound_queue: Box<
+		dyn Fn(Vec<u8>) -> Option<snowbridge_pallet_outbound_queue::Event<Runtime>>,
+	>,
+) where
+	Runtime: frame_system::Config
+		+ pallet_balances::Config
+		+ pallet_session::Config
+		+ pallet_xcm::Config
+		+ parachain_info::Config
+		+ pallet_collator_selection::Config
+		+ pallet_message_queue::Config
+		+ cumulus_pallet_parachain_system::Config
+		+ snowbridge_pallet_outbound_queue::Config
+		+ snowbridge_pallet_system::Config
+		+ pallet_timestamp::Config,
+	XcmConfig: xcm_executor::Config,
+	AllPalletsWithoutSystem:
+		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
+	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
+	<Runtime as frame_system::Config>::AccountId: From<sp_runtime::AccountId32> + AsRef<[u8]>,
+{
+	ExtBuilder::<Runtime>::default()
+		.with_collators(collator_session_key.collators())
+		.with_session_keys(collator_session_key.session_keys())
+		.with_para_id(runtime_para_id.into())
+		.with_tracing()
+		.build()
+		.execute_with(|| {
+			<snowbridge_pallet_system::Pallet<Runtime>>::initialize(
+				runtime_para_id.into(),
+				assethub_parachain_id.into(),
+			)
+			.unwrap();
+
+			// fund asset hub sovereign account enough so it can pay fees
+			initial_fund::<Runtime>(assethub_parachain_id, 5_000_000_000_000);
+
+			let outcome = send_transfer_token_message::<Runtime, XcmConfig>(
+				assethub_parachain_id,
+				weth_contract_address,
+				destination_address,
+				fee_amount,
+			);
+
+			assert_ok!(outcome.ensure_complete());
+
+			// check events
+			let mut events = <frame_system::Pallet<Runtime>>::events()
+				.into_iter()
+				.filter_map(|e| snowbridge_pallet_outbound_queue(e.event.encode()));
+			assert!(events.any(|e| matches!(
+				e,
+				snowbridge_pallet_outbound_queue::Event::MessageQueued { .. }
+			)));
+
+			let next_block_number: U256 = <frame_system::Pallet<Runtime>>::block_number()
+				.saturating_add(BlockNumberFor::<Runtime>::from(1u32))
+				.into();
+
+			let included_head =
+				RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block_with_finalize(
+					next_block_number.as_u32(),
+				);
+			let digest = included_head.digest();
+			let digest_items = digest.logs();
+
+			let mut found_outbound_digest = false;
+			for digest_item in digest_items {
+				match digest_item {
+					DigestItem::Other(_) => found_outbound_digest = true,
+					_ => {},
+				}
+			}
+
+			assert_eq!(found_outbound_digest, true);
+		});
+}
+
 pub fn send_unpaid_transfer_token_message<Runtime, XcmConfig>(
 	collator_session_key: CollatorSessionKeys<Runtime>,
 	runtime_para_id: u32,
@@ -213,7 +303,8 @@ pub fn send_unpaid_transfer_token_message<Runtime, XcmConfig>(
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
-		+ snowbridge_pallet_outbound_queue::Config,
+		+ snowbridge_pallet_outbound_queue::Config
+		+ pallet_timestamp::Config,
 	XcmConfig: xcm_executor::Config,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 {
@@ -301,7 +392,8 @@ pub fn send_transfer_token_message_failure<Runtime, XcmConfig>(
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
 		+ snowbridge_pallet_outbound_queue::Config
-		+ snowbridge_pallet_system::Config,
+		+ snowbridge_pallet_system::Config
+		+ pallet_timestamp::Config,
 	XcmConfig: xcm_executor::Config,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 {
@@ -349,7 +441,8 @@ pub fn ethereum_extrinsic<Runtime>(
 		+ cumulus_pallet_parachain_system::Config
 		+ snowbridge_pallet_outbound_queue::Config
 		+ snowbridge_pallet_system::Config
-		+ snowbridge_pallet_ethereum_client::Config,
+		+ snowbridge_pallet_ethereum_client::Config
+		+ pallet_timestamp::Config,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 	<Runtime as pallet_utility::Config>::RuntimeCall:
 		From<snowbridge_pallet_ethereum_client::Call<Runtime>>,
@@ -430,7 +523,8 @@ pub fn ethereum_to_polkadot_message_extrinsics_work<Runtime>(
 		+ cumulus_pallet_parachain_system::Config
 		+ snowbridge_pallet_outbound_queue::Config
 		+ snowbridge_pallet_system::Config
-		+ snowbridge_pallet_ethereum_client::Config,
+		+ snowbridge_pallet_ethereum_client::Config
+		+ pallet_timestamp::Config,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 	<Runtime as pallet_utility::Config>::RuntimeCall:
 		From<snowbridge_pallet_ethereum_client::Call<Runtime>>,
diff --git a/bridges/snowbridge/scripts/contribute-upstream.sh b/bridges/snowbridge/scripts/contribute-upstream.sh
new file mode 100755
index 00000000000..8aa2d2a7035
--- /dev/null
+++ b/bridges/snowbridge/scripts/contribute-upstream.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+
+# A script to cleanup the Snowfork fork of the polkadot-sdk to contribute it upstream back to parity/polkadot-sdk
+# ./bridges/snowbridge/scripts/contribute-upstream.sh <branchname>
+
+# show CLI help
+function show_help() {
+  set +x
+  echo " "
+  echo Error: $1
+  echo "Usage:"
+  echo "  ./bridges/snowbridge/scripts/contribute-upstream.sh <branchname>         Exit with code 0 if pallets code is well decoupled from the other code in the repo"
+  exit 1
+}
+
+if [[ -z "$1" ]]; then
+    echo "Please provide a branch name you would like your upstream branch to be named"
+    exit 1
+fi
+
+branch_name=$1
+
+set -eux
+
+# let's avoid any restrictions on where this script can be called for - snowbridge repo may be
+# plugged into any other repo folder. So the script (and other stuff that needs to be removed)
+# may be located either in call dir, or one of it subdirs.
+SNOWBRIDGE_FOLDER="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/../"
+
+# Get the current Git branch name
+current_branch=$(git rev-parse --abbrev-ref HEAD)
+
+if [ "$current_branch" = "$branch_name" ] || git branch | grep -q "$branch_name"; then
+    echo "Already on requested branch or branch exists, not creating."
+else
+    git branch "$branch_name"
+fi
+
+git checkout "$branch_name"
+
+# remove everything we think is not required for our needs
+rm -rf rust-toolchain.toml
+rm -rf $SNOWBRIDGE_FOLDER/.cargo
+rm -rf $SNOWBRIDGE_FOLDER/.github
+rm -rf $SNOWBRIDGE_FOLDER/SECURITY.md
+rm -rf $SNOWBRIDGE_FOLDER/.gitignore
+rm -rf $SNOWBRIDGE_FOLDER/templates
+rm -rf $SNOWBRIDGE_FOLDER/pallets/ethereum-client/fuzz
+
+pushd $SNOWBRIDGE_FOLDER
+
+# let's test if everything we need compiles
+cargo check -p snowbridge-pallet-ethereum-client
+cargo check -p snowbridge-pallet-ethereum-client --features runtime-benchmarks
+cargo check -p snowbridge-pallet-ethereum-client --features try-runtime
+cargo check -p snowbridge-pallet-inbound-queue
+cargo check -p snowbridge-pallet-inbound-queue --features runtime-benchmarks
+cargo check -p snowbridge-pallet-inbound-queue --features try-runtime
+cargo check -p snowbridge-pallet-outbound-queue
+cargo check -p snowbridge-pallet-outbound-queue --features runtime-benchmarks
+cargo check -p snowbridge-pallet-outbound-queue --features try-runtime
+cargo check -p snowbridge-pallet-system
+cargo check -p snowbridge-pallet-system --features runtime-benchmarks
+cargo check -p snowbridge-pallet-system --features try-runtime
+
+# we're removing lock file after all checks are done. Otherwise we may use different
+# Substrate/Polkadot/Cumulus commits and our checks will fail
+rm -f $SNOWBRIDGE_FOLDER/Cargo.toml
+rm -f $SNOWBRIDGE_FOLDER/Cargo.lock
+
+popd
+
+# Replace Parity's CI files, that we have overwritten in our fork, to run our own CI
+rm -rf .github
+git remote -v | grep -w parity || git remote add parity https://github.com/paritytech/polkadot-sdk
+git fetch parity master
+git checkout parity/master -- .github
+git add -- .github
+
+echo "OK"
diff --git a/bridges/snowbridge/scripts/verify-pallets-build.sh b/bridges/snowbridge/scripts/verify-pallets-build.sh
deleted file mode 100755
index a62f48c84d4..00000000000
--- a/bridges/snowbridge/scripts/verify-pallets-build.sh
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/bin/bash
-
-# A script to remove everything from snowbridge repository/subtree, except:
-#
-# - parachain
-# - readme
-# - license
-
-set -eu
-
-# show CLI help
-function show_help() {
-  set +x
-  echo " "
-  echo Error: $1
-  echo "Usage:"
-  echo "  ./scripts/verify-pallets-build.sh          Exit with code 0 if pallets code is well decoupled from the other code in the repo"
-  echo "Options:"
-  echo "  --no-revert                                Leaves only runtime code on exit"
-  echo "  --ignore-git-state                         Ignores git actual state"
-  exit 1
-}
-
-# parse CLI args
-NO_REVERT=
-IGNORE_GIT_STATE=
-for i in "$@"
-do
-	case $i in
-		--no-revert)
-			NO_REVERT=true
-			shift
-			;;
-		--ignore-git-state)
-			IGNORE_GIT_STATE=true
-			shift
-			;;
-		*)
-			show_help "Unknown option: $i"
-			;;
-	esac
-done
-
-# the script is able to work only on clean git copy, unless we want to ignore this check
-[[ ! -z "${IGNORE_GIT_STATE}" ]] || [[ -z "$(git status --porcelain)" ]] || { echo >&2 "The git copy must be clean"; exit 1; }
-
-# let's avoid any restrictions on where this script can be called for - snowbridge repo may be
-# plugged into any other repo folder. So the script (and other stuff that needs to be removed)
-# may be located either in call dir, or one of it subdirs.
-SNOWBRIDGE_FOLDER="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/../.."
-
-# remove everything we think is not required for our needs
-rm -rf $SNOWBRIDGE_FOLDER/.cargo
-rm -rf $SNOWBRIDGE_FOLDER/.github
-rm -rf $SNOWBRIDGE_FOLDER/contracts
-rm -rf $SNOWBRIDGE_FOLDER/codecov.yml
-rm -rf $SNOWBRIDGE_FOLDER/docs
-rm -rf $SNOWBRIDGE_FOLDER/hooks
-rm -rf $SNOWBRIDGE_FOLDER/relayer
-rm -rf $SNOWBRIDGE_FOLDER/scripts
-rm -rf $SNOWBRIDGE_FOLDER/SECURITY.md
-rm -rf $SNOWBRIDGE_FOLDER/smoketest
-rm -rf $SNOWBRIDGE_FOLDER/web
-rm -rf $SNOWBRIDGE_FOLDER/.envrc-example
-rm -rf $SNOWBRIDGE_FOLDER/.gitbook.yaml
-rm -rf $SNOWBRIDGE_FOLDER/.gitignore
-rm -rf $SNOWBRIDGE_FOLDER/.gitmodules
-rm -rf $SNOWBRIDGE_FOLDER/_typos.toml
-rm -rf $SNOWBRIDGE_FOLDER/_codecov.yml
-rm -rf $SNOWBRIDGE_FOLDER/flake.lock
-rm -rf $SNOWBRIDGE_FOLDER/flake.nix
-rm -rf $SNOWBRIDGE_FOLDER/go.work
-rm -rf $SNOWBRIDGE_FOLDER/go.work.sum
-rm -rf $SNOWBRIDGE_FOLDER/polkadot-sdk
-rm -rf $SNOWBRIDGE_FOLDER/rust-toolchain.toml
-rm -rf $SNOWBRIDGE_FOLDER/parachain/rustfmt.toml
-rm -rf $SNOWBRIDGE_FOLDER/parachain/.gitignore
-rm -rf $SNOWBRIDGE_FOLDER/parachain/templates
-rm -rf $SNOWBRIDGE_FOLDER/parachain/.cargo
-rm -rf $SNOWBRIDGE_FOLDER/parachain/.config
-rm -rf $SNOWBRIDGE_FOLDER/parachain/pallets/ethereum-client/fuzz
-
-cd bridges/snowbridge/parachain
-
-# fix polkadot-sdk paths in Cargo.toml files
-find "." -name 'Cargo.toml' | while read -r file; do
-    replace=$(printf '../../' )
-    if [[ "$(uname)" = "Darwin" ]] || [[ "$(uname)" = *BSD ]]; then
-        sed -i '' "s|polkadot-sdk/|$replace|g" "$file"
-    else
-        sed -i "s|polkadot-sdk/|$replace|g" "$file"
-    fi
-done
-
-# let's test if everything we need compiles
-cargo check -p snowbridge-pallet-ethereum-client
-cargo check -p snowbridge-pallet-ethereum-client --features runtime-benchmarks
-cargo check -p snowbridge-pallet-ethereum-client --features try-runtime
-cargo check -p snowbridge-pallet-inbound-queue
-cargo check -p snowbridge-pallet-inbound-queue --features runtime-benchmarks
-cargo check -p snowbridge-pallet-inbound-queue --features try-runtime
-cargo check -p snowbridge-pallet-outbound-queue
-cargo check -p snowbridge-pallet-outbound-queue --features runtime-benchmarks
-cargo check -p snowbridge-pallet-outbound-queue --features try-runtime
-cargo check -p snowbridge-pallet-system
-cargo check -p snowbridge-pallet-system --features runtime-benchmarks
-cargo check -p snowbridge-pallet-system --features try-runtime
-
-cd -
-
-# we're removing lock file after all checks are done. Otherwise we may use different
-# Substrate/Polkadot/Cumulus commits and our checks will fail
-rm -f $SNOWBRIDGE_FOLDER/parachain/Cargo.toml
-rm -f $SNOWBRIDGE_FOLDER/parachain/Cargo.lock
-
-echo "OK"
diff --git a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml
index 89c4925cb1a..883c93c97b4 100644
--- a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml
@@ -17,6 +17,7 @@ frame-support = { path = "../../../../../substrate/frame/support", default-featu
 frame-system = { path = "../../../../../substrate/frame/system", default-features = false }
 pallet-assets = { path = "../../../../../substrate/frame/assets", default-features = false }
 pallet-balances = { path = "../../../../../substrate/frame/balances", default-features = false }
+pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default-features = false }
 pallet-session = { path = "../../../../../substrate/frame/session", default-features = false }
 sp-io = { path = "../../../../../substrate/primitives/io", default-features = false }
 sp-runtime = { path = "../../../../../substrate/primitives/runtime", default-features = false }
@@ -59,6 +60,7 @@ std = [
 	"pallet-balances/std",
 	"pallet-collator-selection/std",
 	"pallet-session/std",
+	"pallet-timestamp/std",
 	"pallet-xcm-bridge-hub-router/std",
 	"pallet-xcm/std",
 	"parachain-info/std",
diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs
index 4007d926983..53e10956bd0 100644
--- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs
+++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs
@@ -70,7 +70,8 @@ pub fn teleports_for_native_asset_works<
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
-		+ cumulus_pallet_xcmp_queue::Config,
+		+ cumulus_pallet_xcmp_queue::Config
+		+ pallet_timestamp::Config,
 	AllPalletsWithoutSystem:
 		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
@@ -350,7 +351,8 @@ pub fn teleports_for_foreign_assets_works<
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
 		+ cumulus_pallet_xcmp_queue::Config
-		+ pallet_assets::Config<ForeignAssetsPalletInstance>,
+		+ pallet_assets::Config<ForeignAssetsPalletInstance>
+		+ pallet_timestamp::Config,
 	AllPalletsWithoutSystem:
 		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
@@ -701,7 +703,8 @@ pub fn asset_transactor_transfer_with_local_consensus_currency_works<Runtime, Xc
 		+ pallet_xcm::Config
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
-		+ cumulus_pallet_parachain_system::Config,
+		+ cumulus_pallet_parachain_system::Config
+		+ pallet_timestamp::Config,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 	BalanceOf<Runtime>: From<Balance>,
@@ -826,7 +829,8 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works<
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
-		+ pallet_assets::Config<AssetsPalletInstance>,
+		+ pallet_assets::Config<AssetsPalletInstance>
+		+ pallet_timestamp::Config,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 	BalanceOf<Runtime>: From<Balance>,
@@ -1093,7 +1097,8 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
-		+ pallet_assets::Config<ForeignAssetsPalletInstance>,
+		+ pallet_assets::Config<ForeignAssetsPalletInstance>
+		+ pallet_timestamp::Config,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 	BalanceOf<Runtime>: From<Balance>,
@@ -1422,7 +1427,8 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works<
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
-		+ cumulus_pallet_xcmp_queue::Config,
+		+ cumulus_pallet_xcmp_queue::Config
+		+ pallet_timestamp::Config,
 	AllPalletsWithoutSystem:
 		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs
index 66ed3417951..1cce3b647cf 100644
--- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs
+++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs
@@ -70,7 +70,8 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works<
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
-		+ cumulus_pallet_xcmp_queue::Config,
+		+ cumulus_pallet_xcmp_queue::Config
+		+ pallet_timestamp::Config,
 	AllPalletsWithoutSystem:
 		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
@@ -347,7 +348,8 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works<
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
 		+ cumulus_pallet_xcmp_queue::Config
-		+ pallet_assets::Config<ForeignAssetsPalletInstance>,
+		+ pallet_assets::Config<ForeignAssetsPalletInstance>
+		+ pallet_timestamp::Config,
 	AllPalletsWithoutSystem:
 		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
 	AccountIdOf<Runtime>: Into<[u8; 32]> + From<[u8; 32]>,
@@ -510,7 +512,8 @@ pub fn report_bridge_status_from_xcm_bridge_router_works<
 		+ pallet_collator_selection::Config
 		+ cumulus_pallet_parachain_system::Config
 		+ cumulus_pallet_xcmp_queue::Config
-		+ pallet_xcm_bridge_hub_router::Config<XcmBridgeHubRouterInstance>,
+		+ pallet_xcm_bridge_hub_router::Config<XcmBridgeHubRouterInstance>
+		+ pallet_timestamp::Config,
 	AllPalletsWithoutSystem:
 		OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
 	AccountIdOf<Runtime>: Into<[u8; 32]>,
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
index d1eac089f67..ae50d2a93cb 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
@@ -730,7 +730,7 @@ construct_runtime!(
 
 		// Message Queue. Importantly, is registered last so that messages are processed after
 		// the `on_initialize` hooks of bridging pallets.
-		MessageQueue: pallet_message_queue = 250,
+		MessageQueue: pallet_message_queue = 175,
 	}
 );
 
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs
index b2e5cc9ef06..b9f43624b65 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs
@@ -20,9 +20,9 @@ use bp_polkadot_core::Signature;
 use bridge_hub_rococo_runtime::{
 	bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages,
 	bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages,
-	xcm_config::XcmConfig, BridgeRejectObsoleteHeadersAndMessages, Executive,
-	MessageQueueServiceWeight, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, SignedExtra,
-	UncheckedExtrinsic,
+	xcm_config::XcmConfig, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages,
+	Executive, MessageQueueServiceWeight, Runtime, RuntimeCall, RuntimeEvent, SessionKeys,
+	SignedExtra, UncheckedExtrinsic,
 };
 use codec::{Decode, Encode};
 use cumulus_primitives_core::XcmError::{FailedToTransactAsset, NotHoldingFees};
@@ -135,6 +135,32 @@ fn ethereum_to_polkadot_message_extrinsics_work() {
 	);
 }
 
+/// Tests that the digest items are as expected when a Ethereum Outbound message is received.
+/// If the MessageQueue pallet is configured before (i.e. the MessageQueue pallet is listed before
+/// the EthereumOutboundQueue in the construct_runtime macro) the EthereumOutboundQueue, this test
+/// will fail.
+#[test]
+pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works() {
+	snowbridge_runtime_test_common::ethereum_outbound_queue_processes_messages_before_message_queue_works::<
+		Runtime,
+		XcmConfig,
+		AllPalletsWithoutSystem,
+	>(
+		collator_session_keys(),
+		1013,
+		1000,
+		H160::random(),
+		H160::random(),
+		DefaultBridgeHubEthereumBaseFee::get(),
+		Box::new(|runtime_event_encoded: Vec<u8>| {
+			match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
+				Ok(RuntimeEvent::EthereumOutboundQueue(event)) => Some(event),
+				_ => None,
+			}
+		}),
+	)
+}
+
 fn construct_extrinsic(
 	sender: sp_keyring::AccountKeyring,
 	call: RuntimeCall,
diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml
index d34b5cd0eed..5f2a6e050d8 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml
+++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml
@@ -25,6 +25,7 @@ sp-std = { path = "../../../../../substrate/primitives/std", default-features =
 sp-tracing = { path = "../../../../../substrate/primitives/tracing" }
 pallet-balances = { path = "../../../../../substrate/frame/balances", default-features = false }
 pallet-utility = { path = "../../../../../substrate/frame/utility", default-features = false }
+pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default-features = false }
 
 # Cumulus
 asset-test-utils = { path = "../../assets/test-utils" }
@@ -73,6 +74,7 @@ std = [
 	"pallet-bridge-messages/std",
 	"pallet-bridge-parachains/std",
 	"pallet-bridge-relayers/std",
+	"pallet-timestamp/std",
 	"pallet-utility/std",
 	"parachains-common/std",
 	"parachains-runtimes-test-utils/std",
diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs
index 4f634c184aa..2b48f2e3d51 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs
@@ -197,7 +197,9 @@ where
 pub(crate) fn initialize_bridge_grandpa_pallet<Runtime, GPI>(
 	init_data: bp_header_chain::InitializationData<BridgedHeader<Runtime, GPI>>,
 ) where
-	Runtime: BridgeGrandpaConfig<GPI>,
+	Runtime: BridgeGrandpaConfig<GPI>
+		+ cumulus_pallet_parachain_system::Config
+		+ pallet_timestamp::Config,
 {
 	pallet_bridge_grandpa::Pallet::<Runtime, GPI>::initialize(
 		RuntimeHelper::<Runtime>::root_origin(),
diff --git a/cumulus/parachains/runtimes/test-utils/Cargo.toml b/cumulus/parachains/runtimes/test-utils/Cargo.toml
index a61e05de13f..eda88beb7da 100644
--- a/cumulus/parachains/runtimes/test-utils/Cargo.toml
+++ b/cumulus/parachains/runtimes/test-utils/Cargo.toml
@@ -17,6 +17,7 @@ frame-support = { path = "../../../../substrate/frame/support", default-features
 frame-system = { path = "../../../../substrate/frame/system", default-features = false }
 pallet-balances = { path = "../../../../substrate/frame/balances", default-features = false }
 pallet-session = { path = "../../../../substrate/frame/session", default-features = false }
+pallet-timestamp = { path = "../../../../substrate/frame/timestamp", default-features = false }
 sp-consensus-aura = { path = "../../../../substrate/primitives/consensus/aura", default-features = false }
 sp-io = { path = "../../../../substrate/primitives/io", default-features = false }
 sp-runtime = { path = "../../../../substrate/primitives/runtime", default-features = false }
@@ -59,6 +60,7 @@ std = [
 	"pallet-balances/std",
 	"pallet-collator-selection/std",
 	"pallet-session/std",
+	"pallet-timestamp/std",
 	"pallet-xcm/std",
 	"parachain-info/std",
 	"polkadot-parachain-primitives/std",
diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs
index b4eb57fcb66..e62daa16a12 100644
--- a/cumulus/parachains/runtimes/test-utils/src/lib.rs
+++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs
@@ -34,7 +34,7 @@ use polkadot_parachain_primitives::primitives::{
 };
 use sp_consensus_aura::{SlotDuration, AURA_ENGINE_ID};
 use sp_core::{Encode, U256};
-use sp_runtime::{traits::Header, BuildStorage, Digest, DigestItem};
+use sp_runtime::{traits::Header, BuildStorage, Digest, DigestItem, SaturatedConversion};
 use xcm::{
 	latest::{Asset, Location, XcmContext, XcmHash},
 	prelude::*,
@@ -129,6 +129,7 @@ pub trait BasicParachainRuntime:
 	+ parachain_info::Config
 	+ pallet_collator_selection::Config
 	+ cumulus_pallet_parachain_system::Config
+	+ pallet_timestamp::Config
 {
 }
 
@@ -140,7 +141,8 @@ where
 		+ pallet_xcm::Config
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
-		+ cumulus_pallet_parachain_system::Config,
+		+ cumulus_pallet_parachain_system::Config
+		+ pallet_timestamp::Config,
 	ValidatorIdOf<T>: From<AccountIdOf<T>>,
 {
 }
@@ -259,8 +261,10 @@ pub struct RuntimeHelper<Runtime, AllPalletsWithoutSystem>(
 );
 /// Utility function that advances the chain to the desired block number.
 /// If an author is provided, that author information is injected to all the blocks in the meantime.
-impl<Runtime: frame_system::Config, AllPalletsWithoutSystem>
-	RuntimeHelper<Runtime, AllPalletsWithoutSystem>
+impl<
+		Runtime: frame_system::Config + cumulus_pallet_parachain_system::Config + pallet_timestamp::Config,
+		AllPalletsWithoutSystem,
+	> RuntimeHelper<Runtime, AllPalletsWithoutSystem>
 where
 	AccountIdOf<Runtime>:
 		Into<<<Runtime as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId>,
@@ -296,6 +300,65 @@ where
 		last_header.expect("run_to_block empty block range")
 	}
 
+	pub fn run_to_block_with_finalize(n: u32) -> HeaderFor<Runtime> {
+		let mut last_header = None;
+		loop {
+			let block_number = frame_system::Pallet::<Runtime>::block_number();
+			if block_number >= n.into() {
+				break
+			}
+			// Set the new block number and author
+			let header = frame_system::Pallet::<Runtime>::finalize();
+
+			let pre_digest = Digest {
+				logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, block_number.encode())],
+			};
+			frame_system::Pallet::<Runtime>::reset_events();
+
+			let next_block_number = block_number + 1u32.into();
+			frame_system::Pallet::<Runtime>::initialize(
+				&next_block_number,
+				&header.hash(),
+				&pre_digest,
+			);
+			AllPalletsWithoutSystem::on_initialize(next_block_number);
+
+			let parent_head = HeadData(header.encode());
+			let sproof_builder = RelayStateSproofBuilder {
+				para_id: <Runtime>::SelfParaId::get(),
+				included_para_head: parent_head.clone().into(),
+				..Default::default()
+			};
+
+			let (relay_parent_storage_root, relay_chain_state) =
+				sproof_builder.into_state_root_and_proof();
+			let inherent_data = ParachainInherentData {
+				validation_data: PersistedValidationData {
+					parent_head,
+					relay_parent_number: (block_number.saturated_into::<u32>() * 2 + 1).into(),
+					relay_parent_storage_root,
+					max_pov_size: 100_000_000,
+				},
+				relay_chain_state,
+				downward_messages: Default::default(),
+				horizontal_messages: Default::default(),
+			};
+
+			let _ = cumulus_pallet_parachain_system::Pallet::<Runtime>::set_validation_data(
+				Runtime::RuntimeOrigin::none(),
+				inherent_data,
+			);
+			let _ = pallet_timestamp::Pallet::<Runtime>::set(
+				Runtime::RuntimeOrigin::none(),
+				300_u32.into(),
+			);
+			AllPalletsWithoutSystem::on_finalize(next_block_number);
+			let header = frame_system::Pallet::<Runtime>::finalize();
+			last_header = Some(header);
+		}
+		last_header.expect("run_to_block empty block range")
+	}
+
 	pub fn root_origin() -> <Runtime as frame_system::Config>::RuntimeOrigin {
 		<Runtime as frame_system::Config>::RuntimeOrigin::root()
 	}
diff --git a/cumulus/parachains/runtimes/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
index f78bf9877ec..1c58df189b6 100644
--- a/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
+++ b/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
@@ -37,7 +37,8 @@ pub fn change_storage_constant_by_governance_works<Runtime, StorageConstant, Sto
 		+ pallet_xcm::Config
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
-		+ cumulus_pallet_parachain_system::Config,
+		+ cumulus_pallet_parachain_system::Config
+		+ pallet_timestamp::Config,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 	StorageConstant: Get<StorageConstantType>,
 	StorageConstantType: Encode + PartialEq + std::fmt::Debug,
@@ -107,7 +108,8 @@ pub fn set_storage_keys_by_governance_works<Runtime>(
 		+ pallet_xcm::Config
 		+ parachain_info::Config
 		+ pallet_collator_selection::Config
-		+ cumulus_pallet_parachain_system::Config,
+		+ cumulus_pallet_parachain_system::Config
+		+ pallet_timestamp::Config,
 	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
 {
 	let mut runtime = ExtBuilder::<Runtime>::default()
-- 
GitLab