mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
XCM v2: Scripting, Query responses, Exception handling and Error reporting (#3629)
* Intoduce XCM v2 Also some minor fix for v0/v1 * Minor version cleanup * Minor version cleanup * Introduce SendError for XcmSend trait to avoid cycles with having Outcome in Xcm * comment * Corrent type * Docs * Fix build * Fixes * Introduce the basic impl * Docs * Add function * Basic implementation * Weighed responses and on_report * Make XCM more script-like * Remove BuyExecution::orders * Fixes * Fixes * Fixes * Formatting * Initial draft and make pallet-xcm build * fix XCM tests * Formatting * Fixes * Formatting * spelling * Fixes * Fixes * spelling * tests for translation * extra fields to XCM pallet * Formatting * Fixes * spelling * first integration test * Another integration test * Formatting * fix tests * all tests * Fixes * Fixes * Formatting * Fixes * Fixes * Formatting * Bump * Remove unneeded structuring * add instruction * Fixes * spelling * Fixes * Fixes * Formatting * Fixes * Fixes * Formatting * Introduce and use VersionedResponse * Introduce versioning to dispatchables' params * Fixes * Formatting * Rest of merge * more work * Formatting * Basic logic * Fixes * Fixes * Add test * Fixes * Formatting * Fixes * Fixes * Fixes * Nits * Simplify * Spelling * Formatting * Return weight of unexecuted instructions in case of error as surplus * Formatting * Fixes * Test for instruction count limiting * Formatting * Docs
This commit is contained in:
@@ -14,11 +14,12 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::mock::*;
|
||||
use crate::{mock::*, QueryStatus};
|
||||
use frame_support::{assert_noop, assert_ok, traits::Currency};
|
||||
use polkadot_parachain::primitives::{AccountIdConversion, Id as ParaId};
|
||||
use std::convert::TryInto;
|
||||
use xcm::{v1::prelude::*, VersionedXcm};
|
||||
use xcm::{latest::prelude::*, VersionedXcm};
|
||||
use xcm_executor::XcmExecutor;
|
||||
|
||||
const ALICE: AccountId = AccountId::new([0u8; 32]);
|
||||
const BOB: AccountId = AccountId::new([1u8; 32]);
|
||||
@@ -26,6 +27,111 @@ const PARA_ID: u32 = 2000;
|
||||
const INITIAL_BALANCE: u128 = 100;
|
||||
const SEND_AMOUNT: u128 = 10;
|
||||
|
||||
#[test]
|
||||
fn report_outcome_notify_works() {
|
||||
let balances =
|
||||
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||
let sender = AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
|
||||
let mut message = Xcm(vec![TransferAsset {
|
||||
assets: (Here, SEND_AMOUNT).into(),
|
||||
beneficiary: sender.clone(),
|
||||
}]);
|
||||
let call = pallet_test_notifier::Call::notification_received(0, Default::default());
|
||||
let notify = Call::TestNotifier(call);
|
||||
new_test_ext_with_balances(balances).execute_with(|| {
|
||||
XcmPallet::report_outcome_notify(&mut message, Parachain(PARA_ID).into(), notify, 100);
|
||||
assert_eq!(
|
||||
message,
|
||||
Xcm(vec![
|
||||
SetAppendix(Xcm(vec![ReportError {
|
||||
query_id: 0,
|
||||
dest: Parent.into(),
|
||||
max_response_weight: 1_000_000
|
||||
},])),
|
||||
TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender.clone() },
|
||||
])
|
||||
);
|
||||
let status = QueryStatus::Pending {
|
||||
responder: MultiLocation::from(Parachain(PARA_ID)).into(),
|
||||
maybe_notify: Some((4, 2)),
|
||||
timeout: 100,
|
||||
};
|
||||
assert_eq!(crate::Queries::<Test>::iter().collect::<Vec<_>>(), vec![(0, status)]);
|
||||
|
||||
let r = XcmExecutor::<XcmConfig>::execute_xcm(
|
||||
Parachain(PARA_ID).into(),
|
||||
Xcm(vec![QueryResponse {
|
||||
query_id: 0,
|
||||
response: Response::ExecutionResult(Ok(())),
|
||||
max_weight: 1_000_000,
|
||||
}]),
|
||||
1_000_000_000,
|
||||
);
|
||||
assert_eq!(r, Outcome::Complete(1_000));
|
||||
assert_eq!(
|
||||
last_events(2),
|
||||
vec![
|
||||
Event::TestNotifier(pallet_test_notifier::Event::ResponseReceived(
|
||||
Parachain(PARA_ID).into(),
|
||||
0,
|
||||
Response::ExecutionResult(Ok(())),
|
||||
)),
|
||||
Event::XcmPallet(crate::Event::Notified(0, 4, 2)),
|
||||
]
|
||||
);
|
||||
assert_eq!(crate::Queries::<Test>::iter().collect::<Vec<_>>(), vec![]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn report_outcome_works() {
|
||||
let balances =
|
||||
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||
let sender = AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
|
||||
let mut message = Xcm(vec![TransferAsset {
|
||||
assets: (Here, SEND_AMOUNT).into(),
|
||||
beneficiary: sender.clone(),
|
||||
}]);
|
||||
new_test_ext_with_balances(balances).execute_with(|| {
|
||||
XcmPallet::report_outcome(&mut message, Parachain(PARA_ID).into(), 100);
|
||||
assert_eq!(
|
||||
message,
|
||||
Xcm(vec![
|
||||
SetAppendix(Xcm(vec![ReportError {
|
||||
query_id: 0,
|
||||
dest: Parent.into(),
|
||||
max_response_weight: 0
|
||||
},])),
|
||||
TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender.clone() },
|
||||
])
|
||||
);
|
||||
let status = QueryStatus::Pending {
|
||||
responder: MultiLocation::from(Parachain(PARA_ID)).into(),
|
||||
maybe_notify: None,
|
||||
timeout: 100,
|
||||
};
|
||||
assert_eq!(crate::Queries::<Test>::iter().collect::<Vec<_>>(), vec![(0, status)]);
|
||||
|
||||
let r = XcmExecutor::<XcmConfig>::execute_xcm(
|
||||
Parachain(PARA_ID).into(),
|
||||
Xcm(vec![QueryResponse {
|
||||
query_id: 0,
|
||||
response: Response::ExecutionResult(Ok(())),
|
||||
max_weight: 0,
|
||||
}]),
|
||||
1_000_000_000,
|
||||
);
|
||||
assert_eq!(r, Outcome::Complete(1_000));
|
||||
assert_eq!(
|
||||
last_event(),
|
||||
Event::XcmPallet(crate::Event::ResponseReady(0, Response::ExecutionResult(Ok(())),))
|
||||
);
|
||||
|
||||
let response = Some((Response::ExecutionResult(Ok(())), 1));
|
||||
assert_eq!(XcmPallet::take_response(0), response);
|
||||
});
|
||||
}
|
||||
|
||||
/// Test sending an `XCM` message (`XCM::ReserveAssetDeposit`)
|
||||
///
|
||||
/// Asserts that the expected message is sent and the event is emitted
|
||||
@@ -34,30 +140,26 @@ fn send_works() {
|
||||
let balances =
|
||||
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||
new_test_ext_with_balances(balances).execute_with(|| {
|
||||
let weight = 2 * BaseXcmWeight::get();
|
||||
let sender: MultiLocation =
|
||||
AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
|
||||
let message = Xcm::ReserveAssetDeposited {
|
||||
assets: (Parent, SEND_AMOUNT).into(),
|
||||
effects: vec![
|
||||
buy_execution((Parent, SEND_AMOUNT), weight),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
|
||||
],
|
||||
};
|
||||
assert_ok!(XcmPallet::send(
|
||||
Origin::signed(ALICE),
|
||||
Box::new(RelayLocation::get().into()),
|
||||
Box::new(VersionedXcm::from(message.clone()))
|
||||
));
|
||||
let message = Xcm(vec![
|
||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
||||
ClearOrigin,
|
||||
buy_execution((Parent, SEND_AMOUNT)),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
|
||||
]);
|
||||
let versioned_dest = Box::new(RelayLocation::get().into());
|
||||
let versioned_message = Box::new(VersionedXcm::from(message.clone()));
|
||||
assert_ok!(XcmPallet::send(Origin::signed(ALICE), versioned_dest, versioned_message));
|
||||
assert_eq!(
|
||||
sent_xcm(),
|
||||
vec![(
|
||||
Here.into(),
|
||||
RelayedFrom {
|
||||
who: sender.clone().try_into().unwrap(),
|
||||
message: Box::new(message.clone()),
|
||||
}
|
||||
)]
|
||||
Xcm(Some(DescendOrigin(sender.clone().try_into().unwrap()))
|
||||
.into_iter()
|
||||
.chain(message.0.clone().into_iter())
|
||||
.collect())
|
||||
)],
|
||||
);
|
||||
assert_eq!(
|
||||
last_event(),
|
||||
@@ -75,16 +177,13 @@ fn send_fails_when_xcm_router_blocks() {
|
||||
let balances =
|
||||
vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)];
|
||||
new_test_ext_with_balances(balances).execute_with(|| {
|
||||
let weight = 2 * BaseXcmWeight::get();
|
||||
let sender: MultiLocation =
|
||||
Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
|
||||
let message = Xcm::ReserveAssetDeposited {
|
||||
assets: (Parent, SEND_AMOUNT).into(),
|
||||
effects: vec![
|
||||
buy_execution((Parent, SEND_AMOUNT), weight),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
|
||||
],
|
||||
};
|
||||
let message = Xcm(vec![
|
||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
||||
buy_execution((Parent, SEND_AMOUNT)),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
|
||||
]);
|
||||
assert_noop!(
|
||||
XcmPallet::send(
|
||||
Origin::signed(ALICE),
|
||||
@@ -113,7 +212,6 @@ fn teleport_assets_works() {
|
||||
Box::new(AccountId32 { network: Any, id: BOB.into() }.into().into()),
|
||||
Box::new((Here, SEND_AMOUNT).into()),
|
||||
0,
|
||||
weight,
|
||||
));
|
||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
||||
assert_eq!(
|
||||
@@ -142,7 +240,6 @@ fn reserve_transfer_assets_works() {
|
||||
Box::new(dest.clone().into()),
|
||||
Box::new((Here, SEND_AMOUNT).into()),
|
||||
0,
|
||||
weight
|
||||
));
|
||||
// Alice spent amount
|
||||
assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
||||
@@ -153,13 +250,12 @@ fn reserve_transfer_assets_works() {
|
||||
sent_xcm(),
|
||||
vec![(
|
||||
Parachain(PARA_ID).into(),
|
||||
Xcm::ReserveAssetDeposited {
|
||||
assets: (Parent, SEND_AMOUNT).into(),
|
||||
effects: vec![
|
||||
buy_execution((Parent, SEND_AMOUNT), weight),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||
]
|
||||
}
|
||||
Xcm(vec![
|
||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
||||
ClearOrigin,
|
||||
buy_execution((Parent, SEND_AMOUNT)),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||
]),
|
||||
)]
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -184,13 +280,11 @@ fn execute_withdraw_to_deposit_works() {
|
||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
||||
assert_ok!(XcmPallet::execute(
|
||||
Origin::signed(ALICE),
|
||||
Box::new(VersionedXcm::from(Xcm::WithdrawAsset {
|
||||
assets: (Here, SEND_AMOUNT).into(),
|
||||
effects: vec![
|
||||
buy_execution((Here, SEND_AMOUNT), weight),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }
|
||||
],
|
||||
})),
|
||||
Box::new(VersionedXcm::from(Xcm(vec![
|
||||
WithdrawAsset((Here, SEND_AMOUNT).into()),
|
||||
buy_execution((Here, SEND_AMOUNT)),
|
||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||
]))),
|
||||
weight
|
||||
));
|
||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
||||
|
||||
Reference in New Issue
Block a user