referrerpolicy=no-referrer-when-downgrade

bridge_hub_westend_runtime/
bridge_common_config.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3// SPDX-License-Identifier: Apache-2.0
4
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// 	http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17//! Bridge definitions that can be used by multiple BridgeHub flavors.
18//! All configurations here should be dedicated to a single chain; in other words, we don't need two
19//! chains for a single pallet configuration.
20//!
21//! For example, the messaging pallet needs to know the sending and receiving chains, but the
22//! GRANDPA tracking pallet only needs to be aware of one chain.
23
24use super::{weights, AccountId, Balance, Balances, BlockNumber, Runtime, RuntimeEvent};
25use crate::{
26	bridge_to_ethereum_config::InboundQueueV2Location, xcm_config::XcmConfig, RuntimeCall,
27	XcmRouter,
28};
29use bp_messages::LegacyLaneId;
30use bp_relayers::RewardsAccountParams;
31use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
32use frame_support::parameter_types;
33use scale_info::TypeInfo;
34use testnet_parachains_constants::westend::{
35	locations::AssetHubLocation, snowbridge::EthereumNetwork,
36};
37use xcm::{opaque::latest::Location, VersionedLocation};
38use xcm_executor::XcmExecutor;
39
40parameter_types! {
41	pub storage RequiredStakeForStakeAndSlash: Balance = 1_000_000;
42	pub const RelayerStakeLease: u32 = 8;
43	pub const RelayerStakeReserveId: [u8; 8] = *b"brdgrlrs";
44}
45
46/// Showcasing that we can handle multiple different rewards with the same pallet.
47#[derive(
48	Clone,
49	Copy,
50	Debug,
51	Decode,
52	DecodeWithMemTracking,
53	Encode,
54	Eq,
55	MaxEncodedLen,
56	PartialEq,
57	TypeInfo,
58)]
59pub enum BridgeReward {
60	/// Rewards for the R/W bridge—distinguished by the `RewardsAccountParams` key.
61	RococoWestend(RewardsAccountParams<LegacyLaneId>),
62	/// Rewards for Snowbridge.
63	Snowbridge,
64}
65
66impl From<RewardsAccountParams<LegacyLaneId>> for BridgeReward {
67	fn from(value: RewardsAccountParams<LegacyLaneId>) -> Self {
68		Self::RococoWestend(value)
69	}
70}
71
72/// An enum representing the different types of supported beneficiaries.
73#[derive(
74	Clone, Debug, Decode, DecodeWithMemTracking, Encode, Eq, MaxEncodedLen, PartialEq, TypeInfo,
75)]
76pub enum BridgeRewardBeneficiaries {
77	/// A local chain account.
78	LocalAccount(AccountId),
79	/// A beneficiary specified by a VersionedLocation.
80	AssetHubLocation(VersionedLocation),
81}
82
83impl From<sp_runtime::AccountId32> for BridgeRewardBeneficiaries {
84	fn from(value: sp_runtime::AccountId32) -> Self {
85		BridgeRewardBeneficiaries::LocalAccount(value)
86	}
87}
88
89/// Implementation of `bp_relayers::PaymentProcedure` as a pay/claim rewards scheme.
90pub struct BridgeRewardPayer;
91impl bp_relayers::PaymentProcedure<AccountId, BridgeReward, u128> for BridgeRewardPayer {
92	type Error = sp_runtime::DispatchError;
93	type Beneficiary = BridgeRewardBeneficiaries;
94
95	fn pay_reward(
96		relayer: &AccountId,
97		reward_kind: BridgeReward,
98		reward: u128,
99		beneficiary: BridgeRewardBeneficiaries,
100	) -> Result<(), Self::Error> {
101		match reward_kind {
102			BridgeReward::RococoWestend(lane_params) => {
103				match beneficiary {
104					BridgeRewardBeneficiaries::LocalAccount(account) => {
105						bp_relayers::PayRewardFromAccount::<
106							Balances,
107							AccountId,
108							LegacyLaneId,
109							u128,
110						>::pay_reward(
111							&relayer, lane_params, reward, account,
112						)
113					},
114					BridgeRewardBeneficiaries::AssetHubLocation(_) => Err(Self::Error::Other("`AssetHubLocation` beneficiary is not supported for `RococoWestend` rewards!")),
115				}
116			},
117			BridgeReward::Snowbridge => {
118				match beneficiary {
119					BridgeRewardBeneficiaries::LocalAccount(_) => Err(Self::Error::Other("`LocalAccount` beneficiary is not supported for `Snowbridge` rewards!")),
120					BridgeRewardBeneficiaries::AssetHubLocation(account_location) => {
121						let account_location = Location::try_from(account_location)
122							.map_err(|_| Self::Error::Other("`AssetHubLocation` beneficiary location version is not supported for `Snowbridge` rewards!"))?;
123						snowbridge_core::reward::PayAccountOnLocation::<
124							AccountId,
125							u128,
126							EthereumNetwork,
127							AssetHubLocation,
128							InboundQueueV2Location,
129							XcmRouter,
130							XcmExecutor<XcmConfig>,
131							RuntimeCall
132						>::pay_reward(
133							relayer, (), reward, account_location
134						)
135					}
136				}
137			}
138		}
139	}
140}
141
142/// Allows collect and claim rewards for relayers
143pub type BridgeRelayersInstance = ();
144impl pallet_bridge_relayers::Config<BridgeRelayersInstance> for Runtime {
145	type RuntimeEvent = RuntimeEvent;
146
147	type RewardBalance = u128;
148	type Reward = BridgeReward;
149	type PaymentProcedure = BridgeRewardPayer;
150
151	type StakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed<
152		AccountId,
153		BlockNumber,
154		Balances,
155		RelayerStakeReserveId,
156		RequiredStakeForStakeAndSlash,
157		RelayerStakeLease,
158	>;
159	type Balance = Balance;
160	type WeightInfo = weights::pallet_bridge_relayers::WeightInfo<Runtime>;
161}