Skip to content
Snippets Groups Projects
Commit 6d4f4bfb authored by Éloïs's avatar Éloïs Committed by Pascal Engélibert
Browse files

PoC about oneshot accounts

parent 33630d52
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !51. Comments created here will be created in the context of that merge request.
...@@ -26,7 +26,7 @@ use frame_support::traits::{OnUnbalanced, StoredMap}; ...@@ -26,7 +26,7 @@ use frame_support::traits::{OnUnbalanced, StoredMap};
use frame_system::pallet_prelude::*; use frame_system::pallet_prelude::*;
use pallet_provide_randomness::RequestId; use pallet_provide_randomness::RequestId;
use sp_core::H256; use sp_core::H256;
use sp_runtime::traits::{Convert, Saturating, Zero}; use sp_runtime::traits::{Convert, Saturating, StaticLookup, Zero};
#[frame_support::pallet] #[frame_support::pallet]
pub mod pallet { pub mod pallet {
...@@ -60,6 +60,11 @@ pub mod pallet { ...@@ -60,6 +60,11 @@ pub mod pallet {
// STORAGE // // STORAGE //
#[pallet::storage]
#[pallet::getter(fn oneshot_account)]
pub type OneshotAccounts<T: Config> =
StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, OptionQuery>;
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn pending_random_id_assignments)] #[pallet::getter(fn pending_random_id_assignments)]
pub type PendingRandomIdAssignments<T: Config> = pub type PendingRandomIdAssignments<T: Config> =
...@@ -133,14 +138,40 @@ pub mod pallet { ...@@ -133,14 +138,40 @@ pub mod pallet {
/// the account creation price. /// the account creation price.
/// [who, balance] /// [who, balance]
ForceDestroy { ForceDestroy {
balance: T::Balance,
who: T::AccountId, who: T::AccountId,
},
OneshotAccountCreated {
account: T::AccountId,
balance: T::Balance, balance: T::Balance,
creator: T::AccountId,
},
OneshotAccountConsumed {
account: T::AccountId,
balance: T::Balance,
dest: T::AccountId,
}, },
/// Random id assigned /// Random id assigned
/// [account_id, random_id] /// [account_id, random_id]
RandomIdAssigned { who: T::AccountId, random_id: H256 }, RandomIdAssigned { who: T::AccountId, random_id: H256 },
} }
// ERRORS //
#[pallet::error]
pub enum Error<T> {
/// DestAccountNotExist
DestAccountNotExist,
/// ExistentialDeposit
ExistentialDeposit,
/// InsufficientBalance
InsufficientBalance,
/// OneshotAccouncAlreadyCreated
OneshotAccountAlreadyCreated,
/// OneshotAccountNotExist
OneshotAccountNotExist,
}
// HOOKS // // HOOKS //
#[pallet::hooks] #[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> { impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
...@@ -217,6 +248,89 @@ pub mod pallet { ...@@ -217,6 +248,89 @@ pub mod pallet {
total_weight total_weight
} }
} }
// CALLS //
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(500_000_000)]
pub fn create_oneshot_account(
origin: OriginFor<T>,
dest: <T::Lookup as StaticLookup>::Source,
#[pallet::compact] value: T::Balance,
) -> DispatchResult {
let transactor = ensure_signed(origin)?;
let dest = T::Lookup::lookup(dest)?;
ensure!(
value >= T::ExistentialDeposit::get(),
Error::<T>::ExistentialDeposit
);
ensure!(
OneshotAccounts::<T>::get(&dest).is_none(),
Error::<T>::OneshotAccountAlreadyCreated
);
let transactor_data = frame_system::Account::<T>::get(&transactor).data;
let transactor_free_and_reserved = transactor_data
.free
.saturating_add(transactor_data.reserved);
let sufficient_balance = value.saturating_add(T::ExistentialDeposit::get());
ensure!(
transactor_data.free >= value && transactor_free_and_reserved >= sufficient_balance,
Error::<T>::InsufficientBalance
);
frame_system::Account::<T>::mutate(&transactor, |a| a.data.sub_free(value));
OneshotAccounts::<T>::insert(&dest, value);
Self::deposit_event(Event::OneshotAccountCreated {
account: dest,
balance: value,
creator: transactor,
});
Ok(())
}
#[pallet::weight(500_000_000)]
pub fn consume_oneshot_account(
origin: OriginFor<T>,
dest: (bool, <T::Lookup as StaticLookup>::Source),
) -> DispatchResult {
let transactor = ensure_signed(origin)?;
let dest_is_oneshot = dest.0;
let dest = T::Lookup::lookup(dest.1)?;
let value = OneshotAccounts::<T>::take(&transactor)
.ok_or(Error::<T>::OneshotAccountNotExist)?;
if dest_is_oneshot {
ensure!(
OneshotAccounts::<T>::get(&dest).is_none(),
Error::<T>::OneshotAccountAlreadyCreated
);
OneshotAccounts::<T>::insert(&dest, value);
Self::deposit_event(Event::OneshotAccountConsumed {
account: transactor.clone(),
balance: value,
dest: dest.clone(),
});
Self::deposit_event(Event::OneshotAccountCreated {
account: dest,
balance: value,
creator: transactor,
});
} else {
let dest_data = frame_system::Account::<T>::get(&dest).data;
ensure!(dest_data.was_providing(), Error::<T>::DestAccountNotExist);
Self::deposit_event(Event::OneshotAccountConsumed {
account: transactor,
balance: value,
dest,
});
}
Ok(())
}
}
} }
impl<T> pallet_provide_randomness::OnFilledRandomness for Pallet<T> impl<T> pallet_provide_randomness::OnFilledRandomness for Pallet<T>
......
...@@ -18,7 +18,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; ...@@ -18,7 +18,7 @@ use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::pallet_prelude::*; use frame_support::pallet_prelude::*;
use scale_info::TypeInfo; use scale_info::TypeInfo;
use sp_core::H256; use sp_core::H256;
use sp_runtime::traits::Zero; use sp_runtime::traits::{Saturating, Zero};
#[derive(Clone, Decode, Default, Encode, Eq, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)] #[derive(Clone, Decode, Default, Encode, Eq, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)]
pub struct AccountData<Balance> { pub struct AccountData<Balance> {
...@@ -28,12 +28,18 @@ pub struct AccountData<Balance> { ...@@ -28,12 +28,18 @@ pub struct AccountData<Balance> {
fee_frozen: Balance, fee_frozen: Balance,
} }
impl<Balance: Zero> AccountData<Balance> { impl<Balance: Copy + Saturating + Zero> AccountData<Balance> {
pub fn free_and_reserved(&self) -> Balance {
self.free.saturating_add(self.reserved)
}
pub fn set_balances(&mut self, new_balances: pallet_balances::AccountData<Balance>) { pub fn set_balances(&mut self, new_balances: pallet_balances::AccountData<Balance>) {
self.free = new_balances.free; self.free = new_balances.free;
self.reserved = new_balances.reserved; self.reserved = new_balances.reserved;
self.fee_frozen = new_balances.fee_frozen; self.fee_frozen = new_balances.fee_frozen;
} }
pub fn sub_free(&mut self, amount: Balance) {
self.free = self.free.saturating_sub(amount);
}
pub fn was_providing(&self) -> bool { pub fn was_providing(&self) -> bool {
!self.free.is_zero() || !self.reserved.is_zero() !self.free.is_zero() || !self.reserved.is_zero()
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment