Skip to content
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

Change XcmDryRunApi::dry_run_extrinsic to take a call instead #4621

Merged
merged 19 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@

use crate::imports::*;

use sp_keyring::AccountKeyring::Alice;
use sp_runtime::{generic, MultiSignature};
use frame_system::RawOrigin;
use xcm_fee_payment_runtime_api::{
dry_run::runtime_decl_for_xcm_dry_run_api::XcmDryRunApiV1,
fees::runtime_decl_for_xcm_payment_api::XcmPaymentApiV1,
Expand All @@ -42,6 +41,7 @@ fn teleport_relay_system_para_works() {
<Westend as TestExt>::new_ext().execute_with(|| {
type Runtime = <Westend as Chain>::Runtime;
type RuntimeCall = <Westend as Chain>::RuntimeCall;
type OriginCaller = <Westend as Chain>::OriginCaller;

let call = RuntimeCall::XcmPallet(pallet_xcm::Call::transfer_assets {
dest: Box::new(VersionedLocation::V4(destination.clone())),
Expand All @@ -50,9 +50,8 @@ fn teleport_relay_system_para_works() {
fee_asset_item: 0,
weight_limit: Unlimited,
});
let sender = Alice; // Is the same as `WestendSender`.
let extrinsic = construct_extrinsic_westend(sender, call);
let result = Runtime::dry_run_extrinsic(extrinsic).unwrap();
let origin = OriginCaller::system(RawOrigin::Signed(WestendSender::get()));
let result = Runtime::dry_run_call(origin, call).unwrap();
assert_eq!(result.forwarded_xcms.len(), 1);
let (destination_to_query, messages_to_query) = &result.forwarded_xcms[0];
assert_eq!(messages_to_query.len(), 1);
Expand Down Expand Up @@ -142,6 +141,7 @@ fn multi_hop_works() {
<PenpalA as TestExt>::execute_with(|| {
type Runtime = <PenpalA as Chain>::Runtime;
type RuntimeCall = <PenpalA as Chain>::RuntimeCall;
type OriginCaller = <PenpalA as Chain>::OriginCaller;

let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::transfer_assets {
dest: Box::new(VersionedLocation::V4(destination.clone())),
Expand All @@ -150,9 +150,8 @@ fn multi_hop_works() {
fee_asset_item: 0,
weight_limit: Unlimited,
});
let sender = Alice; // Same as `PenpalASender`.
let extrinsic = construct_extrinsic_penpal(sender, call);
let result = Runtime::dry_run_extrinsic(extrinsic).unwrap();
let origin = OriginCaller::system(RawOrigin::Signed(PenpalASender::get()));
let result = Runtime::dry_run_call(origin, call).unwrap();
assert_eq!(result.forwarded_xcms.len(), 1);
let (destination_to_query, messages_to_query) = &result.forwarded_xcms[0];
assert_eq!(messages_to_query.len(), 1);
Expand Down Expand Up @@ -304,68 +303,3 @@ fn transfer_assets_para_to_para(test: ParaToParaThroughRelayTest) -> DispatchRes
test.args.weight_limit,
)
}

// Constructs the SignedExtra component of an extrinsic for the Westend runtime.
fn construct_extrinsic_westend(
sender: sp_keyring::AccountKeyring,
call: westend_runtime::RuntimeCall,
) -> westend_runtime::UncheckedExtrinsic {
type Runtime = <Westend as Chain>::Runtime;
let account_id = <Runtime as frame_system::Config>::AccountId::from(sender.public());
let tip = 0;
let extra: westend_runtime::SignedExtra = (
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckMortality::<Runtime>::from(sp_runtime::generic::Era::immortal()),
frame_system::CheckNonce::<Runtime>::from(
frame_system::Pallet::<Runtime>::account(&account_id).nonce,
),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
);
let raw_payload = westend_runtime::SignedPayload::new(call, extra).unwrap();
let signature = raw_payload.using_encoded(|payload| sender.sign(payload));
let (call, extra, _) = raw_payload.deconstruct();
westend_runtime::UncheckedExtrinsic::new_signed(
call,
account_id.into(),
MultiSignature::Sr25519(signature),
extra,
)
}

// Constructs the SignedExtra component of an extrinsic for the Westend runtime.
fn construct_extrinsic_penpal(
sender: sp_keyring::AccountKeyring,
call: penpal_runtime::RuntimeCall,
) -> penpal_runtime::UncheckedExtrinsic {
type Runtime = <PenpalA as Chain>::Runtime;
let account_id = <Runtime as frame_system::Config>::AccountId::from(sender.public());
let tip = 0;
let extra: penpal_runtime::SignedExtra = (
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckEra::<Runtime>::from(generic::Era::immortal()),
frame_system::CheckNonce::<Runtime>::from(
frame_system::Pallet::<Runtime>::account(&account_id).nonce,
),
frame_system::CheckWeight::<Runtime>::new(),
pallet_asset_tx_payment::ChargeAssetTxPayment::<Runtime>::from(tip, None),
);
type SignedPayload =
generic::SignedPayload<penpal_runtime::RuntimeCall, penpal_runtime::SignedExtra>;
let raw_payload = SignedPayload::new(call, extra).unwrap();
let signature = raw_payload.using_encoded(|payload| sender.sign(payload));
let (call, extra, _) = raw_payload.deconstruct();
penpal_runtime::UncheckedExtrinsic::new_signed(
call,
account_id.into(),
MultiSignature::Sr25519(signature),
extra,
)
}
64 changes: 5 additions & 59 deletions cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1332,67 +1332,13 @@ impl_runtime_apis! {
}
}

impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, RuntimeCall, RuntimeEvent> for Runtime {
fn dry_run_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> Result<ExtrinsicDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
use xcm_builder::InspectMessageQueues;
use xcm_executor::RecordXcm;
use xcm::prelude::*;

pallet_xcm::Pallet::<Runtime>::set_record_xcm(true);
let result = Executive::apply_extrinsic(extrinsic).map_err(|error| {
log::error!(
target: "xcm::XcmDryRunApi::dry_run_extrinsic",
"Applying extrinsic failed with error {:?}",
error,
);
XcmDryRunApiError::InvalidExtrinsic
})?;
let local_xcm = pallet_xcm::Pallet::<Runtime>::recorded_xcm();
let forwarded_xcms = xcm_config::XcmRouter::get_messages();
let events: Vec<RuntimeEvent> = System::read_events_no_consensus().map(|record| record.event.clone()).collect();
Ok(ExtrinsicDryRunEffects {
local_xcm: local_xcm.map(VersionedXcm::<()>::from),
forwarded_xcms,
emitted_events: events,
execution_result: result,
})
impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result<ExtrinsicDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call)
}

fn dry_run_xcm(origin_location: VersionedLocation, program: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
use xcm_builder::InspectMessageQueues;
use xcm::prelude::*;

let origin_location: Location = origin_location.try_into().map_err(|error| {
log::error!(
target: "xcm::XcmDryRunApi::dry_run_xcm",
"Location version conversion failed with error: {:?}",
error,
);
XcmDryRunApiError::VersionedConversionFailed
})?;
let program: Xcm<RuntimeCall> = program.try_into().map_err(|error| {
log::error!(
target: "xcm::XcmDryRunApi::dry_run_xcm",
"Xcm version conversion failed with error {:?}",
error,
);
XcmDryRunApiError::VersionedConversionFailed
})?;
let mut hash = program.using_encoded(sp_core::hashing::blake2_256);
let result = xcm_executor::XcmExecutor::<xcm_config::XcmConfig>::prepare_and_execute(
origin_location,
program,
&mut hash,
Weight::MAX, // Max limit available for execution.
Weight::zero(),
);
let forwarded_xcms = xcm_config::XcmRouter::get_messages();
let events: Vec<RuntimeEvent> = System::read_events_no_consensus().map(|record| record.event.clone()).collect();
Ok(XcmDryRunEffects {
forwarded_xcms,
emitted_events: events,
execution_result: result,
})
fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
}
}

Expand Down
64 changes: 5 additions & 59 deletions cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1368,67 +1368,13 @@ impl_runtime_apis! {
}
}

impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, RuntimeCall, RuntimeEvent> for Runtime {
fn dry_run_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> Result<ExtrinsicDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
use xcm_builder::InspectMessageQueues;
use xcm_executor::RecordXcm;
use xcm::prelude::*;

pallet_xcm::Pallet::<Runtime>::set_record_xcm(true);
let result = Executive::apply_extrinsic(extrinsic).map_err(|error| {
log::error!(
target: "xcm::XcmDryRunApi::dry_run_extrinsic",
"Applying extrinsic failed with error {:?}",
error,
);
XcmDryRunApiError::InvalidExtrinsic
})?;
let local_xcm = pallet_xcm::Pallet::<Runtime>::recorded_xcm();
let forwarded_xcms = xcm_config::XcmRouter::get_messages();
let events: Vec<RuntimeEvent> = System::read_events_no_consensus().map(|record| record.event.clone()).collect();
Ok(ExtrinsicDryRunEffects {
local_xcm: local_xcm.map(VersionedXcm::<()>::from),
forwarded_xcms,
emitted_events: events,
execution_result: result,
})
impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result<ExtrinsicDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call)
}

fn dry_run_xcm(origin_location: VersionedLocation, program: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
use xcm_builder::InspectMessageQueues;
use xcm::prelude::*;

let origin_location: Location = origin_location.try_into().map_err(|error| {
log::error!(
target: "xcm::XcmDryRunApi::dry_run_xcm",
"Location version conversion failed with error: {:?}",
error,
);
XcmDryRunApiError::VersionedConversionFailed
})?;
let program: Xcm<RuntimeCall> = program.try_into().map_err(|error| {
log::error!(
target: "xcm::XcmDryRunApi::dry_run_xcm",
"Xcm version conversion failed with error {:?}",
error,
);
XcmDryRunApiError::VersionedConversionFailed
})?;
let mut hash = program.using_encoded(sp_core::hashing::blake2_256);
let result = xcm_executor::XcmExecutor::<xcm_config::XcmConfig>::prepare_and_execute(
origin_location,
program,
&mut hash,
Weight::MAX, // Max limit available for execution.
Weight::zero(),
);
let forwarded_xcms = xcm_config::XcmRouter::get_messages();
let events: Vec<RuntimeEvent> = System::read_events_no_consensus().map(|record| record.event.clone()).collect();
Ok(XcmDryRunEffects {
forwarded_xcms,
emitted_events: events,
execution_result: result,
})
fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
}
}

