Skip to content
Snippets Groups Projects

Oneshot accounts

Merged Pascal Engélibert requested to merge poc-oneshot-accounts into master
Compare and Show latest version
4 files
+ 79
45
Compare changes
  • Side-by-side
  • Inline
Files
4
@@ -19,9 +19,10 @@
pub use pallet::*;
use frame_support::pallet_prelude::*;
use frame_support::traits::{IsSubType, StoredMap};
use frame_support::traits::{
Currency, ExistenceRequirement, Imbalance, IsSubType, WithdrawReasons,
};
use frame_system::pallet_prelude::*;
use pallet_balances::NegativeImbalance;
use sp_runtime::traits::{DispatchInfoOf, PostDispatchInfoOf, Saturating, StaticLookup, Zero};
#[frame_support::pallet]
@@ -41,9 +42,8 @@ pub mod pallet {
// CONFIG //
#[pallet::config]
pub trait Config:
frame_system::Config + pallet_balances::Config + pallet_transaction_payment::Config
{
pub trait Config: frame_system::Config + pallet_transaction_payment::Config {
type Currency: Currency<Self::AccountId>;
/// The overarching event type.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
}
@@ -52,8 +52,13 @@ pub mod pallet {
#[pallet::storage]
#[pallet::getter(fn oneshot_account)]
pub type OneshotAccounts<T: Config> =
StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, OptionQuery>;
pub type OneshotAccounts<T: Config> = StorageMap<
_,
Blake2_128Concat,
T::AccountId,
<T::Currency as Currency<T::AccountId>>::Balance,
OptionQuery,
>;
// EVENTS //
@@ -62,17 +67,23 @@ pub mod pallet {
pub enum Event<T: Config> {
OneshotAccountCreated {
account: T::AccountId,
balance: T::Balance,
balance: <T::Currency as Currency<T::AccountId>>::Balance,
creator: T::AccountId,
},
OneshotAccountConsumed {
account: T::AccountId,
dest1: (T::AccountId, T::Balance),
dest2: Option<(T::AccountId, T::Balance)>,
dest1: (
T::AccountId,
<T::Currency as Currency<T::AccountId>>::Balance,
),
dest2: Option<(
T::AccountId,
<T::Currency as Currency<T::AccountId>>::Balance,
)>,
},
Withdraw {
account: T::AccountId,
balance: T::Balance,
balance: <T::Currency as Currency<T::AccountId>>::Balance,
},
}
@@ -107,13 +118,13 @@ pub mod pallet {
pub fn create_oneshot_account(
origin: OriginFor<T>,
dest: <T::Lookup as StaticLookup>::Source,
#[pallet::compact] value: T::Balance,
#[pallet::compact] value: <T::Currency as Currency<T::AccountId>>::Balance,
) -> DispatchResult {
let transactor = ensure_signed(origin)?;
let dest = T::Lookup::lookup(dest)?;
ensure!(
value >= T::ExistentialDeposit::get(),
value >= <T::Currency as Currency<T::AccountId>>::minimum_balance(),
Error::<T>::ExistentialDeposit
);
ensure!(
@@ -121,11 +132,12 @@ pub mod pallet {
Error::<T>::OneshotAccountAlreadyCreated
);
let transactor_data = <T as pallet_balances::Config>::AccountStore::get(&transactor);
/*let transactor_data = <T as pallet_balances::Config>::AccountStore::get(&transactor);
let transactor_free_and_reserved = transactor_data
.free
.saturating_add(transactor_data.reserved);
let sufficient_balance = value.saturating_add(T::ExistentialDeposit::get());
let sufficient_balance =
value.saturating_add(<T::Currency as Currency<T::AccountId>>::minimum_balance());
ensure!(
transactor_data.free >= value && transactor_free_and_reserved >= sufficient_balance,
Error::<T>::InsufficientBalance
@@ -133,7 +145,14 @@ pub mod pallet {
<T as pallet_balances::Config>::AccountStore::mutate(&transactor, |a| {
a.free = a.free.saturating_sub(value)
})?;
})?;*/
<T::Currency as Currency<T::AccountId>>::withdraw(
&transactor,
value,
WithdrawReasons::TRANSFER,
ExistenceRequirement::KeepAlive,
)?;
OneshotAccounts::<T>::insert(&dest, value);
Self::deposit_event(Event::OneshotAccountCreated {
account: dest,
@@ -181,14 +200,15 @@ pub mod pallet {
creator: transactor.clone(),
});
} else {
let dest_data = <T as pallet_balances::Config>::AccountStore::get(&dest);
/*let dest_data = <T as pallet_balances::Config>::AccountStore::get(&dest);
ensure!(
!dest_data.free.is_zero() || !dest_data.reserved.is_zero(),
Error::<T>::DestAccountNotExist
);
<T as pallet_balances::Config>::AccountStore::mutate(&dest, |a| {
a.free = a.free.saturating_add(value)
})?;
})?;*/
<T::Currency as Currency<T::AccountId>>::deposit_into_existing(&dest, value)?;
}
OneshotAccounts::<T>::remove(&transactor);
Self::deposit_event(Event::OneshotAccountConsumed {
@@ -215,7 +235,7 @@ pub mod pallet {
dest_is_oneshot: bool,
dest2: <T::Lookup as StaticLookup>::Source,
dest2_is_oneshot: bool,
#[pallet::compact] balance: T::Balance,
#[pallet::compact] balance: <T::Currency as Currency<T::AccountId>>::Balance,
) -> DispatchResult {
let transactor = ensure_signed(origin)?;
let dest1 = T::Lookup::lookup(dest)?;
@@ -241,14 +261,18 @@ pub mod pallet {
Error::<T>::OneshotAccountAlreadyCreated
);
ensure!(
balance1 >= T::ExistentialDeposit::get(),
balance1 >= <T::Currency as Currency<T::AccountId>>::minimum_balance(),
Error::<T>::ExistentialDeposit
);
} else {
let dest1_data = <T as pallet_balances::Config>::AccountStore::get(&dest1);
/*let dest1_data = <T as pallet_balances::Config>::AccountStore::get(&dest1);
ensure!(
!dest1_data.free.is_zero() || !dest1_data.reserved.is_zero(),
Error::<T>::DestAccountNotExist
);*/
ensure!(
!<T::Currency as Currency<T::AccountId>>::free_balance(&dest1).is_zero(),
Error::<T>::DestAccountNotExist
);
}
if dest2_is_oneshot {
@@ -257,7 +281,7 @@ pub mod pallet {
Error::<T>::OneshotAccountAlreadyCreated
);
ensure!(
balance2 >= T::ExistentialDeposit::get(),
balance2 >= <T::Currency as Currency<T::AccountId>>::minimum_balance(),
Error::<T>::ExistentialDeposit
);
OneshotAccounts::<T>::insert(&dest2, balance2);
@@ -267,14 +291,15 @@ pub mod pallet {
creator: transactor.clone(),
});
} else {
let dest2_data = <T as pallet_balances::Config>::AccountStore::get(&dest2);
/*let dest2_data = <T as pallet_balances::Config>::AccountStore::get(&dest2);
ensure!(
!dest2_data.free.is_zero() || !dest2_data.reserved.is_zero(),
Error::<T>::DestAccountNotExist
);
<T as pallet_balances::Config>::AccountStore::mutate(&dest2, |a| {
a.free = a.free.saturating_add(balance2)
})?;
})?;*/
<T::Currency as Currency<T::AccountId>>::deposit_into_existing(&dest2, balance2)?;
}
if dest_is_oneshot {
OneshotAccounts::<T>::insert(&dest1, balance1);
@@ -284,9 +309,10 @@ pub mod pallet {
creator: transactor.clone(),
});
} else {
<T as pallet_balances::Config>::AccountStore::mutate(&dest1, |a| {
/*<T as pallet_balances::Config>::AccountStore::mutate(&dest1, |a| {
a.free = a.free.saturating_add(balance1)
})?;
})?;*/
<T::Currency as Currency<T::AccountId>>::deposit_into_existing(&dest1, balance1)?;
}
OneshotAccounts::<T>::remove(&transactor);
Self::deposit_event(Event::OneshotAccountConsumed {
@@ -303,14 +329,29 @@ pub mod pallet {
impl<T: Config> pallet_transaction_payment::OnChargeTransaction<T> for Pallet<T>
where
T::Call: IsSubType<Call<T>>,
T::OnChargeTransaction: pallet_transaction_payment::OnChargeTransaction<
T,
Balance = T::Balance,
LiquidityInfo = Option<pallet_balances::NegativeImbalance<T>>,
T::Currency:
Currency<
T::AccountId,
Balance = <T::OnChargeTransaction as pallet_transaction_payment::OnChargeTransaction<
T,
>>::Balance,
>,
<T::Currency as Currency<T::AccountId>>::PositiveImbalance: Imbalance<
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance,
Opposite = <T::Currency as Currency<T::AccountId>>::NegativeImbalance,
>,
<T::Currency as Currency<T::AccountId>>::NegativeImbalance: Imbalance<
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance,
Opposite = <T::Currency as Currency<T::AccountId>>::PositiveImbalance,
>,
/*T::OnChargeTransaction: pallet_transaction_payment::OnChargeTransaction<
T,
Balance = <T::Currency as Currency<T::AccountId>>::Balance,
LiquidityInfo = Option<<T::Currency as Currency<T::AccountId>>::NegativeImbalance>,
>,*/
{
type Balance = T::Balance;
type LiquidityInfo = Option<pallet_balances::NegativeImbalance<T>>;
type Balance = <T::Currency as Currency<T::AccountId>>::Balance;
type LiquidityInfo = Option<<T::Currency as Currency<T::AccountId>>::NegativeImbalance>;
fn withdraw_fee(
who: &T::AccountId,
call: &T::Call,
@@ -333,7 +374,10 @@ where
account: who.clone(),
balance: fee,
});
return Ok(Some(NegativeImbalance::new(fee)));
// TODO
return Ok(Some(
<T::Currency as Currency<T::AccountId>>::NegativeImbalance::zero(),
));
}
}
Err(TransactionValidityError::Invalid(
Loading