diff --git a/Cargo.lock b/Cargo.lock index 6befa15909..7497ae4eda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,7 +173,6 @@ dependencies = [ "bifrost-runtime-common", "bifrost-salp", "bifrost-salp-lite", - "bifrost-salp-lite-rpc-runtime-api", "bifrost-salp-rpc-runtime-api", "bifrost-token-issuer", "bifrost-vesting", @@ -858,7 +857,6 @@ dependencies = [ "bifrost-runtime-common", "bifrost-salp", "bifrost-salp-lite", - "bifrost-salp-lite-rpc-runtime-api", "bifrost-salp-rpc-runtime-api", "bifrost-token-issuer", "bifrost-vesting", @@ -1052,15 +1050,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "bifrost-salp-lite-rpc-runtime-api" -version = "0.8.0" -dependencies = [ - "node-primitives", - "parity-scale-codec", - "sp-api", -] - [[package]] name = "bifrost-salp-rpc-api" version = "0.8.0" @@ -4987,7 +4976,7 @@ dependencies = [ [[package]] name = "node-cli" -version = "0.9.6" +version = "0.9.8" dependencies = [ "cumulus-client-cli", "cumulus-client-service", diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 52e31ccab5..ee85ec4751 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-cli" -version = "0.9.6" +version = "0.9.8" authors = ["Liebi Technologies "] description = "Bifrost Parachain Node" build = "build.rs" diff --git a/node/service/src/lib.rs b/node/service/src/lib.rs index b4f95819c4..f9685ce9a2 100644 --- a/node/service/src/lib.rs +++ b/node/service/src/lib.rs @@ -244,7 +244,7 @@ where /// /// This is the actual implementation that is abstract over the executor and the /// runtime api. -#[sc_tracing::logging::prefix_logs_with("Parachain")] +#[sc_tracing::logging::prefix_logs_with("Parachain🌈")] async fn start_node_impl( parachain_config: Configuration, polkadot_config: Configuration, @@ -340,15 +340,6 @@ where }) }; - if parachain_config.offchain_worker.enabled { - sc_service::build_offchain_workers( - ¶chain_config, - task_manager.spawn_handle(), - client.clone(), - network.clone(), - ); - }; - sc_service::spawn_tasks(sc_service::SpawnTasksParams { on_demand: None, remote_blockchain: None, diff --git a/pallets/salp-lite/rpc/Cargo.toml b/pallets/salp-lite/rpc/Cargo.toml deleted file mode 100644 index 0134f43b50..0000000000 --- a/pallets/salp-lite/rpc/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "bifrost-salp-lite-rpc-api" -version = "0.8.0" -authors = ["Ron Yang "] -edition = "2018" - -[dependencies] -serde = { version = "1.0.124", features = ["derive"] } -codec = { package = "parity-scale-codec", version = "2.3.0", default-features = false, features = ["derive"] } -jsonrpc-core = "15.1.0" -jsonrpc-core-client = "15.1.0" -jsonrpc-derive = "15.1.0" -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12" } -sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12" } -node-primitives = { path = "../../../node/primitives", default-features = false } -bifrost-salp-lite-rpc-runtime-api = { path = "./runtime-api" } diff --git a/pallets/salp-lite/rpc/runtime-api/Cargo.toml b/pallets/salp-lite/rpc/runtime-api/Cargo.toml deleted file mode 100644 index 72b3033052..0000000000 --- a/pallets/salp-lite/rpc/runtime-api/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "bifrost-salp-lite-rpc-runtime-api" -version = "0.8.0" -authors = ["Ron Yang"] -edition = "2018" - -[dependencies] -codec = { package = "parity-scale-codec", version = "2.3.0", default-features = false, features = ["derive"] } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12", default-features = false } -node-primitives = { path = "../../../../node/primitives", default-features = false } - -[features] -default = ["std"] -std = [ - "codec/std", - "sp-api/std", - "node-primitives/std", -] diff --git a/pallets/salp-lite/rpc/runtime-api/src/lib.rs b/pallets/salp-lite/rpc/runtime-api/src/lib.rs deleted file mode 100644 index 1ff6fe7807..0000000000 --- a/pallets/salp-lite/rpc/runtime-api/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -// This file is part of Bifrost. - -// Copyright (C) 2019-2021 Liebi Technologies (UK) 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 . - -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::Codec; -use node_primitives::{Balance, RpcContributionStatus}; -use sp_api::decl_runtime_apis; - -decl_runtime_apis! { - pub trait SalpRuntimeApi where - ParaId: Codec, - AccountId: Codec, - { - fn get_contribution( - index: ParaId, - who: AccountId - ) -> (Balance,RpcContributionStatus); - } -} diff --git a/pallets/salp-lite/rpc/src/lib.rs b/pallets/salp-lite/rpc/src/lib.rs deleted file mode 100644 index 1f88cd373f..0000000000 --- a/pallets/salp-lite/rpc/src/lib.rs +++ /dev/null @@ -1,86 +0,0 @@ -// This file is part of Bifrost. - -// Copyright (C) 2019-2021 Liebi Technologies (UK) 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 . - -use std::{marker::PhantomData, sync::Arc}; - -pub use bifrost_salp_rpc_runtime_api::{self as runtime_api, SalpRuntimeApi}; -use codec::Codec; -use jsonrpc_core::{Error as RpcError, ErrorCode, Result as JsonRpcResult}; -use jsonrpc_derive::rpc; -use node_primitives::RpcContributionStatus; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::HeaderBackend; -use sp_rpc::number::NumberOrHex; -use sp_runtime::{generic::BlockId, traits::Block as BlockT, SaturatedConversion}; - -pub use self::gen_client::Client as SalpClient; - -#[derive(Clone, Debug)] -pub struct SalpRpcWrapper { - client: Arc, - _marker: PhantomData, -} - -impl SalpRpcWrapper { - pub fn new(client: Arc) -> Self { - Self { client, _marker: PhantomData } - } -} - -#[rpc] -pub trait SalpRpcApi { - /// rpc method for getting current contribution - #[rpc(name = "salp_getContribution")] - fn get_contribution( - &self, - index: ParaId, - who: AccountId, - at: Option, - ) -> JsonRpcResult<(NumberOrHex, RpcContributionStatus)>; -} - -impl SalpRpcApi<::Hash, ParaId, AccountId> - for SalpRpcWrapper -where - Block: BlockT, - C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, - C::Api: SalpRuntimeApi, - ParaId: Codec, - AccountId: Codec, -{ - fn get_contribution( - &self, - index: ParaId, - account: AccountId, - at: Option<::Hash>, - ) -> JsonRpcResult<(NumberOrHex, RpcContributionStatus)> { - let salp_rpc_api = self.client.runtime_api(); - let at = BlockId::::hash(at.unwrap_or_else(|| self.client.info().best_hash)); - - let rs = salp_rpc_api.get_contribution(&at, index, account); - - match rs { - Ok((val, status)) => Ok((NumberOrHex::Number(val.saturated_into()), status)), - Err(e) => Err(RpcError { - code: ErrorCode::InternalError, - message: "Failed to get salp contribution.".to_owned(), - data: Some(format!("{:?}", e).into()), - }), - } - } -} diff --git a/pallets/salp-lite/src/benchmarking.rs b/pallets/salp-lite/src/benchmarking.rs index a84784e4ea..bc2663b1bf 100644 --- a/pallets/salp-lite/src/benchmarking.rs +++ b/pallets/salp-lite/src/benchmarking.rs @@ -72,38 +72,6 @@ benchmarks! { assert_last_event::(Event::::Refunded(caller.clone(), fund_index, contribution).into()) } - unlock { - let fund_index = create_fund::(1); - let caller: T::AccountId = whitelisted_caller(); - let caller_origin: T::Origin = RawOrigin::Signed(caller.clone()).into(); - let contribution = T::MinContribution::get(); - contribute_fund::(&caller,fund_index); - assert_ok!(Salp::::fund_success(RawOrigin::Root.into(), fund_index)); - }: _(RawOrigin::Root, caller.clone(),fund_index) - verify { - let fund = Salp::::funds(fund_index).unwrap(); - let (_, status) = Salp::::contribution(fund.trie_index, &caller); - assert_eq!(status, ContributionStatus::Unlocked); - } - - batch_unlock { - let k in 1 .. T::BatchKeysLimit::get(); - let fund_index = create_fund::(1); - let contribution = T::MinContribution::get(); - let mut caller: T::AccountId = whitelisted_caller(); - for i in 0 .. k { - caller = account("contributor", i, 0); - contribute_fund::(&caller,fund_index); - } - assert_ok!(Salp::::fund_success(RawOrigin::Root.into(), fund_index)); - }: _(RawOrigin::Signed(caller.clone()), fund_index) - verify { - let fund = Salp::::funds(fund_index).unwrap(); - let (_, status) = Salp::::contribution(fund.trie_index, &caller); - assert_eq!(status, ContributionStatus::Unlocked); - assert_last_event::(Event::::AllUnlocked(fund_index).into()); - } - redeem { let fund_index = create_fund::(1); let caller: T::AccountId = whitelisted_caller(); diff --git a/pallets/salp-lite/src/lib.rs b/pallets/salp-lite/src/lib.rs index 13dd5be9ca..eb90da5d4d 100644 --- a/pallets/salp-lite/src/lib.rs +++ b/pallets/salp-lite/src/lib.rs @@ -19,12 +19,6 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -pub mod migration { - pub fn migrate() { - log::info!("salp migration..."); - } -} - #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; #[cfg(test)] @@ -106,7 +100,7 @@ pub mod pallet { use super::*; #[pallet::config] - pub trait Config: frame_system::Config + TypeInfo { + pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; /// ModuleID for the crowdloan module. An appropriate value could be @@ -382,7 +376,7 @@ pub mod pallet { } /// Unlock the reserved vsToken/vsBond after fund success - #[pallet::weight(T::WeightInfo::batch_unlock(T::BatchKeysLimit::get()))] + #[pallet::weight(T::WeightInfo::batch_migrate(T::BatchKeysLimit::get()))] #[transactional] pub fn batch_migrate( origin: OriginFor, @@ -413,11 +407,7 @@ pub mod pallet { #[allow(non_snake_case)] let (_, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - let balance = T::MultiCurrency::slash_reserved(vsBond, &who, contributed); - ensure!( - balance == Zero::zero(), - Error::::NotEnoughReservedAssetsToRefund - ); + T::MultiCurrency::slash_reserved(vsBond, &who, contributed); let (_, vs_bond_new) = Self::vsAssets( index, @@ -447,100 +437,6 @@ pub mod pallet { Ok(()) } - /// Unlock the reserved vsToken/vsBond after fund success - #[pallet::weight(T::WeightInfo::unlock())] - #[transactional] - pub fn unlock( - _origin: OriginFor, - who: AccountIdOf, - #[pallet::compact] index: ParaId, - ) -> DispatchResult { - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!( - fund.status == FundStatus::Success || - fund.status == FundStatus::Retired || - fund.status == FundStatus::RedeemWithdrew || - fund.status == FundStatus::End, - Error::::InvalidFundStatus - ); - - let (contributed, status) = Self::contribution(fund.trie_index, &who); - ensure!(status == ContributionStatus::Idle, Error::::InvalidContributionStatus); - - #[allow(non_snake_case)] - let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - - let balance = T::MultiCurrency::unreserve(vsToken, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); - let balance = T::MultiCurrency::unreserve(vsBond, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); - - Self::put_contribution( - fund.trie_index, - &who, - contributed, - ContributionStatus::Unlocked, - ); - - Self::deposit_event(Event::::Unlocked(who, index, contributed)); - - Ok(()) - } - - /// Unlock the reserved vsToken/vsBond after fund success - #[pallet::weight(T::WeightInfo::batch_unlock(T::BatchKeysLimit::get()))] - #[transactional] - pub fn batch_unlock( - origin: OriginFor, - #[pallet::compact] index: ParaId, - ) -> DispatchResult { - ensure_signed(origin)?; - - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!( - fund.status == FundStatus::Success || - fund.status == FundStatus::Retired || - fund.status == FundStatus::RedeemWithdrew || - fund.status == FundStatus::End, - Error::::InvalidFundStatus - ); - - let mut unlock_count = 0u32; - let contributions = Self::contribution_iterator(fund.trie_index); - // Assume everyone will be refunded. - let mut all_unlocked = true; - - for (who, (contributed, status)) in contributions { - if unlock_count >= T::BatchKeysLimit::get() { - // Not everyone was able to be refunded this time around. - all_unlocked = false; - break; - } - if status != ContributionStatus::Unlocked { - #[allow(non_snake_case)] - let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - let balance = T::MultiCurrency::unreserve(vsToken, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); - let balance = T::MultiCurrency::unreserve(vsBond, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); - - Self::put_contribution( - fund.trie_index, - &who, - contributed, - ContributionStatus::Unlocked, - ); - unlock_count += 1; - } - } - - if all_unlocked { - Self::deposit_event(Event::::AllUnlocked(index)); - } - - Ok(()) - } - /// Create a new crowdloaning campaign for a parachain slot deposit for the current auction. #[pallet::weight(( 0, @@ -618,9 +514,7 @@ pub mod pallet { // Issue reserved vsToken/vsBond to contributor T::MultiCurrency::deposit(vs_token, &who, value)?; - T::MultiCurrency::reserve(vs_token, &who, value)?; T::MultiCurrency::deposit(vs_bond, &who, value)?; - T::MultiCurrency::reserve(vs_bond, &who, value)?; // Update the raised of fund let fund_new = FundInfo { raised: fund.raised.saturating_add(value), ..fund }; @@ -676,10 +570,6 @@ pub mod pallet { let who = ensure_signed(origin.clone())?; let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!( - fund.status == FundStatus::Failed || fund.status == FundStatus::RefundWithdrew, - Error::::InvalidFundStatus - ); let (contributed, status) = Self::contribution(fund.trie_index, &who); ensure!(contributed > Zero::zero(), Error::::ZeroContribution); @@ -689,21 +579,11 @@ pub mod pallet { #[allow(non_snake_case)] let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - ensure!( - T::MultiCurrency::reserved_balance(vsToken, &who) >= contributed, - Error::::NotEnoughReservedAssetsToRefund - ); - ensure!( - T::MultiCurrency::reserved_balance(vsBond, &who) >= contributed, - Error::::NotEnoughReservedAssetsToRefund - ); fund.raised = fund.raised.saturating_sub(contributed); - let balance = T::MultiCurrency::slash_reserved(vsToken, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughReservedAssetsToRefund); - let balance = T::MultiCurrency::slash_reserved(vsBond, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughReservedAssetsToRefund); + T::MultiCurrency::slash_reserved(vsToken, &who, contributed); + T::MultiCurrency::slash_reserved(vsBond, &who, contributed); Self::kill_contribution(fund.trie_index, &who); @@ -722,32 +602,35 @@ pub mod pallet { let who = ensure_signed(origin.clone())?; let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!(fund.status == FundStatus::RedeemWithdrew, Error::::InvalidFundStatus); - ensure!(fund.raised >= value, Error::::NotEnoughBalanceInRedeemPool); - - let (contributed, status) = Self::contribution(fund.trie_index, &who); ensure!( - status == ContributionStatus::Idle || - status == ContributionStatus::Unlocked || - status == ContributionStatus::Redeemed, - Error::::InvalidContributionStatus + fund.status == FundStatus::RefundWithdrew || + fund.status == FundStatus::RedeemWithdrew, + Error::::InvalidFundStatus ); + ensure!(fund.raised >= value, Error::::NotEnoughBalanceInRedeemPool); - ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRedeemPool); - + let (contributed, _) = Self::contribution(fund.trie_index, &who); #[allow(non_snake_case)] let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - T::MultiCurrency::ensure_can_withdraw(vsToken, &who, value) - .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; - T::MultiCurrency::ensure_can_withdraw(vsBond, &who, value) - .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; - T::MultiCurrency::withdraw(vsToken, &who, value)?; - T::MultiCurrency::withdraw(vsBond, &who, value)?; + if fund.status == FundStatus::RedeemWithdrew { + ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRedeemPool); + T::MultiCurrency::ensure_can_withdraw(vsToken, &who, value) + .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; + T::MultiCurrency::ensure_can_withdraw(vsBond, &who, value) + .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; + } - fund.raised = fund.raised.saturating_sub(value); - RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); + if fund.status == FundStatus::RedeemWithdrew { + T::MultiCurrency::withdraw(vsToken, &who, value)?; + T::MultiCurrency::withdraw(vsBond, &who, value)?; + RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); + } else if fund.status == FundStatus::RefundWithdrew { + T::MultiCurrency::slash_reserved(vsToken, &who, contributed); + T::MultiCurrency::slash_reserved(vsBond, &who, contributed); + } + fund.raised = fund.raised.saturating_sub(value); let contributed_new = contributed.saturating_sub(value); Self::put_contribution( fund.trie_index, @@ -918,19 +801,14 @@ pub mod pallet { } pub trait WeightInfo { - fn unlock() -> Weight; - fn batch_unlock(k: u32) -> Weight; + fn batch_migrate(k: u32) -> Weight; fn refund() -> Weight; fn redeem() -> Weight; } // For backwards compatibility and tests impl WeightInfo for () { - fn unlock() -> Weight { - 50_000_000 as Weight - } - - fn batch_unlock(_k: u32) -> Weight { + fn batch_migrate(_k: u32) -> Weight { 50_000_000 as Weight } diff --git a/pallets/salp-lite/src/mock.rs b/pallets/salp-lite/src/mock.rs index e7dae24376..7a7dbc65d7 100644 --- a/pallets/salp-lite/src/mock.rs +++ b/pallets/salp-lite/src/mock.rs @@ -247,10 +247,6 @@ impl salp::Config for Test { pub struct SalpWeightInfo; impl WeightInfo for SalpWeightInfo { - fn unlock() -> Weight { - 0 - } - fn redeem() -> Weight { 0 } @@ -259,7 +255,7 @@ impl WeightInfo for SalpWeightInfo { 0 } - fn batch_unlock(_k: u32) -> Weight { + fn batch_migrate(_k: u32) -> Weight { 0 } } diff --git a/pallets/salp-lite/src/tests.rs b/pallets/salp-lite/src/tests.rs index eb7dfa4b12..a7aab23356 100644 --- a/pallets/salp-lite/src/tests.rs +++ b/pallets/salp-lite/src/tests.rs @@ -18,9 +18,9 @@ // Ensure we're `no_std` when compiling for Wasm. -use frame_support::{assert_noop, assert_ok, dispatch::DispatchError, traits::BalanceStatus as BS}; +use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use node_primitives::ContributionStatus; -use orml_traits::{MultiCurrency, MultiReservableCurrency}; +use orml_traits::MultiCurrency; use crate::{mock::*, Error, FundStatus}; @@ -243,81 +243,6 @@ fn set_fund_end_with_wrong_fund_status_should_fail() { }); } -#[test] -fn unlock_should_work() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX,)); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); - - #[allow(non_snake_case)] - let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - - assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 100); - assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); - assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 100); - assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); - }); -} - -#[test] -fn unlock_with_wrong_fund_status_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX,)); - assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); - - assert_noop!( - Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000), - Error::::InvalidFundStatus - ); - }); -} - -#[test] -fn unlock_when_already_unlocked_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX,)); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); - - assert_noop!( - Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000), - Error::::InvalidContributionStatus - ); - }); -} - -#[test] -fn unlock_without_enough_reserved_vsassets_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - - // ABSOLUTELY NOT HAPPEN AT NORMAL PROCESS! - #[allow(non_snake_case)] - let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - Tokens::slash_reserved(vsToken, &BRUCE, 50); - Tokens::slash_reserved(vsBond, &BRUCE, 50); - - // ``` - // // The following code will produce a supernatural bug. - // // DONT ASK WHY, I DONT KNOW! - // assert_noop!( - // Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000), - // Error::::NotEnoughBalanceToUnlock - // ); - // ``` - let result = Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000); - assert_noop!(result, Error::::NotEnoughBalanceToUnlock); - }); -} - #[test] fn contribute_should_work() { new_test_ext().execute_with(|| { @@ -332,12 +257,12 @@ fn contribute_should_work() { #[allow(non_snake_case)] let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 100); assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 100); - assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 100); assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 100); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); }); } @@ -357,12 +282,12 @@ fn double_contribute_should_work() { #[allow(non_snake_case)] let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 200); assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 200); - assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 200); assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 200); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); }); } @@ -381,12 +306,12 @@ fn confirm_contribute_later_should_work() { #[allow(non_snake_case)] let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 100); assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 100); - assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 100); assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); - assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 100); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); }); } @@ -545,35 +470,15 @@ fn refund_should_work() { #[allow(non_snake_case)] let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 100); assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); - assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 100); assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); }); } -#[test] -fn refund_without_enough_vsassets_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); - assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); - - #[allow(non_snake_case)] - let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - assert_ok!(Tokens::repatriate_reserved(vsToken, &BRUCE, &ALICE, 50, BS::Reserved)); - assert_ok!(Tokens::repatriate_reserved(vsBond, &BRUCE, &ALICE, 50, BS::Reserved)); - - assert_noop!( - Salp::refund(Some(BRUCE).into(), 3_000), - Error::::NotEnoughReservedAssetsToRefund - ); - }); -} - #[test] fn refund_with_zero_contribution_should_fail() { new_test_ext().execute_with(|| { @@ -611,25 +516,6 @@ fn refund_with_wrong_para_id_should_fail() { }); } -#[test] -fn refund_with_wrong_fund_status_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::fund_end(Some(ALICE).into(), 3_000)); - - assert_noop!(Salp::refund(Some(BRUCE).into(), 3_000), Error::::InvalidFundStatus); - - assert_ok!(Salp::create(Some(ALICE).into(), 4_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 4_000)); - assert_ok!(Salp::fund_retire(Some(ALICE).into(), 4_000)); - assert_ok!(Salp::withdraw(Some(ALICE).into(), 4_000)); - - assert_noop!(Salp::refund(Some(BRUCE).into(), 4_000), Error::::InvalidFundStatus); - }); -} - #[test] fn refund_with_when_ump_wrong_should_fail() { // TODO: Require an solution to settle with parallel test workflow @@ -706,7 +592,6 @@ fn redeem_should_work() { assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); // Mock the BlockNumber let block_begin_redeem = (SlotLength::get() + 1) * LeasePeriod::get(); @@ -748,7 +633,6 @@ fn redeem_with_speical_vsbond_should_work() { assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 2001, 100, CONTRIBUTON_INDEX)); assert_ok!(Salp::fund_success(Some(ALICE).into(), 2001)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 2001)); // Mock the BlockNumber let block_begin_redeem = (SlotLength::get() + 1) * LeasePeriod::get(); @@ -789,7 +673,6 @@ fn redeem_with_wrong_origin_should_fail() { assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); // Mock the BlockNumber let block_begin_redeem = (SlotLength::get() + 1) * LeasePeriod::get(); @@ -809,7 +692,6 @@ fn redeem_with_not_redeemable_vsbond_should_fail() { assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); // Mock the BlockNumber let block_not_redeemable = LeasePeriod::get(); @@ -833,7 +715,6 @@ fn redeem_without_enough_vsassets_should_fail() { assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); // Mock the BlockNumber let block_begin_redeem = (SlotLength::get() + 1) * LeasePeriod::get(); @@ -866,7 +747,6 @@ fn redeem_without_enough_balance_in_pool_should_fail() { assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); // Mock the BlockNumber let block_begin_redeem = (SlotLength::get() + 1) * LeasePeriod::get(); @@ -905,7 +785,6 @@ fn release_from_redeem_to_bancor_should_work() { assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); assert_ok!(Salp::fund_retire(Some(ALICE).into(), 3_000)); assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); @@ -926,16 +805,6 @@ fn check_next_trie_index() { }); } -#[test] -fn batch_unlock_should_work() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::batch_unlock(Some(ALICE).into(), 3_000)); - }) -} - #[test] fn batch_migrate_should_work() { new_test_ext().execute_with(|| { @@ -954,8 +823,7 @@ fn batch_migrate_should_work() { let to_migrate_fund = Salp::to_migrate_funds(3_000).unwrap(); assert_eq!(to_migrate_fund.first_slot, 2); - let (_, vs_bond) = Salp::vsAssets(3000, 1, SlotLength::get()); - assert_eq!(Tokens::accounts(BRUCE, vs_bond).reserved, 100); + let (_, _) = Salp::vsAssets(3000, 1, SlotLength::get()); assert_ok!(Salp::batch_migrate(Some(ALICE).into(), 3_000)); @@ -965,10 +833,61 @@ fn batch_migrate_should_work() { let fund = Salp::funds(3_000).unwrap(); assert_eq!(fund.status, FundStatus::Ongoing); assert_eq!(fund.first_slot, 2); - - let (_, vs_bond) = Salp::vsAssets(3000, 1, SlotLength::get()); - assert_eq!(Tokens::accounts(BRUCE, vs_bond).reserved, 0); - let (_, vs_bond_new) = Salp::vsAssets(3000, 2, SlotLength::get() + 1); - assert_eq!(Tokens::accounts(BRUCE, vs_bond_new).reserved, 100); }) } + +#[test] +fn refund_when_fund_ongoing_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); + assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); + assert_ok!(Salp::refund(Some(BRUCE).into(), 3_000)); + + #[allow(non_snake_case)] + let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 100); + assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 100); + assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).free, INIT_BALANCE); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).reserved, 0); + }); +} + +#[test] +fn redeem_when_fund_failed_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); + assert_ok!(Salp::issue(Some(ALICE).into(), BRUCE, 3_000, 100, CONTRIBUTON_INDEX)); + + assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); + assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); + + #[allow(non_snake_case)] + let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); + + assert_ok!(>::transfer(vsToken, &BRUCE, &CATHI, 50)); + assert_ok!(>::transfer(vsBond, &BRUCE, &CATHI, 50)); + + assert_ok!(Salp::redeem(Some(BRUCE).into(), 3_000, 50)); + + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 50); + assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 50); + assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); + + assert_ok!(Salp::redeem(Some(CATHI).into(), 3_000, 50)); + + assert_eq!(Tokens::accounts(CATHI, vsToken).free, 50); + assert_eq!(Tokens::accounts(CATHI, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(CATHI, vsBond).free, 50); + assert_eq!(Tokens::accounts(CATHI, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, vsBond).reserved, 0); + }); +} diff --git a/pallets/salp/rpc/runtime-api/src/lib.rs b/pallets/salp/rpc/runtime-api/src/lib.rs index 1ff6fe7807..a8a2f4f0bc 100644 --- a/pallets/salp/rpc/runtime-api/src/lib.rs +++ b/pallets/salp/rpc/runtime-api/src/lib.rs @@ -31,5 +31,10 @@ decl_runtime_apis! { index: ParaId, who: AccountId ) -> (Balance,RpcContributionStatus); + + fn get_lite_contribution( + index: ParaId, + who: AccountId + ) -> (Balance,RpcContributionStatus); } } diff --git a/pallets/salp/rpc/src/lib.rs b/pallets/salp/rpc/src/lib.rs index 1f88cd373f..8810e5d3dc 100644 --- a/pallets/salp/rpc/src/lib.rs +++ b/pallets/salp/rpc/src/lib.rs @@ -22,11 +22,11 @@ pub use bifrost_salp_rpc_runtime_api::{self as runtime_api, SalpRuntimeApi}; use codec::Codec; use jsonrpc_core::{Error as RpcError, ErrorCode, Result as JsonRpcResult}; use jsonrpc_derive::rpc; -use node_primitives::RpcContributionStatus; +use node_primitives::{Balance, RpcContributionStatus}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_rpc::number::NumberOrHex; -use sp_runtime::{generic::BlockId, traits::Block as BlockT, SaturatedConversion}; +use sp_runtime::{generic::BlockId, sp_std::convert::TryInto, traits::Block as BlockT}; pub use self::gen_client::Client as SalpClient; @@ -52,6 +52,16 @@ pub trait SalpRpcApi { who: AccountId, at: Option, ) -> JsonRpcResult<(NumberOrHex, RpcContributionStatus)>; + + #[rpc(name = "salp_getLiteContribution")] + fn get_lite_contribution( + &self, + index: ParaId, + who: AccountId, + at: Option, + ) -> JsonRpcResult<(NumberOrHex, RpcContributionStatus)>; + + fn convert_rpc_params(val: Balance) -> Result; } impl SalpRpcApi<::Hash, ParaId, AccountId> @@ -63,6 +73,13 @@ where ParaId: Codec, AccountId: Codec, { + fn convert_rpc_params(value: Balance) -> Result { + value.try_into().map_err(|_| RpcError { + code: ErrorCode::InvalidParams, + message: format!("{} doesn't fit in NumberOrHex representation", value), + data: None, + }) + } fn get_contribution( &self, index: ParaId, @@ -75,7 +92,34 @@ where let rs = salp_rpc_api.get_contribution(&at, index, account); match rs { - Ok((val, status)) => Ok((NumberOrHex::Number(val.saturated_into()), status)), + Ok((val, status)) => match Self::convert_rpc_params(val) { + Ok(value) => Ok((value, status)), + Err(e) => Err(e), + }, + Err(e) => Err(RpcError { + code: ErrorCode::InternalError, + message: "Failed to get salp contribution.".to_owned(), + data: Some(format!("{:?}", e).into()), + }), + } + } + + fn get_lite_contribution( + &self, + index: ParaId, + account: AccountId, + at: Option<::Hash>, + ) -> JsonRpcResult<(NumberOrHex, RpcContributionStatus)> { + let salp_rpc_api = self.client.runtime_api(); + let at = BlockId::::hash(at.unwrap_or_else(|| self.client.info().best_hash)); + + let rs = salp_rpc_api.get_lite_contribution(&at, index, account); + + match rs { + Ok((val, status)) => match Self::convert_rpc_params(val) { + Ok(value) => Ok((value, status)), + Err(e) => Err(e), + }, Err(e) => Err(RpcError { code: ErrorCode::InternalError, message: "Failed to get salp contribution.".to_owned(), diff --git a/pallets/salp/src/lib.rs b/pallets/salp/src/lib.rs index 947448196c..04883061e9 100644 --- a/pallets/salp/src/lib.rs +++ b/pallets/salp/src/lib.rs @@ -461,24 +461,14 @@ pub mod pallet { #[pallet::compact] index: ParaId, ) -> DispatchResult { let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!( - fund.status == FundStatus::Success || - fund.status == FundStatus::Retired || - fund.status == FundStatus::RedeemWithdrew || - fund.status == FundStatus::End, - Error::::InvalidFundStatus - ); - let (contributed, status) = Self::contribution(fund.trie_index, &who); - ensure!(status == ContributionStatus::Idle, Error::::InvalidContributionStatus); + let (contributed, _) = Self::contribution(fund.trie_index, &who); #[allow(non_snake_case)] let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - let balance = T::MultiCurrency::unreserve(vsToken, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); - let balance = T::MultiCurrency::unreserve(vsBond, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); + T::MultiCurrency::unreserve(vsToken, &who, contributed); + T::MultiCurrency::unreserve(vsBond, &who, contributed); Self::put_contribution( fund.trie_index, @@ -502,13 +492,6 @@ pub mod pallet { ensure_signed(origin)?; let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!( - fund.status == FundStatus::Success || - fund.status == FundStatus::Retired || - fund.status == FundStatus::RedeemWithdrew || - fund.status == FundStatus::End, - Error::::InvalidFundStatus - ); let mut unlock_count = 0u32; let contributions = Self::contribution_iterator(fund.trie_index); @@ -524,10 +507,8 @@ pub mod pallet { if status != ContributionStatus::Unlocked { #[allow(non_snake_case)] let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - let balance = T::MultiCurrency::unreserve(vsToken, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); - let balance = T::MultiCurrency::unreserve(vsBond, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughBalanceToUnlock); + T::MultiCurrency::unreserve(vsToken, &who, contributed); + T::MultiCurrency::unreserve(vsBond, &who, contributed); Self::put_contribution( fund.trie_index, @@ -755,8 +736,6 @@ pub mod pallet { let who = ensure_signed(origin.clone())?; let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!(fund.status == FundStatus::RefundWithdrew, Error::::InvalidFundStatus); - let (contributed, status) = Self::contribution(fund.trie_index, &who); ensure!(contributed > Zero::zero(), Error::::ZeroContribution); ensure!(status == ContributionStatus::Idle, Error::::InvalidContributionStatus); @@ -765,21 +744,11 @@ pub mod pallet { #[allow(non_snake_case)] let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - ensure!( - T::MultiCurrency::reserved_balance(vsToken, &who) >= contributed, - Error::::NotEnoughReservedAssetsToRefund - ); - ensure!( - T::MultiCurrency::reserved_balance(vsBond, &who) >= contributed, - Error::::NotEnoughReservedAssetsToRefund - ); fund.raised = fund.raised.saturating_sub(contributed); - let balance = T::MultiCurrency::slash_reserved(vsToken, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughReservedAssetsToRefund); - let balance = T::MultiCurrency::slash_reserved(vsBond, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughReservedAssetsToRefund); + T::MultiCurrency::slash_reserved(vsToken, &who, contributed); + T::MultiCurrency::slash_reserved(vsBond, &who, contributed); if T::TransactType::get() == ParachainTransactType::Xcm { T::MultiCurrency::transfer( @@ -789,12 +758,7 @@ pub mod pallet { contributed, )?; } - Self::put_contribution( - fund.trie_index, - &who, - Zero::zero(), - ContributionStatus::Refunded, - ); + Self::kill_contribution(fund.trie_index, &who); Self::deposit_event(Event::Refunded(who, index, contributed)); @@ -828,10 +792,8 @@ pub mod pallet { let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); fund.raised = fund.raised.saturating_sub(contributed); - let balance = T::MultiCurrency::slash_reserved(vsToken, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughReservedAssetsToRefund); - let balance = T::MultiCurrency::slash_reserved(vsBond, &who, contributed); - ensure!(balance == Zero::zero(), Error::::NotEnoughReservedAssetsToRefund); + T::MultiCurrency::slash_reserved(vsToken, &who, contributed); + T::MultiCurrency::slash_reserved(vsBond, &who, contributed); if T::TransactType::get() == ParachainTransactType::Xcm { T::MultiCurrency::transfer( @@ -841,12 +803,7 @@ pub mod pallet { contributed, )?; } - Self::put_contribution( - fund.trie_index, - &who, - Zero::zero(), - ContributionStatus::Refunded, - ); + Self::kill_contribution(fund.trie_index, &who); refund_count += 1; } } @@ -868,33 +825,37 @@ pub mod pallet { let who = ensure_signed(origin.clone())?; let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - ensure!(fund.status == FundStatus::RedeemWithdrew, Error::::InvalidFundStatus); - ensure!(fund.raised >= value, Error::::NotEnoughBalanceInRedeemPool); - - let (contributed, status) = Self::contribution(fund.trie_index, &who); ensure!( - status == ContributionStatus::Idle || - status == ContributionStatus::Unlocked || - status == ContributionStatus::Redeemed, - Error::::InvalidContributionStatus + fund.status == FundStatus::RefundWithdrew || + fund.status == FundStatus::RedeemWithdrew, + Error::::InvalidFundStatus ); + ensure!(fund.raised >= value, Error::::NotEnoughBalanceInRedeemPool); - ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRedeemPool); - let cur_block = >::block_number(); - ensure!(!Self::is_expired(cur_block, fund.last_slot), Error::::VSBondExpired); - + let (contributed, _) = Self::contribution(fund.trie_index, &who); #[allow(non_snake_case)] let (vsToken, vsBond) = Self::vsAssets(index, fund.first_slot, fund.last_slot); - T::MultiCurrency::ensure_can_withdraw(vsToken, &who, value) - .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; - T::MultiCurrency::ensure_can_withdraw(vsBond, &who, value) - .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; - T::MultiCurrency::withdraw(vsToken, &who, value)?; - T::MultiCurrency::withdraw(vsBond, &who, value)?; + if fund.status == FundStatus::RedeemWithdrew { + ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRedeemPool); + let cur_block = >::block_number(); + ensure!(!Self::is_expired(cur_block, fund.last_slot), Error::::VSBondExpired); + T::MultiCurrency::ensure_can_withdraw(vsToken, &who, value) + .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; + T::MultiCurrency::ensure_can_withdraw(vsBond, &who, value) + .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; + } + + if fund.status == FundStatus::RedeemWithdrew { + T::MultiCurrency::withdraw(vsToken, &who, value)?; + T::MultiCurrency::withdraw(vsBond, &who, value)?; + RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); + } else if fund.status == FundStatus::RefundWithdrew { + T::MultiCurrency::slash_reserved(vsToken, &who, contributed); + T::MultiCurrency::slash_reserved(vsBond, &who, contributed); + } fund.raised = fund.raised.saturating_sub(value); - RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); if T::TransactType::get() == ParachainTransactType::Xcm { T::MultiCurrency::transfer( diff --git a/pallets/salp/src/tests.rs b/pallets/salp/src/tests.rs index ee014988c6..5ea78839b6 100644 --- a/pallets/salp/src/tests.rs +++ b/pallets/salp/src/tests.rs @@ -18,9 +18,9 @@ // Ensure we're `no_std` when compiling for Wasm. -use frame_support::{assert_noop, assert_ok, dispatch::DispatchError, traits::BalanceStatus as BS}; +use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use node_primitives::ContributionStatus; -use orml_traits::{MultiCurrency, MultiReservableCurrency}; +use orml_traits::MultiCurrency; use crate::{mock::*, Error, FundStatus}; @@ -270,82 +270,6 @@ fn unlock_should_work() { }); } -#[test] -fn unlock_with_wrong_fund_status_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); - assert_ok!(Salp::confirm_contribute( - Some(ALICE).into(), - BRUCE, - 3_000, - true, - CONTRIBUTON_INDEX - )); - assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); - - assert_noop!( - Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000), - Error::::InvalidFundStatus - ); - }); -} - -#[test] -fn unlock_when_already_unlocked_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); - assert_ok!(Salp::confirm_contribute( - Some(ALICE).into(), - BRUCE, - 3_000, - true, - CONTRIBUTON_INDEX - )); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); - - assert_noop!( - Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000), - Error::::InvalidContributionStatus - ); - }); -} - -#[test] -fn unlock_without_enough_reserved_vsassets_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); - assert_ok!(Salp::confirm_contribute( - Some(ALICE).into(), - BRUCE, - 3_000, - true, - CONTRIBUTON_INDEX - )); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); - - // ABSOLUTELY NOT HAPPEN AT NORMAL PROCESS! - #[allow(non_snake_case)] - let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - Tokens::slash_reserved(vsToken, &BRUCE, 50); - Tokens::slash_reserved(vsBond, &BRUCE, 50); - - // ``` - // // The following code will produce a supernatural bug. - // // DONT ASK WHY, I DONT KNOW! - // assert_noop!( - // Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000), - // Error::::NotEnoughBalanceToUnlock - // ); - // ``` - let result = Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000); - assert_noop!(result, Error::::NotEnoughBalanceToUnlock); - }); -} - #[test] fn contribute_should_work() { new_test_ext().execute_with(|| { @@ -749,11 +673,6 @@ fn refund_should_work() { assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); assert_ok!(Salp::refund(Some(BRUCE).into(), 3_000)); - let fund = Salp::funds(3_000).unwrap(); - let (contributed, status) = Salp::contribution(fund.trie_index, &BRUCE); - assert_eq!(contributed, 0); - assert_eq!(status, ContributionStatus::Refunded); - #[allow(non_snake_case)] let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); @@ -784,11 +703,6 @@ fn refund_when_xcm_error_should_work() { assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); assert_ok!(Salp::refund(Some(BRUCE).into(), 3_000)); - let fund = Salp::funds(3_000).unwrap(); - let (contributed, status) = Salp::contribution(fund.trie_index, &BRUCE); - assert_eq!(contributed, 0); - assert_eq!(status, ContributionStatus::Refunded); - #[allow(non_snake_case)] let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); @@ -819,33 +733,6 @@ fn double_refund_when_one_of_xcm_error_should_work() { }); } -#[test] -fn refund_without_enough_vsassets_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); - assert_ok!(Salp::confirm_contribute( - Some(ALICE).into(), - BRUCE, - 3_000, - true, - CONTRIBUTON_INDEX - )); - assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); - - #[allow(non_snake_case)] - let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); - assert_ok!(Tokens::repatriate_reserved(vsToken, &BRUCE, &ALICE, 50, BS::Reserved)); - assert_ok!(Tokens::repatriate_reserved(vsBond, &BRUCE, &ALICE, 50, BS::Reserved)); - - assert_noop!( - Salp::refund(Some(BRUCE).into(), 3_000), - Error::::NotEnoughReservedAssetsToRefund - ); - }); -} - #[test] fn refund_with_zero_contribution_should_fail() { new_test_ext().execute_with(|| { @@ -890,25 +777,6 @@ fn refund_with_wrong_para_id_should_fail() { }); } -#[test] -fn refund_with_wrong_fund_status_should_fail() { - new_test_ext().execute_with(|| { - assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); - assert_ok!(Salp::fund_end(Some(ALICE).into(), 3_000)); - - assert_noop!(Salp::refund(Some(BRUCE).into(), 3_000), Error::::InvalidFundStatus); - - assert_ok!(Salp::create(Some(ALICE).into(), 4_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::fund_success(Some(ALICE).into(), 4_000)); - assert_ok!(Salp::fund_retire(Some(ALICE).into(), 4_000)); - assert_ok!(Salp::withdraw(Some(ALICE).into(), 4_000)); - - assert_noop!(Salp::refund(Some(BRUCE).into(), 4_000), Error::::InvalidFundStatus); - }); -} - #[test] fn refund_with_when_ump_wrong_should_fail() { // TODO: Require an solution to settle with parallel test workflow @@ -1347,3 +1215,123 @@ fn edit_fund_should_work() { assert_eq!(fund.status, FundStatus::Ongoing); }) } + +#[test] +fn unlock_when_fund_ongoing_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); + assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); + assert_ok!(Salp::confirm_contribute( + Some(ALICE).into(), + BRUCE, + 3_000, + true, + CONTRIBUTON_INDEX + )); + assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); + + #[allow(non_snake_case)] + let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); + + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 100); + assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 100); + assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); + }); +} + +#[test] +fn refund_when_fund_ongoing_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); + assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); + assert_ok!(Salp::confirm_contribute( + Some(ALICE).into(), + BRUCE, + 3_000, + true, + CONTRIBUTON_INDEX + )); + assert_ok!(Salp::refund(Some(BRUCE).into(), 3_000)); + + #[allow(non_snake_case)] + let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).free, INIT_BALANCE); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).reserved, 0); + }); +} + +#[test] +fn redeem_when_fund_failed_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); + assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); + assert_ok!(Salp::confirm_contribute( + Some(ALICE).into(), + BRUCE, + 3_000, + true, + CONTRIBUTON_INDEX + )); + + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).free, INIT_BALANCE - 100); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).reserved, 0); + + assert_eq!( + Tokens::accounts(Salp::fund_account_id(3_000), RelayCurrencyId::get()).free, + 100 + ); + assert_eq!( + Tokens::accounts(Salp::fund_account_id(3_000), RelayCurrencyId::get()).frozen, + 0 + ); + assert_eq!( + Tokens::accounts(Salp::fund_account_id(3_000), RelayCurrencyId::get()).reserved, + 0 + ); + + assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 3_000)); + assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); + assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); + + #[allow(non_snake_case)] + let (vsToken, vsBond) = Salp::vsAssets(3_000, 1, SlotLength::get()); + + assert_ok!(>::transfer(vsToken, &BRUCE, &CATHI, 50)); + assert_ok!(>::transfer(vsBond, &BRUCE, &CATHI, 50)); + + assert_ok!(Salp::redeem(Some(BRUCE).into(), 3_000, 50)); + + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 50); + assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 50); + assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).free, INIT_BALANCE - 50); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).reserved, 0); + + assert_ok!(Salp::redeem(Some(CATHI).into(), 3_000, 50)); + + assert_eq!(Tokens::accounts(CATHI, vsToken).free, 50); + assert_eq!(Tokens::accounts(CATHI, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(CATHI, vsBond).free, 50); + assert_eq!(Tokens::accounts(CATHI, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, vsBond).reserved, 0); + assert_eq!(Tokens::accounts(CATHI, RelayCurrencyId::get()).free, INIT_BALANCE + 50); + assert_eq!(Tokens::accounts(CATHI, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, RelayCurrencyId::get()).reserved, 0); + }); +} diff --git a/runtime/asgard/Cargo.toml b/runtime/asgard/Cargo.toml index 6bef22fb73..89eff95a14 100644 --- a/runtime/asgard/Cargo.toml +++ b/runtime/asgard/Cargo.toml @@ -94,7 +94,6 @@ bifrost-runtime-common = { package = "bifrost-runtime-common", path = "../common bifrost-salp = { path = "../../pallets/salp", default-features = false } bifrost-salp-rpc-runtime-api = { path = "../../pallets/salp/rpc/runtime-api", default-features = false } bifrost-salp-lite = { path = "../../pallets/salp-lite", default-features = false } -bifrost-salp-lite-rpc-runtime-api = { path = "../../pallets/salp-lite/rpc/runtime-api", default-features = false } bifrost-liquidity-mining-rpc-runtime-api = { path = "../../pallets/liquidity-mining/rpc/runtime-api", default-features = false } bifrost-vsbond-auction = { path = "../../pallets/vsbond-auction", default-features = false } bifrost-vtoken-mint = { path = "../../pallets/vtoken-mint", default-features = false } @@ -191,7 +190,6 @@ std = [ "bifrost-salp/std", "bifrost-salp-rpc-runtime-api/std", "bifrost-salp-lite/std", - "bifrost-salp-lite-rpc-runtime-api/std", "bifrost-vsbond-auction/std", "bifrost-vtoken-mint/std", "bifrost-liquidity-mining/std", diff --git a/runtime/asgard/src/lib.rs b/runtime/asgard/src/lib.rs index 7bd1bdb9b9..9e76efe41e 100644 --- a/runtime/asgard/src/lib.rs +++ b/runtime/asgard/src/lib.rs @@ -1903,6 +1903,14 @@ impl_runtime_apis! { _ => (Zero::zero(),RpcContributionStatus::Idle), } } + + fn get_lite_contribution(index: ParaId, who: AccountId) -> (Balance,RpcContributionStatus) { + let rs = SalpLite::contribution_by_fund(index, &who); + match rs { + Ok((val,status)) => (val,status.to_rpc()), + _ => (Zero::zero(),RpcContributionStatus::Idle), + } + } } impl bifrost_liquidity_mining_rpc_runtime_api::LiquidityMiningRuntimeApi for Runtime { diff --git a/runtime/asgard/src/weights/bifrost_salp_lite.rs b/runtime/asgard/src/weights/bifrost_salp_lite.rs index 9a1db00d87..7414b44019 100644 --- a/runtime/asgard/src/weights/bifrost_salp_lite.rs +++ b/runtime/asgard/src/weights/bifrost_salp_lite.rs @@ -60,18 +60,7 @@ impl bifrost_salp_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(10 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } - // Storage: SalpLite Funds (r:1 w:0) - // Storage: Tokens Accounts (r:2 w:2) - // Storage: System Number (r:1 w:0) - // Storage: System ExecutionPhase (r:1 w:0) - // Storage: System EventCount (r:1 w:1) - // Storage: System Events (r:1 w:1) - // Storage: unknown [0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291] (r:1 w:1) - fn unlock() -> Weight { - (128_872_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - } + // Storage: SalpLite Funds (r:1 w:0) // Storage: Tokens Accounts (r:2 w:2) // Storage: System Account (r:1 w:1) @@ -576,7 +565,7 @@ impl bifrost_salp_lite::WeightInfo for WeightInfo { // Storage: unknown [0xd35ed52d5edd31264c21a0c30d3994d5600b3e19ebb66d6f8099661d6dcc57c0] (r:1 w:1) // Storage: unknown [0xf5b993b187b5029b7a30de61f1bce1be780f8790b3daf85742ec63b66f79cc80] (r:1 w:1) // Storage: unknown [0xf98428e38450dcc80131bed1b84059f80938df6d2941d17917c968e553afa753] (r:1 w:1) - fn batch_unlock(k: u32, ) -> Weight { + fn batch_migrate(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 53_000 .saturating_add((107_557_000 as Weight).saturating_mul(k as Weight)) diff --git a/runtime/bifrost/Cargo.toml b/runtime/bifrost/Cargo.toml index 2b1727fa3d..2ca603b3b9 100644 --- a/runtime/bifrost/Cargo.toml +++ b/runtime/bifrost/Cargo.toml @@ -89,7 +89,6 @@ bifrost-runtime-common = { package = "bifrost-runtime-common", path = "../common bifrost-salp = { path = "../../pallets/salp", default-features = false } bifrost-salp-rpc-runtime-api = { path = "../../pallets/salp/rpc/runtime-api", default-features = false } bifrost-salp-lite = { path = "../../pallets/salp-lite", default-features = false } -bifrost-salp-lite-rpc-runtime-api = { path = "../../pallets/salp-lite/rpc/runtime-api", default-features = false } pallet-vesting = { package = "bifrost-vesting", path = "../../pallets/vesting", default-features = false } bifrost-liquidity-mining = { path = "../../pallets/liquidity-mining", default-features = false } bifrost-liquidity-mining-rpc-runtime-api = { path = "../../pallets/liquidity-mining/rpc/runtime-api", default-features = false } @@ -180,7 +179,6 @@ std = [ "bifrost-salp/std", "bifrost-salp-rpc-runtime-api/std", "bifrost-salp-lite/std", - "bifrost-salp-lite-rpc-runtime-api/std", "bifrost-liquidity-mining/std", "bifrost-liquidity-mining-rpc-runtime-api/std", "bifrost-token-issuer/std", diff --git a/runtime/bifrost/src/constants.rs b/runtime/bifrost/src/constants.rs index 7bdca48f8c..1e83f803c5 100644 --- a/runtime/bifrost/src/constants.rs +++ b/runtime/bifrost/src/constants.rs @@ -111,6 +111,7 @@ pub mod time { pub const WEEKS: BlockNumber = DAYS * 7; // The `LeasePeriod` defination from `polkadot`. + pub const POLKA_LEASE_PERIOD: BlockNumber = 12 * WEEKS; pub const KUSAMA_LEASE_PERIOD: BlockNumber = 6 * WEEKS; pub const ROCOCO_LEASE_PERIOD: BlockNumber = 1 * DAYS; pub const WESTEND_LEASE_PERIOD: BlockNumber = 28 * DAYS; diff --git a/runtime/bifrost/src/lib.rs b/runtime/bifrost/src/lib.rs index 18055659f0..5b1fce9b40 100644 --- a/runtime/bifrost/src/lib.rs +++ b/runtime/bifrost/src/lib.rs @@ -134,7 +134,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bifrost"), impl_name: create_runtime_str!("bifrost"), authoring_version: 1, - spec_version: 906, + spec_version: 908, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -300,6 +300,7 @@ parameter_types! { parameter_types! { pub const TreasuryPalletId: PalletId = PalletId(*b"bf/trsry"); pub const BifrostCrowdloanId: PalletId = PalletId(*b"bf/salp#"); + pub const BifrostSalpLiteCrowdloanId: PalletId = PalletId(*b"bf/salpl"); pub const LiquidityMiningPalletId: PalletId = PalletId(*b"bf/lm###"); pub const LighteningRedeemPalletId: PalletId = PalletId(*b"bf/ltnrd"); } @@ -338,7 +339,7 @@ impl frame_system::Config for Runtime { /// Converts a module to an index of this module in the runtime. type PalletInfo = PalletInfo; type SS58Prefix = SS58Prefix; - type SystemWeightInfo = weights::frame_system::WeightInfo; + type SystemWeightInfo = (); /// Runtime version. type Version = Version; } @@ -352,7 +353,7 @@ impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = Moment; type OnTimestampSet = (); - type WeightInfo = weights::pallet_timestamp::WeightInfo; + type WeightInfo = (); } parameter_types! { @@ -368,7 +369,7 @@ parameter_types! { impl pallet_utility::Config for Runtime { type Call = Call; type Event = Event; - type WeightInfo = weights::pallet_utility::WeightInfo; + type WeightInfo = (); } parameter_types! { @@ -481,7 +482,7 @@ impl pallet_proxy::Config for Runtime { type ProxyDepositBase = ProxyDepositBase; type ProxyDepositFactor = ProxyDepositFactor; type ProxyType = ProxyType; - type WeightInfo = pallet_proxy::weights::SubstrateWeight; + type WeightInfo = (); } parameter_types! { @@ -498,7 +499,7 @@ impl pallet_scheduler::Config for Runtime { type Origin = Origin; type PalletsOrigin = OriginCaller; type ScheduleOrigin = EnsureRoot; - type WeightInfo = weights::pallet_scheduler::WeightInfo; + type WeightInfo = (); } parameter_types! { @@ -516,7 +517,7 @@ impl pallet_multisig::Config for Runtime { type DepositFactor = DepositFactor; type Event = Event; type MaxSignatories = MaxSignatories; - type WeightInfo = pallet_multisig::weights::SubstrateWeight; + type WeightInfo = (); } parameter_types! { @@ -541,7 +542,7 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = MoreThanHalfCouncil; type RegistrarOrigin = MoreThanHalfCouncil; - type WeightInfo = pallet_identity::weights::SubstrateWeight; + type WeightInfo = (); } parameter_types! { @@ -553,7 +554,7 @@ impl pallet_indices::Config for Runtime { type Currency = Balances; type Deposit = IndexDeposit; type Event = Event; - type WeightInfo = weights::pallet_indices::WeightInfo; + type WeightInfo = (); } impl pallet_balances::Config for Runtime { @@ -567,7 +568,7 @@ impl pallet_balances::Config for Runtime { type MaxLocks = MaxLocks; type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; - type WeightInfo = weights::pallet_balances::WeightInfo; + type WeightInfo = (); } parameter_types! { @@ -584,7 +585,7 @@ impl pallet_collective::Config for Runtime { type MotionDuration = CouncilMotionDuration; type Origin = Origin; type Proposal = Call; - type WeightInfo = pallet_collective::weights::SubstrateWeight; + type WeightInfo = (); } parameter_types! { @@ -601,7 +602,7 @@ impl pallet_collective::Config for Runtime { type MotionDuration = TechnicalMotionDuration; type Origin = Origin; type Proposal = Call; - type WeightInfo = pallet_collective::weights::SubstrateWeight; + type WeightInfo = (); } impl pallet_membership::Config for Runtime { @@ -614,7 +615,7 @@ impl pallet_membership::Config for Runtime { type RemoveOrigin = MoreThanHalfCouncil; type ResetOrigin = MoreThanHalfCouncil; type SwapOrigin = MoreThanHalfCouncil; - type WeightInfo = pallet_membership::weights::SubstrateWeight; + type WeightInfo = (); } impl pallet_membership::Config for Runtime { @@ -627,7 +628,7 @@ impl pallet_membership::Config for Runtime { type RemoveOrigin = MoreThanHalfCouncil; type ResetOrigin = MoreThanHalfCouncil; type SwapOrigin = MoreThanHalfCouncil; - type WeightInfo = pallet_membership::weights::SubstrateWeight; + type WeightInfo = (); } parameter_types! { @@ -661,7 +662,7 @@ impl pallet_elections_phragmen::Config for Runtime { type TermDuration = TermDuration; type VotingBondBase = VotingBondBase; type VotingBondFactor = VotingBondFactor; - type WeightInfo = pallet_elections_phragmen::weights::SubstrateWeight; + type WeightInfo = (); } parameter_types! { @@ -726,7 +727,7 @@ impl pallet_democracy::Config for Runtime { type VetoOrigin = pallet_collective::EnsureMember; type VoteLockingPeriod = EnactmentPeriod; // Same as EnactmentPeriod type VotingPeriod = VotingPeriod; - type WeightInfo = pallet_democracy::weights::SubstrateWeight; + type WeightInfo = (); } parameter_types! { @@ -768,7 +769,7 @@ impl pallet_treasury::Config for Runtime { type RejectOrigin = MoreThanHalfCouncil; type SpendFunds = Bounties; type SpendPeriod = SpendPeriod; - type WeightInfo = weights::pallet_treasury::WeightInfo; + type WeightInfo = (); } impl pallet_bounties::Config for Runtime { @@ -780,7 +781,7 @@ impl pallet_bounties::Config for Runtime { type DataDepositPerByte = DataDepositPerByte; type Event = Event; type MaximumReasonLength = MaximumReasonLength; - type WeightInfo = weights::pallet_bounties::WeightInfo; + type WeightInfo = (); } impl pallet_tips::Config for Runtime { @@ -791,7 +792,7 @@ impl pallet_tips::Config for Runtime { type TipFindersFee = TipFindersFee; type TipReportDepositBase = TipReportDepositBase; type Tippers = PhragmenElection; - type WeightInfo = pallet_tips::weights::SubstrateWeight; + type WeightInfo = (); } impl pallet_transaction_payment::Config for Runtime { @@ -823,8 +824,6 @@ impl parachain_info::Config for Runtime {} impl cumulus_pallet_aura_ext::Config for Runtime {} -impl pallet_randomness_collective_flip::Config for Runtime {} - parameter_types! { pub const KsmLocation: MultiLocation = MultiLocation::parent(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; @@ -1105,7 +1104,7 @@ impl pallet_vesting::Config for Runtime { type Currency = Balances; type Event = Event; type MinVestedTransfer = ExistentialDeposit; - type WeightInfo = weights::pallet_vesting::WeightInfo; + type WeightInfo = (); } // orml runtime start @@ -1115,7 +1114,7 @@ impl orml_currencies::Config for Runtime { type GetNativeCurrencyId = NativeCurrencyId; type MultiCurrency = Tokens; type NativeCurrency = BasicCurrencyAdapter; - type WeightInfo = weights::orml_currencies::WeightInfo; + type WeightInfo = (); } orml_traits::parameter_type_with_key! { @@ -1143,8 +1142,9 @@ impl Contains for DustRemovalWhitelist { fn contains(a: &AccountId) -> bool { AccountIdConversion::::into_account(&TreasuryPalletId::get()).eq(a) || AccountIdConversion::::into_account(&BifrostCrowdloanId::get()).eq(a) || - AccountIdConversion::::into_account(&LighteningRedeemPalletId::get()) - .eq(a) || LiquidityMiningPalletId::get().check_sub_account::(a) + AccountIdConversion::::into_account(&BifrostSalpLiteCrowdloanId::get()) + .eq(a) || AccountIdConversion::::into_account(&LighteningRedeemPalletId::get()) + .eq(a) || LiquidityMiningPalletId::get().check_sub_account::(a) } } @@ -1161,7 +1161,7 @@ impl orml_tokens::Config for Runtime { type ExistentialDeposits = ExistentialDeposits; type MaxLocks = MaxLocks; type OnDust = orml_tokens::TransferDust; - type WeightInfo = weights::orml_tokens::WeightInfo; + type WeightInfo = (); } parameter_types! { @@ -1246,7 +1246,7 @@ impl bifrost_flexible_fee::Config for Runtime { type AlternativeFeeCurrencyId = RelayCurrencyId; type AltFeeCurrencyExchangeRate = AltFeeCurrencyExchangeRate; type OnUnbalanced = Treasury; - type WeightInfo = weights::bifrost_flexible_fee::WeightInfo; + type WeightInfo = (); type ExtraFeeMatcher = ExtraFeeMatcher; type MiscFeeHandler = MiscFeeHandler< Runtime, @@ -1322,7 +1322,7 @@ impl bifrost_salp::Config for Runtime { type SlotLength = SlotLength; type VSBondValidPeriod = VSBondValidPeriod; type XcmTransferOrigin = XcmTransferOrigin; - type WeightInfo = weights::bifrost_salp::WeightInfo; + type WeightInfo = (); type SelfParaId = SelfParaId; type ContributionWeight = ContributionWeight; type BaseXcmWeight = XcmWeight; @@ -1338,21 +1338,49 @@ impl bifrost_salp::Config for Runtime { type RelayNetwork = RelayNetwork; } +parameter_types! { + pub const PolkaMinContribution: Balance = 5 * 10_000_000_000; + pub const PolkaLeasePeriod: BlockNumber = POLKA_LEASE_PERIOD; + pub PolkaConfirmAsMultiSig: AccountId = hex!["e4f78719c654cd8e8ac1375c447b7a80f9476cfe6505ea401c4b15bd6b967c93"].into(); +} + +pub struct EnsureSalpLiteConfirmAsMultiSig; +impl EnsureOrigin for EnsureSalpLiteConfirmAsMultiSig { + type Success = AccountId; + + fn try_origin(o: Origin) -> Result { + Into::, Origin>>::into(o).and_then(|o| match o { + RawOrigin::Signed(who) => + if who == PolkaConfirmAsMultiSig::get() { + Ok(who) + } else { + Err(Origin::from(Some(who))) + }, + r => Err(Origin::from(r)), + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> Origin { + Origin::from(RawOrigin::Signed(Default::default())) + } +} + impl bifrost_salp_lite::Config for Runtime { type BancorPool = (); type Event = Event; - type LeasePeriod = LeasePeriod; - type MinContribution = MinContribution; + type LeasePeriod = PolkaLeasePeriod; + type MinContribution = PolkaMinContribution; type MultiCurrency = Currencies; - type PalletId = BifrostCrowdloanId; + type PalletId = BifrostSalpLiteCrowdloanId; type RelayChainToken = PolkadotCurrencyId; type ReleaseCycle = ReleaseCycle; type ReleaseRatio = ReleaseRatio; type BatchKeysLimit = RemoveKeysLimit; type SlotLength = SlotLength; - type WeightInfo = weights::bifrost_salp_lite::WeightInfo; + type WeightInfo = (); type EnsureConfirmAsMultiSig = - EnsureOneOf; + EnsureOneOf; type EnsureConfirmAsGovernance = EnsureOneOf; } @@ -1379,7 +1407,7 @@ impl bifrost_liquidity_mining::Config for Runtime { type MaximumCharged = MaximumCharged; type MaximumOptionRewards = MaximumOptionRewards; type PalletId = LiquidityMiningPalletId; - type WeightInfo = weights::bifrost_liquidity_mining::WeightInfo; + type WeightInfo = (); } impl bifrost_token_issuer::Config for Runtime { @@ -1387,7 +1415,7 @@ impl bifrost_token_issuer::Config for Runtime { type MultiCurrency = Currencies; type ControlOrigin = EnsureOneOf; - type WeightInfo = weights::bifrost_token_issuer::WeightInfo; + type WeightInfo = (); } impl bifrost_lightening_redeem::Config for Runtime { @@ -1396,14 +1424,14 @@ impl bifrost_lightening_redeem::Config for Runtime { type ControlOrigin = EnsureOneOf; type PalletId = LighteningRedeemPalletId; - type WeightInfo = weights::bifrost_lightening_redeem::WeightInfo; + type WeightInfo = (); } impl bifrost_call_switchgear::Config for Runtime { type Event = Event; type UpdateOrigin = EnsureOneOf; - type WeightInfo = weights::bifrost_call_switchgear::WeightInfo; + type WeightInfo = (); } // Bifrost modules end @@ -1523,7 +1551,6 @@ construct_runtime! { System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 1, Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 2, - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 4, ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned} = 5, ParachainInfo: parachain_info::{Pallet, Storage, Config} = 6, @@ -1625,7 +1652,7 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPallets, - CustomOnRuntimeUpgrade, + (), >; impl_runtime_apis! { @@ -1811,6 +1838,14 @@ impl_runtime_apis! { _ => (Zero::zero(),RpcContributionStatus::Idle), } } + + fn get_lite_contribution(index: ParaId, who: AccountId) -> (Balance,RpcContributionStatus) { + let rs = SalpLite::contribution_by_fund(index, &who); + match rs { + Ok((val,status)) => (val,status.to_rpc()), + _ => (Zero::zero(),RpcContributionStatus::Idle), + } + } } impl bifrost_liquidity_mining_rpc_runtime_api::LiquidityMiningRuntimeApi for Runtime { @@ -1832,7 +1867,7 @@ impl_runtime_apis! { list_benchmark!(list, extra, bifrost_flexible_fee, FlexibleFee); list_benchmark!(list, extra, bifrost_salp, Salp); - // list_benchmark!(list, extra, bifrost_salp_lite, SalpLite); + list_benchmark!(list, extra, bifrost_salp_lite, SalpLite); list_benchmark!(list, extra, bifrost_liquidity_mining, LiquidityMining); list_benchmark!(list, extra, bifrost_token_issuer, TokenIssuer); list_benchmark!(list, extra, bifrost_lightening_redeem, LighteningRedeem); @@ -1870,7 +1905,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, bifrost_flexible_fee, FlexibleFee); add_benchmark!(params, batches, bifrost_salp, Salp); - // add_benchmark!(params, batches, bifrost_salp_lite, SalpLite); + add_benchmark!(params, batches, bifrost_salp_lite, SalpLite); add_benchmark!(params, batches, bifrost_liquidity_mining, LiquidityMining); add_benchmark!(params, batches, bifrost_token_issuer, TokenIssuer); add_benchmark!(params, batches, bifrost_lightening_redeem, LighteningRedeem); diff --git a/runtime/bifrost/src/weights/bifrost_salp_lite.rs b/runtime/bifrost/src/weights/bifrost_salp_lite.rs index 5756e80c5b..6a51f65e30 100644 --- a/runtime/bifrost/src/weights/bifrost_salp_lite.rs +++ b/runtime/bifrost/src/weights/bifrost_salp_lite.rs @@ -62,18 +62,6 @@ impl bifrost_salp_lite::WeightInfo for WeightInfo { } // Storage: SalpLite Funds (r:1 w:0) // Storage: Tokens Accounts (r:2 w:2) - // Storage: System Number (r:1 w:0) - // Storage: System ExecutionPhase (r:1 w:0) - // Storage: System EventCount (r:1 w:1) - // Storage: System Events (r:1 w:1) - // Storage: unknown [0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291] (r:1 w:1) - fn unlock() -> Weight { - (128_872_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - } - // Storage: SalpLite Funds (r:1 w:0) - // Storage: Tokens Accounts (r:2 w:2) // Storage: System Account (r:1 w:1) // Storage: System Number (r:1 w:0) // Storage: System ExecutionPhase (r:1 w:0) @@ -576,7 +564,7 @@ impl bifrost_salp_lite::WeightInfo for WeightInfo { // Storage: unknown [0xd35ed52d5edd31264c21a0c30d3994d5600b3e19ebb66d6f8099661d6dcc57c0] (r:1 w:1) // Storage: unknown [0xf5b993b187b5029b7a30de61f1bce1be780f8790b3daf85742ec63b66f79cc80] (r:1 w:1) // Storage: unknown [0xf98428e38450dcc80131bed1b84059f80938df6d2941d17917c968e553afa753] (r:1 w:1) - fn batch_unlock(k: u32, ) -> Weight { + fn batch_migrate(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 53_000 .saturating_add((107_557_000 as Weight).saturating_mul(k as Weight))