-
Notifications
You must be signed in to change notification settings - Fork 690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
staging-xcm
: Use versioned_type!
for VersionedXcm
#4378
base: master
Are you sure you want to change the base?
Changes from 3 commits
61a62b7
37c8a6b
794b59c
6cf04ba
bda5a4c
a28429d
06b9211
bcc1db2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,37 @@ pub trait TryAs<T> { | |
} | ||
|
||
macro_rules! versioned_type { | ||
(@internal $n:ident, $v3:ty, ) => { | ||
// only impl `MaxEncodedLen` for enums without generic type parameters | ||
impl MaxEncodedLen for $n { | ||
fn max_encoded_len() -> usize { | ||
<$v3>::max_encoded_len() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be the max of all variants. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. some enums' 2nd versions do not implement |
||
} | ||
} | ||
impl IntoVersion for $n { | ||
fn into_version(self, n: Version) -> Result<Self, ()> { | ||
Ok(match n { | ||
1 | 2 => Self::V2(self.try_into()?), | ||
3 => Self::V3(self.try_into()?), | ||
4 => Self::V4(self.try_into()?), | ||
_ => return Err(()), | ||
}) | ||
} | ||
} | ||
}; | ||
(@internal $n:ident, $v3:ty, $t:ident) => { | ||
// `VersionedXcm` doesn't have version 1, so we don't need to handle it. | ||
dastansam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
impl<$t> IntoVersion for $n<$t>{ | ||
fn into_version(self, n: Version) -> Result<Self, ()> { | ||
Ok(match n { | ||
2 => Self::V2(self.try_into()?), | ||
3 => Self::V3(self.try_into()?), | ||
4 => Self::V4(self.try_into()?), | ||
_ => return Err(()), | ||
}) | ||
} | ||
} | ||
}; | ||
($(#[$attr:meta])* pub enum $n:ident { | ||
$(#[$index3:meta])+ | ||
V3($v3:ty), | ||
|
@@ -176,7 +207,7 @@ macro_rules! versioned_type { | |
} | ||
}; | ||
|
||
($(#[$attr:meta])* pub enum $n:ident { | ||
($(#[$attr:meta])* pub enum $n:ident $(<$($gen:ident)*>)?{ | ||
$(#[$index2:meta])+ | ||
V2($v2:ty), | ||
$(#[$index3:meta])+ | ||
|
@@ -193,68 +224,59 @@ macro_rules! versioned_type { | |
)] | ||
#[codec(encode_bound())] | ||
#[codec(decode_bound())] | ||
$(#[scale_info(bounds(), skip_type_params($($gen)+))])? | ||
#[scale_info(replace_segment("staging_xcm", "xcm"))] | ||
$(#[$attr])* | ||
pub enum $n { | ||
pub enum $n $(<$($gen),+>)? { | ||
$(#[$index2])* | ||
V2($v2), | ||
$(#[$index3])* | ||
V3($v3), | ||
$(#[$index4])* | ||
V4($v4), | ||
} | ||
impl $n { | ||
impl$(<$($gen),+>)? $n $(<$($gen),+>)? { | ||
dastansam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub fn try_as<T>(&self) -> Result<&T, ()> where Self: TryAs<T> { | ||
<Self as TryAs<T>>::try_as(&self) | ||
} | ||
} | ||
impl TryAs<$v2> for $n { | ||
impl$(<$($gen),+>)? TryAs<$v2> for $n $(<$($gen),+>)?{ | ||
fn try_as(&self) -> Result<&$v2, ()> { | ||
match &self { | ||
Self::V2(ref x) => Ok(x), | ||
_ => Err(()), | ||
} | ||
} | ||
} | ||
impl TryAs<$v3> for $n { | ||
impl$(<$($gen),+>)? TryAs<$v3> for $n $(<$($gen),+>)?{ | ||
fn try_as(&self) -> Result<&$v3, ()> { | ||
match &self { | ||
Self::V3(ref x) => Ok(x), | ||
_ => Err(()), | ||
} | ||
} | ||
} | ||
impl TryAs<$v4> for $n { | ||
impl$(<$($gen),+>)? TryAs<$v4> for $n $(<$($gen),+>)? { | ||
fn try_as(&self) -> Result<&$v4, ()> { | ||
match &self { | ||
Self::V4(ref x) => Ok(x), | ||
_ => Err(()), | ||
} | ||
} | ||
} | ||
impl IntoVersion for $n { | ||
fn into_version(self, n: Version) -> Result<Self, ()> { | ||
Ok(match n { | ||
1 | 2 => Self::V2(self.try_into()?), | ||
3 => Self::V3(self.try_into()?), | ||
4 => Self::V4(self.try_into()?), | ||
_ => return Err(()), | ||
}) | ||
} | ||
} | ||
impl From<$v2> for $n { | ||
impl$(<$($gen),+>)? From<$v2> for $n $(<$($gen),+>)? { | ||
fn from(x: $v2) -> Self { | ||
$n::V2(x) | ||
} | ||
} | ||
impl<T: Into<$v4>> From<T> for $n { | ||
impl<$($($gen,),+)? T: Into<$v4>> From<T> for $n $(<$($gen),+>)? { | ||
fn from(x: T) -> Self { | ||
$n::V4(x.into()) | ||
} | ||
} | ||
impl TryFrom<$n> for $v2 { | ||
impl$(<$($gen),+>)?TryFrom<$n $(<$($gen),+>)?> for $v2 { | ||
type Error = (); | ||
fn try_from(x: $n) -> Result<Self, ()> { | ||
fn try_from(x: $n $(<$($gen),+>)?) -> Result<Self, ()> { | ||
use $n::*; | ||
match x { | ||
V2(x) => Ok(x), | ||
|
@@ -266,9 +288,9 @@ macro_rules! versioned_type { | |
} | ||
} | ||
} | ||
impl TryFrom<$n> for $v3 { | ||
impl$(<$($gen),+>)? TryFrom<$n $(<$($gen),+>)?> for $v3 { | ||
type Error = (); | ||
fn try_from(x: $n) -> Result<Self, ()> { | ||
fn try_from(x: $n $(<$($gen),+>)?) -> Result<Self, ()> { | ||
use $n::*; | ||
match x { | ||
V2(x) => x.try_into(), | ||
|
@@ -277,9 +299,9 @@ macro_rules! versioned_type { | |
} | ||
} | ||
} | ||
impl TryFrom<$n> for $v4 { | ||
impl$(<$($gen),+>)?TryFrom<$n $(<$($gen),+>)?> for $v4 { | ||
type Error = (); | ||
fn try_from(x: $n) -> Result<Self, ()> { | ||
fn try_from(x: $n $(<$($gen),+>)?) -> Result<Self, ()> { | ||
use $n::*; | ||
match x { | ||
V2(x) => { | ||
|
@@ -291,12 +313,8 @@ macro_rules! versioned_type { | |
} | ||
} | ||
} | ||
impl MaxEncodedLen for $n { | ||
fn max_encoded_len() -> usize { | ||
<$v3>::max_encoded_len() | ||
} | ||
} | ||
impl IdentifyVersion for $n { | ||
versioned_type!(@internal $n, $v3, $($($gen),+)?); | ||
impl$(<$($gen),+>)? IdentifyVersion for $n $(<$($gen),+>)? { | ||
fn identify_version(&self) -> Version { | ||
use $n::*; | ||
match self { | ||
|
@@ -416,40 +434,14 @@ versioned_type! { | |
#[deprecated(note = "Use `VersionedAssets` instead")] | ||
pub type VersionedMultiAssets = VersionedAssets; | ||
|
||
/// A single XCM message, together with its version code. | ||
#[derive(Derivative, Encode, Decode, TypeInfo)] | ||
#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] | ||
#[codec(encode_bound())] | ||
#[codec(decode_bound())] | ||
#[scale_info(bounds(), skip_type_params(RuntimeCall))] | ||
#[scale_info(replace_segment("staging_xcm", "xcm"))] | ||
pub enum VersionedXcm<RuntimeCall> { | ||
#[codec(index = 2)] | ||
V2(v2::Xcm<RuntimeCall>), | ||
#[codec(index = 3)] | ||
V3(v3::Xcm<RuntimeCall>), | ||
#[codec(index = 4)] | ||
V4(v4::Xcm<RuntimeCall>), | ||
} | ||
|
||
impl<C> IntoVersion for VersionedXcm<C> { | ||
fn into_version(self, n: Version) -> Result<Self, ()> { | ||
Ok(match n { | ||
2 => Self::V2(self.try_into()?), | ||
3 => Self::V3(self.try_into()?), | ||
4 => Self::V4(self.try_into()?), | ||
_ => return Err(()), | ||
}) | ||
} | ||
} | ||
|
||
impl<C> IdentifyVersion for VersionedXcm<C> { | ||
fn identify_version(&self) -> Version { | ||
match self { | ||
Self::V2(_) => v2::VERSION, | ||
Self::V3(_) => v3::VERSION, | ||
Self::V4(_) => v4::VERSION, | ||
} | ||
versioned_type! { | ||
pub enum VersionedXcm<RuntimeCall> { | ||
#[codec(index = 2)] | ||
V2(v2::Xcm<RuntimeCall>), | ||
#[codec(index = 3)] | ||
V3(v3::Xcm<RuntimeCall>), | ||
#[codec(index = 4)] | ||
V4(v4::Xcm<RuntimeCall>), | ||
} | ||
} | ||
|
||
|
@@ -470,66 +462,12 @@ impl<C> VersionedXcm<C> { | |
} | ||
} | ||
|
||
impl<RuntimeCall> From<v2::Xcm<RuntimeCall>> for VersionedXcm<RuntimeCall> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Beautiful |
||
fn from(x: v2::Xcm<RuntimeCall>) -> Self { | ||
VersionedXcm::V2(x) | ||
} | ||
} | ||
|
||
impl<RuntimeCall> From<v3::Xcm<RuntimeCall>> for VersionedXcm<RuntimeCall> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this staying? |
||
fn from(x: v3::Xcm<RuntimeCall>) -> Self { | ||
VersionedXcm::V3(x) | ||
} | ||
} | ||
|
||
impl<RuntimeCall> From<v4::Xcm<RuntimeCall>> for VersionedXcm<RuntimeCall> { | ||
fn from(x: v4::Xcm<RuntimeCall>) -> Self { | ||
VersionedXcm::V4(x) | ||
} | ||
} | ||
|
||
impl<RuntimeCall> TryFrom<VersionedXcm<RuntimeCall>> for v2::Xcm<RuntimeCall> { | ||
type Error = (); | ||
fn try_from(x: VersionedXcm<RuntimeCall>) -> Result<Self, ()> { | ||
use VersionedXcm::*; | ||
match x { | ||
V2(x) => Ok(x), | ||
V3(x) => x.try_into(), | ||
V4(x) => { | ||
let v3: v3::Xcm<RuntimeCall> = x.try_into()?; | ||
v3.try_into() | ||
}, | ||
} | ||
} | ||
} | ||
|
||
impl<Call> TryFrom<VersionedXcm<Call>> for v3::Xcm<Call> { | ||
type Error = (); | ||
fn try_from(x: VersionedXcm<Call>) -> Result<Self, ()> { | ||
use VersionedXcm::*; | ||
match x { | ||
V2(x) => x.try_into(), | ||
V3(x) => Ok(x), | ||
V4(x) => x.try_into(), | ||
} | ||
} | ||
} | ||
|
||
impl<Call> TryFrom<VersionedXcm<Call>> for v4::Xcm<Call> { | ||
type Error = (); | ||
fn try_from(x: VersionedXcm<Call>) -> Result<Self, ()> { | ||
use VersionedXcm::*; | ||
match x { | ||
V2(x) => { | ||
let v3: v3::Xcm<Call> = x.try_into()?; | ||
v3.try_into() | ||
}, | ||
V3(x) => x.try_into(), | ||
V4(x) => Ok(x), | ||
} | ||
} | ||
} | ||
|
||
/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `Location` which will | ||
/// interpret it. | ||
pub trait WrapVersion { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 | ||
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json | ||
|
||
title: "Use `versioned_type!` macro for `VersionedXcm`" | ||
|
||
doc: | ||
- audience: Runtime Dev | ||
description: | | ||
Currently, all other versioned types in the `stagin-xcm` are created using `versioned_type!` macro, except for `VersionedXcm`. | ||
franciscoaguirre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This PR adds changes `versioned_type` macro so that it can be used for `VersionedXcm` as well. This is done by adding optional | ||
franciscoaguirre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
generic type param to an enum that is passed to the macro. | ||
|
||
crates: | ||
- name: staging-xcm | ||
bump: minor | ||
bkchr marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes no sense that this is separate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MaxEncodedLen
is not implemented forXcm
structs ofVersionedXcm
, so impl it fails. This is a workaround I did to excludeVersionedXcm
from it implementingMaxEncodedLen
. Open to suggestions for a more idiomatic way of handling it