referrerpolicy=no-referrer-when-downgrade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Cumulus.

// Cumulus 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.

// Cumulus 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 Cumulus.  If not, see <http://www.gnu.org/licenses/>.

//! Generating test data, used by all tests.

pub mod from_grandpa_chain;
pub mod from_parachain;

use bp_messages::{
	target_chain::{DispatchMessage, DispatchMessageData},
	MessageKey,
};
use codec::Encode;
use frame_support::traits::Get;
use pallet_bridge_grandpa::BridgedHeader;
use xcm::latest::prelude::*;

use bp_messages::MessageNonce;
use bp_runtime::BasicOperatingMode;
use bp_test_utils::authority_list;
use xcm::GetVersion;
use xcm_builder::{BridgeMessage, HaulBlob, HaulBlobError, HaulBlobExporter};
use xcm_executor::traits::{validate_export, ExportXcm};

pub fn prepare_inbound_xcm(xcm_message: Xcm<()>, destination: InteriorLocation) -> Vec<u8> {
	let location = xcm::VersionedInteriorLocation::from(destination);
	let xcm = xcm::VersionedXcm::<()>::from(xcm_message);

	// (double encoding, because `.encode()` is called on original Xcm BLOB when it is pushed to the
	// storage)
	BridgeMessage { universal_dest: location, message: xcm }.encode().encode()
}

/// Helper that creates InitializationData mock data, that can be used to initialize bridge
/// GRANDPA pallet
pub fn initialization_data<
	Runtime: pallet_bridge_grandpa::Config<GrandpaPalletInstance>,
	GrandpaPalletInstance: 'static,
>(
	block_number: u32,
) -> bp_header_chain::InitializationData<BridgedHeader<Runtime, GrandpaPalletInstance>> {
	bp_header_chain::InitializationData {
		header: Box::new(bp_test_utils::test_header(block_number.into())),
		authority_list: authority_list(),
		set_id: 1,
		operating_mode: BasicOperatingMode::Normal,
	}
}

/// Dummy xcm
pub(crate) fn dummy_xcm() -> Xcm<()> {
	vec![Trap(42)].into()
}

pub(crate) fn dispatch_message<LaneId: Encode>(
	lane_id: LaneId,
	nonce: MessageNonce,
	payload: Vec<u8>,
) -> DispatchMessage<Vec<u8>, LaneId> {
	DispatchMessage {
		key: MessageKey { lane_id, nonce },
		data: DispatchMessageData { payload: Ok(payload) },
	}
}

/// Macro used for simulate_export_message and capturing bytes
macro_rules! grab_haul_blob (
	($name:ident, $grabbed_payload:ident) => {
		std::thread_local! {
			static $grabbed_payload: std::cell::RefCell<Option<Vec<u8>>> = std::cell::RefCell::new(None);
		}

		struct $name;
		impl HaulBlob for $name {
			fn haul_blob(blob: Vec<u8>) -> Result<(), HaulBlobError>{
				$grabbed_payload.with(|rm| *rm.borrow_mut() = Some(blob));
				Ok(())
			}
		}
	}
);

/// Simulates `HaulBlobExporter` and all its wrapping and captures generated plain bytes,
/// which are transferred over bridge.
pub(crate) fn simulate_message_exporter_on_bridged_chain<
	SourceNetwork: Get<NetworkId>,
	DestinationNetwork: Get<Location>,
	DestinationVersion: GetVersion,
>(
	(destination_network, destination_junctions): (NetworkId, Junctions),
) -> Vec<u8> {
	grab_haul_blob!(GrabbingHaulBlob, GRABBED_HAUL_BLOB_PAYLOAD);

	// lets pretend that some parachain on bridged chain exported the message
	let universal_source_on_bridged_chain: Junctions =
		[GlobalConsensus(SourceNetwork::get()), Parachain(5678)].into();
	let channel = 1_u32;

	// simulate XCM message export
	let (ticket, fee) = validate_export::<
		HaulBlobExporter<GrabbingHaulBlob, DestinationNetwork, DestinationVersion, ()>,
	>(
		destination_network,
		channel,
		universal_source_on_bridged_chain,
		destination_junctions,
		dummy_xcm(),
	)
	.expect("validate_export to pass");
	log::info!(
		target: "simulate_message_exporter_on_bridged_chain",
		"HaulBlobExporter::validate fee: {:?}",
		fee
	);
	let xcm_hash =
		HaulBlobExporter::<GrabbingHaulBlob, DestinationNetwork, DestinationVersion, ()>::deliver(
			ticket,
		)
		.expect("deliver to pass");
	log::info!(
		target: "simulate_message_exporter_on_bridged_chain",
		"HaulBlobExporter::deliver xcm_hash: {:?}",
		xcm_hash
	);

	GRABBED_HAUL_BLOB_PAYLOAD.with(|r| r.take().expect("Encoded message should be here"))
}