Skip to content

Commit

Permalink
Feat/flexible fee ban vbnc (#1488)
Browse files Browse the repository at this point in the history
* Prohibit setting VBNC as the default fee currency.

* Modify code formatting.

* Add data migration code.
  • Loading branch information
SunTiebing authored Oct 31, 2024
1 parent 90774f7 commit b0a58c0
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 3 deletions.
12 changes: 11 additions & 1 deletion pallets/flexible-fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ pub mod pallet {
}

/// The current storage version, we set to 2 our new version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);

/// Universal fee currency order list for all users
#[pallet::storage]
Expand Down Expand Up @@ -188,12 +188,19 @@ pub mod pallet {

#[pallet::error]
pub enum Error<T> {
/// The account does not have enough balance to perform the operation.
NotEnoughBalance,
/// An error occurred during currency conversion.
ConversionError,
/// No weight or fee information is available for the requested operation.
WeightAndFeeNotExist,
/// The message cannot be weighed, possibly due to insufficient information.
UnweighableMessage,
/// The XCM execution has failed.
XcmExecutionFailed,
/// The specified currency is not supported by the system.
CurrencyNotSupport,
/// The maximum number of currencies that can be handled has been reached.
MaxCurrenciesReached,
}

Expand All @@ -212,6 +219,9 @@ pub mod pallet {
let who = ensure_signed(origin)?;

if let Some(fee_currency) = &currency_id {
// VBNC is not supported.
ensure!(fee_currency != &VBNC, Error::<T>::CurrencyNotSupport);

UserDefaultFeeCurrency::<T>::insert(&who, fee_currency);
} else {
UserDefaultFeeCurrency::<T>::remove(&who);
Expand Down
3 changes: 3 additions & 0 deletions pallets/flexible-fee/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@

/// Version 2.
pub mod v2;

/// Version 3.
pub mod v3;
118 changes: 118 additions & 0 deletions pallets/flexible-fee/src/migrations/v3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// This file is part of Bifrost.

// Copyright (C) Liebi Technologies PTE. LTD.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// 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::BNC;
use frame_support::traits::OnRuntimeUpgrade;
#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;

const LOG_TARGET: &str = "flexible-fee::migration";

pub struct MigrateToV3<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for MigrateToV3<T> {
fn on_runtime_upgrade() -> frame_support::weights::Weight {
// Check the storage version
let onchain_version = Pallet::<T>::on_chain_storage_version();
if onchain_version < 3 {
log::info!(target: LOG_TARGET, "Start to migrate flexible-fee storage...");

let mut count: u64 = 0;

// Traversal UserDefaultFeeCurrency storage
UserDefaultFeeCurrency::<T>::iter().for_each(|(account_id, currency_id)| {
// If currency_id is vbnc, change it to bnc
if currency_id == VBNC {
count += 1;
UserDefaultFeeCurrency::<T>::insert(account_id, BNC);
}
});

// Update the storage version
StorageVersion::new(3).put::<Pallet<T>>();

// Return the consumed weight
Weight::from(T::DbWeight::get().reads_writes(count + 1, count + 1))
} else {
// We don't do anything here.
Weight::zero()
}
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
let total_count = UserDefaultFeeCurrency::<T>::iter().count();

let mut vbnc_count: u64 = 0;
UserDefaultFeeCurrency::<T>::iter().for_each(|(_, currency_id)| {
if currency_id == VBNC {
vbnc_count += 1;
}
});

// print out the pre-migrate storage count
log::info!(
target: LOG_TARGET,
"UserDefaultFeeCurrency pre-migrate storage total count: {:?}",
total_count
);
log::info!(
target: LOG_TARGET,
"UserDefaultFeeCurrency pre-migrate storage vbnc count: {:?}",
vbnc_count
);
Ok((total_count as u64).encode())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(cnt: Vec<u8>) -> Result<(), TryRuntimeError> {
let old_total_count: u64 = Decode::decode(&mut cnt.as_slice())
.expect("the state parameter should be something that was generated by pre_upgrade");

let new_total_count = UserDefaultFeeCurrency::<T>::iter().count();

let mut new_vbnc_count: u64 = 0;
UserDefaultFeeCurrency::<T>::iter().for_each(|(_, currency_id)| {
if currency_id == VBNC {
new_vbnc_count += 1;
}
});

// print out the post-migrate storage count
log::info!(
target: LOG_TARGET,
"UserDefaultFeeCurrency post-migrate storage total count: {:?}",
new_total_count
);
log::info!(
target: LOG_TARGET,
"UserDefaultFeeCurrency post-migrate storage vbnc count: {:?}",
new_vbnc_count
);

ensure!(
new_total_count as u64 == old_total_count,
"Post-migration storage total count does not match pre-migration total count"
);
ensure!(
new_vbnc_count == 0,
"Post-migration storage vbnc count does not match pre-migration vbnc count"
);
Ok(())
}
}
18 changes: 16 additions & 2 deletions pallets/flexible-fee/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
#![cfg(test)]
use crate::{
impls::on_charge_transaction::PaymentInfo, mock::*, BlockNumberFor, BoundedVec, Config,
DispatchError::BadOrigin, UserDefaultFeeCurrency,
DispatchError::BadOrigin, Error, UserDefaultFeeCurrency,
};
use bifrost_primitives::{
AccountFeeCurrency, BalanceCmp, CurrencyId, TryConvertFrom, BNC, DOT, KSM, MANTA, VDOT, WETH,
AccountFeeCurrency, BalanceCmp, CurrencyId, TryConvertFrom, BNC, DOT, KSM, MANTA, VBNC, VDOT,
WETH,
};
use frame_support::{
assert_noop, assert_ok,
Expand Down Expand Up @@ -151,6 +152,19 @@ fn set_user_default_fee_currency_should_work() {
});
}

#[test]
fn set_user_default_fee_currency_should_fail_with_error_currency() {
new_test_ext().execute_with(|| {
let origin_signed_alice = RuntimeOrigin::signed(ALICE);
assert_noop!(
FlexibleFee::set_user_default_fee_currency(origin_signed_alice.clone(), Some(VBNC)),
Error::<Test>::CurrencyNotSupport
);

assert_eq!(UserDefaultFeeCurrency::<Test>::get(ALICE).is_none(), true);
});
}

#[test]
fn set_default_fee_currency_list_should_work() {
new_test_ext().execute_with(|| {
Expand Down
1 change: 1 addition & 0 deletions runtime/bifrost-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2034,6 +2034,7 @@ pub mod migrations {
>,
// permanent migration, do not remove
pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
bifrost_flexible_fee::migrations::v3::MigrateToV3<Runtime>,
);
}

Expand Down

0 comments on commit b0a58c0

Please sign in to comment.