From 6acf4787e168eea447b82b0a1f32e47bc794ae28 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 15 Apr 2024 09:37:04 +0300 Subject: [PATCH] Bridge: slash destination may be an explicit account (#4106) Extracted to a separate PR as requested here: https://github.com/paritytech/parity-bridges-common/pull/2873#discussion_r1562459573 --- .../extensions/refund_relayer_extension.rs | 7 ++-- bridges/modules/relayers/src/benchmarking.rs | 2 +- bridges/modules/relayers/src/lib.rs | 7 ++-- bridges/modules/relayers/src/stake_adapter.rs | 36 ++++++++++++++----- bridges/primitives/relayers/src/lib.rs | 2 +- .../primitives/relayers/src/registration.rs | 19 ++++++++-- 6 files changed, 56 insertions(+), 17 deletions(-) diff --git a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs index f97b23ecaaa9..64ae1d0b669f 100644 --- a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs @@ -23,7 +23,7 @@ use crate::messages_call_ext::{ CallHelper as MessagesCallHelper, CallInfo as MessagesCallInfo, MessagesCallSubType, }; use bp_messages::{LaneId, MessageNonce}; -use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; +use bp_relayers::{ExplicitOrAccountParams, RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::{Chain, Parachain, ParachainIdOf, RangeInclusiveExt, StaticStrProvider}; use codec::{Codec, Decode, Encode}; use frame_support::{ @@ -589,7 +589,10 @@ where ); }, RelayerAccountAction::Slash(relayer, slash_account) => - RelayersPallet::::slash_and_deregister(&relayer, slash_account), + RelayersPallet::::slash_and_deregister( + &relayer, + ExplicitOrAccountParams::Params(slash_account), + ), } Ok(()) diff --git a/bridges/modules/relayers/src/benchmarking.rs b/bridges/modules/relayers/src/benchmarking.rs index 00c3814a4c38..ca312d44edfd 100644 --- a/bridges/modules/relayers/src/benchmarking.rs +++ b/bridges/modules/relayers/src/benchmarking.rs @@ -106,7 +106,7 @@ benchmarks! { let slash_destination = RewardsAccountParams::new(lane, *b"test", RewardsAccountOwner::ThisChain); T::prepare_rewards_account(slash_destination, Zero::zero()); }: { - crate::Pallet::::slash_and_deregister(&relayer, slash_destination) + crate::Pallet::::slash_and_deregister(&relayer, slash_destination.into()) } verify { assert!(!crate::Pallet::::is_registration_active(&relayer)); diff --git a/bridges/modules/relayers/src/lib.rs b/bridges/modules/relayers/src/lib.rs index ce66c9df48e0..7a3a0f9ea94c 100644 --- a/bridges/modules/relayers/src/lib.rs +++ b/bridges/modules/relayers/src/lib.rs @@ -21,7 +21,8 @@ #![warn(missing_docs)] use bp_relayers::{ - PaymentProcedure, Registration, RelayerRewardsKeyProvider, RewardsAccountParams, StakeAndSlash, + ExplicitOrAccountParams, PaymentProcedure, Registration, RelayerRewardsKeyProvider, + RewardsAccountParams, StakeAndSlash, }; use bp_runtime::StorageDoubleMapKeyProvider; use frame_support::fail; @@ -242,7 +243,7 @@ pub mod pallet { /// It may fail inside, but error is swallowed and we only log it. pub fn slash_and_deregister( relayer: &T::AccountId, - slash_destination: RewardsAccountParams, + slash_destination: ExplicitOrAccountParams, ) { let registration = match RegisteredRelayers::::take(relayer) { Some(registration) => registration, @@ -259,7 +260,7 @@ pub mod pallet { match T::StakeAndSlash::repatriate_reserved( relayer, - slash_destination, + slash_destination.clone(), registration.stake, ) { Ok(failed_to_slash) if failed_to_slash.is_zero() => { diff --git a/bridges/modules/relayers/src/stake_adapter.rs b/bridges/modules/relayers/src/stake_adapter.rs index 88af9b1877bf..7ba90d91dfd9 100644 --- a/bridges/modules/relayers/src/stake_adapter.rs +++ b/bridges/modules/relayers/src/stake_adapter.rs @@ -17,7 +17,7 @@ //! Code that allows `NamedReservableCurrency` to be used as a `StakeAndSlash` //! mechanism of the relayers pallet. -use bp_relayers::{PayRewardFromAccount, RewardsAccountParams, StakeAndSlash}; +use bp_relayers::{ExplicitOrAccountParams, PayRewardFromAccount, StakeAndSlash}; use codec::Codec; use frame_support::traits::{tokens::BalanceStatus, NamedReservableCurrency}; use sp_runtime::{traits::Get, DispatchError, DispatchResult}; @@ -55,11 +55,14 @@ where fn repatriate_reserved( relayer: &AccountId, - beneficiary: RewardsAccountParams, + beneficiary: ExplicitOrAccountParams, amount: Currency::Balance, ) -> Result { - let beneficiary_account = - PayRewardFromAccount::<(), AccountId>::rewards_account(beneficiary); + let beneficiary_account = match beneficiary { + ExplicitOrAccountParams::Explicit(account) => account, + ExplicitOrAccountParams::Params(params) => + PayRewardFromAccount::<(), AccountId>::rewards_account(params), + }; Currency::repatriate_reserved_named( &ReserveId::get(), relayer, @@ -134,7 +137,11 @@ mod tests { Balances::mint_into(&beneficiary_account, expected_balance).unwrap(); assert_eq!( - TestStakeAndSlash::repatriate_reserved(&1, beneficiary, test_stake()), + TestStakeAndSlash::repatriate_reserved( + &1, + ExplicitOrAccountParams::Params(beneficiary), + test_stake() + ), Ok(test_stake()) ); assert_eq!(Balances::free_balance(1), 0); @@ -146,7 +153,11 @@ mod tests { Balances::mint_into(&2, test_stake() * 2).unwrap(); TestStakeAndSlash::reserve(&2, test_stake() / 3).unwrap(); assert_eq!( - TestStakeAndSlash::repatriate_reserved(&2, beneficiary, test_stake()), + TestStakeAndSlash::repatriate_reserved( + &2, + ExplicitOrAccountParams::Params(beneficiary), + test_stake() + ), Ok(test_stake() - test_stake() / 3) ); assert_eq!(Balances::free_balance(2), test_stake() * 2 - test_stake() / 3); @@ -158,7 +169,11 @@ mod tests { Balances::mint_into(&3, test_stake() * 2).unwrap(); TestStakeAndSlash::reserve(&3, test_stake()).unwrap(); assert_eq!( - TestStakeAndSlash::repatriate_reserved(&3, beneficiary, test_stake()), + TestStakeAndSlash::repatriate_reserved( + &3, + ExplicitOrAccountParams::Params(beneficiary), + test_stake() + ), Ok(0) ); assert_eq!(Balances::free_balance(3), test_stake()); @@ -176,7 +191,12 @@ mod tests { Balances::mint_into(&3, test_stake() * 2).unwrap(); TestStakeAndSlash::reserve(&3, test_stake()).unwrap(); - assert!(TestStakeAndSlash::repatriate_reserved(&3, beneficiary, test_stake()).is_err()); + assert!(TestStakeAndSlash::repatriate_reserved( + &3, + ExplicitOrAccountParams::Params(beneficiary), + test_stake() + ) + .is_err()); assert_eq!(Balances::free_balance(3), test_stake()); assert_eq!(Balances::reserved_balance(3), test_stake()); assert_eq!(Balances::free_balance(beneficiary_account), 0); diff --git a/bridges/primitives/relayers/src/lib.rs b/bridges/primitives/relayers/src/lib.rs index c808c437b54c..2a9ef6a8e1e9 100644 --- a/bridges/primitives/relayers/src/lib.rs +++ b/bridges/primitives/relayers/src/lib.rs @@ -19,7 +19,7 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -pub use registration::{Registration, StakeAndSlash}; +pub use registration::{ExplicitOrAccountParams, Registration, StakeAndSlash}; use bp_messages::LaneId; use bp_runtime::{ChainId, StorageDoubleMapKeyProvider}; diff --git a/bridges/primitives/relayers/src/registration.rs b/bridges/primitives/relayers/src/registration.rs index 38fa7c2d9075..9d9b7e481220 100644 --- a/bridges/primitives/relayers/src/registration.rs +++ b/bridges/primitives/relayers/src/registration.rs @@ -46,6 +46,21 @@ use sp_runtime::{ DispatchError, DispatchResult, }; +/// Either explicit account reference or `RewardsAccountParams`. +#[derive(Clone, Debug)] +pub enum ExplicitOrAccountParams { + /// Explicit account reference. + Explicit(AccountId), + /// Account, referenced using `RewardsAccountParams`. + Params(RewardsAccountParams), +} + +impl From for ExplicitOrAccountParams { + fn from(params: RewardsAccountParams) -> Self { + ExplicitOrAccountParams::Params(params) + } +} + /// Relayer registration. #[derive(Copy, Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen)] pub struct Registration { @@ -90,7 +105,7 @@ pub trait StakeAndSlash { /// Returns `Ok(_)` with non-zero balance if we have failed to repatriate some portion of stake. fn repatriate_reserved( relayer: &AccountId, - beneficiary: RewardsAccountParams, + beneficiary: ExplicitOrAccountParams, amount: Balance, ) -> Result; } @@ -113,7 +128,7 @@ where fn repatriate_reserved( _relayer: &AccountId, - _beneficiary: RewardsAccountParams, + _beneficiary: ExplicitOrAccountParams, _amount: Balance, ) -> Result { Ok(Zero::zero())