mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 02:51:08 +00:00
Lazy reaping (#4895)
* Squash and rebase from gav-lazy-reaping * Bump version * Bump runtime again * Docs. * Remove old functions * Update frame/balances/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Update frame/contracts/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Warnings * Bump runtime version * Update frame/democracy/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Update frame/system/src/lib.rs * Clean up OnReapAccount * Use frame_support debug * Bump spec * Renames and fix * Fix * Fix rename * Fix * Increase time for test Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Benjamin Kampmann <ben.kampmann@googlemail.com>
This commit is contained in:
@@ -159,9 +159,8 @@ use codec::{Encode, Decode};
|
||||
|
||||
use frame_support::{
|
||||
decl_module, decl_event, decl_storage, decl_error, ensure,
|
||||
Parameter, RuntimeDebug,
|
||||
weights::{GetDispatchInfo, SimpleDispatchInfo, FunctionOf},
|
||||
traits::{Currency, ReservableCurrency, Get, OnReapAccount, BalanceStatus},
|
||||
Parameter, RuntimeDebug, weights::{GetDispatchInfo, SimpleDispatchInfo, FunctionOf},
|
||||
traits::{Currency, ReservableCurrency, Get, BalanceStatus},
|
||||
};
|
||||
use frame_system::{self as system, ensure_signed, ensure_root};
|
||||
|
||||
@@ -241,6 +240,7 @@ decl_storage! {
|
||||
pub Recoverable get(fn recovery_config):
|
||||
map hasher(blake2_256) T::AccountId
|
||||
=> Option<RecoveryConfig<T::BlockNumber, BalanceOf<T>, T::AccountId>>;
|
||||
|
||||
/// Active recovery attempts.
|
||||
///
|
||||
/// First account is the account to be recovered, and the second account
|
||||
@@ -248,10 +248,11 @@ decl_storage! {
|
||||
pub ActiveRecoveries get(fn active_recovery):
|
||||
double_map hasher(twox_64_concat) T::AccountId, hasher(twox_64_concat) T::AccountId =>
|
||||
Option<ActiveRecovery<T::BlockNumber, BalanceOf<T>, T::AccountId>>;
|
||||
/// The final list of recovered accounts.
|
||||
|
||||
/// The list of allowed proxy accounts.
|
||||
///
|
||||
/// Map from the recovered account to the user who can access it.
|
||||
pub Recovered get(fn recovered_account):
|
||||
/// Map from the user who can access it to the recovered account.
|
||||
pub Proxy get(fn proxy):
|
||||
map hasher(blake2_256) T::AccountId => Option<T::AccountId>;
|
||||
}
|
||||
}
|
||||
@@ -308,6 +309,8 @@ decl_error! {
|
||||
StillActive,
|
||||
/// There was an overflow in a calculation
|
||||
Overflow,
|
||||
/// This account is already set up for recovery
|
||||
AlreadyProxy,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,7 +335,7 @@ decl_module! {
|
||||
/// - One storage lookup to check account is recovered by `who`. O(1)
|
||||
/// # </weight>
|
||||
#[weight = FunctionOf(
|
||||
|args: (&T::AccountId, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().weight + 10_000,
|
||||
|args: (&T::AccountId, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().weight + 10_000,
|
||||
|args: (&T::AccountId, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().class,
|
||||
true
|
||||
)]
|
||||
@@ -342,7 +345,8 @@ decl_module! {
|
||||
) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
// Check `who` is allowed to make a call on behalf of `account`
|
||||
ensure!(Self::recovered_account(&account) == Some(who), Error::<T>::NotAllowed);
|
||||
let target = Self::proxy(&who).ok_or(Error::<T>::NotAllowed)?;
|
||||
ensure!(&target == &account, Error::<T>::NotAllowed);
|
||||
call.dispatch(frame_system::RawOrigin::Signed(account).into())
|
||||
}
|
||||
|
||||
@@ -363,7 +367,7 @@ decl_module! {
|
||||
fn set_recovered(origin, lost: T::AccountId, rescuer: T::AccountId) {
|
||||
ensure_root(origin)?;
|
||||
// Create the recovery storage item.
|
||||
<Recovered<T>>::insert(&lost, &rescuer);
|
||||
<Proxy<T>>::insert(&rescuer, &lost);
|
||||
Self::deposit_event(RawEvent::AccountRecovered(lost, rescuer));
|
||||
}
|
||||
|
||||
@@ -428,6 +432,7 @@ decl_module! {
|
||||
};
|
||||
// Create the recovery configuration storage item
|
||||
<Recoverable<T>>::insert(&who, recovery_config);
|
||||
|
||||
Self::deposit_event(RawEvent::RecoveryCreated(who));
|
||||
}
|
||||
|
||||
@@ -545,6 +550,7 @@ decl_module! {
|
||||
let recovery_config = Self::recovery_config(&account).ok_or(Error::<T>::NotRecoverable)?;
|
||||
// Get the active recovery process for the rescuer
|
||||
let active_recovery = Self::active_recovery(&account, &who).ok_or(Error::<T>::NotStarted)?;
|
||||
ensure!(!Proxy::<T>::contains_key(&who), Error::<T>::AlreadyProxy);
|
||||
// Make sure the delay period has passed
|
||||
let current_block_number = <system::Module<T>>::block_number();
|
||||
let recoverable_block_number = active_recovery.created
|
||||
@@ -557,7 +563,8 @@ decl_module! {
|
||||
Error::<T>::Threshold
|
||||
);
|
||||
// Create the recovery storage item
|
||||
<Recovered<T>>::insert(&account, &who);
|
||||
Proxy::<T>::insert(&who, &account);
|
||||
system::Module::<T>::inc_ref(&who);
|
||||
Self::deposit_event(RawEvent::AccountRecovered(account, who));
|
||||
}
|
||||
|
||||
@@ -592,7 +599,7 @@ decl_module! {
|
||||
Self::deposit_event(RawEvent::RecoveryClosed(who, rescuer));
|
||||
}
|
||||
|
||||
/// Remove the recovery process for your account.
|
||||
/// Remove the recovery process for your account. Recovered accounts are still accessible.
|
||||
///
|
||||
/// NOTE: The user must make sure to call `close_recovery` on all active
|
||||
/// recovery attempts before calling this function else it will fail.
|
||||
@@ -621,10 +628,30 @@ decl_module! {
|
||||
ensure!(active_recoveries.next().is_none(), Error::<T>::StillActive);
|
||||
// Take the recovery configuration for this account.
|
||||
let recovery_config = <Recoverable<T>>::take(&who).ok_or(Error::<T>::NotRecoverable)?;
|
||||
|
||||
// Unreserve the initial deposit for the recovery configuration.
|
||||
T::Currency::unreserve(&who, recovery_config.deposit);
|
||||
Self::deposit_event(RawEvent::RecoveryRemoved(who));
|
||||
}
|
||||
|
||||
/// Cancel the ability to use `as_recovered` for `account`.
|
||||
///
|
||||
/// The dispatch origin for this call must be _Signed_ and registered to
|
||||
/// be able to make calls on behalf of the recovered account.
|
||||
///
|
||||
/// Parameters:
|
||||
/// - `account`: The recovered account you are able to call on-behalf-of.
|
||||
///
|
||||
/// # <weight>
|
||||
/// - One storage mutation to check account is recovered by `who`. O(1)
|
||||
/// # </weight>
|
||||
fn cancel_recovered(origin, account: T::AccountId) {
|
||||
let who = ensure_signed(origin)?;
|
||||
// Check `who` is allowed to make a call on behalf of `account`
|
||||
ensure!(Self::proxy(&who) == Some(account), Error::<T>::NotAllowed);
|
||||
Proxy::<T>::remove(&who);
|
||||
system::Module::<T>::dec_ref(&who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,11 +666,3 @@ impl<T: Trait> Module<T> {
|
||||
friends.binary_search(&friend).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> OnReapAccount<T::AccountId> for Module<T> {
|
||||
/// Remove any existing access another account might have when the account is reaped.
|
||||
/// This removes the final storage item managed by this module for any given account.
|
||||
fn on_reap_account(who: &T::AccountId) {
|
||||
<Recovered<T>>::remove(who);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ impl frame_system::Trait for Test {
|
||||
type ModuleToIndex = ();
|
||||
type AccountData = pallet_balances::AccountData<u128>;
|
||||
type OnNewAccount = ();
|
||||
type OnReapAccount = (Balances, Recovery);
|
||||
type OnKilledAccount = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
|
||||
@@ -31,7 +31,7 @@ use frame_support::{
|
||||
fn basic_setup_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Nothing in storage to start
|
||||
assert_eq!(Recovery::recovered_account(&1), None);
|
||||
assert_eq!(Recovery::proxy(&2), None);
|
||||
assert_eq!(Recovery::active_recovery(&1, &2), None);
|
||||
assert_eq!(Recovery::recovery_config(&1), None);
|
||||
// Everyone should have starting balance of 100
|
||||
@@ -91,10 +91,13 @@ fn recovery_life_cycle_works() {
|
||||
// All funds have been fully recovered!
|
||||
assert_eq!(Balances::free_balance(1), 200);
|
||||
assert_eq!(Balances::free_balance(5), 0);
|
||||
// Remove the proxy link.
|
||||
assert_ok!(Recovery::cancel_recovered(Origin::signed(1), 5));
|
||||
|
||||
// All storage items are removed from the module
|
||||
assert!(!<ActiveRecoveries<Test>>::contains_key(&5, &1));
|
||||
assert!(!<Recoverable<Test>>::contains_key(&5));
|
||||
assert!(!<Recovered<Test>>::contains_key(&5));
|
||||
assert!(!<Proxy<Test>>::contains_key(&1));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -335,7 +338,7 @@ fn claim_recovery_works() {
|
||||
// Account can be recovered.
|
||||
assert_ok!(Recovery::claim_recovery(Origin::signed(1), 5));
|
||||
// Recovered storage item is correctly created
|
||||
assert_eq!(<Recovered<Test>>::get(&5), Some(1));
|
||||
assert_eq!(<Proxy<Test>>::get(&1), Some(5));
|
||||
// Account could be re-recovered in the case that the recoverer account also gets lost.
|
||||
assert_ok!(Recovery::initiate_recovery(Origin::signed(4), 5));
|
||||
assert_ok!(Recovery::vouch_recovery(Origin::signed(2), 5, 4));
|
||||
@@ -347,7 +350,7 @@ fn claim_recovery_works() {
|
||||
// Account is re-recovered.
|
||||
assert_ok!(Recovery::claim_recovery(Origin::signed(4), 5));
|
||||
// Recovered storage item is correctly updated
|
||||
assert_eq!(<Recovered<Test>>::get(&5), Some(4));
|
||||
assert_eq!(<Proxy<Test>>::get(&4), Some(5));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user