Skip to content

Commit

Permalink
allow clear_origin in safe xcm builder (paritytech#4777)
Browse files Browse the repository at this point in the history
Fixes paritytech#3770 

Added `clear_origin` as an allowed command after commands that load the
holdings register, in the safe xcm builder.

Checklist
- [x] My PR includes a detailed description as outlined in the
"Description" section above
- [x] My PR follows the [labeling
requirements](https://github.com/paritytech/polkadot-sdk/blob/master/docs/contributor/CONTRIBUTING.md#Process)
of this project (at minimum one label for T required)
- [x] I have made corresponding changes to the documentation (if
applicable)
- [x] I have added tests that prove my fix is effective or that my
feature works (if applicable)

---------

Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
Co-authored-by: gupnik <mail.guptanikhil@gmail.com>
  • Loading branch information
3 people authored and TomaszWaszczyk committed Jul 13, 2024
1 parent 3a0bc2c commit f07463e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
27 changes: 27 additions & 0 deletions polkadot/xcm/procedural/src/builder_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,32 @@ fn generate_builder_impl(name: &Ident, data_enum: &DataEnum) -> Result<TokenStre
}
};

// Some operations are allowed after the holding register is loaded
let allowed_after_load_holding_methods: Vec<TokenStream2> = data_enum
.variants
.iter()
.filter(|variant| variant.ident == "ClearOrigin")
.map(|variant| {
let variant_name = &variant.ident;
let method_name_string = &variant_name.to_string().to_snake_case();
let method_name = syn::Ident::new(method_name_string, variant_name.span());
let docs = get_doc_comments(variant);
let method = match &variant.fields {
Fields::Unit => {
quote! {
#(#docs)*
pub fn #method_name(mut self) -> XcmBuilder<Call, LoadedHolding> {
self.instructions.push(#name::<Call>::#variant_name);
self
}
}
},
_ => return Err(Error::new_spanned(variant, "ClearOrigin should have no fields")),
};
Ok(method)
})
.collect::<std::result::Result<Vec<_>, _>>()?;

// Then we require fees to be paid
let buy_execution_method = data_enum
.variants
Expand Down Expand Up @@ -276,6 +302,7 @@ fn generate_builder_impl(name: &Ident, data_enum: &DataEnum) -> Result<TokenStre

let second_impl = quote! {
impl<Call> XcmBuilder<Call, LoadedHolding> {
#(#allowed_after_load_holding_methods)*
#buy_execution_method
}
};
Expand Down
21 changes: 21 additions & 0 deletions polkadot/xcm/procedural/tests/builder_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,24 @@ fn default_builder_requires_buy_execution() {
])
);
}

#[test]
fn default_builder_allows_clear_origin_before_buy_execution() {
let asset: Asset = (Here, 100u128).into();
let beneficiary: Location = [0u8; 32].into();
let message: Xcm<()> = Xcm::builder()
.receive_teleported_asset(asset.clone())
.clear_origin()
.buy_execution(asset.clone(), Unlimited)
.deposit_asset(asset.clone(), beneficiary.clone())
.build();
assert_eq!(
message,
Xcm(vec![
ReceiveTeleportedAsset(asset.clone().into()),
ClearOrigin,
BuyExecution { fees: asset.clone(), weight_limit: Unlimited },
DepositAsset { assets: asset.into(), beneficiary },
])
);
}
27 changes: 27 additions & 0 deletions prdoc/pr_4777.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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: XCM builder pattern allows clear_origin before buy_execution.

doc:
- audience: Runtime Dev
description: |
Added clear_origin as an allowed command after commands that load the holdings register, in the safe xcm builder.
Previously, although it's logically allowed, an XCM could not be built like this:
```rust
let xcm = Xcm::builder()
.withdraw_asset((Parent, 100u128))
.clear_origin()
.buy_execution((Parent, 1u128))
.deposit_asset(All, [0u8; 32])
.build();
```
You had to use the unsafe_builder.
Now, it's allowed using the default builder.

crates:
- name: "xcm-procedural"
bump: minor
- name: "staging-xcm"
bump: minor

0 comments on commit f07463e

Please sign in to comment.