Skip to content

Commit

Permalink
feat: unique usage of balance type in interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
neutrinoks committed Mar 8, 2024
1 parent f3c2522 commit 51c721d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 64 deletions.
20 changes: 4 additions & 16 deletions pallet/src/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,15 @@ impl<T: Config> From<Error<T>> for StatusCode {

/// Balance adapter for providing basic access to balance cheques within the MoveVM.
#[derive(Clone)]
pub struct BalanceAdapter<T: Config + SysConfig>
where
BalanceOf<T>: From<u128> + Into<u128>,
{
pub struct BalanceAdapter<T: Config + SysConfig> {
_pd_config: PhantomData<T>,
/// Virtual cheques record of involved users.
cheques: Rc<RefCell<HashMap<EncodedAccount, BalanceOf<T>>>>,
/// Copy of initial state, without tracking it.
initial_state: HashMap<EncodedAccount, BalanceOf<T>>,
}

impl<T: Config + SysConfig> BalanceAdapter<T>
where
BalanceOf<T>: From<u128> + Into<u128>,
{
impl<T: Config + SysConfig> BalanceAdapter<T> {
/// Create a new [`BalanceAdapter`].
pub fn new() -> Self {
BalanceAdapter {
Expand Down Expand Up @@ -180,19 +174,13 @@ where
}
}

impl<T: Config> Default for BalanceAdapter<T>
where
BalanceOf<T>: From<u128> + Into<u128>,
{
impl<T: Config> Default for BalanceAdapter<T> {
fn default() -> Self {
Self::new()
}
}

impl<T: Config> BalanceHandler for BalanceAdapter<T>
where
BalanceOf<T>: From<u128> + Into<u128>,
{
impl<T: Config> BalanceHandler for BalanceAdapter<T> {
type Error = StatusCode;

fn transfer(
Expand Down
33 changes: 23 additions & 10 deletions pallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,22 @@ pub mod pallet {
#[pallet::config]
pub trait Config: frame_system::Config {
/// The currency mechanism.
type Currency: Currency<Self::AccountId>
+ ReservableCurrency<Self::AccountId>
+ LockableCurrency<Self::AccountId>;
type Currency: Currency<Self::AccountId, Balance = Self::CurrencyBalance>
+ ReservableCurrency<Self::AccountId, Balance = Self::CurrencyBalance>
+ LockableCurrency<Self::AccountId, Balance = Self::CurrencyBalance>;

/// Just the `Currency::Balance` type; we have this item to allow us to
/// constrain it to `From<u128>` and `Into<u128>`.
type CurrencyBalance: sp_runtime::traits::AtLeast32BitUnsigned
+ FullCodec
+ Copy
+ MaybeSerializeDeserialize
+ core::fmt::Debug
+ Default
+ From<u128>
+ Into<u128>
+ TypeInfo
+ MaxEncodedLen;

/// Maximum life time for requests.
#[pallet::constant]
Expand Down Expand Up @@ -171,8 +184,8 @@ pub mod pallet {

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T>
where
BalanceOf<T>: From<u128> + Into<u128>,
// where
// BalanceOf<T>: From<u128> + Into<u128> + Default,
{
fn on_idle(block_height: BlockNumberFor<T>, mut remaining_weight: Weight) -> Weight {
let len = MultisigStorage::<T>::iter_keys().count() as u64;
Expand Down Expand Up @@ -235,8 +248,8 @@ pub mod pallet {
// Dispatchable functions must be annotated with a weight and must return a DispatchResult.
#[pallet::call]
impl<T: Config> Pallet<T>
where
BalanceOf<T>: From<u128> + Into<u128>,
// where
// BalanceOf<T>: From<u128> + Into<u128> + Default,
{
/// Execute Move script transaction sent by the user.
// TODO(eiger) in M3: ensure the weight depends on basic extrinsic cost + gas_limit + size of the
Expand Down Expand Up @@ -288,7 +301,7 @@ pub mod pallet {
};
if signer_count > 0 {
let lock_id = Self::multi_signer_lock_id(&who, &transaction_bc[..], &cheque_limit);
signature_handler.sign_script(&who, cheque_limit.into(), lock_id)?;
signature_handler.sign_script(&who, &cheque_limit, lock_id)?;
}

// If the script is signed correctly, we can execute it in MoveVM and update the
Expand Down Expand Up @@ -413,8 +426,8 @@ pub mod pallet {
}

impl<T: Config> Pallet<T>
where
BalanceOf<T>: From<u128> + Into<u128>,
// where
// BalanceOf<T>: From<u128> + Into<u128> + Default,
{
// Internal helper for creating new MoveVM instance with StorageAdapter.
fn move_vm() -> MvmResult<T> {
Expand Down
1 change: 1 addition & 0 deletions pallet/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ parameter_types! {

impl pallet_move::Config for Test {
type Currency = Balances;
type CurrencyBalance = Balance;
type MaxLifetimeRequests = MaxLifetimeRequests;
type MaxScriptSigners = MaxScriptSigners;
type RuntimeEvent = RuntimeEvent;
Expand Down
65 changes: 27 additions & 38 deletions pallet/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{

// Some alias definition to make life easier.
pub type MaxSignersOf<T> = <T as Config>::MaxScriptSigners;
pub type MultisigOf<T> = Multisig<AccountIdOf<T>, BlockNumberFor<T>, MaxSignersOf<T>>;
pub type MultisigOf<T> = Multisig<AccountIdOf<T>, BalanceOf<T>, BlockNumberFor<T>, MaxSignersOf<T>>;

/// This definition stores the hash value of a script transaction.
pub type CallHash = [u8; 32];
Expand Down Expand Up @@ -59,33 +59,35 @@ impl<T> From<MultisigError> for Error<T> {
}

#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct SignerData {
pub struct SignerData<Balance> {
/// State of the user's signature.
pub signature: Signature,
/// Individual cheque-limit.
pub cheque_limit: u128,
pub cheque_limit: Balance,
/// Lock ID for locked currency.
pub lock_id: LockIdentifier,
}

/// Storage struct definition for a multi-signer request.
#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
#[scale_info(skip_type_params(Size))]
pub struct Multisig<AccountId, BlockNumber, Size>
pub struct Multisig<AccountId, Balance, BlockNumber, Size>
where
AccountId: Parameter + Ord + MaybeSerializeDeserialize,
Balance: From<u128> + Into<u128> + Default,
BlockNumber: Parameter + Ord + MaybeSerializeDeserialize + Default,
Size: Get<u32>,
{
/// The signers of a script transaction.
signers: BoundedBTreeMap<AccountId, SignerData, Size>,
signers: BoundedBTreeMap<AccountId, SignerData<Balance>, Size>,
/// The block number when this `Multisig` was created and stored.
block_height: BlockNumber,
}

impl<AccountId, BlockNumber, Size> Multisig<AccountId, BlockNumber, Size>
impl<AccountId, Balance, BlockNumber, Size> Multisig<AccountId, Balance, BlockNumber, Size>
where
AccountId: Parameter + Ord + MaybeSerializeDeserialize,
Balance: From<u128> + Into<u128> + Default,
BlockNumber: Parameter + Ord + MaybeSerializeDeserialize + Default,
Size: Get<u32>,
{
Expand All @@ -95,7 +97,7 @@ where
return Err(MultisigError::MaxSignersExceeded);
}

let mut multisig_info = Multisig::<AccountId, BlockNumber, Size> {
let mut multisig_info = Multisig::<AccountId, Balance, BlockNumber, Size> {
block_height,
..Default::default()
};
Expand All @@ -113,22 +115,26 @@ where
}
}

impl<AccountId, BlockNumber, Size> core::ops::Deref for Multisig<AccountId, BlockNumber, Size>
impl<AccountId, Balance, BlockNumber, Size> core::ops::Deref
for Multisig<AccountId, Balance, BlockNumber, Size>
where
AccountId: Parameter + Ord + MaybeSerializeDeserialize,
Balance: From<u128> + Into<u128> + Default,
BlockNumber: Parameter + Ord + MaybeSerializeDeserialize + Default,
Size: Get<u32>,
{
type Target = BoundedBTreeMap<AccountId, SignerData, Size>;
type Target = BoundedBTreeMap<AccountId, SignerData<Balance>, Size>;

fn deref(&self) -> &Self::Target {
&self.signers
}
}

impl<AccountId, BlockNumber, Size> core::ops::DerefMut for Multisig<AccountId, BlockNumber, Size>
impl<AccountId, Balance, BlockNumber, Size> core::ops::DerefMut
for Multisig<AccountId, Balance, BlockNumber, Size>
where
AccountId: Parameter + Ord + MaybeSerializeDeserialize,
Balance: From<u128> + Into<u128> + Default,
BlockNumber: Parameter + Ord + MaybeSerializeDeserialize + Default,
Size: Get<u32>,
{
Expand All @@ -138,40 +144,30 @@ where
}

// Because in substrate_move::AccountAddress Default impl is missing.
impl<AccountId, BlockNumber, Size> Default for Multisig<AccountId, BlockNumber, Size>
impl<AccountId, Balance, BlockNumber, Size> Default
for Multisig<AccountId, Balance, BlockNumber, Size>
where
AccountId: Parameter + Ord + MaybeSerializeDeserialize,
Balance: From<u128> + Into<u128> + Default,
BlockNumber: Parameter + Ord + MaybeSerializeDeserialize + Default,
Size: Get<u32>,
{
fn default() -> Self {
Multisig {
signers: BoundedBTreeMap::<AccountId, SignerData, Size>::new(),
signers: BoundedBTreeMap::<AccountId, SignerData<Balance>, Size>::new(),
block_height: BlockNumber::default(),
}
}
}

/// Script signature handler tracks required signatures for the provided script.
pub(crate) struct ScriptSignatureHandler<T>
where
T: Config + SysConfig,
T::AccountId: Parameter + Ord + MaybeSerializeDeserialize,
BlockNumberFor<T>: Parameter + Ord + MaybeSerializeDeserialize,
BalanceOf<T>: From<u128> + Into<u128>,
{
pub(crate) struct ScriptSignatureHandler<T: Config + SysConfig> {
_pd_config: PhantomData<T>,
/// All required multisig_info.
multisig_info: MultisigOf<T>,
}

impl<T> ScriptSignatureHandler<T>
where
T: Config + SysConfig,
T::AccountId: Parameter + Ord + MaybeSerializeDeserialize,
BlockNumberFor<T>: Parameter + Ord + MaybeSerializeDeserialize,
BalanceOf<T>: From<u128> + Into<u128>,
{
impl<T: Config + SysConfig> ScriptSignatureHandler<T> {
/// Creates a new [`ScriptSignatureHandler`] with all blank signatures for the provided script.
pub(crate) fn new(
accounts: Vec<T::AccountId>,
Expand All @@ -194,18 +190,17 @@ where
pub(crate) fn sign_script(
&mut self,
account: &T::AccountId,
cheque_limit: u128,
cheque_limit: &BalanceOf<T>,
lock_id: LockIdentifier,
) -> Result<(), Error<T>> {
if let Some(ms_data) = self.multisig_info.get_mut(account) {
if matches!(ms_data.signature, Signature::Approved) {
Err(Error::<T>::UserHasAlreadySigned)
} else {
ms_data.signature = Signature::Approved;
ms_data.cheque_limit = cheque_limit;
ms_data.cheque_limit = *cheque_limit;
ms_data.lock_id = lock_id;
let amount = BalanceOf::<T>::from(cheque_limit);
T::Currency::set_lock(lock_id, account, amount, WithdrawReasons::all());
T::Currency::set_lock(lock_id, account, *cheque_limit, WithdrawReasons::all());
Ok(())
}
} else {
Expand All @@ -227,7 +222,7 @@ where
for (account, ms_data) in self.multisig_info.iter() {
T::Currency::remove_lock(ms_data.lock_id, account);
balances
.write_cheque(account, &BalanceOf::<T>::from(ms_data.cheque_limit))
.write_cheque(account, &ms_data.cheque_limit)
.map_err(|_| Error::<T>::InsufficientBalance)?;
}

Expand All @@ -246,13 +241,7 @@ where
}
}

impl<T> From<MultisigOf<T>> for ScriptSignatureHandler<T>
where
T: Config + SysConfig,
T::AccountId: Parameter + Ord + MaybeSerializeDeserialize,
BlockNumberFor<T>: Parameter + Ord + MaybeSerializeDeserialize,
BalanceOf<T>: From<u128> + Into<u128>,
{
impl<T: Config + SysConfig> From<MultisigOf<T>> for ScriptSignatureHandler<T> {
fn from(multisig_info: MultisigOf<T>) -> Self {
Self {
_pd_config: PhantomData,
Expand Down

0 comments on commit 51c721d

Please sign in to comment.