Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

How to support multiple currencies in pallet_treasury? #5081

Closed
clearloop opened this issue Feb 27, 2020 · 3 comments
Closed

How to support multiple currencies in pallet_treasury? #5081

clearloop opened this issue Feb 27, 2020 · 3 comments
Labels
J0-enhancement An additional feature request.
Milestone

Comments

@clearloop
Copy link
Contributor

clearloop commented Feb 27, 2020

Spec

propose_spend receive a Currency<AccountId>::Balance as an argument, what if we declare multiple currencies in Trait and write different logics?

  1. Multiple currencies in pallet_treasury::Trait
pub trait Trait: frame_system::Trait {                                                                                                                                                                                    
    type CurrencyA: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;                                                                                                                                                                                  
    type CurrencyB: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
    // ...
}
  1. propose_spend method in Call
pub enum Call<T: Trait> {
    propose_spend(
        balance: <<T as Trait>::Currency as Currency<<T as Trait>::AccountId>>::Balance, 
        source: <T::Lookup as StaticLookup>::Source
    ) {
        match balance {
                CurrencyA => {},
                CurrencyB => {},
        }
    }
    // ....
}

Is it possible to compose the Balance argument as an enum, or implement different traits to infer which currency is passing in?

I've just tried both of enum an trait and failed both of them.

enum solution

enum Balances {
    CurrencyA::Balance,
    CurrencyB::Balance,
}

Macro parse failed, lack of Encode and Decode trait, even derive them to the enum.

trait solution

enum BalanceMarker {
    A,
    B,
}

trait Marker {
    fn marker() -> BalanceMarker;
}

impl<_> Marker for CurrencyA::Balance<_> {
    // ...
}

impl<_> Marker for CurrencyB::Balance<_> {
    // ...
}

This seems impossible because Trait is totally all types and doesn't have Sized to compile.

sp_std::any::TypeId solution

Failed as trait one.

Wondering

If it is unnecessary or impossible implementing CurrencyA, CurrencyB.... in pallet_treasury? If it is, how can I reach different logics for different Balances in propose_spend method?

@bkchr
Copy link
Member

bkchr commented Feb 27, 2020

Hey, that is currently not supported, but sounds like a good idea!

@bkchr bkchr added the J0-enhancement An additional feature request. label Feb 27, 2020
@bkchr bkchr added this to the Ideas milestone Feb 27, 2020
@clearloop
Copy link
Contributor Author

Hi, we just got a solution as a reference,

// Currencies
trait Trait: system::Trait {
    type CurrencyA: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
    type CurrencyB: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
    type CommonBalanceT<T> = CommonBalance<BalanceA<T>, BalanceB<T>>;
}

// Balances
type BalanceA<T> = <CurrencyA<T> as Currency<AccountId<T>>>::Balance;
type BalanceB<T> = <CurrencyB<T> as Currency<AccountId<T>>>::Balance;
type CommonBalanceT<T> = CommonBalance<BalanceA<T>, BalanceB<T>>;

// The enum
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
pub enum CommonBalance<A, B>
where
    A: HasCompact,
    B: HasCompact,
{
    BalanceA(A),
    BalanceB(B),
}

// propose_spend
fn propose_spend(
        origin,
        value: CommonBalanceT<T>,
        beneficiary: <T::Lookup as StaticLookup>::Source
) {
       match value { 
           // ... 
       }
}

Compose enum with currencies as generics.

@bkchr
Copy link
Member

bkchr commented Jul 27, 2020

TY for reporting back.

@bkchr bkchr closed this as completed Jul 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
J0-enhancement An additional feature request.
Projects
None yet
Development

No branches or pull requests

2 participants