bridge_hub_westend_runtime/
bridge_common_config.rs1use 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#[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 RococoWestend(RewardsAccountParams<LegacyLaneId>),
62 Snowbridge,
64}
65
66impl From<RewardsAccountParams<LegacyLaneId>> for BridgeReward {
67 fn from(value: RewardsAccountParams<LegacyLaneId>) -> Self {
68 Self::RococoWestend(value)
69 }
70}
71
72#[derive(
74 Clone, Debug, Decode, DecodeWithMemTracking, Encode, Eq, MaxEncodedLen, PartialEq, TypeInfo,
75)]
76pub enum BridgeRewardBeneficiaries {
77 LocalAccount(AccountId),
79 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
89pub 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
142pub 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}