Skip to content

Commit

Permalink
Feat/slpx mint add commission (#1273)
Browse files Browse the repository at this point in the history
* SLPx mint support commission id

* remove the channel_id parameter from the mint method

* add mint_with_channel_id method

* perform data migration for OrderQueue storage

* slpx: set the default value of channel_id to 0

* resolve conflicts

* change the location of the old data structure during storage migration
  • Loading branch information
SunTiebing authored Jun 19, 2024
1 parent fa21d8e commit 75df8c6
Show file tree
Hide file tree
Showing 12 changed files with 235 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pallets/slpx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ bifrost-asset-registry = { workspace = true }
bifrost-stable-pool = { workspace = true }
bifrost-stable-asset = { workspace = true }
orml-tokens = { workspace = true }
log = { workspace = true }

[dev-dependencies]
hex = { workspace = true }
Expand Down Expand Up @@ -77,6 +78,7 @@ std = [
"bifrost-asset-registry/std",
"bifrost-stable-pool/std",
"bifrost-stable-asset/std",
"log/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand Down
16 changes: 15 additions & 1 deletion pallets/slpx/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,21 @@ mod benchmarks {
KSM,
TargetChain::Astar(receiver),
BoundedVec::default(),
None,
);
}

#[benchmark]
fn mint_with_channel_id() {
let (caller, receiver) = init_whitelist::<T>();

#[extrinsic_call]
_(
RawOrigin::Signed(caller),
receiver,
KSM,
TargetChain::Astar(receiver),
BoundedVec::default(),
0u32,
);
}

Expand Down
48 changes: 43 additions & 5 deletions pallets/slpx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ pub mod pallet {
use frame_system::ensure_root;
use zenlink_protocol::{AssetId, ExportZenlink};

const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(_);

#[pallet::config]
Expand Down Expand Up @@ -442,7 +445,6 @@ pub mod pallet {
currency_id: CurrencyIdOf<T>,
target_chain: TargetChain<AccountIdOf<T>>,
remark: BoundedVec<u8, ConstU32<32>>,
channel_id: Option<u32>,
) -> DispatchResultWithPostInfo {
let (source_chain_caller, derivative_account, bifrost_chain_caller) =
Self::ensure_singer_on_whitelist(origin.clone(), evm_caller, &target_chain)?;
Expand All @@ -457,7 +459,8 @@ pub mod pallet {
currency_id,
remark,
target_chain,
channel_id,
// default to 0
channel_id: 0u32,
};

OrderQueue::<T>::mutate(|order_queue| -> DispatchResultWithPostInfo {
Expand Down Expand Up @@ -517,7 +520,8 @@ pub mod pallet {
bifrost_chain_caller,
derivative_account,
target_chain,
channel_id: None,
// default to 0
channel_id: 0u32,
};

OrderQueue::<T>::mutate(|order_queue| -> DispatchResultWithPostInfo {
Expand Down Expand Up @@ -741,7 +745,41 @@ pub mod pallet {
currency_id,
remark,
target_chain,
channel_id: None,
// default to 0
channel_id: 0u32,
};

OrderQueue::<T>::mutate(|order_queue| -> DispatchResultWithPostInfo {
order_queue.try_push(order.clone()).map_err(|_| Error::<T>::ArgumentsError)?;
Self::deposit_event(Event::<T>::CreateOrder { order });
Ok(().into())
})
}

#[pallet::call_index(13)]
#[pallet::weight(<T as Config>::WeightInfo::mint_with_channel_id())]
pub fn mint_with_channel_id(
origin: OriginFor<T>,
evm_caller: H160,
currency_id: CurrencyIdOf<T>,
target_chain: TargetChain<AccountIdOf<T>>,
remark: BoundedVec<u8, ConstU32<32>>,
channel_id: u32,
) -> DispatchResultWithPostInfo {
let (source_chain_caller, derivative_account, bifrost_chain_caller) =
Self::ensure_singer_on_whitelist(origin.clone(), evm_caller, &target_chain)?;

let order = Order {
create_block_number: <frame_system::Pallet<T>>::block_number(),
order_type: OrderType::Mint,
currency_amount: Default::default(),
source_chain_caller,
bifrost_chain_caller,
derivative_account,
currency_id,
remark,
target_chain,
channel_id,
};

OrderQueue::<T>::mutate(|order_queue| -> DispatchResultWithPostInfo {
Expand Down Expand Up @@ -1002,7 +1040,7 @@ impl<T: Config> Pallet<T> {
order.currency_id,
currency_amount,
order.remark.clone(),
order.channel_id,
Some(order.channel_id),
)
.map_err(|_| Error::<T>::ArgumentsError)?;
let vtoken_id = T::VtokenMintingInterface::vtoken_id(order.currency_id)
Expand Down
108 changes: 105 additions & 3 deletions pallets/slpx/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::*;
use bifrost_primitives::currency::{ASTR, BNC, DOT, GLMR, KSM, MANTA, MOVR};
use frame_support::traits::OnRuntimeUpgrade;
use frame_support::{storage_alias, traits::OnRuntimeUpgrade};
#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;

use bifrost_primitives::currency::{ASTR, BNC, DOT, GLMR, KSM, MANTA, MOVR};

use crate::*;

pub struct BifrostKusamaAddCurrencyToSupportXcmFee<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for BifrostKusamaAddCurrencyToSupportXcmFee<T> {
fn on_runtime_upgrade() -> Weight {
Expand Down Expand Up @@ -73,3 +75,103 @@ impl<T: Config> OnRuntimeUpgrade for BifrostPolkadotAddCurrencyToSupportXcmFee<T
Ok(())
}
}

mod v0 {
use super::*;
use frame_support::pallet_prelude::ValueQuery;
use parity_scale_codec::{Decode, Encode};

#[storage_alias]
pub(super) type OrderQueue<T: Config> = StorageValue<
Pallet<T>,
BoundedVec<
OldOrder<AccountIdOf<T>, CurrencyIdOf<T>, BalanceOf<T>, BlockNumberFor<T>>,
ConstU32<1000>,
>,
ValueQuery,
>;

#[derive(Encode, Decode)]
pub struct OldOrder<AccountId, CurrencyId, Balance, BlockNumber> {
pub source_chain_caller: OrderCaller<AccountId>,
pub bifrost_chain_caller: AccountId,
pub derivative_account: AccountId,
pub create_block_number: BlockNumber,
pub currency_id: CurrencyId,
pub currency_amount: Balance,
pub order_type: OrderType,
pub remark: BoundedVec<u8, ConstU32<32>>,
pub target_chain: TargetChain<AccountId>,
}
}

pub mod v1 {
use frame_support::traits::StorageVersion;

use super::*;

pub struct MigrateToV1<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> {
fn on_runtime_upgrade() -> Weight {
if StorageVersion::get::<Pallet<T>>() == 0 {
let weight_consumed = migrate_to_v1::<T>();
log::info!("Migrating slpx storage to v1");
StorageVersion::new(1).put::<Pallet<T>>();
weight_consumed.saturating_add(T::DbWeight::get().writes(1))
} else {
log::warn!("slpx migration should be removed.");
T::DbWeight::get().reads(1)
}
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::DispatchError> {
log::info!("slpx before migration: version: {:?}", StorageVersion::get::<Pallet<T>>());
log::info!("slpx before migration: v0 count: {}", v0::OrderQueue::<T>::get().len());

Ok(Vec::new())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
log::info!("slpx after migration: version: {:?}", StorageVersion::get::<Pallet<T>>());
log::info!("slpx after migration: v1 count: {}", OrderQueue::<T>::get().len());

Ok(())
}
}
}

pub fn migrate_to_v1<T: Config>() -> Weight {
let mut weight: Weight = Weight::zero();

let old_orders = v0::OrderQueue::<T>::get();

let mut new_orders: BoundedVec<_, ConstU32<1000>> = BoundedVec::default();
for old_order in old_orders.into_iter() {
new_orders
.try_push(Order {
source_chain_caller: old_order.source_chain_caller,
bifrost_chain_caller: old_order.bifrost_chain_caller,
derivative_account: old_order.derivative_account,
create_block_number: old_order.create_block_number,
currency_id: old_order.currency_id,
currency_amount: old_order.currency_amount,
order_type: old_order.order_type,
remark: old_order.remark,
target_chain: old_order.target_chain,
// default to 0
channel_id: 0u32,
})
.expect("BoundedVec should not overflow");
weight = weight.saturating_add(T::DbWeight::get().reads_writes(0, 1));
}

OrderQueue::<T>::put(new_orders);
weight = weight.saturating_add(T::DbWeight::get().writes(1));

v0::OrderQueue::<T>::kill();
weight = weight.saturating_add(T::DbWeight::get().writes(1));

weight
}
30 changes: 26 additions & 4 deletions pallets/slpx/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,7 @@ fn test_add_order() {
source_chain_caller,
DOT,
TargetChain::Astar(source_chain_caller),
BoundedVec::default(),
None
BoundedVec::default()
));
assert_eq!(OrderQueue::<Test>::get().len(), 1usize);
assert_ok!(Slpx::redeem(
Expand All @@ -380,6 +379,30 @@ fn test_add_order() {
})
}

#[test]
fn test_mint_with_channel_id() {
sp_io::TestExternalities::default().execute_with(|| {
assert_ok!(Slpx::add_whitelist(RuntimeOrigin::root(), SupportChain::Astar, ALICE));
let source_chain_caller = H160::default();
assert_ok!(Slpx::mint_with_channel_id(
RuntimeOrigin::signed(ALICE),
source_chain_caller,
DOT,
TargetChain::Astar(source_chain_caller),
BoundedVec::default(),
0u32
));
assert_eq!(OrderQueue::<Test>::get().len(), 1usize);
assert_ok!(Slpx::redeem(
RuntimeOrigin::signed(ALICE),
source_chain_caller,
VDOT,
TargetChain::Astar(source_chain_caller)
));
assert_eq!(OrderQueue::<Test>::get().len(), 2usize);
})
}

#[test]
fn test_hook() {
sp_io::TestExternalities::default().execute_with(|| {
Expand All @@ -390,8 +413,7 @@ fn test_hook() {
source_chain_caller,
DOT,
TargetChain::Astar(source_chain_caller),
BoundedVec::default(),
None
BoundedVec::default()
));
assert_eq!(OrderQueue::<Test>::get().len(), 1usize);
<frame_system::Pallet<Test>>::set_block_number(2u32.into());
Expand Down
2 changes: 1 addition & 1 deletion pallets/slpx/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,5 @@ pub struct Order<AccountId, CurrencyId, Balance, BlockNumber> {
pub order_type: OrderType,
pub remark: BoundedVec<u8, ConstU32<32>>,
pub target_chain: TargetChain<AccountId>,
pub channel_id: Option<u32>,
pub channel_id: u32,
}
14 changes: 14 additions & 0 deletions pallets/slpx/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub trait WeightInfo {
fn set_execution_fee() -> Weight;
fn set_transfer_to_fee() -> Weight;
fn mint() -> Weight;
fn mint_with_channel_id() -> Weight;
fn redeem() -> Weight;
fn zenlink_swap() -> Weight;
fn stable_pool_swap() -> Weight;
Expand Down Expand Up @@ -138,6 +139,19 @@ impl WeightInfo for () {
.saturating_add(RocksDbWeight::get().reads(16_u64))
.saturating_add(RocksDbWeight::get().writes(8_u64))
}
/// Storage: `Slpx::WhitelistAccountId` (r:1 w:0)
/// Proof: `Slpx::WhitelistAccountId` (`max_values`: None, `max_size`: Some(338), added: 2813, mode: `MaxEncodedLen`)
/// Storage: `Slpx::OrderQueue` (r:1 w:1)
/// Proof: `Slpx::OrderQueue` (`max_values`: Some(1), `max_size`: Some(203002), added: 203497, mode: `MaxEncodedLen`)
fn mint_with_channel_id() -> Weight {
// Proof Size summary in bytes:
// Measured: `81`
// Estimated: `204487`
// Minimum execution time: 12_000_000 picoseconds.
Weight::from_parts(12_000_000, 204487)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: Slpx WhitelistAccountId (r:1 w:0)
/// Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen)
/// Storage: Tokens Accounts (r:2 w:2)
Expand Down
2 changes: 1 addition & 1 deletion runtime/bifrost-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,7 @@ pub mod migrations {
use super::*;

/// Unreleased migrations. Add new ones here:
pub type Unreleased = ();
pub type Unreleased = (bifrost_slpx::migration::v1::MigrateToV1<Runtime>,);
}

/// Executive: handles dispatch to the various modules.
Expand Down
13 changes: 13 additions & 0 deletions runtime/bifrost-kusama/src/weights/bifrost_slpx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ impl<T: frame_system::Config> bifrost_slpx::WeightInfo for BifrostWeight<T> {
.saturating_add(T::DbWeight::get().reads(16))
.saturating_add(T::DbWeight::get().writes(8))
}
// Storage: `Slpx::WhitelistAccountId` (r:1 w:0)
// Proof: `Slpx::WhitelistAccountId` (`max_values`: None, `max_size`: Some(338), added: 2813, mode: `MaxEncodedLen`)
// Storage: `Slpx::OrderQueue` (r:1 w:1)
// Proof: `Slpx::OrderQueue` (`max_values`: Some(1), `max_size`: Some(203002), added: 203497, mode: `MaxEncodedLen`)
fn mint_with_channel_id() -> Weight {
// Proof Size summary in bytes:
// Measured: `81`
// Estimated: `204487`
// Minimum execution time: 12_000 nanoseconds.
Weight::from_parts(13_000_000, 204487)
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
}
// Storage: Slpx WhitelistAccountId (r:1 w:0)
// Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen)
// Storage: Tokens Accounts (r:2 w:2)
Expand Down
2 changes: 1 addition & 1 deletion runtime/bifrost-polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1885,7 +1885,7 @@ pub mod migrations {
use super::*;

/// Unreleased migrations. Add new ones here:
pub type Unreleased = ();
pub type Unreleased = (bifrost_slpx::migration::v1::MigrateToV1<Runtime>,);
}

/// Executive: handles dispatch to the various modules.
Expand Down
Loading

0 comments on commit 75df8c6

Please sign in to comment.