Make AssetId and MultiLocation non-Copy; make Instruction 92% smaller#7236
Make AssetId and MultiLocation non-Copy; make Instruction 92% smaller#7236koute wants to merge 1 commit intoparitytech:masterfrom
AssetId and MultiLocation non-Copy; make Instruction 92% smaller#7236Conversation
| type IntoIter = JunctionsIterator; | ||
| fn into_iter(self) -> Self::IntoIter { | ||
| JunctionsIterator(self) | ||
| JunctionsIterator { range: 0..self.len(), junctions: self } |
There was a problem hiding this comment.
would be nice if arg order was switched: junctions, range so it's the same as JunctionsRefIterator above
There was a problem hiding this comment.
This is deliberate. The arg order must be like this because self is moved into JunctionsIterator, and once you move it you can't call self.len().
gilescope
left a comment
There was a problem hiding this comment.
On the whole I really like this.
| pub struct OnlyParachains; | ||
| impl Contains<MultiLocation> for OnlyParachains { | ||
| fn contains(loc: &MultiLocation) -> bool { | ||
| matches!(loc.unpack(), (0, [Parachain(_)])) | ||
| } | ||
| } | ||
|
|
||
| pub struct CollectivesOrFellows; | ||
| impl Contains<MultiLocation> for CollectivesOrFellows { | ||
| fn contains(loc: &MultiLocation) -> bool { | ||
| matches!(loc.unpack(), |(0, [Parachain(COLLECTIVES_ID)])| ( | ||
| 0, | ||
| [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }] | ||
| )) | ||
| } |
There was a problem hiding this comment.
I'd prefer to keep the declarative syntax. As a rule, top-level runtime files should not contain procedural code.
gavofyork
left a comment
There was a problem hiding this comment.
Generally looks like a reasonable direction (modulo the comment).
This should probably go in XCMv4 though since it's a major API breakage.
@gavofyork Hm... well, although it is a source-level API breakage the ABI will stay the same ( I'm not saying we shouldn't care about API-level backwards compatibility, we definitely should, however in my opinion fixing this is worth the API breakage. Having such huge types is a potential performance trap and risks triggering bugs like these not only in our code but in our users' code. So personally I would suggest landing this and, if we're worried about how it will affect downstream users, I could maybe write a migration guide explaining how to update the code to the new API (which is fairly easy, albeit maybe somewhat tedious) and we'd attach that to the release notes? But it is up to you; if you don't want to break the API then I can update this PR to only include non-breaking changes in preparation for V4, but obviously this won't fix the underlying issue, just make it easier to do this when V4 lands. |
|
I note that we currently need to box |
|
This pull request has been mentioned on Polkadot Forum. There might be relevant details there: https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-43/3158/3 |
|
I think it's best to do this on XCMv4. While it's true the binary interface didn't change, the programming interface did, and it does require some effort by XCM developers to change to the new format. |
|
We might reasonably make XCMv4 an API-only change (for this) and deliver NOW, rather than waiting around indefinitely for the rest of v4 to materialize. The new instructions can be done as a v5. |
|
Okay, so just to clarify: release v4 now containing this change, and retarget all existing RFCs to v5? Sounds like we should also pair it with some renaming changes. In any case, this means that this PR needs to create a new folder for v4 and make the changes there, rather than modifying existing v2 and v3 type definitions. |
This PR makes the following changes:
AssetId,MultiLocation,Junctionsare notCopyanymore and need to be explicitlyclone()'d.The sizes of XCM types are now drastically reduced.
Before:
After:
The
Junctionstype is now internally boxed, or more specificallyArc'd, and acts in a copy-on-write fashion. This makes it cheaper to clone (now it only has to bump the refcount instead of copying over half a kilobyte).The canonical way of constructing a
Junctionsis now through a conversion from an array.Before:
let xs = Junctions::X2(OnlyChild, OnlyChild)After:
let xs: Junctions = [OnlyChild, OnlyChild].into()Since Rust doesn't (yet) support pattern matching of boxed values this makes it not possible to directly match on them, however this can be worked around by converting the internal
Junctionsinto a slice and matching on that, for example:Before:
After:
A few of some of the previously
constfunctions and statics were made not-constsince anArccannot be constructed in aconstcontext.Potential open questions
Junctionstype completely opaque? There might not be much of a point in keeping it as an enum now, since you can't directly match on it anyway. (Although this could potentially change in the future when Rust will support matching of boxed values.)Junctions::unpackreturning a tuple, or perhaps introduce aJunctionsReftype so that the parameters are named when matching?(This still needs a Cumulus companion, which I will add once paritytech/substrate#14158 is merged.)