// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Parity Bridges Common. // Parity Bridges Common is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity Bridges Common is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . use crate::Trait; use bp_message_lane::{ source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain}, target_chain::{MessageDispatch, SourceHeaderChain}, LaneId, Message, MessageData, MessageNonce, }; use frame_support::{impl_outer_event, impl_outer_origin, parameter_types, weights::Weight}; use sp_core::H256; use sp_runtime::{ testing::Header as SubstrateHeader, traits::{BlakeTwo256, IdentityLookup}, Perbill, }; pub type AccountId = u64; pub type TestPayload = (u64, Weight); pub type TestMessageFee = u64; #[derive(Clone, Eq, PartialEq, Debug)] pub struct TestRuntime; mod message_lane { pub use crate::Event; } impl_outer_event! { pub enum TestEvent for TestRuntime { frame_system, message_lane, } } impl_outer_origin! { pub enum Origin for TestRuntime where system = frame_system {} } parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for TestRuntime { type Origin = Origin; type Index = u64; type Call = (); type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = SubstrateHeader; type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); type BaseCallFilter = (); type SystemWeightInfo = (); } parameter_types! { pub const MaxMessagesToPruneAtOnce: u64 = 10; } impl Trait for TestRuntime { type Event = TestEvent; type Payload = TestPayload; type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce; type MessageFee = TestMessageFee; type TargetHeaderChain = TestTargetHeaderChain; type LaneMessageVerifier = TestLaneMessageVerifier; type MessageDeliveryAndDispatchPayment = TestMessageDeliveryAndDispatchPayment; type SourceHeaderChain = TestSourceHeaderChain; type MessageDispatch = TestMessageDispatch; } /// Error that is returned by all test implementations. pub const TEST_ERROR: &str = "Test error"; /// Lane that we're using in tests. pub const TEST_LANE_ID: LaneId = [0, 0, 0, 1]; /// Regular message payload. pub const REGULAR_PAYLOAD: TestPayload = (0, 50); /// Payload that is rejected by `TestTargetHeaderChain`. pub const PAYLOAD_REJECTED_BY_TARGET_CHAIN: TestPayload = (1, 50); /// Target header chain that is used in tests. #[derive(Debug, Default)] pub struct TestTargetHeaderChain; impl TargetHeaderChain for TestTargetHeaderChain { type Error = &'static str; type MessagesDeliveryProof = Result<(LaneId, MessageNonce), ()>; fn verify_message(payload: &TestPayload) -> Result<(), Self::Error> { if *payload == PAYLOAD_REJECTED_BY_TARGET_CHAIN { Err(TEST_ERROR) } else { Ok(()) } } fn verify_messages_delivery_proof( proof: Self::MessagesDeliveryProof, ) -> Result<(LaneId, MessageNonce), Self::Error> { proof.map_err(|_| TEST_ERROR) } } /// Lane message verifier that is used in tests. #[derive(Debug, Default)] pub struct TestLaneMessageVerifier; impl LaneMessageVerifier for TestLaneMessageVerifier { type Error = &'static str; fn verify_message( _submitter: &AccountId, delivery_and_dispatch_fee: &TestMessageFee, _lane: &LaneId, _payload: &TestPayload, ) -> Result<(), Self::Error> { if *delivery_and_dispatch_fee != 0 { Ok(()) } else { Err(TEST_ERROR) } } } /// Message fee payment system that is used in tests. #[derive(Debug, Default)] pub struct TestMessageDeliveryAndDispatchPayment; impl TestMessageDeliveryAndDispatchPayment { /// Reject all payments. pub fn reject_payments() { frame_support::storage::unhashed::put(b":reject-message-fee:", &true); } /// Returns true if given fee has been paid by given relayer. pub fn is_fee_paid(submitter: AccountId, fee: TestMessageFee) -> bool { frame_support::storage::unhashed::get(b":message-fee:") == Some((submitter, fee)) } } impl MessageDeliveryAndDispatchPayment for TestMessageDeliveryAndDispatchPayment { type Error = &'static str; fn pay_delivery_and_dispatch_fee(submitter: &AccountId, fee: &TestMessageFee) -> Result<(), Self::Error> { if frame_support::storage::unhashed::get(b":reject-message-fee:") == Some(true) { return Err(TEST_ERROR); } frame_support::storage::unhashed::put(b":message-fee:", &(submitter, fee)); Ok(()) } } /// Source header chain that is used in tests. #[derive(Debug)] pub struct TestSourceHeaderChain; impl SourceHeaderChain for TestSourceHeaderChain { type Error = &'static str; type MessagesProof = Result>, ()>; fn verify_messages_proof( proof: Self::MessagesProof, ) -> Result>, Self::Error> { proof.map_err(|_| TEST_ERROR) } } /// Source header chain that is used in tests. #[derive(Debug)] pub struct TestMessageDispatch; impl MessageDispatch for TestMessageDispatch { fn dispatch_weight(message: &Message) -> Weight { message.data.payload.1 } fn dispatch(_message: Message) {} } /// Return message data with valid fee for given payload. pub fn message_data(payload: TestPayload) -> MessageData { MessageData { payload, fee: 1 } } /// Run message lane test. pub fn run_test(test: impl FnOnce() -> T) -> T { let t = frame_system::GenesisConfig::default() .build_storage::() .unwrap(); let mut ext = sp_io::TestExternalities::new(t); ext.execute_with(test) }