Expand Down
16 changes: 4 additions & 12 deletions cumulus/parachains/runtimes/testing/penpal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT},
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, Dispatchable},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
Expand Down Expand Up @@ -886,21 +886,13 @@ impl_runtime_apis! {
}
}

impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, RuntimeCall, RuntimeEvent> for Runtime {
fn dry_run_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> Result<ExtrinsicDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result<ExtrinsicDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
use xcm_builder::InspectMessageQueues;
use xcm_executor::RecordXcm;
use xcm::prelude::*;

pallet_xcm::Pallet::<Runtime>::set_record_xcm(true);
let result = Executive::apply_extrinsic(extrinsic).map_err(|error| {
log::error!(
target: "xcm::XcmDryRunApi::dry_run_extrinsic",
"Applying extrinsic failed with error {:?}",
error,
);
XcmDryRunApiError::InvalidExtrinsic
})?;
let result = call.dispatch(origin.into());
let local_xcm = pallet_xcm::Pallet::<Runtime>::recorded_xcm();
let forwarded_xcms = xcm_config::XcmRouter::get_messages();
let events: Vec<RuntimeEvent> = System::read_events_no_consensus().map(|record| record.event.clone()).collect();
Expand Down
3 changes: 3 additions & 0 deletions cumulus/xcm/xcm-emulator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ pub trait Chain: TestExt {
type RuntimeOrigin;
type RuntimeEvent;
type System;
type OriginCaller;

fn account_id_of(seed: &str) -> AccountId {
helpers::get_account_id_from_seed::<sr25519::Public>(seed)
Expand Down Expand Up @@ -366,6 +367,7 @@ macro_rules! decl_test_relay_chains {
type RuntimeOrigin = $runtime::RuntimeOrigin;
type RuntimeEvent = $runtime::RuntimeEvent;
type System = $crate::SystemPallet::<Self::Runtime>;
type OriginCaller = $runtime::OriginCaller;

fn account_data_of(account: $crate::AccountIdOf<Self::Runtime>) -> $crate::AccountData<$crate::Balance> {
<Self as $crate::TestExt>::ext_wrapper(|| $crate::SystemPallet::<Self::Runtime>::account(account).data.into())
Expand Down Expand Up @@ -600,6 +602,7 @@ macro_rules! decl_test_parachains {
type RuntimeOrigin = $runtime::RuntimeOrigin;
type RuntimeEvent = $runtime::RuntimeEvent;
type System = $crate::SystemPallet::<Self::Runtime>;
type OriginCaller = $runtime::OriginCaller;
type Network = N;

fn account_data_of(account: $crate::AccountIdOf<Self::Runtime>) -> $crate::AccountData<$crate::Balance> {
Expand Down
4 changes: 2 additions & 2 deletions polkadot/node/service/src/fake_runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ sp_api::impl_runtime_apis! {
}
}

impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, (), ()> for Runtime {
fn dry_run_extrinsic(_: <Block as BlockT>::Extrinsic) -> Result<xcm_fee_payment_runtime_api::dry_run::ExtrinsicDryRunEffects<()>, xcm_fee_payment_runtime_api::dry_run::Error> {
impl xcm_fee_payment_runtime_api::dry_run::XcmDryRunApi<Block, (), (), ()> for Runtime {
fn dry_run_call(_: (), _: ()) -> Result<xcm_fee_payment_runtime_api::dry_run::ExtrinsicDryRunEffects<()>, xcm_fee_payment_runtime_api::dry_run::Error> {
unimplemented!()
}

Expand Down
Loading
Loading