// Copyright (C) Parity Technologies (UK) Ltd. // This file is part of Pezcumulus. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #![cfg(test)] use bp_asset_hub_zagros::ASSET_HUB_ZAGROS_TEYRCHAIN_ID; use bp_bridge_hub_zagros::BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID; use bp_pezkuwi_core::Signature; use codec::{Decode, Encode}; use pezbridge_hub_zagros_runtime::{ bridge_to_pezkuwichain_config, xcm_config::XcmConfig, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, MessageQueueServiceWeight, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, TxExtension, UncheckedExtrinsic, }; use pezcumulus_primitives_core::XcmError::FailedToTransactAsset; use pezframe_support::parameter_types; use pezsnowbridge_pezpallet_ethereum_client::WeightInfo; use pezsp_core::H160; use pezsp_runtime::{ generic::{Era, SignedPayload}, AccountId32, }; use teyrchains_common::{AccountId, AuraId, Balance}; parameter_types! { pub const DefaultBridgeHubEthereumBaseFee: Balance = 3_833_568_200_000; } fn collator_session_keys() -> pezbridge_hub_test_utils::CollatorSessionKeys { use pezsp_keyring::Sr25519Keyring::Alice; pezbridge_hub_test_utils::CollatorSessionKeys::new( AccountId::from(Alice), AccountId::from(Alice), SessionKeys { aura: AuraId::from(Alice.public()) }, ) } #[test] pub fn transfer_token_to_ethereum_works() { pezsnowbridge_runtime_test_common::send_transfer_token_message_success::( 11155111, collator_session_keys(), BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID, ASSET_HUB_ZAGROS_TEYRCHAIN_ID, H160::random(), H160::random(), DefaultBridgeHubEthereumBaseFee::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { Ok(RuntimeEvent::EthereumOutboundQueue(event)) => Some(event), _ => None, } }), ) } #[test] pub fn unpaid_transfer_token_to_ethereum_should_work() { pezsnowbridge_runtime_test_common::send_unpaid_transfer_token_message::( 11155111, collator_session_keys(), BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID, ASSET_HUB_ZAGROS_TEYRCHAIN_ID, H160::random(), H160::random(), ) } #[test] pub fn transfer_token_to_ethereum_insufficient_fund() { pezsnowbridge_runtime_test_common::send_transfer_token_message_failure::( 11155111, collator_session_keys(), BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID, ASSET_HUB_ZAGROS_TEYRCHAIN_ID, 1_000_000_000, H160::random(), H160::random(), DefaultBridgeHubEthereumBaseFee::get(), FailedToTransactAsset("Funds are unavailable"), ) } #[test] fn max_message_queue_service_weight_is_more_than_beacon_extrinsic_weights() { let max_message_queue_weight = MessageQueueServiceWeight::get(); let force_checkpoint = ::WeightInfo::force_checkpoint( ); let submit_checkpoint = ::WeightInfo::submit(); max_message_queue_weight.all_gt(force_checkpoint); max_message_queue_weight.all_gt(submit_checkpoint); } #[test] fn ethereum_client_consensus_extrinsics_work() { pezsnowbridge_runtime_test_common::ethereum_extrinsic( collator_session_keys(), BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID, construct_and_apply_extrinsic, ); } #[test] fn ethereum_to_pezkuwi_message_extrinsics_work() { pezsnowbridge_runtime_test_common::ethereum_to_pezkuwi_message_extrinsics_work( collator_session_keys(), BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID, construct_and_apply_extrinsic, ); } /// Tests that the digest items are as expected when a Ethereum Outbound message is received. /// If the MessageQueue pezpallet is configured before (i.e. the MessageQueue pezpallet 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() { pezsnowbridge_runtime_test_common::ethereum_outbound_queue_processes_messages_before_message_queue_works::< Runtime, XcmConfig, AllPalletsWithoutSystem, >( 11155111, collator_session_keys(), BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID, ASSET_HUB_ZAGROS_TEYRCHAIN_ID, H160::random(), H160::random(), DefaultBridgeHubEthereumBaseFee::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { Ok(RuntimeEvent::EthereumOutboundQueue(event)) => Some(event), _ => None, } }), ) } fn construct_extrinsic( sender: pezsp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); let extra: TxExtension = ( ( pezframe_system::AuthorizeCall::::new(), pezframe_system::CheckNonZeroSender::::new(), pezframe_system::CheckSpecVersion::::new(), pezframe_system::CheckTxVersion::::new(), pezframe_system::CheckGenesis::::new(), pezframe_system::CheckEra::::from(Era::immortal()), pezframe_system::CheckNonce::::from( pezframe_system::Pezpallet::::account(&account_id).nonce, ), pezframe_system::CheckWeight::::new(), ), pezpallet_transaction_payment::ChargeTransactionPayment::::from(0), BridgeRejectObsoleteHeadersAndMessages::default(), (bridge_to_pezkuwichain_config::OnBridgeHubZagrosRefundBridgeHubPezkuwichainMessages::default(),), pezframe_metadata_hash_extension::CheckMetadataHash::::new(false), ) .into(); let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed(call, account_id.into(), Signature::Sr25519(signature), extra) } fn construct_and_apply_extrinsic( origin: pezsp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> pezsp_runtime::DispatchOutcome { let xt = construct_extrinsic(origin, call); let r = Executive::apply_extrinsic(xt); r.unwrap() }