From 1e96eb4d202500c1ec9b226da7ca2033540c29dc Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Thu, 22 Jun 2023 08:31:24 -0300 Subject: [PATCH 1/5] RFC: WithPushedOrigin instruction --- proposals/0000-with-pushed-origin.md | 95 ++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 proposals/0000-with-pushed-origin.md diff --git a/proposals/0000-with-pushed-origin.md b/proposals/0000-with-pushed-origin.md new file mode 100644 index 0000000..a78f78b --- /dev/null +++ b/proposals/0000-with-pushed-origin.md @@ -0,0 +1,95 @@ +--- +Title: WithPushedOrigin instruction +Number: 0 +Status: Draft +Version: 0 +Authors: + - Francisco Aguirre +Created: 2023-06-21 +Impact: Low +Requires: +Replaces: +--- + +## Summary + +The proposed change is the introduction of a `WithPushedOrigin` instruction. +The instruction allows the XCVM to "push" a new origin for just a few instructions and then return to the original origin when those instructions are done. +It can be seen as pushing a new origin on a stack for the execution of a block of instructions and then popping it back when the block is done. +The new origin can only be empty (clear the origin) or a child of the current origin. + +The goal is to give developers more flexibility and a better experience when handling origins in their messages. + +## Motivation + +Right now, XCM has two instructions for modifying the origin: `ClearOrigin` and `DescendOrigin`. +These work for manipulating the origins in safe ways. +However, these instructions are final, once you use them, there's no standard way of going back to the original origin. +This results in a complicated developer experience, where the order of operations needs to be highly taken into account to perform the operations needed, with the correct origins for each. + +This new instruction, `WithPushedOrigin`, provides a way of pushing an origin and popping to return to the original one. +It makes scenarios where multiple operations need to be performed by multiple origins much easier to do. +It gives a standard way of doing things like buying execution from a user's account and then returning to the previous origin to perform other operations that require the priviledges associated with it. +It also allows for previously impossible scenarios like acting on behalf of many sibling origins. + +## Specification + +The instruction looks like this: + +```rust +WithPushedOrigin { origin: Option, xcm: Xcm } +``` + +If the `pushed_origin` is `None`, then `ClearOrigin` will be called before executing the inner `xcm`. +The previous origin will be restored once the inner `xcm` has finished executing. + +If the `pushed_origin` is `Some(interior_location)`, then `DescendOrigin(interior_location)` will be called before executing the inner `xcm`. +The previous origin will be restored once the inner `xcm` has finished executing. + +### Examples + +#### Clearing the origin + +```rust +// Withdraw assets from the origin +WithdrawAsset(/* ...snip... */); +WithClearOrigin { + origin: None, + xcm: Xcm(vec![ + // Deposit assets without an origin + DepositAsset { /* ...snip... */ } + ]), +} +``` + +#### Buying execution with an account + +```rust +/* Origin: ../Parachain(1000) */ + +WithClearOrigin { + origin: Some(AccountId32 { /* ...snip... */ }), + xcm: Xcm(vec![ + BuyExecution { /* ...snip... */ }, + ].into()), +} +// Transact with the parachain origin +Transact { + origin_kind: OriginKind::SovereignAccount, + /* ...snip... */ +} +``` + +## Security considerations + +This instruction does not allow for arbitrary origin manipulation, which would be a serious issue. +It only mixes the current `DescendOrigin` and `ClearOrigin` instructions in an easier-to-use way. + +## Impact + +The impact is Low since it introduces a new instruction. XCVM implementations would need to be updated. + +## Alternatives + +The alternative right now is to use `ClearOrigin` or `DescendOrigin` by themselves, which depends on the order of operations, which is subject to barriers. +There are some situations that are impossible to express without this new instruction, like dealing with multiple sibling origins. From 6b8a3316f2dab72cac495902c9e9e076e58800a0 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Fri, 23 Jun 2023 12:36:51 -0300 Subject: [PATCH 2/5] Address feedback --- proposals/0000-with-pushed-origin.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/proposals/0000-with-pushed-origin.md b/proposals/0000-with-pushed-origin.md index a78f78b..3d2b078 100644 --- a/proposals/0000-with-pushed-origin.md +++ b/proposals/0000-with-pushed-origin.md @@ -22,7 +22,7 @@ The goal is to give developers more flexibility and a better experience when han ## Motivation -Right now, XCM has two instructions for modifying the origin: `ClearOrigin` and `DescendOrigin`. +Right now, XCM has three instructions for modifying the origin: `AliasOrigin`, `ClearOrigin` and `DescendOrigin`. These work for manipulating the origins in safe ways. However, these instructions are final, once you use them, there's no standard way of going back to the original origin. This results in a complicated developer experience, where the order of operations needs to be highly taken into account to perform the operations needed, with the correct origins for each. @@ -53,7 +53,7 @@ The previous origin will be restored once the inner `xcm` has finished executing ```rust // Withdraw assets from the origin WithdrawAsset(/* ...snip... */); -WithClearOrigin { +WithPushedOrigin { origin: None, xcm: Xcm(vec![ // Deposit assets without an origin @@ -67,7 +67,7 @@ WithClearOrigin { ```rust /* Origin: ../Parachain(1000) */ -WithClearOrigin { +WithPushedOrigin { origin: Some(AccountId32 { /* ...snip... */ }), xcm: Xcm(vec![ BuyExecution { /* ...snip... */ }, @@ -80,6 +80,28 @@ Transact { } ``` +#### Acting on behalf of two sibling accounts + +Here we withdraw some assets from two different accounts and then deposit them into another account. + +```rust +/* Origin: ../Parachain(1000) */ + +WithPushedOrigin { + origin: Some(AccountId32 { /* First account */ }), + xcm: Xcm(vec![ + WithdrawAsset(/* ...snip... */), + ].into()), +} +WithPushedOrigin { + origin: Some(AccountId32 { /* Second account */ }), + xcm: Xcm(vec![ + WithdrawAsset(/* ...snip... */), + ].into()), +} +DepositAsset { /* Third account */ } +``` + ## Security considerations This instruction does not allow for arbitrary origin manipulation, which would be a serious issue. From 3247d2104b92ecf09eab52ed6aa9e455f85f0ea5 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Fri, 23 Jun 2023 12:49:19 -0300 Subject: [PATCH 3/5] Rephrase summary --- proposals/0000-with-pushed-origin.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/0000-with-pushed-origin.md b/proposals/0000-with-pushed-origin.md index 3d2b078..a4dd621 100644 --- a/proposals/0000-with-pushed-origin.md +++ b/proposals/0000-with-pushed-origin.md @@ -22,8 +22,7 @@ The goal is to give developers more flexibility and a better experience when han ## Motivation -Right now, XCM has three instructions for modifying the origin: `AliasOrigin`, `ClearOrigin` and `DescendOrigin`. -These work for manipulating the origins in safe ways. +Right now, XCM has some good instructions for manipulating the origin during execution in same ways, like `ClearOrigin` and `DescendOrigin`. However, these instructions are final, once you use them, there's no standard way of going back to the original origin. This results in a complicated developer experience, where the order of operations needs to be highly taken into account to perform the operations needed, with the correct origins for each. From f4690eec39a75eb73b418d3f7b3f77b6e63837f5 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Thu, 3 Aug 2023 20:03:47 -0300 Subject: [PATCH 4/5] Rename WithPushedOrigin instruction and bump version --- ...-origin.md => 0038-execute-with-origin.md} | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) rename proposals/{0000-with-pushed-origin.md => 0038-execute-with-origin.md} (77%) diff --git a/proposals/0000-with-pushed-origin.md b/proposals/0038-execute-with-origin.md similarity index 77% rename from proposals/0000-with-pushed-origin.md rename to proposals/0038-execute-with-origin.md index a4dd621..18ec8b0 100644 --- a/proposals/0000-with-pushed-origin.md +++ b/proposals/0038-execute-with-origin.md @@ -1,8 +1,8 @@ --- -Title: WithPushedOrigin instruction -Number: 0 +Title: ExecuteWithOrigin instruction +Number: 38 Status: Draft -Version: 0 +Version: 1 Authors: - Francisco Aguirre Created: 2023-06-21 @@ -13,10 +13,10 @@ Replaces: ## Summary -The proposed change is the introduction of a `WithPushedOrigin` instruction. -The instruction allows the XCVM to "push" a new origin for just a few instructions and then return to the original origin when those instructions are done. +The proposed change is the introduction of an `ExecuteWithOrigin` instruction. +The instruction allows the XCVM to execute a few instructions with a particular origin and then return to the original origin when those instructions are done. It can be seen as pushing a new origin on a stack for the execution of a block of instructions and then popping it back when the block is done. -The new origin can only be empty (clear the origin) or a child of the current origin. +The new origin can either be empty (clear the origin) or a child of the current origin. The goal is to give developers more flexibility and a better experience when handling origins in their messages. @@ -26,7 +26,7 @@ Right now, XCM has some good instructions for manipulating the origin during exe However, these instructions are final, once you use them, there's no standard way of going back to the original origin. This results in a complicated developer experience, where the order of operations needs to be highly taken into account to perform the operations needed, with the correct origins for each. -This new instruction, `WithPushedOrigin`, provides a way of pushing an origin and popping to return to the original one. +This new instruction, `ExecuteWithOrigin`, provides a way of executing a set of instructions with a particular origin. It makes scenarios where multiple operations need to be performed by multiple origins much easier to do. It gives a standard way of doing things like buying execution from a user's account and then returning to the previous origin to perform other operations that require the priviledges associated with it. It also allows for previously impossible scenarios like acting on behalf of many sibling origins. @@ -36,13 +36,13 @@ It also allows for previously impossible scenarios like acting on behalf of many The instruction looks like this: ```rust -WithPushedOrigin { origin: Option, xcm: Xcm } +ExecuteWithOrigin { origin: Option, xcm: Xcm } ``` -If the `pushed_origin` is `None`, then `ClearOrigin` will be called before executing the inner `xcm`. +If the `origin` parameter is `None`, then `ClearOrigin` will be called before executing the inner `xcm`. The previous origin will be restored once the inner `xcm` has finished executing. -If the `pushed_origin` is `Some(interior_location)`, then `DescendOrigin(interior_location)` will be called before executing the inner `xcm`. +If the `origin` parameter is `Some(interior_location)`, then `DescendOrigin(interior_location)` will be called before executing the inner `xcm`. The previous origin will be restored once the inner `xcm` has finished executing. ### Examples @@ -52,7 +52,7 @@ The previous origin will be restored once the inner `xcm` has finished executing ```rust // Withdraw assets from the origin WithdrawAsset(/* ...snip... */); -WithPushedOrigin { +ExecuteWithOrigin { origin: None, xcm: Xcm(vec![ // Deposit assets without an origin @@ -66,7 +66,7 @@ WithPushedOrigin { ```rust /* Origin: ../Parachain(1000) */ -WithPushedOrigin { +ExecuteWithOrigin { origin: Some(AccountId32 { /* ...snip... */ }), xcm: Xcm(vec![ BuyExecution { /* ...snip... */ }, @@ -86,13 +86,13 @@ Here we withdraw some assets from two different accounts and then deposit them i ```rust /* Origin: ../Parachain(1000) */ -WithPushedOrigin { +ExecuteWithOrigin { origin: Some(AccountId32 { /* First account */ }), xcm: Xcm(vec![ WithdrawAsset(/* ...snip... */), ].into()), } -WithPushedOrigin { +ExecuteWithOrigin { origin: Some(AccountId32 { /* Second account */ }), xcm: Xcm(vec![ WithdrawAsset(/* ...snip... */), From 6875af398cc90cc6076351494df728f26b4c67d3 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Thu, 3 Aug 2023 20:44:57 -0300 Subject: [PATCH 5/5] Fix XCM version --- proposals/0038-execute-with-origin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0038-execute-with-origin.md b/proposals/0038-execute-with-origin.md index 18ec8b0..5817b8e 100644 --- a/proposals/0038-execute-with-origin.md +++ b/proposals/0038-execute-with-origin.md @@ -2,7 +2,7 @@ Title: ExecuteWithOrigin instruction Number: 38 Status: Draft -Version: 1 +Version: 4 Authors: - Francisco Aguirre Created: 2023-06-21