Newer
Older
// 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 <http://www.gnu.org/licenses/>.
use crate::Trait;
use bp_message_lane::{
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain},
target_chain::{DispatchMessage, MessageDispatch, SourceHeaderChain},
LaneId, Message, MessageData, MessageKey, 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<T>,
}
}
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<Self::AccountId>;
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 AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type BaseCallFilter = ();
type SystemWeightInfo = ();
}
parameter_types! {
pub const MaxMessagesToPruneAtOnce: u64 = 10;
}
impl Trait for TestRuntime {
type Event = TestEvent;
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
type OutboundPayload = TestPayload;
type OutboundMessageFee = TestMessageFee;
type InboundPayload = TestPayload;
type InboundMessageFee = 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.
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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<TestPayload> 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<AccountId, TestPayload, TestMessageFee> 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<AccountId, TestMessageFee> 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<TestMessageFee> for TestSourceHeaderChain {
type Error = &'static str;
type MessagesProof = Result<Vec<Message<TestMessageFee>>, ()>;
fn verify_messages_proof(proof: Self::MessagesProof) -> Result<Vec<Message<TestMessageFee>>, Self::Error> {
proof.map_err(|_| TEST_ERROR)
}
}
/// Source header chain that is used in tests.
#[derive(Debug)]
pub struct TestMessageDispatch;
impl MessageDispatch<TestMessageFee> for TestMessageDispatch {
type DispatchPayload = TestPayload;
fn dispatch_weight(message: &DispatchMessage<TestPayload, TestMessageFee>) -> Weight {
match message.data.payload.as_ref() {
Ok(payload) => payload.1,
Err(_) => 0,
}
fn dispatch(_message: DispatchMessage<TestPayload, TestMessageFee>) {}
}
/// Return test lane message with given nonce and payload.
pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message<TestMessageFee> {
Message {
key: MessageKey {
lane_id: TEST_LANE_ID,
nonce,
},
data: message_data(payload),
}
}
/// Return message data with valid fee for given payload.
pub fn message_data(payload: TestPayload) -> MessageData<TestMessageFee> {
MessageData {
payload: payload.encode(),
fee: 1,
}
/// Run message lane test.
pub fn run_test<T>(test: impl FnOnce() -> T) -> T {
let t = frame_system::GenesisConfig::default()
.build_storage::<TestRuntime>()
.unwrap();
let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(test)