From f620e39c71e2f200e99145aaa3370df307d060a6 Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Wed, 9 Jun 2021 18:07:25 +0200 Subject: [PATCH 1/8] feat(multi-payment): add fallback price for each accepted currencies to use if pool does not exist --- pallets/transaction-multi-payment/Cargo.toml | 2 + pallets/transaction-multi-payment/src/lib.rs | 48 ++++++++++++------- pallets/transaction-multi-payment/src/mock.rs | 7 ++- .../transaction-multi-payment/src/tests.rs | 26 +++++----- 4 files changed, 50 insertions(+), 33 deletions(-) diff --git a/pallets/transaction-multi-payment/Cargo.toml b/pallets/transaction-multi-payment/Cargo.toml index 855fca888..910d2086e 100644 --- a/pallets/transaction-multi-payment/Cargo.toml +++ b/pallets/transaction-multi-payment/Cargo.toml @@ -62,4 +62,6 @@ std = [ 'sp-runtime/std', 'orml-tokens/std', 'orml-traits/std', + 'pallet-balances/std', + 'pallet-asset-registry/std', ] diff --git a/pallets/transaction-multi-payment/src/lib.rs b/pallets/transaction-multi-payment/src/lib.rs index 92728d012..00fae53c4 100644 --- a/pallets/transaction-multi-payment/src/lib.rs +++ b/pallets/transaction-multi-payment/src/lib.rs @@ -52,8 +52,6 @@ use primitives::asset::AssetPair; use primitives::traits::{CurrencySwap, AMM}; use primitives::{Amount, AssetId, Balance, CORE_ASSET_ID}; -use orml_utilities::OrderedSet; - type NegativeImbalanceOf = ::AccountId>>::NegativeImbalance; // Re-export pallet items so that they can be accessed from the crate namespace. pub use pallet::*; @@ -63,6 +61,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::OriginFor; + use primitives::Price; #[pallet::pallet] pub struct Pallet(_); @@ -146,12 +145,12 @@ pub mod pallet { /// Account currency map #[pallet::storage] #[pallet::getter(fn get_currency)] - pub type AccountCurrencyMap = StorageMap<_, Blake2_128Concat, T::AccountId, Option, ValueQuery>; + pub type AccountCurrencyMap = StorageMap<_, Blake2_128Concat, T::AccountId, AssetId, OptionQuery>; /// Curated list of currencies which fees can be paid with #[pallet::storage] #[pallet::getter(fn currencies)] - pub type AcceptedCurrencies = StorageValue<_, OrderedSet, ValueQuery>; + pub type AcceptedCurrencies = StorageMap<_, Twox64Concat, AssetId, Price, OptionQuery>; #[pallet::storage] #[pallet::getter(fn authorities)] @@ -159,7 +158,7 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { - pub currencies: OrderedSet, + pub currencies: Vec<(AssetId, Price)>, pub authorities: Vec, } @@ -167,8 +166,8 @@ pub mod pallet { impl Default for GenesisConfig { fn default() -> Self { GenesisConfig { - currencies: OrderedSet::new(), authorities: vec![], + currencies: vec![], } } } @@ -177,7 +176,11 @@ pub mod pallet { impl GenesisBuild for GenesisConfig { fn build(&self) { Authorities::::put(self.authorities.clone()); - AcceptedCurrencies::::put(self.currencies.clone()); + + for (asset, price) in &self.currencies { + AcceptedCurrencies::::insert(asset, price); + } + //AcceptedCurrencies::::put(self.currencies.clone()); } } #[pallet::call] @@ -197,12 +200,12 @@ pub mod pallet { pub fn set_currency(origin: OriginFor, currency: AssetId) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - if currency == CORE_ASSET_ID || Self::currencies().contains(¤cy) { + if currency == CORE_ASSET_ID || AcceptedCurrencies::::contains_key(¤cy) { if T::MultiCurrency::free_balance(currency, &who) == Balance::zero() { return Err(Error::::ZeroBalance.into()); } - >::insert(who.clone(), Some(currency)); + >::insert(who.clone(), currency); if T::WithdrawFeeForSetCurrency::get() == Pays::Yes { Self::withdraw_set_fee(&who, currency)?; @@ -224,7 +227,7 @@ pub mod pallet { /// /// Emits `CurrencyAdded` event when successful. #[pallet::weight((::WeightInfo::add_currency(), DispatchClass::Normal, Pays::No))] - pub fn add_currency(origin: OriginFor, currency: AssetId) -> DispatchResultWithPostInfo { + pub fn add_currency(origin: OriginFor, currency: AssetId, price: Price) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!(currency != CORE_ASSET_ID, Error::::CoreAssetNotAllowed); @@ -232,11 +235,15 @@ pub mod pallet { // Only selected accounts can perform this action ensure!(Self::authorities().contains(&who), Error::::NotAllowed); - if AcceptedCurrencies::::mutate(|x| x.insert(currency)) { + AcceptedCurrencies::::try_mutate_exists(currency, |maybe_price| -> DispatchResultWithPostInfo { + if maybe_price.is_some() { + return Err(Error::::AlreadyAccepted.into()); + } + + *maybe_price = Some(price); Self::deposit_event(Event::CurrencyAdded(who, currency)); - return Ok(().into()); - } - Err(Error::::AlreadyAccepted.into()) + Ok(().into()) + }) } /// Remove currency from the list of supported currencies @@ -254,12 +261,17 @@ pub mod pallet { // Only selected accounts can perform this action ensure!(Self::authorities().contains(&who), Error::::NotAllowed); - if AcceptedCurrencies::::mutate(|x| x.remove(¤cy)) { + AcceptedCurrencies::::try_mutate(currency, |x| -> DispatchResultWithPostInfo { + if x.is_none() { + return Err(Error::::UnsupportedCurrency.into()); + } + + *x = None; + Self::deposit_event(Event::CurrencyRemoved(who, currency)); - return Ok(().into()); - } - Err(Error::::UnsupportedCurrency.into()) + Ok(().into()) + }) } /// Add an account as member to list of authorities who can manage list of accepted currencies diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index c538cbc9a..1c5d13994 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -31,7 +31,7 @@ use sp_runtime::{ use frame_support::weights::IdentityFee; use frame_support::weights::Weight; use orml_currencies::BasicCurrencyAdapter; -use primitives::{Amount, AssetId, Balance}; +use primitives::{Amount, AssetId, Balance, Price}; use pallet_xyk::AssetPairAccountIdFor; use std::cell::RefCell; @@ -291,7 +291,10 @@ impl ExtBuilder { .unwrap(); crate::GenesisConfig:: { - currencies: OrderedSet::from(vec![SUPPORTED_CURRENCY_NO_BALANCE, SUPPORTED_CURRENCY_WITH_BALANCE]), + currencies: vec![ + (SUPPORTED_CURRENCY_NO_BALANCE, Price::from(1)), + (SUPPORTED_CURRENCY_WITH_BALANCE, Price::from_float(0.2)), + ], authorities: vec![self.payment_authority], } .assimilate_storage(&mut t) diff --git a/pallets/transaction-multi-payment/src/tests.rs b/pallets/transaction-multi-payment/src/tests.rs index 550870648..48a953f46 100644 --- a/pallets/transaction-multi-payment/src/tests.rs +++ b/pallets/transaction-multi-payment/src/tests.rs @@ -22,7 +22,6 @@ use sp_runtime::traits::SignedExtension; use frame_support::weights::DispatchInfo; use orml_traits::MultiCurrency; -use orml_utilities::OrderedSet; use pallet_balances::Call as BalancesCall; use primitives::Price; @@ -216,29 +215,29 @@ fn fee_payment_non_native_insufficient_balance() { #[test] fn add_new_accepted_currency() { ExtBuilder::default().base_weight(5).build().execute_with(|| { - assert_eq!(PaymentPallet::currencies(), OrderedSet::from(vec![2000, 3000])); - - assert_ok!(PaymentPallet::add_currency(Origin::signed(BOB), 100)); - assert_eq!(PaymentPallet::currencies(), OrderedSet::from(vec![2000, 3000, 100])); + assert_ok!(PaymentPallet::add_currency( + Origin::signed(BOB), + 100, + Price::from_float(1.1) + )); + assert_eq!(PaymentPallet::currencies(100), Some(Price::from_float(1.1))); assert_noop!( - PaymentPallet::add_currency(Origin::signed(ALICE), 1000), + PaymentPallet::add_currency(Origin::signed(ALICE), 1000, Price::from_float(1.2)), Error::::NotAllowed ); assert_noop!( - PaymentPallet::add_currency(Origin::signed(BOB), 100), + PaymentPallet::add_currency(Origin::signed(BOB), 100, Price::from(10)), Error::::AlreadyAccepted ); - assert_eq!(PaymentPallet::currencies(), OrderedSet::from(vec![2000, 3000, 100])); + assert_eq!(PaymentPallet::currencies(100), Some(Price::from_float(1.1))); }); } #[test] fn removed_accepted_currency() { ExtBuilder::default().base_weight(5).build().execute_with(|| { - assert_eq!(PaymentPallet::currencies(), OrderedSet::from(vec![2000, 3000])); - - assert_ok!(PaymentPallet::add_currency(Origin::signed(BOB), 100)); - assert_eq!(PaymentPallet::currencies(), OrderedSet::from(vec![2000, 3000, 100])); + assert_ok!(PaymentPallet::add_currency(Origin::signed(BOB), 100, Price::from(3))); + assert_eq!(PaymentPallet::currencies(100), Some(Price::from(3))); assert_noop!( PaymentPallet::remove_currency(Origin::signed(ALICE), 100), @@ -252,11 +251,12 @@ fn removed_accepted_currency() { assert_ok!(PaymentPallet::remove_currency(Origin::signed(BOB), 100)); + assert_eq!(PaymentPallet::currencies(100), None); + assert_noop!( PaymentPallet::remove_currency(Origin::signed(BOB), 100), Error::::UnsupportedCurrency ); - assert_eq!(PaymentPallet::currencies(), OrderedSet::from(vec![2000, 3000])); }); } From ba6330b625e6bb1beaa4af0b1f8a8a64467ff3eb Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Thu, 10 Jun 2021 10:21:59 +0200 Subject: [PATCH 2/8] add fallback account --- pallets/transaction-multi-payment/src/lib.rs | 17 ++++++++++++++++- pallets/transaction-multi-payment/src/mock.rs | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pallets/transaction-multi-payment/src/lib.rs b/pallets/transaction-multi-payment/src/lib.rs index 00fae53c4..e76595e66 100644 --- a/pallets/transaction-multi-payment/src/lib.rs +++ b/pallets/transaction-multi-payment/src/lib.rs @@ -140,6 +140,9 @@ pub mod pallet { /// Account is not a member of authorities. NotAMember, + + /// Fallback price cannot be zero. + ZeroPrice, } /// Account currency map @@ -156,10 +159,16 @@ pub mod pallet { #[pallet::getter(fn authorities)] pub type Authorities = StorageValue<_, Vec, ValueQuery>; + /// Account to use when pool does not exist. + #[pallet::storage] + #[pallet::getter(fn fallback_acccount)] + pub type FallbackAccount = StorageValue<_, T::AccountId, ValueQuery>; + #[pallet::genesis_config] pub struct GenesisConfig { pub currencies: Vec<(AssetId, Price)>, pub authorities: Vec, + pub fallback_account: T::AccountId, } #[cfg(feature = "std")] @@ -168,6 +177,7 @@ pub mod pallet { GenesisConfig { authorities: vec![], currencies: vec![], + fallback_account: Default::default(), } } } @@ -175,12 +185,17 @@ pub mod pallet { #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { + if self.fallback_account == Default::default() { + panic!("Fallback account is not set"); + } + + FallbackAccount::::put(self.fallback_account.clone()); + Authorities::::put(self.authorities.clone()); for (asset, price) in &self.currencies { AcceptedCurrencies::::insert(asset, price); } - //AcceptedCurrencies::::put(self.currencies.clone()); } } #[pallet::call] diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index 1c5d13994..1c5865d18 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -45,6 +45,7 @@ pub const INITIAL_BALANCE: Balance = 1000_000_000_000_000u128; pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; +pub const FALLBACK_ACCOUNT: AccountId = 300; pub const HDX: AssetId = 0; pub const SUPPORTED_CURRENCY_NO_BALANCE: AssetId = 2000; @@ -296,6 +297,7 @@ impl ExtBuilder { (SUPPORTED_CURRENCY_WITH_BALANCE, Price::from_float(0.2)), ], authorities: vec![self.payment_authority], + fallback_account: FALLBACK_ACCOUNT, } .assimilate_storage(&mut t) .unwrap(); From f03868c101cb0f17aa9a59153d95f3ee8723ab9a Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Thu, 10 Jun 2021 11:06:51 +0200 Subject: [PATCH 3/8] feat(multi-payment): use fixed price if pool does not exist --- pallets/transaction-multi-payment/src/lib.rs | 67 +++++++++++++++---- pallets/transaction-multi-payment/src/mock.rs | 2 +- .../transaction-multi-payment/src/tests.rs | 65 ++++++++++++++++++ .../transaction-multi-payment/src/traits.rs | 11 +++ primitives/src/traits.rs | 5 -- 5 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 pallets/transaction-multi-payment/src/traits.rs diff --git a/pallets/transaction-multi-payment/src/lib.rs b/pallets/transaction-multi-payment/src/lib.rs index e76595e66..64251bb6b 100644 --- a/pallets/transaction-multi-payment/src/lib.rs +++ b/pallets/transaction-multi-payment/src/lib.rs @@ -27,6 +27,7 @@ mod mock; #[cfg(test)] mod tests; +mod traits; use frame_support::{ dispatch::DispatchResult, @@ -46,10 +47,11 @@ use sp_std::prelude::*; use pallet_transaction_payment::OnChargeTransaction; use sp_std::marker::PhantomData; +use frame_support::sp_runtime::FixedPointNumber; use frame_support::weights::{Pays, Weight}; use orml_traits::{MultiCurrency, MultiCurrencyExtended}; use primitives::asset::AssetPair; -use primitives::traits::{CurrencySwap, AMM}; +use primitives::traits::AMM; use primitives::{Amount, AssetId, Balance, CORE_ASSET_ID}; type NegativeImbalanceOf = ::AccountId>>::NegativeImbalance; @@ -143,6 +145,12 @@ pub mod pallet { /// Fallback price cannot be zero. ZeroPrice, + + /// Fallback price was not found. + FallbackPriceNotFound, + + /// Math overflow + Overflow, } /// Account currency map @@ -161,7 +169,7 @@ pub mod pallet { /// Account to use when pool does not exist. #[pallet::storage] - #[pallet::getter(fn fallback_acccount)] + #[pallet::getter(fn fallback_account)] pub type FallbackAccount = StorageValue<_, T::AccountId, ValueQuery>; #[pallet::genesis_config] @@ -330,6 +338,10 @@ pub mod pallet { } impl Pallet { + fn account_currency(who: &T::AccountId) -> AssetId { + Pallet::::get_currency(who).unwrap_or(CORE_ASSET_ID) + } + /// Execute a trade to buy HDX and sell selected currency. pub fn swap_currency(who: &T::AccountId, fee: Balance) -> DispatchResult { // Let's determine currency in which user would like to pay the fee @@ -378,9 +390,34 @@ impl Pallet { } } +use crate::traits::PaymentSwapResult; +use frame_support::dispatch::DispatchError; +use traits::CurrencySwap; + impl CurrencySwap<::AccountId, Balance> for Pallet { - fn swap_currency(who: &T::AccountId, fee: u128) -> DispatchResult { - Self::swap_currency(who, fee) + fn swap(who: &T::AccountId, fee: u128) -> Result { + match Self::account_currency(who) { + CORE_ASSET_ID => Ok(PaymentSwapResult::NATIVE), + currency => { + if T::AMMPool::exists(AssetPair { + asset_in: currency, + asset_out: CORE_ASSET_ID, + }) { + Self::swap_currency(who, fee)?; + Ok(PaymentSwapResult::SWAPPED) + } else { + // If pool does not exists, let's use the currency fixed price + + let price = Self::currencies(currency).ok_or(Error::::FallbackPriceNotFound)?; + + let amount = price.checked_mul_int(fee).ok_or(Error::::Overflow)?; + + T::MultiCurrency::transfer(currency, who, &Self::fallback_account(), amount)?; + + Ok(PaymentSwapResult::TRANSFERRED) + } + } + } } } @@ -423,14 +460,20 @@ where WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP }; - if SW::swap_currency(&who, fee.into()).is_err() { - return Err(InvalidTransaction::Payment.into()); - } - - match C::withdraw(who, fee, withdraw_reason, ExistenceRequirement::KeepAlive) { - Ok(imbalance) => Ok(Some(imbalance)), - Err(_) => Err(InvalidTransaction::Payment.into()), - } + return if let Some(detail) = SW::swap(&who, fee.into()).ok() { + match detail { + PaymentSwapResult::TRANSFERRED => Ok(None), + PaymentSwapResult::ERROR => Err(InvalidTransaction::Payment.into()), + PaymentSwapResult::NATIVE | PaymentSwapResult::SWAPPED => { + match C::withdraw(who, fee, withdraw_reason, ExistenceRequirement::KeepAlive) { + Ok(imbalance) => Ok(Some(imbalance)), + Err(_) => Err(InvalidTransaction::Payment.into()), + } + } + } + } else { + Err(InvalidTransaction::Payment.into()) + }; } /// Hand the fee and the tip over to the `[OnUnbalanced]` implementation. diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index 1c5865d18..47e7b741d 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -294,7 +294,7 @@ impl ExtBuilder { crate::GenesisConfig:: { currencies: vec![ (SUPPORTED_CURRENCY_NO_BALANCE, Price::from(1)), - (SUPPORTED_CURRENCY_WITH_BALANCE, Price::from_float(0.2)), + (SUPPORTED_CURRENCY_WITH_BALANCE, Price::from_float(1.5)), ], authorities: vec![self.payment_authority], fallback_account: FALLBACK_ACCOUNT, diff --git a/pallets/transaction-multi-payment/src/tests.rs b/pallets/transaction-multi-payment/src/tests.rs index 48a953f46..0c731d747 100644 --- a/pallets/transaction-multi-payment/src/tests.rs +++ b/pallets/transaction-multi-payment/src/tests.rs @@ -298,3 +298,68 @@ fn add_member() { ); }); } + +#[test] +fn fee_payment_in_non_native_currency_with_no_pool() { + const CHARLIE: AccountId = 5; + + ExtBuilder::default() + .base_weight(5) + .account_native_balance(CHARLIE, 0) + .account_tokens(CHARLIE, SUPPORTED_CURRENCY_WITH_BALANCE, 1000) + .build() + .execute_with(|| { + // Make sure Charlie ain't got a penny! + assert_eq!(Balances::free_balance(CHARLIE), 0); + + assert_ok!(PaymentPallet::set_currency( + Origin::signed(CHARLIE), + SUPPORTED_CURRENCY_WITH_BALANCE + )); + + let len = 10; + let info = DispatchInfo { + weight: 5, + ..Default::default() + }; + + assert!(ChargeTransactionPayment::::from(0) + .pre_dispatch(&CHARLIE, CALL, &info, len) + .is_ok()); + + //Native balance check - Charlie should be still broke! + assert_eq!(Balances::free_balance(CHARLIE), 0); + + // token check should be less by the fee amount and -1 as fee in amm swap + assert_eq!(Tokens::free_balance(SUPPORTED_CURRENCY_WITH_BALANCE, &CHARLIE), 970); + }); +} + +#[test] +fn fee_payment_non_native_insufficient_balance_with_no_pool() { + const CHARLIE: AccountId = 5; + + ExtBuilder::default() + .base_weight(5) + .account_native_balance(CHARLIE, 0) + .account_tokens(CHARLIE, SUPPORTED_CURRENCY_WITH_BALANCE, 10) + .build() + .execute_with(|| { + assert_ok!(PaymentPallet::set_currency( + Origin::signed(CHARLIE), + SUPPORTED_CURRENCY_WITH_BALANCE + )); + + let len = 10; + let info = DispatchInfo { + weight: 5, + ..Default::default() + }; + + assert!(ChargeTransactionPayment::::from(0) + .pre_dispatch(&CHARLIE, CALL, &info, len) + .is_err()); + + assert_eq!(Tokens::free_balance(SUPPORTED_CURRENCY_WITH_BALANCE, &CHARLIE), 10); + }); +} diff --git a/pallets/transaction-multi-payment/src/traits.rs b/pallets/transaction-multi-payment/src/traits.rs new file mode 100644 index 000000000..6366f9e34 --- /dev/null +++ b/pallets/transaction-multi-payment/src/traits.rs @@ -0,0 +1,11 @@ +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum PaymentSwapResult { + NATIVE, + ERROR, + SWAPPED, + TRANSFERRED, +} + +pub trait CurrencySwap { + fn swap(who: &AccountId, fee: Balance) -> Result; +} diff --git a/primitives/src/traits.rs b/primitives/src/traits.rs index 269adeee4..8b43abf72 100644 --- a/primitives/src/traits.rs +++ b/primitives/src/traits.rs @@ -18,7 +18,6 @@ #![allow(clippy::upper_case_acronyms)] use frame_support::dispatch; -use frame_support::dispatch::DispatchResult; use sp_std::vec::Vec; /// Hold information to perform amm transfer @@ -107,7 +106,3 @@ pub trait Resolver { /// Intention ```intention``` must be validated prior to call this function. fn resolve_matched_intentions(pair_account: &AccountId, intention: &Intention, matched: &[Intention]); } - -pub trait CurrencySwap { - fn swap_currency(who: &AccountId, fee: Balance) -> DispatchResult; -} From 1449395d8a35ae77bf4f7223680bd0cce17292ec Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Thu, 10 Jun 2021 11:19:34 +0200 Subject: [PATCH 4/8] fix benchmarks and update runtime and chainspec --- node/src/chain_spec.rs | 18 ++++++++++++++---- .../benchmarking/src/lib.rs | 19 +++++++++++-------- .../benchmarking/src/mock.rs | 3 ++- runtime/src/lib.rs | 2 +- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index ef4d5c088..9151625ae 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -5,9 +5,9 @@ use hydra_dx_runtime::opaque::SessionKeys; use hydra_dx_runtime::pallet_claims::EthereumAddress; use hydra_dx_runtime::{ AccountId, AssetRegistryConfig, AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ClaimsConfig, CouncilConfig, - ElectionsConfig, FaucetConfig, GenesisConfig, GenesisHistoryConfig, GrandpaConfig, ImOnlineConfig, Perbill, - SessionConfig, Signature, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, - TokensConfig, CORE_ASSET_ID, WASM_BINARY, + ElectionsConfig, FaucetConfig, GenesisConfig, GenesisHistoryConfig, GrandpaConfig, ImOnlineConfig, + MultiTransactionPaymentConfig, Perbill, SessionConfig, Signature, StakerStatus, StakingConfig, SudoConfig, + SystemConfig, TechnicalCommitteeConfig, TokensConfig, CORE_ASSET_ID, WASM_BINARY, }; use pallet_staking::Forcing; use sc_service::ChainType; @@ -317,7 +317,7 @@ fn testnet_genesis( pallet_grandpa: Default::default(), pallet_sudo: SudoConfig { // Assign network admin rights. - key: root_key, + key: root_key.clone(), }, pallet_asset_registry: AssetRegistryConfig { core_asset_id: CORE_ASSET_ID, @@ -335,6 +335,11 @@ fn testnet_genesis( ], next_asset_id: 11, }, + pallet_transaction_multi_payment: MultiTransactionPaymentConfig { + currencies: vec![], + authorities: vec![], + fallback_account: root_key, + }, orml_tokens: TokensConfig { endowed_accounts: endowed_accounts .iter() @@ -470,6 +475,11 @@ fn lerna_genesis( asset_ids: vec![], next_asset_id: 1, }, + pallet_transaction_multi_payment: MultiTransactionPaymentConfig { + currencies: vec![], + authorities: vec![], + fallback_account: hex!["6d6f646c70792f74727372790000000000000000000000000000000000000000"].into(), + }, orml_tokens: TokensConfig { endowed_accounts: endowed_accounts.iter().flat_map(|_x| vec![]).collect(), }, diff --git a/pallets/transaction-multi-payment/benchmarking/src/lib.rs b/pallets/transaction-multi-payment/benchmarking/src/lib.rs index c5b4dec1f..d626c1de1 100644 --- a/pallets/transaction-multi-payment/benchmarking/src/lib.rs +++ b/pallets/transaction-multi-payment/benchmarking/src/lib.rs @@ -20,11 +20,11 @@ mod mock; use sp_std::prelude::*; +use sp_std::vec; use frame_benchmarking::{account, benchmarks}; use frame_system::RawOrigin; use orml_traits::{MultiCurrency, MultiCurrencyExtended}; -use orml_utilities::OrderedSet; use pallet_transaction_multi_payment::Pallet as MultiPaymentModule; use primitives::{Amount, AssetId, Balance, Price}; @@ -69,7 +69,7 @@ benchmarks! { let maker = funded_account::("maker", 1); initialize_pool::(maker.clone(), ASSET_ID, 1000, Price::from(1))?; MultiPaymentModule::::add_new_member(&maker); - MultiPaymentModule::::add_currency(RawOrigin::Signed(maker).into(), ASSET_ID)?; + MultiPaymentModule::::add_currency(RawOrigin::Signed(maker).into(), ASSET_ID, Price::from(10))?; let caller = funded_account::("caller", 2); MultiPaymentModule::::set_currency(RawOrigin::Signed(caller.clone()).into(), ASSET_ID)?; @@ -83,7 +83,7 @@ benchmarks! { set_currency { let maker = funded_account::("maker", 1); MultiPaymentModule::::add_new_member(&maker); - MultiPaymentModule::::add_currency(RawOrigin::Signed(maker).into(), ASSET_ID)?; + MultiPaymentModule::::add_currency(RawOrigin::Signed(maker).into(), ASSET_ID, Price::from(10))?; let caller = funded_account::("caller", 123); @@ -97,21 +97,24 @@ benchmarks! { add_currency { let caller = funded_account::("maker", 1); MultiPaymentModule::::add_new_member(&caller); - }: { MultiPaymentModule::::add_currency(RawOrigin::Signed(caller.clone()).into(), 10)? } + + let price = Price::from(10); + + }: { MultiPaymentModule::::add_currency(RawOrigin::Signed(caller.clone()).into(), 10, price)? } verify { - assert_eq!(MultiPaymentModule::::currencies(), OrderedSet::from(vec![10])); + assert_eq!(MultiPaymentModule::::currencies(10), Some(price)); } remove_currency { let caller = funded_account::("maker", 1); MultiPaymentModule::::add_new_member(&caller); - MultiPaymentModule::::add_currency(RawOrigin::Signed(caller.clone()).into(), 10)?; + MultiPaymentModule::::add_currency(RawOrigin::Signed(caller.clone()).into(), 10, Price::from(2))?; - assert_eq!(MultiPaymentModule::::currencies(), OrderedSet::from(vec![10])); + assert_eq!(MultiPaymentModule::::currencies(10), Some(Price::from(2))); }: { MultiPaymentModule::::remove_currency(RawOrigin::Signed(caller.clone()).into(), 10)? } verify { - assert_eq!(MultiPaymentModule::::currencies(), OrderedSet::::new()) + assert_eq!(MultiPaymentModule::::currencies(10), None) } add_member{ diff --git a/pallets/transaction-multi-payment/benchmarking/src/mock.rs b/pallets/transaction-multi-payment/benchmarking/src/mock.rs index 00abda8b1..74bb3efaa 100644 --- a/pallets/transaction-multi-payment/benchmarking/src/mock.rs +++ b/pallets/transaction-multi-payment/benchmarking/src/mock.rs @@ -249,8 +249,9 @@ impl ExtBuilder { .unwrap(); pallet_transaction_multi_payment::GenesisConfig:: { - currencies: OrderedSet::from(vec![]), + currencies: vec![], authorities: vec![], + fallback_account: 1000, } .assimilate_storage(&mut t) .unwrap(); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index e8498bcd0..fc643e03e 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1009,7 +1009,7 @@ construct_runtime!( Claims: pallet_claims::{Pallet, Call, Storage, Event, Config}, Exchange: pallet_exchange::{Pallet, Call, Storage, Event}, Faucet: pallet_faucet::{Pallet, Call, Storage, Config, Event}, - MultiTransactionPayment: pallet_transaction_multi_payment::{Pallet, Call, Storage, Event}, + MultiTransactionPayment: pallet_transaction_multi_payment::{Pallet, Call, Config, Storage, Event}, GenesisHistory: pallet_genesis_history::{Pallet, Storage, Config}, } ); From 93dfa6e30073c07a9e087160c0d18acdbcd60014 Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Thu, 10 Jun 2021 11:23:45 +0200 Subject: [PATCH 5/8] bump versions --- Cargo.lock | 6 +++--- pallets/transaction-multi-payment/Cargo.toml | 2 +- primitives/Cargo.toml | 2 +- runtime/Cargo.toml | 2 +- runtime/src/lib.rs | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a355af99..9a1374c67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2425,7 +2425,7 @@ dependencies = [ [[package]] name = "hydra-dx-runtime" -version = "15.1.0" +version = "16.0.0" dependencies = [ "frame-benchmarking", "frame-executive", @@ -4612,7 +4612,7 @@ dependencies = [ [[package]] name = "pallet-transaction-multi-payment" -version = "3.1.0" +version = "4.0.0" dependencies = [ "frame-support", "frame-system", @@ -5247,7 +5247,7 @@ dependencies = [ [[package]] name = "primitives" -version = "4.1.0" +version = "4.2.0" dependencies = [ "frame-support", "frame-system", diff --git a/pallets/transaction-multi-payment/Cargo.toml b/pallets/transaction-multi-payment/Cargo.toml index 910d2086e..380a93a7b 100644 --- a/pallets/transaction-multi-payment/Cargo.toml +++ b/pallets/transaction-multi-payment/Cargo.toml @@ -6,7 +6,7 @@ homepage = 'https://github.com/galacticcouncil/hydra-dx' license = 'Apache 2.0' name = 'pallet-transaction-multi-payment' repository = 'https://github.com/galacticcouncil/hydra-dx' -version = '3.1.0' +version = '4.0.0' [package.metadata.docs.rs] targets = ['x86_64-unknown-linux-gnu'] diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index e378ae201..5471f7b34 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -2,7 +2,7 @@ authors = ['GalacticCouncil'] edition = '2018' name = 'primitives' -version = '4.1.0' +version = '4.2.0' [build-dependencies] substrate-wasm-builder = {package = 'substrate-wasm-builder', version = '3.0.0'} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 9be3d7080..b946b748e 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -5,7 +5,7 @@ homepage = 'https://github.com/galacticcouncil/hydradx-node' license = 'Apache 2.0' name = 'hydra-dx-runtime' repository = 'https://github.com/galacticcouncil/hydradx-node' -version = '15.1.0' +version = '16.0.0' [package.metadata.docs.rs] targets = ['x86_64-unknown-linux-gnu'] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index fc643e03e..6e09e5e94 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -148,8 +148,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydra-dx"), impl_name: create_runtime_str!("hydra-dx"), authoring_version: 1, - spec_version: 15, - impl_version: 2, + spec_version: 16, + impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, }; From 4eb805e059ad402e79c37b387d54e093f5dba7eb Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Thu, 10 Jun 2021 11:32:36 +0200 Subject: [PATCH 6/8] update test --- pallets/transaction-multi-payment/src/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/transaction-multi-payment/src/tests.rs b/pallets/transaction-multi-payment/src/tests.rs index 0c731d747..7b3f8864f 100644 --- a/pallets/transaction-multi-payment/src/tests.rs +++ b/pallets/transaction-multi-payment/src/tests.rs @@ -332,6 +332,7 @@ fn fee_payment_in_non_native_currency_with_no_pool() { // token check should be less by the fee amount and -1 as fee in amm swap assert_eq!(Tokens::free_balance(SUPPORTED_CURRENCY_WITH_BALANCE, &CHARLIE), 970); + assert_eq!(Tokens::free_balance(SUPPORTED_CURRENCY_WITH_BALANCE, &FALLBACK_ACCOUNT), 30); }); } From 1fb22f6dcd5eb7560dae08675b9516c3b50676ec Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Thu, 10 Jun 2021 12:07:40 +0200 Subject: [PATCH 7/8] happy clipyp - happy life --- pallets/transaction-multi-payment/src/lib.rs | 16 ++++++++-------- pallets/transaction-multi-payment/src/traits.rs | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pallets/transaction-multi-payment/src/lib.rs b/pallets/transaction-multi-payment/src/lib.rs index 64251bb6b..fd7e24b1e 100644 --- a/pallets/transaction-multi-payment/src/lib.rs +++ b/pallets/transaction-multi-payment/src/lib.rs @@ -397,14 +397,14 @@ use traits::CurrencySwap; impl CurrencySwap<::AccountId, Balance> for Pallet { fn swap(who: &T::AccountId, fee: u128) -> Result { match Self::account_currency(who) { - CORE_ASSET_ID => Ok(PaymentSwapResult::NATIVE), + CORE_ASSET_ID => Ok(PaymentSwapResult::Native), currency => { if T::AMMPool::exists(AssetPair { asset_in: currency, asset_out: CORE_ASSET_ID, }) { Self::swap_currency(who, fee)?; - Ok(PaymentSwapResult::SWAPPED) + Ok(PaymentSwapResult::Swapped) } else { // If pool does not exists, let's use the currency fixed price @@ -414,7 +414,7 @@ impl CurrencySwap<::AccountId, Balance> fo T::MultiCurrency::transfer(currency, who, &Self::fallback_account(), amount)?; - Ok(PaymentSwapResult::TRANSFERRED) + Ok(PaymentSwapResult::Transferred) } } } @@ -460,11 +460,11 @@ where WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP }; - return if let Some(detail) = SW::swap(&who, fee.into()).ok() { + if let Ok(detail) = SW::swap(&who, fee.into()) { match detail { - PaymentSwapResult::TRANSFERRED => Ok(None), - PaymentSwapResult::ERROR => Err(InvalidTransaction::Payment.into()), - PaymentSwapResult::NATIVE | PaymentSwapResult::SWAPPED => { + PaymentSwapResult::Transferred => Ok(None), + PaymentSwapResult::Error => Err(InvalidTransaction::Payment.into()), + PaymentSwapResult::Native | PaymentSwapResult::Swapped => { match C::withdraw(who, fee, withdraw_reason, ExistenceRequirement::KeepAlive) { Ok(imbalance) => Ok(Some(imbalance)), Err(_) => Err(InvalidTransaction::Payment.into()), @@ -473,7 +473,7 @@ where } } else { Err(InvalidTransaction::Payment.into()) - }; + } } /// Hand the fee and the tip over to the `[OnUnbalanced]` implementation. diff --git a/pallets/transaction-multi-payment/src/traits.rs b/pallets/transaction-multi-payment/src/traits.rs index 6366f9e34..619d33d04 100644 --- a/pallets/transaction-multi-payment/src/traits.rs +++ b/pallets/transaction-multi-payment/src/traits.rs @@ -1,9 +1,9 @@ #[derive(Debug, Clone, PartialEq, Eq)] pub enum PaymentSwapResult { - NATIVE, - ERROR, - SWAPPED, - TRANSFERRED, + Native, + Error, + Swapped, + Transferred, } pub trait CurrencySwap { From 1716720eae622e998d7666e8fbd6dcac3e393e52 Mon Sep 17 00:00:00 2001 From: Martin Hloska Date: Thu, 10 Jun 2021 12:47:40 +0200 Subject: [PATCH 8/8] fix benchmarking compilation --- Cargo.lock | 2 +- pallets/transaction-multi-payment/Cargo.toml | 7 ++++--- pallets/transaction-multi-payment/benchmarking/Cargo.toml | 2 +- pallets/transaction-multi-payment/benchmarking/src/mock.rs | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a1374c67..a09bb941e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4444,7 +4444,7 @@ dependencies = [ [[package]] name = "pallet-multi-payment-benchmarking" -version = "3.1.0" +version = "4.0.0" dependencies = [ "frame-benchmarking", "frame-support", diff --git a/pallets/transaction-multi-payment/Cargo.toml b/pallets/transaction-multi-payment/Cargo.toml index 380a93a7b..3eda705f2 100644 --- a/pallets/transaction-multi-payment/Cargo.toml +++ b/pallets/transaction-multi-payment/Cargo.toml @@ -40,14 +40,15 @@ sp-api = {default-features = false, version = '3.0.0'} sp-core = {default-features = false, version = '3.0.0'} sp-runtime = {default-features = false, version = '3.0.0'} sp-std = {default-features = false, version = '3.0.0'} - pallet-transaction-payment = {default-features = false, version = '3.0.0'} -[dev-dependencies] +# These 2 dependencies are for testing only. But need to be here for benchmarking pallet - could not figure out why yet +pallet-asset-registry = {path = '../asset-registry', default-features = false} pallet-balances = {default-features = false, version = '3.0.0'} + +[dev-dependencies] orml-currencies = {default-features = false, version = "0.4.1-dev"} pallet-xyk = {path = '../xyk', default-features = false} -pallet-asset-registry = {path = '../asset-registry', default-features = false} sp-io = {default-features = false, version = '3.0.0'} [features] diff --git a/pallets/transaction-multi-payment/benchmarking/Cargo.toml b/pallets/transaction-multi-payment/benchmarking/Cargo.toml index 3aed3df72..d14cf1a01 100644 --- a/pallets/transaction-multi-payment/benchmarking/Cargo.toml +++ b/pallets/transaction-multi-payment/benchmarking/Cargo.toml @@ -6,7 +6,7 @@ homepage = 'https://github.com/galacticcouncil/hydra-dx' license = 'Apache 2.0' name = 'pallet-multi-payment-benchmarking' repository = 'https://github.com/galacticcouncil/hydra-dx' -version = '3.1.0' +version = '4.0.0' [package.metadata.docs.rs] targets = ['x86_64-unknown-linux-gnu'] diff --git a/pallets/transaction-multi-payment/benchmarking/src/mock.rs b/pallets/transaction-multi-payment/benchmarking/src/mock.rs index 74bb3efaa..8308f07fd 100644 --- a/pallets/transaction-multi-payment/benchmarking/src/mock.rs +++ b/pallets/transaction-multi-payment/benchmarking/src/mock.rs @@ -38,7 +38,6 @@ use pallet_xyk::AssetPairAccountIdFor; use std::cell::RefCell; use frame_benchmarking::frame_support::weights::Pays; -use orml_utilities::OrderedSet; use primitives::fee; pub type AccountId = u64;