From 4dc76030c4fa8df1704d074c74950dac0398e09c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky <svyatonik@gmail.com> Date: Mon, 30 Aug 2021 12:19:20 +0300 Subject: [PATCH] upgrade currency exchange pallet to frame v2 (#1097) --- .../currency-exchange/src/benchmarking.rs | 12 +- bridges/modules/currency-exchange/src/lib.rs | 152 ++++++++++-------- 2 files changed, 89 insertions(+), 75 deletions(-) diff --git a/bridges/modules/currency-exchange/src/benchmarking.rs b/bridges/modules/currency-exchange/src/benchmarking.rs index 574ae93f6ee..db8b2256c80 100644 --- a/bridges/modules/currency-exchange/src/benchmarking.rs +++ b/bridges/modules/currency-exchange/src/benchmarking.rs @@ -18,12 +18,10 @@ //! So we are giving runtime opportunity to prepare environment and construct proof //! before invoking module calls. -use super::{ - Call, Config as CurrencyExchangeConfig, InclusionProofVerifier, Instance, Pallet as CurrencyExchangePallet, -}; +use super::{Call, Config as CurrencyExchangeConfig, InclusionProofVerifier, Pallet as CurrencyExchangePallet}; use sp_std::prelude::*; -use frame_benchmarking::{account, benchmarks_instance}; +use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_system::RawOrigin; const SEED: u32 = 0; @@ -31,7 +29,7 @@ const WORST_TX_SIZE_FACTOR: u32 = 1000; const WORST_PROOF_SIZE_FACTOR: u32 = 1000; /// Pallet we're benchmarking here. -pub struct Pallet<T: Config<I>, I: Instance>(CurrencyExchangePallet<T, I>); +pub struct Pallet<T: Config<I>, I: 'static>(CurrencyExchangePallet<T, I>); /// Proof benchmarking parameters. pub struct ProofParams<Recipient> { @@ -48,14 +46,14 @@ pub struct ProofParams<Recipient> { } /// Config that must be implemented by runtime. -pub trait Config<I: Instance>: CurrencyExchangeConfig<I> { +pub trait Config<I: 'static>: CurrencyExchangeConfig<I> { /// Prepare proof for importing exchange transaction. fn make_proof( proof_params: ProofParams<Self::AccountId>, ) -> <<Self as CurrencyExchangeConfig<I>>::PeerBlockchain as InclusionProofVerifier>::TransactionInclusionProof; } -benchmarks_instance! { +benchmarks_instance_pallet! { // Benchmark `import_peer_transaction` extrinsic with the best possible conditions: // * Proof is the transaction itself. // * Transaction has minimal size. diff --git a/bridges/modules/currency-exchange/src/lib.rs b/bridges/modules/currency-exchange/src/lib.rs index 9a8af5ba501..290e1a9bc95 100644 --- a/bridges/modules/currency-exchange/src/lib.rs +++ b/bridges/modules/currency-exchange/src/lib.rs @@ -22,8 +22,7 @@ use bp_currency_exchange::{ CurrencyConverter, DepositInto, Error as ExchangeError, MaybeLockFundsTransaction, RecipientsMap, }; use bp_header_chain::InclusionProofVerifier; -use frame_support::{decl_error, decl_module, decl_storage, ensure}; -use sp_runtime::DispatchResult; +use frame_support::ensure; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; @@ -34,61 +33,53 @@ pub trait OnTransactionSubmitted<AccountId> { fn on_valid_transaction_submitted(submitter: AccountId); } -/// The module configuration trait -pub trait Config<I = DefaultInstance>: frame_system::Config { - /// Handler for transaction submission result. - type OnTransactionSubmitted: OnTransactionSubmitted<Self::AccountId>; - /// Represents the blockchain that we'll be exchanging currency with. - type PeerBlockchain: InclusionProofVerifier; - /// Peer blockchain transaction parser. - type PeerMaybeLockFundsTransaction: MaybeLockFundsTransaction< - Transaction = <Self::PeerBlockchain as InclusionProofVerifier>::Transaction, - >; - /// Map between blockchains recipients. - type RecipientsMap: RecipientsMap< - PeerRecipient = <Self::PeerMaybeLockFundsTransaction as MaybeLockFundsTransaction>::Recipient, - Recipient = Self::AccountId, - >; - /// This blockchain currency amount type. - type Amount; - /// Converter from peer blockchain currency type into current blockchain currency type. - type CurrencyConverter: CurrencyConverter< - SourceAmount = <Self::PeerMaybeLockFundsTransaction as MaybeLockFundsTransaction>::Amount, - TargetAmount = Self::Amount, - >; - /// Something that could grant money. - type DepositInto: DepositInto<Recipient = Self::AccountId, Amount = Self::Amount>; -} +pub use pallet::*; -decl_error! { - pub enum Error for Pallet<T: Config<I>, I: Instance> { - /// Invalid peer blockchain transaction provided. - InvalidTransaction, - /// Peer transaction has invalid amount. - InvalidAmount, - /// Peer transaction has invalid recipient. - InvalidRecipient, - /// Cannot map from peer recipient to this blockchain recipient. - FailedToMapRecipients, - /// Failed to convert from peer blockchain currency to this blockchain currency. - FailedToConvertCurrency, - /// Deposit has failed. - DepositFailed, - /// Deposit has partially failed (changes to recipient account were made). - DepositPartiallyFailed, - /// Transaction is not finalized. - UnfinalizedTransaction, - /// Transaction funds are already claimed. - AlreadyClaimed, +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config<I: 'static = ()>: frame_system::Config { + /// Handler for transaction submission result. + type OnTransactionSubmitted: OnTransactionSubmitted<Self::AccountId>; + /// Represents the blockchain that we'll be exchanging currency with. + type PeerBlockchain: InclusionProofVerifier; + /// Peer blockchain transaction parser. + type PeerMaybeLockFundsTransaction: MaybeLockFundsTransaction< + Transaction = <Self::PeerBlockchain as InclusionProofVerifier>::Transaction, + >; + /// Map between blockchains recipients. + type RecipientsMap: RecipientsMap< + PeerRecipient = <Self::PeerMaybeLockFundsTransaction as MaybeLockFundsTransaction>::Recipient, + Recipient = Self::AccountId, + >; + /// This blockchain currency amount type. + type Amount; + /// Converter from peer blockchain currency type into current blockchain currency type. + type CurrencyConverter: CurrencyConverter< + SourceAmount = <Self::PeerMaybeLockFundsTransaction as MaybeLockFundsTransaction>::Amount, + TargetAmount = Self::Amount, + >; + /// Something that could grant money. + type DepositInto: DepositInto<Recipient = Self::AccountId, Amount = Self::Amount>; } -} -decl_module! { - pub struct Module<T: Config<I>, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet<T, I = ()>(PhantomData<(T, I)>); + + #[pallet::hooks] + impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {} + + #[pallet::call] + impl<T: Config<I>, I: 'static> Pallet<T, I> { /// Imports lock fund transaction of the peer blockchain. - #[weight = 0] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78) + #[pallet::weight(0)] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78) pub fn import_peer_transaction( - origin, + origin: OriginFor<T>, proof: <<T as Config<I>>::PeerBlockchain as InclusionProofVerifier>::TransactionInclusionProof, ) -> DispatchResult { let submitter = frame_system::ensure_signed(origin)?; @@ -122,16 +113,41 @@ decl_module! { Ok(()) } } -} -decl_storage! { - trait Store for Pallet<T: Config<I>, I: Instance = DefaultInstance> as Bridge { - /// All transfers that have already been claimed. - Transfers: map hasher(blake2_128_concat) <T::PeerMaybeLockFundsTransaction as MaybeLockFundsTransaction>::Id => (); + #[pallet::error] + pub enum Error<T, I = ()> { + /// Invalid peer blockchain transaction provided. + InvalidTransaction, + /// Peer transaction has invalid amount. + InvalidAmount, + /// Peer transaction has invalid recipient. + InvalidRecipient, + /// Cannot map from peer recipient to this blockchain recipient. + FailedToMapRecipients, + /// Failed to convert from peer blockchain currency to this blockchain currency. + FailedToConvertCurrency, + /// Deposit has failed. + DepositFailed, + /// Deposit has partially failed (changes to recipient account were made). + DepositPartiallyFailed, + /// Transaction is not finalized. + UnfinalizedTransaction, + /// Transaction funds are already claimed. + AlreadyClaimed, } + + /// All transfers that have already been claimed. + #[pallet::storage] + pub(super) type Transfers<T: Config<I>, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + <T::PeerMaybeLockFundsTransaction as MaybeLockFundsTransaction>::Id, + (), + ValueQuery, + >; } -impl<T: Config<I>, I: Instance> Pallet<T, I> { +impl<T: Config<I>, I: 'static> Pallet<T, I> { /// Returns true if currency exchange module is able to import given transaction proof in /// its current state. pub fn filter_transaction_proof( @@ -151,7 +167,7 @@ impl<T: Config<I>, I: Instance> Pallet<T, I> { } } -impl<T: Config<I>, I: Instance> From<ExchangeError> for Error<T, I> { +impl<T: Config<I>, I: 'static> From<ExchangeError> for Error<T, I> { fn from(error: ExchangeError) -> Self { match error { ExchangeError::InvalidTransaction => Error::InvalidTransaction, @@ -170,7 +186,7 @@ impl<AccountId> OnTransactionSubmitted<AccountId> for () { } /// Exchange deposit details. -struct DepositDetails<T: Config<I>, I: Instance> { +struct DepositDetails<T: Config<I>, I: 'static> { /// Transfer id. pub transfer_id: <T::PeerMaybeLockFundsTransaction as MaybeLockFundsTransaction>::Id, /// Transfer recipient. @@ -181,7 +197,7 @@ struct DepositDetails<T: Config<I>, I: Instance> { /// Verify and parse transaction proof, preparing everything required for importing /// this transaction proof. -fn prepare_deposit_details<T: Config<I>, I: Instance>( +fn prepare_deposit_details<T: Config<I>, I: 'static>( proof: &<<T as Config<I>>::PeerBlockchain as InclusionProofVerifier>::TransactionInclusionProof, ) -> Result<DepositDetails<T, I>, Error<T, I>> { // ensure that transaction is included in finalized block that we know of @@ -238,7 +254,7 @@ mod tests { impl OnTransactionSubmitted<AccountId> for DummyTransactionSubmissionHandler { fn on_valid_transaction_submitted(submitter: AccountId) { - Transfers::<TestRuntime, DefaultInstance>::insert(submitter, ()); + Transfers::<TestRuntime, ()>::insert(submitter, ()); } } @@ -394,7 +410,7 @@ mod tests { new_test_ext().execute_with(|| { assert_noop!( Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (false, transaction(0))), - Error::<TestRuntime, DefaultInstance>::UnfinalizedTransaction, + Error::<TestRuntime, ()>::UnfinalizedTransaction, ); }); } @@ -407,7 +423,7 @@ mod tests { Origin::signed(SUBMITTER), (true, transaction(INVALID_TRANSACTION_ID)), ), - Error::<TestRuntime, DefaultInstance>::InvalidTransaction, + Error::<TestRuntime, ()>::InvalidTransaction, ); }); } @@ -421,7 +437,7 @@ mod tests { Origin::signed(SUBMITTER), (true, transaction(ALREADY_CLAIMED_TRANSACTION_ID)), ), - Error::<TestRuntime, DefaultInstance>::AlreadyClaimed, + Error::<TestRuntime, ()>::AlreadyClaimed, ); }); } @@ -433,7 +449,7 @@ mod tests { transaction.recipient = UNKNOWN_RECIPIENT_ID; assert_noop!( Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (true, transaction)), - Error::<TestRuntime, DefaultInstance>::FailedToMapRecipients, + Error::<TestRuntime, ()>::FailedToMapRecipients, ); }); } @@ -445,7 +461,7 @@ mod tests { transaction.amount = INVALID_AMOUNT; assert_noop!( Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (true, transaction)), - Error::<TestRuntime, DefaultInstance>::FailedToConvertCurrency, + Error::<TestRuntime, ()>::FailedToConvertCurrency, ); }); } @@ -457,7 +473,7 @@ mod tests { transaction.amount = MAX_DEPOSIT_AMOUNT + 1; assert_noop!( Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (true, transaction)), - Error::<TestRuntime, DefaultInstance>::DepositFailed, + Error::<TestRuntime, ()>::DepositFailed, ); }); } -- GitLab