polkadot-fellows / RFCs

Proposals for change to standards administered by the Fellowship.
https://polkadot-fellows.github.io/RFCs/
Creative Commons Zero v1.0 Universal
111 stars 51 forks source link

Impl Display for MultiLocation #15

Closed olanod closed 9 months ago

olanod commented 1 year ago

In a number of occasions I've wanted to represent a MultiLocation in a short, url friendly way. (if something like it doesn't exist yet) I think we should have such a representation, e.g. similar to how a MultiAddress are displayed.

Before proposing an RFC it would be nice to hear some thoughts about possible ways to represent locations or if the feature is desired in the first place. The first format that naturally comes to mind on a high level is translating junctions into a URL-path-like format, with some prefix to represent parents(and version?), perhaps an "absolute path" representation as well.

Starting with

struct MultiLocation {
    pub parents: u8,
    pub interior: Junctions,
}

We can do something like .N/(junction1)/(junctionX) where N is the number of parents and junctions repeat separated by a /. The "absolute path" can be to just omit the parents prefix and expect the first junction to be of type GlobalConsensus.

Next, with current v3 we have

pub enum Junction {
    Parachain(u32),
    AccountId32 { network: Option<NetworkId>, id: [u8; 32] },
    AccountIndex64 { network: Option<NetworkId>, index: u64 },
    AccountKey20 { network: Option<NetworkId>, key: [u8; 20] },
    PalletInstance(u8),
    GeneralIndex(u128),
    GeneralKey { length: u8, data: [u8; 32] },
    OnlyChild,
    Plurality { id: BodyId, part: BodyPart },
    GlobalConsensus(NetworkId),
}

This junctions can have a long version that simply converts the enum variant to a lowercase snake version(e.g. only_child) and in case it's a tuple/struct variant we include the params wrapped in parentheses or squared brackets(for structs we ignore the name of the field), i.e. parachain(1000), account_id32(polkadot/11111111111111111111111111111111), account_index64(none/1), plurality(legislative/fraction[6/10]).
Now to actually make it short what about using a short form by default where we replace the long words with abbreviations or sigils that act as an alias, when using a sigil parenthesis/brackets could be omitted(?).
Here are some ideas ...

parachain -> : // e.g. `:1000` 
account_id32 -> @ // e.g. `@polkadot/11111111111111111111111111111111` (plain base58, no SS58)
account_index64 -> ! // e.g. `!123`
account_key20 -> k20 // e.g. `k20(-/11111111111111111111)` (none replaced as `-`)
pallet_instance -> p // e.g. `p(99)`
general_index -> idx // e.g. idx(123)
general_key -> key // e.g. `key(2/1)`
only_child -> ~
plurality -> * // e.g. `*technical/voice`
global_consensus -> / // e.g. `/polkadot`

For example purposes only let's imagine for a moment there is a xcm:// URI scheme to illustrate how several URL friendly multi-locations can be "rendered" together(also with multi-assets?) ...

xcm:///polkadot/:1002/*index(10)/at_least_proportion(10/100)?pay=.2/kusama/:1000/!42&asset=$./p(50)/idx(1984)+999999
arrudagates commented 1 year ago

I like this, I think non-rust API libraries and library users would benefit from this a lot.

xlc commented 1 year ago

Related prior art https://github.com/w3f/PSPs/blob/master/PSPs/drafts/psp-2.md https://hackmd.io/gQKQGf42TeOODid3hM4_1w#Identifying-and-utilising-a-fungible-asset-on-Polkadot

vstam1 commented 1 year ago

I believe it might be more appropriate to place this issue/RFC in the xcm-format repository.

rphmeier commented 1 year ago

There's no strict guidance here, but RFC'ing every change like adding Display or Clone to types, or adding utility functions to libraries seems excessive to me.

RFCs are generally meant to be for software architectural, design, and protocol documents.

That said, a small RFC attempting to standardize a format for displaying XCM paths and junctions in an implementation-agnostic way could be fine, but it'd need to be comprehensive.