Skip to content

Commit 3b0862b

Browse files
authored
refund user & remove pending amount if xcm failed (#1058)
* refund user & remove pending amount if xcm failed Signed-off-by: Cheng JIANG <[email protected]> * only allow migrate_pending to be executed in Pending phase Signed-off-by: Cheng JIANG <[email protected]> * prepare for Succeeded phase Signed-off-by: Cheng JIANG <[email protected]>
1 parent 723c7c4 commit 3b0862b

File tree

4 files changed

+68
-47
lines changed

4 files changed

+68
-47
lines changed

pallets/crowdloans/src/benchmarking.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ benchmarks! {
104104
ctoken,
105105
ContributionStrategy::XCM,
106106
CAP,
107-
END_BLOCK
107+
END_BLOCK.into()
108108
)
109109
verify {
110110
assert_last_event::<T>(Event::<T>::VaultCreated(crowdloan, ctoken).into())
@@ -116,12 +116,12 @@ benchmarks! {
116116
let caller: T::AccountId = whitelisted_caller();
117117
initial_set_up::<T>(caller, ctoken);
118118
// create vault before update
119-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK));
119+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK.into()));
120120
}: _(
121121
SystemOrigin::Root,
122122
crowdloan,
123123
Some(1_000_000_000_001),
124-
Some(1_000_000_001u32),
124+
Some(1_000_000_001u32.into()),
125125
Some(ContributionStrategy::XCM)
126126
)
127127
verify {
@@ -134,7 +134,7 @@ benchmarks! {
134134
let crowdloan = ParaId::from(1335u32);
135135

136136
initial_set_up::<T>(caller.clone(), ctoken);
137-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK));
137+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK.into()));
138138
assert_ok!(Crowdloans::<T>::open(SystemOrigin::Root.into(), crowdloan));
139139
}: _(
140140
SystemOrigin::Signed(caller.clone()),
@@ -152,7 +152,7 @@ benchmarks! {
152152
let crowdloan = ParaId::from(1336u32);
153153

154154
initial_set_up::<T>(caller, ctoken);
155-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK));
155+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK.into()));
156156
}: _(
157157
SystemOrigin::Root,
158158
crowdloan
@@ -167,7 +167,7 @@ benchmarks! {
167167
let crowdloan = ParaId::from(1337u32);
168168

169169
initial_set_up::<T>(caller, ctoken);
170-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK));
170+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK.into()));
171171
assert_ok!(Crowdloans::<T>::open(SystemOrigin::Root.into(), crowdloan));
172172
}: _(
173173
SystemOrigin::Root,
@@ -183,7 +183,7 @@ benchmarks! {
183183
let crowdloan = ParaId::from(1338u32);
184184

185185
initial_set_up::<T>(caller, ctoken);
186-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK));
186+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK.into()));
187187
}: _(
188188
SystemOrigin::Root,
189189
vec![ParaId::from(1336u32), ParaId::from(1337u32)]
@@ -199,7 +199,7 @@ benchmarks! {
199199
let crowdloan = ParaId::from(1339u32);
200200

201201
initial_set_up::<T>(caller, ctoken);
202-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK));
202+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK.into()));
203203
assert_ok!(Crowdloans::<T>::open(SystemOrigin::Root.into(), crowdloan));
204204
assert_ok!(Crowdloans::<T>::close(SystemOrigin::Root.into(), crowdloan));
205205
}: _(
@@ -216,7 +216,7 @@ benchmarks! {
216216
let crowdloan = ParaId::from(1340u32);
217217

218218
initial_set_up::<T>(caller.clone(), ctoken);
219-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK));
219+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK.into()));
220220
assert_ok!(Crowdloans::<T>::open(SystemOrigin::Root.into(), crowdloan));
221221
assert_ok!(Crowdloans::<T>::contribute(SystemOrigin::Signed(caller).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new()));
222222
assert_ok!(Crowdloans::<T>::close(SystemOrigin::Root.into(), crowdloan));
@@ -235,7 +235,7 @@ benchmarks! {
235235
let crowdloan = ParaId::from(1341u32);
236236

237237
initial_set_up::<T>(caller.clone(), ctoken);
238-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK));
238+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK.into()));
239239
assert_ok!(Crowdloans::<T>::open(SystemOrigin::Root.into(), crowdloan));
240240
assert_ok!(Crowdloans::<T>::contribute(SystemOrigin::Signed(caller.clone()).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new()));
241241
assert_ok!(Crowdloans::<T>::notification_received(
@@ -265,7 +265,7 @@ benchmarks! {
265265
let crowdloan = ParaId::from(1342u32);
266266

267267
initial_set_up::<T>(caller.clone(), ctoken);
268-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK));
268+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK.into()));
269269
assert_ok!(Crowdloans::<T>::open(SystemOrigin::Root.into(), crowdloan));
270270
assert_ok!(Crowdloans::<T>::contribute(SystemOrigin::Signed(caller).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new()));
271271
assert_ok!(Crowdloans::<T>::close(SystemOrigin::Root.into(), crowdloan));
@@ -283,7 +283,7 @@ benchmarks! {
283283
let crowdloan = ParaId::from(1343u32);
284284

285285
initial_set_up::<T>(caller.clone(), ctoken);
286-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK));
286+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK.into()));
287287
for _ in 0..10 {
288288
assert_ok!(Crowdloans::<T>::contribute(SystemOrigin::Signed(caller.clone()).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new()));
289289
}
@@ -301,7 +301,7 @@ benchmarks! {
301301
let crowdloan = ParaId::from(1344u32);
302302

303303
initial_set_up::<T>(caller.clone(), ctoken);
304-
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK));
304+
assert_ok!(Crowdloans::<T>::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK.into()));
305305
assert_ok!(Crowdloans::<T>::open(SystemOrigin::Root.into(), crowdloan));
306306
assert_ok!(Crowdloans::<T>::contribute(SystemOrigin::Signed(caller).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new()));
307307
}: _(

pallets/crowdloans/src/lib.rs

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,12 @@ pub mod pallet {
4848
},
4949
transactional, Blake2_128Concat, BoundedVec, PalletId,
5050
};
51-
use frame_system::{ensure_signed, pallet_prelude::OriginFor};
51+
use frame_system::{
52+
ensure_signed,
53+
pallet_prelude::{BlockNumberFor, OriginFor},
54+
};
5255
use pallet_xcm::ensure_response;
53-
use primitives::{ump::*, Balance, BlockNumber, CurrencyId, ParaId, TrieIndex};
56+
use primitives::{ump::*, Balance, CurrencyId, ParaId, TrieIndex};
5457
use sp_runtime::{
5558
traits::{AccountIdConversion, BlockNumberProvider, Convert, Hash, Zero},
5659
ArithmeticError, DispatchError,
@@ -143,9 +146,7 @@ pub mod pallet {
143146
type WeightInfo: WeightInfo;
144147

145148
/// The relay's BlockNumber provider
146-
type RelayChainBlockNumberProvider: BlockNumberProvider<
147-
BlockNumber = primitives::BlockNumber,
148-
>;
149+
type RelayChainBlockNumberProvider: BlockNumberProvider<BlockNumber = BlockNumberFor<Self>>;
149150

150151
/// To expose XCM helper functions
151152
type XCM: XcmHelper<Self, BalanceOf<Self>, AssetIdOf<Self>, Self::AccountId>;
@@ -253,7 +254,7 @@ pub mod pallet {
253254
ctoken: AssetIdOf<T>,
254255
contribution_strategy: ContributionStrategy,
255256
#[pallet::compact] cap: BalanceOf<T>,
256-
end_block: BlockNumber,
257+
end_block: BlockNumberFor<T>,
257258
) -> DispatchResult {
258259
T::CreateVaultOrigin::ensure_origin(origin)?;
259260

@@ -319,7 +320,7 @@ pub mod pallet {
319320
origin: OriginFor<T>,
320321
crowdloan: ParaId,
321322
cap: Option<BalanceOf<T>>,
322-
end_block: Option<BlockNumber>,
323+
end_block: Option<BlockNumberFor<T>>,
323324
contribution_strategy: Option<ContributionStrategy>,
324325
) -> DispatchResult {
325326
T::UpdateVaultOrigin::ensure_origin(origin)?;
@@ -425,7 +426,7 @@ pub mod pallet {
425426
Self::do_contribute(&who, crowdloan, amount)?;
426427
}
427428

428-
Self::do_pending_contribution(&who, &mut vault, amount)?;
429+
Self::do_update_pending(&who, &mut vault, amount, true)?;
429430

430431
Vaults::<T>::insert(crowdloan, vault.id, vault);
431432

@@ -592,6 +593,10 @@ pub mod pallet {
592593
T::MigrateOrigin::ensure_origin(origin)?;
593594

594595
let vault = Self::current_vault(crowdloan).ok_or(Error::<T>::VaultDoesNotExist)?;
596+
ensure!(
597+
vault.phase == VaultPhase::Pending,
598+
Error::<T>::IncorrectVaultPhase
599+
);
595600
let contributions = Self::contribution_iterator(vault.trie_index, true);
596601
let mut migrated_count: u32 = 0u32;
597602
let mut all_migrated = true;
@@ -704,19 +709,30 @@ pub mod pallet {
704709
}
705710

706711
#[require_transactional]
707-
fn do_pending_contribution(
712+
fn do_update_pending(
708713
who: &AccountIdOf<T>,
709714
vault: &mut Vault<T>,
710715
amount: BalanceOf<T>,
716+
addition: bool,
711717
) -> DispatchResult {
712-
vault.pending = vault
713-
.pending
714-
.checked_add(amount)
715-
.ok_or(ArithmeticError::Overflow)?;
716718
let (pending, _) = Self::contribution_get(vault.trie_index, who, true);
717-
let new_pending = pending
718-
.checked_add(amount)
719-
.ok_or(ArithmeticError::Overflow)?;
719+
let new_pending = if addition {
720+
vault.pending = vault
721+
.pending
722+
.checked_add(amount)
723+
.ok_or(ArithmeticError::Overflow)?;
724+
pending
725+
.checked_add(amount)
726+
.ok_or(ArithmeticError::Overflow)?
727+
} else {
728+
vault.pending = vault
729+
.pending
730+
.checked_sub(amount)
731+
.ok_or(ArithmeticError::Underflow)?;
732+
pending
733+
.checked_sub(amount)
734+
.ok_or(ArithmeticError::Underflow)?
735+
};
720736
Self::contribution_put(vault.trie_index, who, &new_pending, true);
721737
Ok(())
722738
}
@@ -779,24 +795,27 @@ pub mod pallet {
779795
Vaults::<T>::insert(crowdloan, vault.id, vault);
780796
}
781797
XcmInflightRequest::Contribute {
782-
crowdloan: index,
798+
crowdloan,
783799
who,
784800
amount,
785801
} if !executed => {
786-
// refund
802+
let mut vault =
803+
Self::current_vault(crowdloan).ok_or(Error::<T>::VaultDoesNotExist)?;
787804
T::Assets::transfer(
788805
T::RelayCurrency::get(),
789-
&Self::vault_account_id(index),
806+
&Self::vault_account_id(crowdloan),
790807
&who,
791808
amount,
792809
true,
793810
)?;
811+
Self::do_update_pending(&who, &mut vault, amount, false)?;
812+
Vaults::<T>::insert(crowdloan, vault.id, vault);
794813
}
795814
XcmInflightRequest::Withdraw {
796815
crowdloan,
797816
amount,
798817
target_phase,
799-
} => {
818+
} if executed => {
800819
let mut vault =
801820
Self::current_vault(crowdloan).ok_or(Error::<T>::VaultDoesNotExist)?;
802821
T::Assets::mint_into(

pallets/crowdloans/src/mock.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use polkadot_parachain::primitives::Sibling;
1313
use primitives::{currency::MultiCurrencyAdapter, tokens::*, Balance, ParaId};
1414
use sp_core::H256;
1515
use sp_runtime::{
16-
testing::Header,
16+
generic,
1717
traits::{
1818
AccountIdConversion, AccountIdLookup, BlakeTwo256, BlockNumberProvider, Convert, Zero,
1919
},
@@ -259,11 +259,12 @@ impl orml_xtokens::Config for Test {
259259

260260
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
261261
type Block = frame_system::mocking::MockBlock<Test>;
262-
type BlockNumber = u64;
262+
type BlockNumber = u32;
263+
type Index = u32;
263264
pub const DOT_DECIMAL: u128 = 10u128.pow(10);
264265

265266
parameter_types! {
266-
pub const BlockHashCount: u64 = 250;
267+
pub const BlockHashCount: u32 = 250;
267268
pub const SS58Prefix: u8 = 42;
268269
}
269270

@@ -274,13 +275,13 @@ impl frame_system::Config for Test {
274275
type DbWeight = ();
275276
type Origin = Origin;
276277
type Call = Call;
277-
type Index = u64;
278+
type Index = Index;
278279
type BlockNumber = BlockNumber;
279280
type Hash = H256;
280281
type Hashing = BlakeTwo256;
281282
type AccountId = AccountId;
282283
type Lookup = AccountIdLookup<AccountId, ()>;
283-
type Header = Header;
284+
type Header = generic::Header<BlockNumber, BlakeTwo256>;
284285
type Event = Event;
285286
type BlockHashCount = BlockHashCount;
286287
type Version = ();

pallets/crowdloans/src/types.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,30 @@ use super::{AccountIdOf, AssetIdOf, BalanceOf, Config};
1818

1919
use codec::{Decode, Encode};
2020

21+
use frame_system::pallet_prelude::BlockNumberFor;
2122
use scale_info::TypeInfo;
2223
use sp_runtime::{traits::Zero, RuntimeDebug};
2324

24-
use primitives::{BlockNumber, ParaId, TrieIndex};
25+
use primitives::{ParaId, TrieIndex};
2526

2627
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
2728
pub enum VaultPhase {
2829
/// Vault is open for contributions but wont execute contribute call on relaychain
29-
Pending,
30+
Pending = 0,
3031
/// Vault is open for contributions
31-
Contributing,
32+
Contributing = 1,
3233
/// The vault is closed and we should avoid future contributions. This happens when
3334
/// - there are no contribution
3435
/// - user cancelled
3536
/// - crowdloan reached its cap
3637
/// - parachain won the slot
37-
Closed,
38+
Closed = 2,
3839
/// The vault's crowdloan failed, we have to distribute its assets back
3940
/// to the contributors
40-
Failed,
41+
Failed = 3,
4142
/// The vault's crowdloan and its associated parachain slot expired, it is
4243
/// now possible to get back the money we put in
43-
Expired,
44+
Expired = 5,
4445
}
4546

4647
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
@@ -62,7 +63,7 @@ pub struct Vault<T: Config> {
6263
/// parallel enforced limit
6364
pub cap: BalanceOf<T>,
6465
/// block that vault ends
65-
pub end_block: BlockNumber,
66+
pub end_block: BlockNumberFor<T>,
6667
/// child storage trie index where we store all contributions
6768
pub trie_index: TrieIndex,
6869
}
@@ -74,7 +75,7 @@ impl<T: Config> Vault<T> {
7475
ctoken: AssetIdOf<T>,
7576
contribution_strategy: ContributionStrategy,
7677
cap: BalanceOf<T>,
77-
end_block: BlockNumber,
78+
end_block: BlockNumberFor<T>,
7879
trie_index: TrieIndex,
7980
) -> Self {
8081
Self {
@@ -93,7 +94,7 @@ impl<T: Config> Vault<T> {
9394

9495
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
9596
pub enum ContributionStrategy {
96-
XCM,
97+
XCM = 0,
9798
}
9899

99100
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)]

0 commit comments

Comments
 (0)