Skip to content
Snippets Groups Projects
Commit 5a8ad94e authored by Cédric Moreau's avatar Cédric Moreau
Browse files

fix(#187): remove identity creation fee

parent 3e644842
No related branches found
No related tags found
1 merge request!238Remove account creation fee
......@@ -5,26 +5,26 @@ Feature: Account creation
Then dave should have 5 ĞD
When 1 block later
"""
The blockchain should automatically withdraw account creation tax (3 ĞD)
The blockchain did not automatically withdraw account creation tax (3 ĞD) because this feature has been removed
"""
Then dave should have 2 ĞD
Then dave should have 5 ĞD
Scenario: Create a new account without enough funds then retry with enough funds
When alice sends 2 ĞD to eve
Then eve should have 2 ĞD
When 1 block later
"""
The blockchain should automatically destroy Eve account
because Eve does not have enough funds to pay the new account tax
The blockchain did not automatically destroy Eve account for Eve not having enough funds to pay the new account tax
Because this feature has been removed
"""
Then eve should have 0 ĞD
Then eve should have 2 ĞD
When alice send 5 ĞD to eve
Then eve should have 5 ĞD
Then eve should have 7 ĞD
When 1 block later
"""
The blockchain should automatically withdraw account creation tax (3 ĞD)
The blockchain did not automatically withdraw account creation tax (3 ĞD) because this feature has been removed
"""
Then eve should have 2 ĞD
Then eve should have 7 ĞD
@ignoreErrors
Scenario: Create a new account without any funds
......@@ -37,6 +37,6 @@ Feature: Account creation
Then eve should have 5 ĞD
When 1 block later
"""
The blockchain should automatically withdraw account creation tax (3 ĞD)
The blockchain did not automatically withdraw account creation tax (3 ĞD) because this feature has been removed
"""
Then eve should have 2 ĞD
Then eve should have 5 ĞD
......@@ -29,12 +29,12 @@ pub use types::*;
pub use weights::WeightInfo;
use frame_support::pallet_prelude::*;
use frame_support::traits::{Currency, ExistenceRequirement, StorageVersion};
use frame_support::traits::{OnUnbalanced, StoredMap};
use frame_support::traits::StoredMap;
use frame_support::traits::{Currency, StorageVersion};
use frame_system::pallet_prelude::*;
use pallet_quota::traits::RefundFee;
use pallet_transaction_payment::OnChargeTransaction;
use sp_runtime::traits::{Convert, DispatchInfoOf, PostDispatchInfoOf, Saturating};
use sp_runtime::traits::{DispatchInfoOf, PostDispatchInfoOf, Saturating};
use sp_std::fmt::Debug;
#[frame_support::pallet]
......@@ -63,30 +63,16 @@ pub mod pallet {
+ pallet_treasury::Config<Currency = pallet_balances::Pallet<Self>>
+ pallet_quota::Config
{
type AccountIdToSalt: Convert<Self::AccountId, [u8; 32]>;
#[pallet::constant]
type MaxNewAccountsPerBlock: Get<u32>;
#[pallet::constant]
type NewAccountPrice: Get<Self::Balance>;
/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// Type representing the weight of this pallet
type WeightInfo: WeightInfo;
/// Handler for the unbalanced reduction when the requestor pays fees.
type OnUnbalanced: OnUnbalanced<pallet_balances::NegativeImbalance<Self>>;
/// wrapped type
type InnerOnChargeTransaction: OnChargeTransaction<Self>;
/// type implementing refund behavior
type Refund: pallet_quota::traits::RefundFee<Self>;
}
// STORAGE //
#[pallet::storage]
#[pallet::getter(fn pending_new_accounts)]
pub type PendingNewAccounts<T: Config> =
StorageMap<_, Blake2_128Concat, T::AccountId, (), OptionQuery>;
// GENESIS STUFF //
#[pallet::genesis_config]
......@@ -158,11 +144,6 @@ pub mod pallet {
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Forced destruction of an account due to insufficient free balance to cover the account creation price.
ForceDestroy {
who: T::AccountId,
balance: T::Balance,
},
/// account linked to identity
AccountLinked {
who: T::AccountId,
......@@ -212,69 +193,6 @@ pub mod pallet {
};
}
}
// HOOKS //
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
// on initialize, withdraw account creation tax
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
let mut total_weight = Weight::zero();
for account_id in PendingNewAccounts::<T>::iter_keys()
.drain()
.take(T::MaxNewAccountsPerBlock::get() as usize)
{
if frame_system::Pallet::<T>::sufficients(&account_id) > 0 {
// If the account is self-sufficient, it is exempt from account creation fees
total_weight += <T as pallet::Config>::WeightInfo::on_initialize_sufficient(
T::MaxNewAccountsPerBlock::get(),
);
} else {
// If the account is not self-sufficient, it must pay the account creation fees
let account_data = frame_system::Pallet::<T>::get(&account_id);
let price = T::NewAccountPrice::get();
if account_data.free >= T::ExistentialDeposit::get() + price {
// The account can pay the new account price, we should:
// 1. Withdraw the "new account price" amount
// 2. Manage the funds collected
let res = <pallet_balances::Pallet<T> as Currency<T::AccountId>>::withdraw(
&account_id,
price,
frame_support::traits::WithdrawReasons::FEE,
ExistenceRequirement::KeepAlive,
);
debug_assert!(
res.is_ok(),
"Cannot fail because we checked that the free balance was sufficient"
);
if let Ok(imbalance) = res {
T::OnUnbalanced::on_unbalanced(imbalance);
total_weight +=
<T as pallet::Config>::WeightInfo::on_initialize_with_balance(
T::MaxNewAccountsPerBlock::get(),
);
}
} else {
// The charges could not be deducted, we must destroy the account
let balance_to_suppr =
account_data.free.saturating_add(account_data.reserved);
// Force account data supression
frame_system::Account::<T>::remove(&account_id);
Self::deposit_event(Event::ForceDestroy {
who: account_id,
balance: balance_to_suppr,
});
T::OnUnbalanced::on_unbalanced(pallet_balances::NegativeImbalance::new(
balance_to_suppr,
));
total_weight += <T as pallet::Config>::WeightInfo::on_initialize_no_balance(
T::MaxNewAccountsPerBlock::get(),
);
}
}
}
total_weight
}
}
}
// implement account linker
......@@ -341,7 +259,6 @@ where
// the account has just been created, increment its provider
(false, true) => {
frame_system::Pallet::<T>::inc_providers(account_id);
PendingNewAccounts::<T>::insert(account_id, ());
}
// the account was existing but is not anymore, decrement the provider
(true, false) => {
......
No preview for this file type
......@@ -101,14 +101,10 @@ type RuntimeTask = ();
impl pallet_duniter_account::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type AccountIdToSalt = sp_runtime::traits::ConvertInto;
type MaxNewAccountsPerBlock = frame_support::pallet_prelude::ConstU32<1>;
type NewAccountPrice = frame_support::traits::ConstU64<300>;
type WeightInfo = common_runtime::weights::pallet_duniter_account::WeightInfo<Runtime>;
// does currency adapter in any case, but adds "refund with quota" feature
type InnerOnChargeTransaction = CurrencyAdapter<Balances, HandleFees>;
type Refund = Quota;
type OnUnbalanced = Treasury;
}
// QUOTA //
......
......@@ -943,66 +943,6 @@ fn test_smith_process() {
})
}
/// test create new account with balance lower than existential deposit
// the treasury gets the dust
#[test]
fn test_create_new_account_with_insufficient_balance() {
ExtBuilder::new(1, 3, 4)
.with_initial_balances(vec![(AccountKeyring::Alice.to_account_id(), 1_000)])
.build()
.execute_with(|| {
run_to_block(2);
// Treasury should start empty
// FIXME it actually starts with ED
assert_eq!(Balances::free_balance(Treasury::account_id()), 100);
// Should be able to transfer 4 units to a new account
assert_ok!(Balances::transfer_allow_death(
frame_system::RawOrigin::Signed(AccountKeyring::Alice.to_account_id()).into(),
MultiAddress::Id(AccountKeyring::Eve.to_account_id()),
300
));
System::assert_has_event(RuntimeEvent::System(frame_system::Event::NewAccount {
account: AccountKeyring::Eve.to_account_id(),
}));
System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Endowed {
account: AccountKeyring::Eve.to_account_id(),
free_balance: 300,
}));
System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Transfer {
from: AccountKeyring::Alice.to_account_id(),
to: AccountKeyring::Eve.to_account_id(),
amount: 300,
}));
// At next block, the new account must be reaped because its balance is not sufficient
// to pay the "new account tax"
run_to_block(3);
System::assert_has_event(RuntimeEvent::Account(
pallet_duniter_account::Event::ForceDestroy {
who: AccountKeyring::Eve.to_account_id(),
balance: 300,
},
));
System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Deposit {
who: Treasury::account_id(),
amount: 300,
}));
System::assert_has_event(RuntimeEvent::Treasury(pallet_treasury::Event::Deposit {
value: 300,
}));
assert_eq!(
Balances::free_balance(AccountKeyring::Eve.to_account_id()),
0
);
// 100 initial + 300 recycled from Eve account's destruction
assert_eq!(Balances::free_balance(Treasury::account_id()), 400);
});
}
/// test new account creation
#[test]
fn test_create_new_account() {
......@@ -1033,35 +973,19 @@ fn test_create_new_account() {
amount: 500,
}));
// At next block, the new account must be created,
// and new account tax should be collected and deposited in the treasury
run_to_block(3);
System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Withdraw {
who: AccountKeyring::Eve.to_account_id(),
amount: 300,
}));
System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Deposit {
who: Treasury::account_id(),
amount: 300,
}));
System::assert_has_event(RuntimeEvent::Treasury(pallet_treasury::Event::Deposit {
value: 300,
}));
// The new account must be created immediately
assert_eq!(
Balances::free_balance(AccountKeyring::Eve.to_account_id()),
200
500
);
// 100 initial + 300 deposit
assert_eq!(Balances::free_balance(Treasury::account_id()), 400);
// 100 initial + no deposit (there is no account creation fee)
assert_eq!(Balances::free_balance(Treasury::account_id()), 100);
run_to_block(4);
// can remove an account using transfer
assert_ok!(Balances::transfer_allow_death(
frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(),
MultiAddress::Id(AccountKeyring::Alice.to_account_id()),
200
500
));
// Account reaped
assert_eq!(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment