Skip to content
GitLab
Explore
Sign in
parity
Mirrored projects
polkadot-sdk
Compare revisions
be1d7d05e5f32b1bfa67aec2f6344d2c6ff60f50 to aceda4659509d426d364188fa72555de58b887ba
Show whitespace changes
Inline
Side-by-side
polkadot/runtime/test-runtime/src/lib.rs
View file @
aceda465
...
...
@@ -313,7 +313,6 @@ parameter_types! {
pub
const
RewardCurve
:
&
'static
PiecewiseLinear
<
'static
>
=
&
REWARD_CURVE
;
pub
const
MaxExposurePageSize
:
u32
=
64
;
pub
const
MaxNominators
:
u32
=
256
;
pub
storage
OffendingValidatorsThreshold
:
Perbill
=
Perbill
::
from_percent
(
17
);
pub
const
MaxAuthorities
:
u32
=
100_000
;
pub
const
OnChainMaxWinners
:
u32
=
u32
::
MAX
;
// Unbounded number of election targets and voters.
...
...
@@ -349,7 +348,6 @@ impl pallet_staking::Config for Runtime {
type
SessionInterface
=
Self
;
type
EraPayout
=
pallet_staking
::
ConvertCurve
<
RewardCurve
>
;
type
MaxExposurePageSize
=
MaxExposurePageSize
;
type
OffendingValidatorsThreshold
=
OffendingValidatorsThreshold
;
type
NextNewSession
=
Session
;
type
ElectionProvider
=
onchain
::
OnChainExecution
<
OnChainSeqPhragmen
>
;
type
GenesisElectionProvider
=
onchain
::
OnChainExecution
<
OnChainSeqPhragmen
>
;
...
...
@@ -364,6 +362,7 @@ impl pallet_staking::Config for Runtime {
type
BenchmarkingConfig
=
runtime_common
::
StakingBenchmarkingConfig
;
type
EventListeners
=
();
type
WeightInfo
=
();
type
DisablingStrategy
=
pallet_staking
::
UpToLimitDisablingStrategy
;
}
parameter_types!
{
...
...
polkadot/runtime/westend/build.rs
View file @
aceda465
...
...
@@ -17,9 +17,5 @@
use
substrate_wasm_builder
::
WasmBuilder
;
fn
main
()
{
WasmBuilder
::
new
()
.with_current_project
()
.import_memory
()
.export_heap_base
()
.build
()
WasmBuilder
::
build_using_defaults
();
}
polkadot/runtime/westend/src/impls.rs
View file @
aceda465
...
...
@@ -167,16 +167,11 @@ where
},
]);
let
encoded_versioned_xcm
=
VersionedXcm
::
V4
(
program
)
.encode
()
.try_into
()
.map_err
(|
error
|
{
log
::
error!
(
target
:
"runtime::on_reap_identity"
,
"XCM too large, error: {:?}"
,
error
);
pallet_xcm
::
Error
::
<
Runtime
>
::
XcmTooLarge
})
?
;
// send
let
_
=
<
pallet_xcm
::
Pallet
<
Runtime
>>
::
send
_blob
(
let
_
=
<
pallet_xcm
::
Pallet
<
Runtime
>>
::
send
(
RawOrigin
::
Root
.into
(),
Box
::
new
(
VersionedLocation
::
V4
(
destination
)),
encoded_versioned_xcm
,
Box
::
new
(
VersionedXcm
::
V4
(
program
))
,
)
?
;
Ok
(())
}
...
...
polkadot/runtime/westend/src/lib.rs
View file @
aceda465
...
...
@@ -613,7 +613,6 @@ parameter_types! {
// this is an unbounded number. We just set it to a reasonably high value, 1 full page
// of nominators.
pub
const
MaxNominators
:
u32
=
64
;
pub
const
OffendingValidatorsThreshold
:
Perbill
=
Perbill
::
from_percent
(
17
);
pub
const
MaxNominations
:
u32
=
<
NposCompactSolution16
as
frame_election_provider_support
::
NposSolution
>
::
LIMIT
as
u32
;
pub
const
MaxControllersInDeprecationBatch
:
u32
=
751
;
}
...
...
@@ -634,7 +633,6 @@ impl pallet_staking::Config for Runtime {
type
SessionInterface
=
Self
;
type
EraPayout
=
pallet_staking
::
ConvertCurve
<
RewardCurve
>
;
type
MaxExposurePageSize
=
MaxExposurePageSize
;
type
OffendingValidatorsThreshold
=
OffendingValidatorsThreshold
;
type
NextNewSession
=
Session
;
type
ElectionProvider
=
ElectionProviderMultiPhase
;
type
GenesisElectionProvider
=
onchain
::
OnChainExecution
<
OnChainSeqPhragmen
>
;
...
...
@@ -647,6 +645,7 @@ impl pallet_staking::Config for Runtime {
type
BenchmarkingConfig
=
runtime_common
::
StakingBenchmarkingConfig
;
type
EventListeners
=
NominationPools
;
type
WeightInfo
=
weights
::
pallet_staking
::
WeightInfo
<
Runtime
>
;
type
DisablingStrategy
=
pallet_staking
::
UpToLimitDisablingStrategy
;
}
impl
pallet_fast_unstake
::
Config
for
Runtime
{
...
...
@@ -1189,6 +1188,7 @@ impl parachains_scheduler::Config for Runtime {
parameter_types!
{
pub
const
BrokerId
:
u32
=
BROKER_ID
;
pub
MaxXcmTransactWeight
:
Weight
=
Weight
::
from_parts
(
200_000_000
,
20_000
);
}
impl
coretime
::
Config
for
Runtime
{
...
...
@@ -1198,6 +1198,7 @@ impl coretime::Config for Runtime {
type
BrokerId
=
BrokerId
;
type
WeightInfo
=
weights
::
runtime_parachains_coretime
::
WeightInfo
<
Runtime
>
;
type
SendXcm
=
crate
::
xcm_config
::
XcmRouter
;
type
MaxXcmTransactWeight
=
MaxXcmTransactWeight
;
}
parameter_types!
{
...
...
@@ -1647,36 +1648,8 @@ pub mod migrations {
}
}
// We don't have a limit in the Relay Chain.
const
IDENTITY_MIGRATION_KEY_LIMIT
:
u64
=
u64
::
MAX
;
/// Unreleased migrations. Add new ones here:
pub
type
Unreleased
=
(
parachains_configuration
::
migration
::
v7
::
MigrateToV7
<
Runtime
>
,
pallet_staking
::
migrations
::
v14
::
MigrateToV14
<
Runtime
>
,
assigned_slots
::
migration
::
v1
::
MigrateToV1
<
Runtime
>
,
parachains_scheduler
::
migration
::
MigrateV1ToV2
<
Runtime
>
,
parachains_configuration
::
migration
::
v8
::
MigrateToV8
<
Runtime
>
,
parachains_configuration
::
migration
::
v9
::
MigrateToV9
<
Runtime
>
,
paras_registrar
::
migration
::
MigrateToV1
<
Runtime
,
()
>
,
pallet_referenda
::
migration
::
v1
::
MigrateV0ToV1
<
Runtime
,
()
>
,
pallet_grandpa
::
migrations
::
MigrateV4ToV5
<
Runtime
>
,
parachains_configuration
::
migration
::
v10
::
MigrateToV10
<
Runtime
>
,
pallet_nomination_pools
::
migration
::
unversioned
::
TotalValueLockedSync
<
Runtime
>
,
// Migrate Identity pallet for Usernames
pallet_identity
::
migration
::
versioned
::
V0ToV1
<
Runtime
,
IDENTITY_MIGRATION_KEY_LIMIT
>
,
parachains_configuration
::
migration
::
v11
::
MigrateToV11
<
Runtime
>
,
parachains_configuration
::
migration
::
v12
::
MigrateToV12
<
Runtime
>
,
// permanent
pallet_xcm
::
migration
::
MigrateToLatestXcmVersion
<
Runtime
>
,
// Migrate from legacy lease to coretime. Needs to run after configuration v11
coretime
::
migration
::
MigrateToCoretime
<
Runtime
,
crate
::
xcm_config
::
XcmRouter
,
GetLegacyLeaseImpl
,
>
,
parachains_inclusion
::
migration
::
MigrateToV1
<
Runtime
>
,
);
pub
type
Unreleased
=
(
pallet_staking
::
migrations
::
v15
::
MigrateV14ToV15
<
Runtime
>
,);
}
/// Unchecked extrinsic type as expected by this runtime.
...
...
polkadot/runtime/westend/src/weights/pallet_xcm.rs
View file @
aceda465
...
...
@@ -17,9 +17,9 @@
//! Autogenerated weights for `pallet_xcm`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2024-0
3
-2
1
, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2024-0
2
-2
0
, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `runner-
h2rr8wx7
-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! HOSTNAME: `runner-
bn-ce5rx
-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024
// Executed Command:
...
...
@@ -60,26 +60,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `147`
// Estimated: `3612`
// Minimum execution time: 24_535_000 picoseconds.
Weight
::
from_parts
(
25_618_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
3612
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
4
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
2
))
}
/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn
send_blob
()
->
Weight
{
// Proof Size summary in bytes:
// Measured: `147`
// Estimated: `3612`
// Minimum execution time: 25_376_000 picoseconds.
Weight
::
from_parts
(
26_180_000
,
0
)
// Minimum execution time: 25_725_000 picoseconds.
Weight
::
from_parts
(
26_174_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
3612
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
4
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
2
))
...
...
@@ -98,8 +80,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `250`
// Estimated: `6196`
// Minimum execution time: 1
08_786
_000 picoseconds.
Weight
::
from_parts
(
11
2
_20
8
_000
,
0
)
// Minimum execution time: 1
13_140
_000 picoseconds.
Weight
::
from_parts
(
11
6
_20
4
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
6196
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
6
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
4
))
...
...
@@ -118,8 +100,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `6196`
// Minimum execution time: 10
5_190
_000 picoseconds.
Weight
::
from_parts
(
1
07_14
0_000
,
0
)
// Minimum execution time: 10
8_571
_000 picoseconds.
Weight
::
from_parts
(
1
10_65
0_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
6196
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
6
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
4
))
...
...
@@ -138,8 +120,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `250`
// Estimated: `6196`
// Minimum execution time: 1
09_027
_000 picoseconds.
Weight
::
from_parts
(
11
1_404
_000
,
0
)
// Minimum execution time: 1
11_836
_000 picoseconds.
Weight
::
from_parts
(
11
4_435
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
6196
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
6
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
4
))
...
...
@@ -154,24 +136,14 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
Weight
::
from_parts
(
18_446_744_073_709_551_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
0
))
}
/// Storage: `Benchmark::Override` (r:0 w:0)
/// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn
execute_blob
()
->
Weight
{
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 18_446_744_073_709_551_000 picoseconds.
Weight
::
from_parts
(
18_446_744_073_709_551_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
0
))
}
/// Storage: `XcmPallet::SupportedVersion` (r:0 w:1)
/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn
force_xcm_version
()
->
Weight
{
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time:
6_668
_000 picoseconds.
Weight
::
from_parts
(
7_
013
_000
,
0
)
// Minimum execution time:
7_160
_000 picoseconds.
Weight
::
from_parts
(
7_
477
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
0
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
1
))
}
...
...
@@ -179,8 +151,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 1_
740
_000 picoseconds.
Weight
::
from_parts
(
1_884
_000
,
0
)
// Minimum execution time: 1_
934
_000 picoseconds.
Weight
::
from_parts
(
2_053
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
0
))
}
/// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1)
...
...
@@ -201,8 +173,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `147`
// Estimated: `3612`
// Minimum execution time: 3
0_200
_000 picoseconds.
Weight
::
from_parts
(
3
0
_7
6
8_000
,
0
)
// Minimum execution time: 3
1_123
_000 picoseconds.
Weight
::
from_parts
(
3
1
_7
9
8_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
3612
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
6
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
5
))
...
...
@@ -223,8 +195,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `327`
// Estimated: `3792`
// Minimum execution time: 3
3_928
_000 picoseconds.
Weight
::
from_parts
(
3
5_551
_000
,
0
)
// Minimum execution time: 3
5_175
_000 picoseconds.
Weight
::
from_parts
(
3
6_098
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
3792
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
5
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
4
))
...
...
@@ -235,8 +207,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 1_
759
_000 picoseconds.
Weight
::
from_parts
(
1_880
_000
,
0
)
// Minimum execution time: 1_
974
_000 picoseconds.
Weight
::
from_parts
(
2_096
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
0
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
1
))
}
...
...
@@ -246,8 +218,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `22`
// Estimated: `13387`
// Minimum execution time: 16_
507
_000 picoseconds.
Weight
::
from_parts
(
17_
219
_000
,
0
)
// Minimum execution time: 16_
626
_000 picoseconds.
Weight
::
from_parts
(
17_
170
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
13387
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
5
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
2
))
...
...
@@ -258,8 +230,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `26`
// Estimated: `13391`
// Minimum execution time: 16_
633
_000 picoseconds.
Weight
::
from_parts
(
1
6_889
_000
,
0
)
// Minimum execution time: 16_
937
_000 picoseconds.
Weight
::
from_parts
(
1
7_447
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
13391
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
5
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
2
))
...
...
@@ -270,8 +242,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `40`
// Estimated: `15880`
// Minimum execution time: 19_
29
7_000 picoseconds.
Weight
::
from_parts
(
19_
820
_000
,
0
)
// Minimum execution time: 19_
15
7_000 picoseconds.
Weight
::
from_parts
(
19_
659
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
15880
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
6
))
}
...
...
@@ -289,8 +261,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `183`
// Estimated: `6123`
// Minimum execution time: 30_
364
_000 picoseconds.
Weight
::
from_parts
(
31_
122
_000
,
0
)
// Minimum execution time: 30_
699
_000 picoseconds.
Weight
::
from_parts
(
31_
537
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
6123
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
6
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
3
))
...
...
@@ -301,8 +273,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `69`
// Estimated: `10959`
// Minimum execution time: 1
1_997
_000 picoseconds.
Weight
::
from_parts
(
12_
392
_000
,
0
)
// Minimum execution time: 1
2_303
_000 picoseconds.
Weight
::
from_parts
(
12_
670
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
10959
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
4
))
}
...
...
@@ -312,8 +284,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `33`
// Estimated: `13398`
// Minimum execution time: 1
6_894
_000 picoseconds.
Weight
::
from_parts
(
17_
452
_000
,
0
)
// Minimum execution time: 1
7_129
_000 picoseconds.
Weight
::
from_parts
(
17_
668
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
13398
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
5
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
2
))
...
...
@@ -332,8 +304,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `183`
// Estimated: `13548`
// Minimum execution time: 39_
864
_000 picoseconds.
Weight
::
from_parts
(
4
0_859
_000
,
0
)
// Minimum execution time: 39_
960
_000 picoseconds.
Weight
::
from_parts
(
4
1_068
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
13548
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
9
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
4
))
...
...
@@ -346,8 +318,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `1485`
// Minimum execution time: 2_3
6
3_000 picoseconds.
Weight
::
from_parts
(
2_5
19
_000
,
0
)
// Minimum execution time: 2_3
3
3_000 picoseconds.
Weight
::
from_parts
(
2_5
04
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
1485
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
1
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
2
))
...
...
@@ -358,8 +330,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `7576`
// Estimated: `11041`
// Minimum execution time: 22_
409
_000 picoseconds.
Weight
::
from_parts
(
2
2_776
_000
,
0
)
// Minimum execution time: 22_
932
_000 picoseconds.
Weight
::
from_parts
(
2
3_307
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
11041
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
1
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
1
))
...
...
@@ -370,8 +342,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `23`
// Estimated: `3488`
// Minimum execution time: 3
3
_55
1
_000 picoseconds.
Weight
::
from_parts
(
3
4_127
_000
,
0
)
// Minimum execution time: 3
4
_55
8
_000 picoseconds.
Weight
::
from_parts
(
3
5_299
_000
,
0
)
.saturating_add
(
Weight
::
from_parts
(
0
,
3488
))
.saturating_add
(
T
::
DbWeight
::
get
()
.reads
(
1
))
.saturating_add
(
T
::
DbWeight
::
get
()
.writes
(
1
))
...
...
polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml
View file @
aceda465
...
...
@@ -29,7 +29,6 @@ log = { workspace = true, default-features = true }
[dev-dependencies]
pallet-balances
=
{
path
=
"../../../substrate/frame/balances"
}
pallet-assets
=
{
path
=
"../../../substrate/frame/assets"
}
sp-core
=
{
path
=
"../../../substrate/primitives/core"
}
sp-tracing
=
{
path
=
"../../../substrate/primitives/tracing"
}
xcm
=
{
package
=
"staging-xcm"
,
path
=
".."
}
# temp
...
...
polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs
View file @
aceda465
...
...
@@ -146,8 +146,6 @@ benchmarks_instance_pallet! {
initiate_reserve_withdraw
{
let
(
sender_account
,
sender_location
)
=
account_and_location
::
<
T
>
(
1
);
let
holding
=
T
::
worst_case_holding
(
1
);
let
assets_filter
=
AssetFilter
::
Definite
(
holding
.clone
()
.into_inner
()
.into_iter
()
.take
(
MAX_ITEMS_IN_ASSETS
)
.collect
::
<
Vec
<
_
>>
()
.into
());
let
reserve
=
T
::
valid_destination
()
.map_err
(|
_
|
BenchmarkError
::
Skip
)
?
;
let
(
expected_fees_mode
,
expected_assets_in_holding
)
=
T
::
DeliveryHelper
::
ensure_successful_delivery
(
...
...
@@ -157,15 +155,29 @@ benchmarks_instance_pallet! {
);
let
sender_account_balance_before
=
T
::
TransactAsset
::
balance
(
&
sender_account
);
// generate holding and add possible required fees
let
holding
=
if
let
Some
(
expected_assets_in_holding
)
=
expected_assets_in_holding
{
let
mut
holding
=
T
::
worst_case_holding
(
1
+
expected_assets_in_holding
.len
()
as
u32
);
for
a
in
expected_assets_in_holding
.into_inner
()
{
holding
.push
(
a
);
}
holding
}
else
{
T
::
worst_case_holding
(
1
)
};
let
mut
executor
=
new_executor
::
<
T
>
(
sender_location
);
executor
.set_holding
(
holding
.into
());
executor
.set_holding
(
holding
.
clone
()
.
into
());
if
let
Some
(
expected_fees_mode
)
=
expected_fees_mode
{
executor
.set_fees_mode
(
expected_fees_mode
);
}
if
let
Some
(
expected_assets_in_holding
)
=
expected_assets_in_holding
{
executor
.set_holding
(
expected_assets_in_holding
.into
());
}
let
instruction
=
Instruction
::
InitiateReserveWithdraw
{
assets
:
assets_filter
,
reserve
,
xcm
:
Xcm
(
vec!
[])
};
let
instruction
=
Instruction
::
InitiateReserveWithdraw
{
// Worst case is looking through all holdings for every asset explicitly - respecting the limit `MAX_ITEMS_IN_ASSETS`.
assets
:
Definite
(
holding
.into_inner
()
.into_iter
()
.take
(
MAX_ITEMS_IN_ASSETS
)
.collect
::
<
Vec
<
_
>>
()
.into
()),
reserve
,
xcm
:
Xcm
(
vec!
[])
};
let
xcm
=
Xcm
(
vec!
[
instruction
]);
}:
{
executor
.bench_process
(
xcm
)
?
;
...
...
polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs
View file @
aceda465
...
...
@@ -16,17 +16,16 @@
//! A mock runtime for XCM benchmarking.
use
crate
::{
fungible
as
xcm_balances_benchmark
,
mock
::
*
};
use
crate
::{
fungible
as
xcm_balances_benchmark
,
generate_holding_assets
,
mock
::
*
};
use
frame_benchmarking
::
BenchmarkError
;
use
frame_support
::{
derive_impl
,
parameter_types
,
traits
::{
ConstU32
,
Everything
,
Nothing
},
weights
::
Weight
,
traits
::{
Everything
,
Nothing
},
};
use
sp_core
::
H256
;
use
sp_runtime
::
traits
::{
BlakeTwo256
,
IdentityLookup
};
use
xcm
::
latest
::
prelude
::
*
;
use
xcm_builder
::{
AllowUnpaidExecutionFrom
,
FrameTransactionalProcessor
,
MintLocation
};
use
xcm_builder
::{
AllowUnpaidExecutionFrom
,
EnsureDecodableXcm
,
FrameTransactionalProcessor
,
MintLocation
,
};
type
Block
=
frame_system
::
mocking
::
MockBlock
<
Test
>
;
...
...
@@ -40,37 +39,10 @@ frame_support::construct_runtime!(
}
);
parameter_types!
{
pub
const
BlockHashCount
:
u64
=
250
;
pub
BlockWeights
:
frame_system
::
limits
::
BlockWeights
=
frame_system
::
limits
::
BlockWeights
::
simple_max
(
Weight
::
from_parts
(
1024
,
u64
::
MAX
));
}
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl
frame_system
::
Config
for
Test
{
type
BaseCallFilter
=
Everything
;
type
BlockWeights
=
();
type
BlockLength
=
();
type
DbWeight
=
();
type
RuntimeOrigin
=
RuntimeOrigin
;
type
Nonce
=
u64
;
type
Hash
=
H256
;
type
RuntimeCall
=
RuntimeCall
;
type
Hashing
=
BlakeTwo256
;
type
AccountId
=
u64
;
type
Lookup
=
IdentityLookup
<
Self
::
AccountId
>
;
type
Block
=
Block
;
type
RuntimeEvent
=
RuntimeEvent
;
type
BlockHashCount
=
BlockHashCount
;
type
Version
=
();
type
PalletInfo
=
PalletInfo
;
type
AccountData
=
pallet_balances
::
AccountData
<
u64
>
;
type
OnNewAccount
=
();
type
OnKilledAccount
=
();
type
SystemWeightInfo
=
();
type
SS58Prefix
=
();
type
OnSetCode
=
();
type
MaxConsumers
=
ConstU32
<
16
>
;
}
parameter_types!
{
...
...
@@ -121,7 +93,7 @@ parameter_types! {
pub
struct
XcmConfig
;
impl
xcm_executor
::
Config
for
XcmConfig
{
type
RuntimeCall
=
RuntimeCall
;
type
XcmSender
=
DevNull
;
type
XcmSender
=
EnsureDecodableXcm
<
DevNull
>
;
type
AssetTransactor
=
AssetTransactor
;
type
OriginConverter
=
();
type
IsReserve
=
TrustedReserves
;
...
...
@@ -160,9 +132,8 @@ impl crate::Config for Test {
Ok
(
valid_destination
)
}
fn
worst_case_holding
(
depositable_count
:
u32
)
->
Assets
{
crate
::
mock_worst_case_holding
(
depositable_count
,
<
XcmConfig
as
xcm_executor
::
Config
>
::
MaxAssetsIntoHolding
::
get
(),
generate_holding_assets
(
<
XcmConfig
as
xcm_executor
::
Config
>
::
MaxAssetsIntoHolding
::
get
()
-
depositable_count
,
)
}
}
...
...
polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs
View file @
aceda465
...
...
@@ -19,9 +19,9 @@ use crate::{account_and_location, new_executor, EnsureDelivery, XcmCallOf};
use
codec
::
Encode
;
use
frame_benchmarking
::{
benchmarks
,
BenchmarkError
};
use
frame_support
::{
dispatch
::
GetDispatchInfo
,
traits
::
fungible
::
Inspect
};
use
sp_std
::
vec
;
use
sp_std
::
{
prelude
::
*
,
vec
}
;
use
xcm
::{
latest
::{
prelude
::
*
,
MaxDispatchErrorLen
,
MaybeErrorCode
,
Weight
},
latest
::{
prelude
::
*
,
MaxDispatchErrorLen
,
MaybeErrorCode
,
Weight
,
MAX_ITEMS_IN_ASSETS
},
DoubleEncoded
,
};
use
xcm_executor
::{
...
...
@@ -32,7 +32,6 @@ use xcm_executor::{
benchmarks!
{
report_holding
{
let
(
sender_account
,
sender_location
)
=
account_and_location
::
<
T
>
(
1
);
let
holding
=
T
::
worst_case_holding
(
0
);
let
destination
=
T
::
valid_destination
()
.map_err
(|
_
|
BenchmarkError
::
Skip
)
?
;
let
(
expected_fees_mode
,
expected_assets_in_holding
)
=
T
::
DeliveryHelper
::
ensure_successful_delivery
(
...
...
@@ -42,14 +41,22 @@ benchmarks! {
);
let
sender_account_balance_before
=
T
::
TransactAsset
::
balance
(
&
sender_account
);
// generate holding and add possible required fees
let
holding
=
if
let
Some
(
expected_assets_in_holding
)
=
expected_assets_in_holding
{
let
mut
holding
=
T
::
worst_case_holding
(
expected_assets_in_holding
.len
()
as
u32
);
for
a
in
expected_assets_in_holding
.into_inner
()
{
holding
.push
(
a
);
}
holding
}
else
{
T
::
worst_case_holding
(
0
)
};
let
mut
executor
=
new_executor
::
<
T
>
(
sender_location
);
executor
.set_holding
(
holding
.clone
()
.into
());
if
let
Some
(
expected_fees_mode
)
=
expected_fees_mode
{
executor
.set_fees_mode
(
expected_fees_mode
);
}
if
let
Some
(
expected_assets_in_holding
)
=
expected_assets_in_holding
{
executor
.set_holding
(
expected_assets_in_holding
.into
());
}
let
instruction
=
Instruction
::
<
XcmCallOf
<
T
>>
::
ReportHolding
{
response_info
:
QueryResponseInfo
{
...
...
@@ -57,8 +64,8 @@ benchmarks! {
query_id
:
Default
::
default
(),
max_weight
:
Weight
::
MAX
,
},
// Worst case is looking through all holdings for every asset explicitly.
assets
:
Definite
(
holding
),
// Worst case is looking through all holdings for every asset explicitly
- respecting the limit `MAX_ITEMS_IN_ASSETS`
.
assets
:
Definite
(
holding
.into_inner
()
.into_iter
()
.take
(
MAX_ITEMS_IN_ASSETS
)
.collect
::
<
Vec
<
_
>>
()
.into
()
),
};
let
xcm
=
Xcm
(
vec!
[
instruction
]);
...
...
@@ -612,14 +619,19 @@ benchmarks! {
let
sender_account
=
T
::
AccountIdConverter
::
convert_location
(
&
owner
)
.unwrap
();
let
sender_account_balance_before
=
T
::
TransactAsset
::
balance
(
&
sender_account
);
// generate holding and add possible required fees
let
mut
holding
:
Assets
=
asset
.clone
()
.into
();
if
let
Some
(
expected_assets_in_holding
)
=
expected_assets_in_holding
{
for
a
in
expected_assets_in_holding
.into_inner
()
{
holding
.push
(
a
);
}
};
let
mut
executor
=
new_executor
::
<
T
>
(
owner
);
executor
.set_holding
(
asset
.clone
()
.into
());
executor
.set_holding
(
holding
.into
());
if
let
Some
(
expected_fees_mode
)
=
expected_fees_mode
{
executor
.set_fees_mode
(
expected_fees_mode
);
}
if
let
Some
(
expected_assets_in_holding
)
=
expected_assets_in_holding
{
executor
.set_holding
(
expected_assets_in_holding
.into
());
}
let
instruction
=
Instruction
::
LockAsset
{
asset
,
unlocker
};
let
xcm
=
Xcm
(
vec!
[
instruction
]);
...
...
polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs
View file @
aceda465
...
...
@@ -21,16 +21,15 @@ use codec::Decode;
use
frame_support
::{
derive_impl
,
parameter_types
,
traits
::{
Contains
,
Everything
,
OriginTrait
},
weights
::
Weight
,
};
use
sp_core
::
H256
;
use
sp_runtime
::
traits
::{
BlakeTwo256
,
IdentityLookup
,
TrailingZeroInput
};
use
sp_runtime
::
traits
::
TrailingZeroInput
;
use
xcm_builder
::{
test_utils
::{
AssetsInHolding
,
TestAssetExchanger
,
TestAssetLocker
,
TestAssetTrap
,
TestSubscriptionService
,
TestUniversalAliases
,
},
AliasForeignAccountId32
,
AllowUnpaidExecutionFrom
,
FrameTransactionalProcessor
,
AliasForeignAccountId32
,
AllowUnpaidExecutionFrom
,
EnsureDecodableXcm
,
FrameTransactionalProcessor
,
};
use
xcm_executor
::
traits
::
ConvertOrigin
;
...
...
@@ -45,37 +44,10 @@ frame_support::construct_runtime!(
}
);
parameter_types!
{
pub
const
BlockHashCount
:
u64
=
250
;
pub
BlockWeights
:
frame_system
::
limits
::
BlockWeights
=
frame_system
::
limits
::
BlockWeights
::
simple_max
(
Weight
::
from_parts
(
1024
,
u64
::
MAX
));
}
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl
frame_system
::
Config
for
Test
{
type
BaseCallFilter
=
Everything
;
type
BlockWeights
=
();
type
BlockLength
=
();
type
DbWeight
=
();
type
RuntimeOrigin
=
RuntimeOrigin
;
type
Nonce
=
u64
;
type
Hash
=
H256
;
type
RuntimeCall
=
RuntimeCall
;
type
Hashing
=
BlakeTwo256
;
type
AccountId
=
u64
;
type
Lookup
=
IdentityLookup
<
Self
::
AccountId
>
;
type
Block
=
Block
;
type
RuntimeEvent
=
RuntimeEvent
;
type
BlockHashCount
=
BlockHashCount
;
type
Version
=
();
type
PalletInfo
=
PalletInfo
;
type
AccountData
=
pallet_balances
::
AccountData
<
u64
>
;
type
OnNewAccount
=
();
type
OnKilledAccount
=
();
type
SystemWeightInfo
=
();
type
SS58Prefix
=
();
type
OnSetCode
=
();
type
MaxConsumers
=
frame_support
::
traits
::
ConstU32
<
16
>
;
}
/// The benchmarks in this pallet should never need an asset transactor to begin with.
...
...
@@ -110,7 +82,7 @@ type Aliasers = AliasForeignAccountId32<OnlyParachains>;
pub
struct
XcmConfig
;
impl
xcm_executor
::
Config
for
XcmConfig
{
type
RuntimeCall
=
RuntimeCall
;
type
XcmSender
=
DevNull
;
type
XcmSender
=
EnsureDecodableXcm
<
DevNull
>
;
type
AssetTransactor
=
NoAssetTransactor
;
type
OriginConverter
=
AlwaysSignedByDefault
<
RuntimeOrigin
>
;
type
IsReserve
=
AllAssetLocationsPass
;
...
...
@@ -161,9 +133,8 @@ impl crate::Config for Test {
Ok
(
valid_destination
)
}
fn
worst_case_holding
(
depositable_count
:
u32
)
->
Assets
{
crate
::
mock_worst_case_holding
(
depositable_count
,
<
XcmConfig
as
xcm_executor
::
Config
>
::
MaxAssetsIntoHolding
::
get
(),
generate_holding_assets
(
<
XcmConfig
as
xcm_executor
::
Config
>
::
MaxAssetsIntoHolding
::
get
()
-
depositable_count
,
)
}
}
...
...
polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs
View file @
aceda465
...
...
@@ -50,6 +50,8 @@ pub trait Config: frame_system::Config {
fn
valid_destination
()
->
Result
<
Location
,
BenchmarkError
>
;
/// Worst case scenario for a holding account in this runtime.
/// - `depositable_count` specifies the count of assets we plan to add to the holding on top of
/// those generated by the `worst_case_holding` implementation.
fn
worst_case_holding
(
depositable_count
:
u32
)
->
Assets
;
}
...
...
@@ -64,19 +66,22 @@ pub type AssetTransactorOf<T> = <<T as Config>::XcmConfig as XcmConfig>::AssetTr
/// The call type of executor's config. Should eventually resolve to the same overarching call type.
pub
type
XcmCallOf
<
T
>
=
<<
T
as
Config
>
::
XcmConfig
as
XcmConfig
>
::
RuntimeCall
;
pub
fn
mock_worst_case_holding
(
depositable_count
:
u32
,
max_assets
:
u32
)
->
Assets
{
pub
fn
generate_holding_assets
(
max_assets
:
u32
)
->
Assets
{
let
fungibles_amount
:
u128
=
100
;
let
holding_fungibles
=
max_assets
/
2
-
depositable_count
;
let
holding_non_fungibles
=
holding_fungibles
;
let
holding_fungibles
=
max_assets
/
2
;
let
holding_non_fungibles
=
max_assets
-
holding_fungibles
-
1
;
// -1 because of adding `Here` asset
// add count of `holding_fungibles`
(
0
..
holding_fungibles
)
.map
(|
i
|
{
Asset
{
id
:
AssetId
(
GeneralIndex
(
i
as
u128
)
.into
()),
fun
:
Fungible
(
fungibles_amount
*
i
as
u128
),
fun
:
Fungible
(
fungibles_amount
*
(
i
+
1
)
as
u128
),
// non-zero amount
}
.into
()
})
// add one more `Here` asset
.chain
(
core
::
iter
::
once
(
Asset
{
id
:
AssetId
(
Here
.into
()),
fun
:
Fungible
(
u128
::
MAX
)
}))
// add count of `holding_non_fungibles`
.chain
((
0
..
holding_non_fungibles
)
.map
(|
i
|
Asset
{
id
:
AssetId
(
GeneralIndex
(
i
as
u128
)
.into
()),
fun
:
NonFungible
(
asset_instance_from
(
i
)),
...
...
polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs
View file @
aceda465
...
...
@@ -58,7 +58,7 @@ impl xcm_executor::traits::ConvertLocation<u64> for AccountIdConverter {
}
parameter_types!
{
pub
UniversalLocation
:
InteriorLocation
=
Junction
::
Parachain
(
101
)
.into
();
pub
UniversalLocation
:
InteriorLocation
=
[
GlobalConsensus
(
ByGenesis
([
1
;
32
])),
Junction
::
Parachain
(
101
)
]
.into
();
pub
UnitWeightCost
:
Weight
=
Weight
::
from_parts
(
10
,
10
);
pub
WeightPrice
:
(
AssetId
,
u128
,
u128
)
=
(
AssetId
(
Here
.into
()),
1_000_000
,
1024
);
}
...
...
polkadot/xcm/pallet-xcm/src/benchmarking.rs
View file @
aceda465
...
...
@@ -16,7 +16,6 @@
use
super
::
*
;
use
bounded_collections
::{
ConstU32
,
WeakBoundedVec
};
use
codec
::
Encode
;
use
frame_benchmarking
::{
benchmarks
,
whitelisted_caller
,
BenchmarkError
,
BenchmarkResult
};
use
frame_support
::{
assert_ok
,
weights
::
Weight
};
use
frame_system
::
RawOrigin
;
...
...
@@ -101,21 +100,6 @@ benchmarks! {
let
versioned_msg
=
VersionedXcm
::
from
(
msg
);
}:
_
<
RuntimeOrigin
<
T
>>
(
send_origin
,
Box
::
new
(
versioned_dest
),
Box
::
new
(
versioned_msg
))
send_blob
{
let
send_origin
=
T
::
SendXcmOrigin
::
try_successful_origin
()
.map_err
(|
_
|
BenchmarkError
::
Weightless
)
?
;
if
T
::
SendXcmOrigin
::
try_origin
(
send_origin
.clone
())
.is_err
()
{
return
Err
(
BenchmarkError
::
Override
(
BenchmarkResult
::
from_weight
(
Weight
::
MAX
)))
}
let
msg
=
Xcm
::
<
()
>
(
vec!
[
ClearOrigin
]);
let
versioned_dest
:
VersionedLocation
=
T
::
reachable_dest
()
.ok_or
(
BenchmarkError
::
Override
(
BenchmarkResult
::
from_weight
(
Weight
::
MAX
)),
)
?
.into
();
let
versioned_msg
=
VersionedXcm
::
from
(
msg
);
let
encoded_versioned_msg
=
versioned_msg
.encode
()
.try_into
()
.unwrap
();
}:
_
<
RuntimeOrigin
<
T
>>
(
send_origin
,
Box
::
new
(
versioned_dest
),
encoded_versioned_msg
)
teleport_assets
{
let
(
asset
,
destination
)
=
T
::
teleportable_asset_and_dest
()
.ok_or
(
BenchmarkError
::
Override
(
BenchmarkResult
::
from_weight
(
Weight
::
MAX
)),
...
...
@@ -263,19 +247,6 @@ benchmarks! {
let
versioned_msg
=
VersionedXcm
::
from
(
msg
);
}:
_
<
RuntimeOrigin
<
T
>>
(
execute_origin
,
Box
::
new
(
versioned_msg
),
Weight
::
MAX
)
execute_blob
{
let
execute_origin
=
T
::
ExecuteXcmOrigin
::
try_successful_origin
()
.map_err
(|
_
|
BenchmarkError
::
Weightless
)
?
;
let
origin_location
=
T
::
ExecuteXcmOrigin
::
try_origin
(
execute_origin
.clone
())
.map_err
(|
_
|
BenchmarkError
::
Override
(
BenchmarkResult
::
from_weight
(
Weight
::
MAX
)))
?
;
let
msg
=
Xcm
(
vec!
[
ClearOrigin
]);
if
!
T
::
XcmExecuteFilter
::
contains
(
&
(
origin_location
,
msg
.clone
()))
{
return
Err
(
BenchmarkError
::
Override
(
BenchmarkResult
::
from_weight
(
Weight
::
MAX
)))
}
let
versioned_msg
=
VersionedXcm
::
from
(
msg
);
let
encoded_versioned_msg
=
versioned_msg
.encode
()
.try_into
()
.unwrap
();
}:
_
<
RuntimeOrigin
<
T
>>
(
execute_origin
,
encoded_versioned_msg
,
Weight
::
MAX
)
force_xcm_version
{
let
loc
=
T
::
reachable_dest
()
.ok_or
(
BenchmarkError
::
Override
(
BenchmarkResult
::
from_weight
(
Weight
::
MAX
)),
...
...
polkadot/xcm/pallet-xcm/src/lib.rs
View file @
aceda465
...
...
@@ -45,13 +45,13 @@ use sp_runtime::{
AccountIdConversion
,
BadOrigin
,
BlakeTwo256
,
BlockNumberProvider
,
Dispatchable
,
Hash
,
Saturating
,
Zero
,
},
RuntimeDebug
,
Either
,
RuntimeDebug
,
};
use
sp_std
::{
boxed
::
Box
,
marker
::
PhantomData
,
prelude
::
*
,
result
::
Result
,
vec
};
use
xcm
::{
latest
::
QueryResponseInfo
,
prelude
::
*
};
use
xcm_builder
::{
ExecuteController
,
ExecuteControllerWeightInfo
,
MaxXcmEncodedSize
,
QueryController
,
QueryControllerWeightInfo
,
SendController
,
SendControllerWeightInfo
,
ExecuteController
,
ExecuteControllerWeightInfo
,
QueryController
,
QueryController
WeightInfo
,
SendController
,
SendControllerWeightInfo
,
};
use
xcm_executor
::{
traits
::{
...
...
@@ -87,8 +87,6 @@ pub trait WeightInfo {
fn
new_query
()
->
Weight
;
fn
take_response
()
->
Weight
;
fn
claim_assets
()
->
Weight
;
fn
execute_blob
()
->
Weight
;
fn
send_blob
()
->
Weight
;
}
/// fallback implementation
...
...
@@ -173,14 +171,6 @@ impl WeightInfo for TestWeightInfo {
fn
claim_assets
()
->
Weight
{
Weight
::
from_parts
(
100_000_000
,
0
)
}
fn
execute_blob
()
->
Weight
{
Weight
::
from_parts
(
100_000_000
,
0
)
}
fn
send_blob
()
->
Weight
{
Weight
::
from_parts
(
100_000_000
,
0
)
}
}
#[frame_support::pallet]
...
...
@@ -296,49 +286,76 @@ pub mod pallet {
}
impl
<
T
:
Config
>
ExecuteControllerWeightInfo
for
Pallet
<
T
>
{
fn
execute
_blob
()
->
Weight
{
T
::
WeightInfo
::
execute
_blob
()
fn
execute
()
->
Weight
{
T
::
WeightInfo
::
execute
()
}
}
impl
<
T
:
Config
>
ExecuteController
<
OriginFor
<
T
>
,
<
T
as
Config
>
::
RuntimeCall
>
for
Pallet
<
T
>
{
type
WeightInfo
=
Self
;
fn
execute
_blob
(
fn
execute
(
origin
:
OriginFor
<
T
>
,
encoded_
message
:
Bo
undedVec
<
u8
,
MaxXcmEncodedSize
>
,
message
:
Bo
x
<
VersionedXcm
<<
T
as
Config
>
::
RuntimeCall
>
>
,
max_weight
:
Weight
,
)
->
Result
<
Weight
,
DispatchErrorWithPostInfo
>
{
log
::
trace!
(
target
:
"xcm::pallet_xcm::execute"
,
"message {:?}, max_weight {:?}"
,
message
,
max_weight
);
let
outcome
=
(||
{
let
origin_location
=
T
::
ExecuteXcmOrigin
::
ensure_origin
(
origin
)
?
;
let
message
=
VersionedXcm
::
<<
T
as
Config
>
::
RuntimeCall
>
::
decode
(
&
mut
&
encoded_message
[
..
])
.map_err
(|
error
|
{
log
::
error!
(
target
:
"xcm::execute_blob"
,
"Unable to decode XCM, error: {:?}"
,
error
);
Error
::
<
T
>
::
UnableToDecode
let
mut
hash
=
message
.using_encoded
(
sp_io
::
hashing
::
blake2_256
);
let
message
=
(
*
message
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
value
=
(
origin_location
,
message
);
ensure!
(
T
::
XcmExecuteFilter
::
contains
(
&
value
),
Error
::
<
T
>
::
Filtered
);
let
(
origin_location
,
message
)
=
value
;
Ok
(
T
::
XcmExecutor
::
prepare_and_execute
(
origin_location
,
message
,
&
mut
hash
,
max_weight
,
max_weight
,
))
})()
.map_err
(|
e
:
DispatchError
|
{
e
.with_weight
(
<
Self
::
WeightInfo
as
ExecuteControllerWeightInfo
>
::
execute
())
})
?
;
Self
::
deposit_event
(
Event
::
Attempted
{
outcome
:
outcome
.clone
()
});
let
weight_used
=
outcome
.weight_used
();
outcome
.ensure_complete
()
.map_err
(|
error
|
{
log
::
error!
(
target
:
"xcm::pallet_xcm::execute"
,
"XCM execution failed with error {:?}"
,
error
);
Error
::
<
T
>
::
LocalExecutionIncomplete
.with_weight
(
weight_used
.saturating_add
(
<
Self
::
WeightInfo
as
ExecuteControllerWeightInfo
>
::
execute
(),
),
)
})
?
;
Self
::
execute_base
(
origin_location
,
Box
::
new
(
message
),
max_
weight
)
Ok
(
weight
_used
)
}
}
impl
<
T
:
Config
>
SendControllerWeightInfo
for
Pallet
<
T
>
{
fn
send
_blob
()
->
Weight
{
T
::
WeightInfo
::
send
_blob
()
fn
send
()
->
Weight
{
T
::
WeightInfo
::
send
()
}
}
impl
<
T
:
Config
>
SendController
<
OriginFor
<
T
>>
for
Pallet
<
T
>
{
type
WeightInfo
=
Self
;
fn
send
_blob
(
fn
send
(
origin
:
OriginFor
<
T
>
,
dest
:
Box
<
VersionedLocation
>
,
encoded_
message
:
Bo
undedVec
<
u8
,
MaxXcmEncodedSize
>
,
message
:
Bo
x
<
VersionedXcm
<
()
>
>
,
)
->
Result
<
XcmHash
,
DispatchError
>
{
let
origin_location
=
T
::
SendXcmOrigin
::
ensure_origin
(
origin
)
?
;
let
message
=
VersionedXcm
::
<
()
>
::
decode
(
&
mut
&
encoded_message
[
..
])
.map_err
(|
error
|
{
log
::
error!
(
target
:
"xcm::send_blob"
,
"Unable to decode XCM, error: {:?}"
,
error
);
Error
::
<
T
>
::
UnableToDecode
})
?
;
Self
::
send_base
(
origin_location
,
dest
,
Box
::
new
(
message
))
let
interior
:
Junctions
=
origin_location
.clone
()
.try_into
()
.map_err
(|
_
|
Error
::
<
T
>
::
InvalidOrigin
)
?
;
let
dest
=
Location
::
try_from
(
*
dest
)
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
message
:
Xcm
<
()
>
=
(
*
message
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
message_id
=
Self
::
send_xcm
(
interior
,
dest
.clone
(),
message
.clone
())
.map_err
(
Error
::
<
T
>
::
from
)
?
;
let
e
=
Event
::
Sent
{
origin
:
origin_location
,
destination
:
dest
,
message
,
message_id
};
Self
::
deposit_event
(
e
);
Ok
(
message_id
)
}
}
...
...
@@ -547,13 +564,6 @@ pub mod pallet {
/// Local XCM execution incomplete.
#[codec(index
=
24
)]
LocalExecutionIncomplete
,
/// Could not decode XCM.
#[codec(index
=
25
)]
UnableToDecode
,
/// XCM encoded length is too large.
/// Returned when an XCM encoded length is larger than `MaxXcmEncodedSize`.
#[codec(index
=
26
)]
XcmTooLarge
,
}
impl
<
T
:
Config
>
From
<
SendError
>
for
Error
<
T
>
{
...
...
@@ -890,72 +900,15 @@ pub mod pallet {
}
}
impl
<
T
:
Config
>
Pallet
<
T
>
{
/// Underlying logic for both [`execute_blob`] and [`execute`].
fn
execute_base
(
origin_location
:
Location
,
message
:
Box
<
VersionedXcm
<<
T
as
Config
>
::
RuntimeCall
>>
,
max_weight
:
Weight
,
)
->
Result
<
Weight
,
DispatchErrorWithPostInfo
>
{
log
::
trace!
(
target
:
"xcm::pallet_xcm::execute"
,
"message {:?}, max_weight {:?}"
,
message
,
max_weight
);
let
outcome
=
(||
{
let
mut
hash
=
message
.using_encoded
(
sp_io
::
hashing
::
blake2_256
);
let
message
=
(
*
message
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
value
=
(
origin_location
,
message
);
ensure!
(
T
::
XcmExecuteFilter
::
contains
(
&
value
),
Error
::
<
T
>
::
Filtered
);
let
(
origin_location
,
message
)
=
value
;
Ok
(
T
::
XcmExecutor
::
prepare_and_execute
(
origin_location
,
message
,
&
mut
hash
,
max_weight
,
max_weight
,
))
})()
.map_err
(|
e
:
DispatchError
|
e
.with_weight
(
T
::
WeightInfo
::
execute
()))
?
;
Self
::
deposit_event
(
Event
::
Attempted
{
outcome
:
outcome
.clone
()
});
let
weight_used
=
outcome
.weight_used
();
outcome
.ensure_complete
()
.map_err
(|
error
|
{
log
::
error!
(
target
:
"xcm::pallet_xcm::execute"
,
"XCM execution failed with error {:?}"
,
error
);
Error
::
<
T
>
::
LocalExecutionIncomplete
.with_weight
(
weight_used
.saturating_add
(
T
::
WeightInfo
::
execute
()))
})
?
;
Ok
(
weight_used
)
}
/// Underlying logic for both [`send_blob`] and [`send`].
fn
send_base
(
origin_location
:
Location
,
dest
:
Box
<
VersionedLocation
>
,
message
:
Box
<
VersionedXcm
<
()
>>
,
)
->
Result
<
XcmHash
,
DispatchError
>
{
let
interior
:
Junctions
=
origin_location
.clone
()
.try_into
()
.map_err
(|
_
|
Error
::
<
T
>
::
InvalidOrigin
)
?
;
let
dest
=
Location
::
try_from
(
*
dest
)
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
message
:
Xcm
<
()
>
=
(
*
message
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
message_id
=
Self
::
send_xcm
(
interior
,
dest
.clone
(),
message
.clone
())
.map_err
(
Error
::
<
T
>
::
from
)
?
;
let
e
=
Event
::
Sent
{
origin
:
origin_location
,
destination
:
dest
,
message
,
message_id
};
Self
::
deposit_event
(
e
);
Ok
(
message_id
)
}
}
#[pallet::call(weight(
<
T
as
Config
>
::WeightInfo))]
impl
<
T
:
Config
>
Pallet
<
T
>
{
/// WARNING: DEPRECATED. `send` will be removed after June 2024. Use `send_blob` instead.
#[allow(deprecated)]
#[deprecated(note
=
"`send` will be removed after June 2024. Use `send_blob` instead."
)]
#[pallet::call_index(
0
)]
pub
fn
send
(
origin
:
OriginFor
<
T
>
,
dest
:
Box
<
VersionedLocation
>
,
message
:
Box
<
VersionedXcm
<
()
>>
,
)
->
DispatchResult
{
let
origin_location
=
T
::
SendXcmOrigin
::
ensure_origin
(
origin
)
?
;
Self
::
send_base
(
origin_location
,
dest
,
message
)
?
;
<
Self
as
SendController
<
_
>>
::
send
(
origin
,
dest
,
message
)
?
;
Ok
(())
}
...
...
@@ -1052,13 +1005,6 @@ pub mod pallet {
/// No more than `max_weight` will be used in its attempted execution. If this is less than
/// the maximum amount of weight that the message could take to be executed, then no
/// execution attempt will be made.
///
/// WARNING: DEPRECATED. `execute` will be removed after June 2024. Use `execute_blob`
/// instead.
#[allow(deprecated)]
#[deprecated(
note
=
"`execute` will be removed after June 2024. Use `execute_blob` instead."
)]
#[pallet::call_index(
3
)]
#[pallet::weight(max_weight
.
saturating_add(T::WeightInfo::execute()))]
pub
fn
execute
(
...
...
@@ -1066,8 +1012,8 @@ pub mod pallet {
message
:
Box
<
VersionedXcm
<<
T
as
Config
>
::
RuntimeCall
>>
,
max_weight
:
Weight
,
)
->
DispatchResultWithPostInfo
{
let
origin_location
=
T
::
ExecuteXcmOrigin
::
ensure_origin
(
origin
)
?
;
let
weight_used
=
Self
::
execute
_base
(
origin
_location
,
message
,
max_weight
)
?
;
let
weight_used
=
<
Self
as
ExecuteController
<
_
,
_
>>
::
execute
(
origin
,
message
,
max_weight
)
?
;
Ok
(
Some
(
weight_used
.saturating_add
(
T
::
WeightInfo
::
execute
()))
.into
())
}
...
...
@@ -1311,7 +1257,7 @@ pub mod pallet {
Self
::
do_transfer_assets
(
origin
,
dest
,
beneficiary
,
Either
::
Left
(
beneficiary
)
,
assets
,
assets_transfer_type
,
fee_asset_item
,
...
...
@@ -1362,47 +1308,6 @@ pub mod pallet {
Ok
(())
}
/// Execute an XCM from a local, signed, origin.
///
/// An event is deposited indicating whether the message could be executed completely
/// or only partially.
///
/// No more than `max_weight` will be used in its attempted execution. If this is less than
/// the maximum amount of weight that the message could take to be executed, then no
/// execution attempt will be made.
///
/// The message is passed in encoded. It needs to be decodable as a [`VersionedXcm`].
#[pallet::call_index(
13
)]
#[pallet::weight(max_weight
.
saturating_add(T::WeightInfo::execute_blob()))]
pub
fn
execute_blob
(
origin
:
OriginFor
<
T
>
,
encoded_message
:
BoundedVec
<
u8
,
MaxXcmEncodedSize
>
,
max_weight
:
Weight
,
)
->
DispatchResultWithPostInfo
{
let
weight_used
=
<
Self
as
ExecuteController
<
_
,
_
>>
::
execute_blob
(
origin
,
encoded_message
,
max_weight
,
)
?
;
Ok
(
Some
(
weight_used
.saturating_add
(
T
::
WeightInfo
::
execute_blob
()))
.into
())
}
/// Send an XCM from a local, signed, origin.
///
/// The destination, `dest`, will receive this message with a `DescendOrigin` instruction
/// that makes the origin of the message be the origin on this system.
///
/// The message is passed in encoded. It needs to be decodable as a [`VersionedXcm`].
#[pallet::call_index(
14
)]
pub
fn
send_blob
(
origin
:
OriginFor
<
T
>
,
dest
:
Box
<
VersionedLocation
>
,
encoded_message
:
BoundedVec
<
u8
,
MaxXcmEncodedSize
>
,
)
->
DispatchResult
{
<
Self
as
SendController
<
_
>>
::
send_blob
(
origin
,
dest
,
encoded_message
)
?
;
Ok
(())
}
/// Transfer assets from the local chain to the destination chain using explicit transfer
/// types for assets and fees.
///
...
...
@@ -1421,50 +1326,60 @@ pub mod pallet {
/// - `TransferType::Teleport`: burn local assets and forward XCM to `dest` chain to
/// mint/teleport assets and deposit them to `beneficiary`.
///
/// Fee payment on the source, destination and all intermediary hops, is specified through
/// `fees_id`, but make sure enough of the specified `fees_id` asset is included in the
/// given list of `assets`. `fees_id` should be enough to pay for `weight_limit`. If more
/// weight is needed than `weight_limit`, then the operation will fail and the sent assets
/// may be at risk.
/// On the destination chain, as well as any intermediary hops, `BuyExecution` is used to
/// buy execution using transferred `assets` identified by `remote_fees_id`.
/// Make sure enough of the specified `remote_fees_id` asset is included in the given list
/// of `assets`. `remote_fees_id` should be enough to pay for `weight_limit`. If more weight
/// is needed than `weight_limit`, then the operation will fail and the sent assets may be
/// at risk.
///
/// `remote_fees_id` may use different transfer type than rest of `assets` and can be
/// specified through `fees_transfer_type`.
///
/// `fees_id` may use different transfer type than rest of `assets` and can be specified
/// through `fees_transfer_type`.
/// The caller needs to specify what should happen to the transferred assets once they reach
/// the `dest` chain. This is done through the `custom_xcm_on_dest` parameter, which
/// contains the instructions to execute on `dest` as a final step.
/// This is usually as simple as:
/// `Xcm(vec![DepositAsset { assets: Wild(AllCounted(assets.len())), beneficiary }])`,
/// but could be something more exotic like sending the `assets` even further.
///
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
/// - `dest`: Destination context for the assets. Will typically be `[Parent,
/// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from
/// relay to parachain, or `(parents: 2, (GlobalConsensus(..), ..))` to send from
/// parachain across a bridge to another ecosystem destination.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will
/// generally be an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the
/// fee on the `dest` (and possibly reserve) chains.
/// - `assets_transfer_type`: The XCM `TransferType` used to transfer the `assets`.
/// - `fees_id`: One of the included `assets` to be be used to pay fees.
/// - `
remote_
fees_id`: One of the included `assets` to be be used to pay fees.
/// - `fees_transfer_type`: The XCM `TransferType` used to transfer the `fees` assets.
/// - `custom_xcm_on_dest`: The XCM to be executed on `dest` chain as the last step of the
/// transfer, which also determines what happens to the assets on the destination chain.
/// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase.
#[pallet::call_index(
1
5
)]
#[pallet::call_index(
1
3
)]
#[pallet::weight(T::WeightInfo::transfer_assets())]
pub
fn
transfer_assets_using_type
(
pub
fn
transfer_assets_using_type
_and_then
(
origin
:
OriginFor
<
T
>
,
dest
:
Box
<
VersionedLocation
>
,
beneficiary
:
Box
<
VersionedLocation
>
,
assets
:
Box
<
VersionedAssets
>
,
assets_transfer_type
:
Box
<
TransferType
>
,
fees_id
:
Box
<
VersionedAssetId
>
,
remote_
fees_id
:
Box
<
VersionedAssetId
>
,
fees_transfer_type
:
Box
<
TransferType
>
,
custom_xcm_on_dest
:
Box
<
VersionedXcm
<
()
>>
,
weight_limit
:
WeightLimit
,
)
->
DispatchResult
{
let
origin_location
=
T
::
ExecuteXcmOrigin
::
ensure_origin
(
origin
)
?
;
let
dest
:
Location
=
(
*
dest
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
beneficiary
:
Location
=
(
*
beneficiary
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
assets
:
Assets
=
(
*
assets
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
fees_id
:
AssetId
=
(
*
fees_id
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
fees_id
:
AssetId
=
(
*
remote_fees_id
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
let
remote_xcm
:
Xcm
<
()
>
=
(
*
custom_xcm_on_dest
)
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
;
log
::
debug!
(
target
:
"xcm::pallet_xcm::transfer_assets_using_type"
,
"origin {:?}, dest {:?}, beneficiary {:?}, assets {:?} through {:?}, fees-id {:?} through {:?}"
,
origin_location
,
dest
,
beneficiary
,
assets
,
assets_transfer_type
,
fees_id
,
fees_transfer_type
,
target
:
"xcm::pallet_xcm::transfer_assets_using_type_and_then"
,
"origin {origin_location:?}, dest {dest:?}, assets {assets:?} through {assets_transfer_type:?},
\
remote_fees_id {fees_id:?} through {fees_transfer_type:?},
\
custom_xcm_on_dest {remote_xcm:?}, weight-limit {weight_limit:?}"
,
);
let
assets
=
assets
.into_inner
();
...
...
@@ -1475,7 +1390,7 @@ pub mod pallet {
Self
::
do_transfer_assets
(
origin_location
,
dest
,
beneficiary
,
Either
::
Right
(
remote_xcm
)
,
assets
,
*
assets_transfer_type
,
fee_asset_index
,
...
...
@@ -1650,7 +1565,7 @@ impl<T: Config> Pallet<T> {
let
(
local_xcm
,
remote_xcm
)
=
Self
::
build_xcm_transfer_type
(
origin
.clone
(),
dest
.clone
(),
beneficiary
,
Either
::
Left
(
beneficiary
)
,
assets
,
assets_transfer_type
,
FeesHandling
::
Batched
{
fees
},
...
...
@@ -1692,7 +1607,7 @@ impl<T: Config> Pallet<T> {
let
(
local_xcm
,
remote_xcm
)
=
Self
::
build_xcm_transfer_type
(
origin_location
.clone
(),
dest
.clone
(),
beneficiary
,
Either
::
Left
(
beneficiary
)
,
assets
,
TransferType
::
Teleport
,
FeesHandling
::
Batched
{
fees
},
...
...
@@ -1704,7 +1619,7 @@ impl<T: Config> Pallet<T> {
fn
do_transfer_assets
(
origin
:
Location
,
dest
:
Location
,
beneficiary
:
Location
,
beneficiary
:
Either
<
Location
,
Xcm
<
()
>>
,
mut
assets
:
Vec
<
Asset
>
,
assets_transfer_type
:
TransferType
,
fee_asset_index
:
usize
,
...
...
@@ -1770,7 +1685,7 @@ impl<T: Config> Pallet<T> {
fn
build_xcm_transfer_type
(
origin
:
Location
,
dest
:
Location
,
beneficiary
:
Location
,
beneficiary
:
Either
<
Location
,
Xcm
<
()
>>
,
assets
:
Vec
<
Asset
>
,
transfer_type
:
TransferType
,
fees
:
FeesHandling
<
T
>
,
...
...
@@ -1782,57 +1697,51 @@ impl<T: Config> Pallet<T> {
fees_handling {:?}, weight_limit: {:?}"
,
origin
,
dest
,
beneficiary
,
assets
,
transfer_type
,
fees
,
weight_limit
,
);
Ok
(
match
transfer_type
{
TransferType
::
LocalReserve
=>
{
let
(
local
,
remote
)
=
Self
::
local_reserve_transfer_programs
(
match
transfer_type
{
TransferType
::
LocalReserve
=>
Self
::
local_reserve_transfer_programs
(
origin
.clone
(),
dest
.clone
(),
beneficiary
,
assets
,
fees
,
weight_limit
,
)
?
;
(
local
,
Some
(
remote
))
},
TransferType
::
DestinationReserve
=>
{
let
(
local
,
remote
)
=
Self
::
destination_reserve_transfer_programs
(
)
.map
(|(
local
,
remote
)|
(
local
,
Some
(
remote
))),
TransferType
::
DestinationReserve
=>
Self
::
destination_reserve_transfer_programs
(
origin
.clone
(),
dest
.clone
(),
beneficiary
,
assets
,
fees
,
weight_limit
,
)
?
;
(
local
,
Some
(
remote
))
},
)
.map
(|(
local
,
remote
)|
(
local
,
Some
(
remote
))),
TransferType
::
RemoteReserve
(
reserve
)
=>
{
let
fees
=
match
fees
{
FeesHandling
::
Batched
{
fees
}
=>
fees
,
_
=>
return
Err
(
Error
::
<
T
>
::
InvalidAssetUnsupportedReserve
.into
()),
};
let
local
=
Self
::
remote_reserve_transfer_program
(
Self
::
remote_reserve_transfer_program
(
origin
.clone
(),
reserve
.try_into
()
.map_err
(|()|
Error
::
<
T
>
::
BadVersion
)
?
,
dest
.clone
(),
beneficiary
,
dest
.clone
(),
assets
,
fees
,
weight_limit
,
)
?
;
(
local
,
None
)
)
.map
(|
local
|
(
local
,
None
)
)
},
TransferType
::
Teleport
=>
{
let
(
local
,
remote
)
=
Self
::
teleport_assets_program
(
TransferType
::
Teleport
=>
Self
::
teleport_assets_program
(
origin
.clone
(),
dest
.clone
(),
beneficiary
,
assets
,
fees
,
weight_limit
,
)
?
;
(
local
,
Some
(
remote
))
},
})
)
.map
(|(
local
,
remote
)|
(
local
,
Some
(
remote
))),
}
}
fn
execute_xcm_transfer
(
...
...
@@ -1947,7 +1856,7 @@ impl<T: Config> Pallet<T> {
fn
local_reserve_transfer_programs
(
origin
:
Location
,
dest
:
Location
,
beneficiary
:
Location
,
beneficiary
:
Either
<
Location
,
Xcm
<
()
>>
,
assets
:
Vec
<
Asset
>
,
fees
:
FeesHandling
<
T
>
,
weight_limit
:
WeightLimit
,
...
...
@@ -1980,10 +1889,16 @@ impl<T: Config> Pallet<T> {
]);
// handle fees
Self
::
add_fees_to_xcm
(
dest
,
fees
,
weight_limit
,
&
mut
local_execute_xcm
,
&
mut
xcm_on_dest
)
?
;
// Use custom XCM on remote chain, or just default to depositing everything to beneficiary.
let
custom_remote_xcm
=
match
beneficiary
{
Either
::
Right
(
custom_xcm
)
=>
custom_xcm
,
Either
::
Left
(
beneficiary
)
=>
{
// deposit all remaining assets in holding to `beneficiary` location
xcm_on_dest
.inner_mut
()
.push
(
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
});
Xcm
(
vec!
[
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
}])
},
};
xcm_on_dest
.0
.extend
(
custom_remote_xcm
.into_iter
());
Ok
((
local_execute_xcm
,
xcm_on_dest
))
}
...
...
@@ -2022,7 +1937,7 @@ impl<T: Config> Pallet<T> {
fn
destination_reserve_transfer_programs
(
origin
:
Location
,
dest
:
Location
,
beneficiary
:
Location
,
beneficiary
:
Either
<
Location
,
Xcm
<
()
>>
,
assets
:
Vec
<
Asset
>
,
fees
:
FeesHandling
<
T
>
,
weight_limit
:
WeightLimit
,
...
...
@@ -2058,10 +1973,15 @@ impl<T: Config> Pallet<T> {
// handle fees
Self
::
add_fees_to_xcm
(
dest
,
fees
,
weight_limit
,
&
mut
local_execute_xcm
,
&
mut
xcm_on_dest
)
?
;
// Use custom XCM on remote chain, or just default to depositing everything to beneficiary.
let
custom_remote_xcm
=
match
beneficiary
{
Either
::
Right
(
custom_xcm
)
=>
custom_xcm
,
Either
::
Left
(
beneficiary
)
=>
{
// deposit all remaining assets in holding to `beneficiary` location
xcm_on_dest
.inner_mut
()
.push
(
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
});
Xcm
(
vec!
[
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
}])
},
};
xcm_on_dest
.0
.extend
(
custom_remote_xcm
.into_iter
());
Ok
((
local_execute_xcm
,
xcm_on_dest
))
}
...
...
@@ -2070,8 +1990,8 @@ impl<T: Config> Pallet<T> {
fn
remote_reserve_transfer_program
(
origin
:
Location
,
reserve
:
Location
,
beneficiary
:
Either
<
Location
,
Xcm
<
()
>>
,
dest
:
Location
,
beneficiary
:
Location
,
assets
:
Vec
<
Asset
>
,
fees
:
Asset
,
weight_limit
:
WeightLimit
,
...
...
@@ -2096,10 +2016,17 @@ impl<T: Config> Pallet<T> {
// identifies `dest` as seen by `reserve`
let
dest
=
dest
.reanchored
(
&
reserve
,
&
context
)
.map_err
(|
_
|
Error
::
<
T
>
::
CannotReanchor
)
?
;
// xcm to be executed at dest
let
xcm_on_dest
=
Xcm
(
vec!
[
BuyExecution
{
fees
:
dest_fees
,
weight_limit
:
weight_limit
.clone
()
},
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
},
]);
let
mut
xcm_on_dest
=
Xcm
(
vec!
[
BuyExecution
{
fees
:
dest_fees
,
weight_limit
:
weight_limit
.clone
()
}]);
// Use custom XCM on remote chain, or just default to depositing everything to beneficiary.
let
custom_xcm_on_dest
=
match
beneficiary
{
Either
::
Right
(
custom_xcm
)
=>
custom_xcm
,
Either
::
Left
(
beneficiary
)
=>
{
// deposit all remaining assets in holding to `beneficiary` location
Xcm
(
vec!
[
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
}])
},
};
xcm_on_dest
.0
.extend
(
custom_xcm_on_dest
.into_iter
());
// xcm to be executed on reserve
let
xcm_on_reserve
=
Xcm
(
vec!
[
BuyExecution
{
fees
:
reserve_fees
,
weight_limit
},
...
...
@@ -2171,7 +2098,7 @@ impl<T: Config> Pallet<T> {
fn
teleport_assets_program
(
origin
:
Location
,
dest
:
Location
,
beneficiary
:
Location
,
beneficiary
:
Either
<
Location
,
Xcm
<
()
>>
,
assets
:
Vec
<
Asset
>
,
fees
:
FeesHandling
<
T
>
,
weight_limit
:
WeightLimit
,
...
...
@@ -2231,10 +2158,16 @@ impl<T: Config> Pallet<T> {
]);
// handle fees
Self
::
add_fees_to_xcm
(
dest
,
fees
,
weight_limit
,
&
mut
local_execute_xcm
,
&
mut
xcm_on_dest
)
?
;
// Use custom XCM on remote chain, or just default to depositing everything to beneficiary.
let
custom_remote_xcm
=
match
beneficiary
{
Either
::
Right
(
custom_xcm
)
=>
custom_xcm
,
Either
::
Left
(
beneficiary
)
=>
{
// deposit all remaining assets in holding to `beneficiary` location
xcm_on_dest
.inner_mut
()
.push
(
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
});
Xcm
(
vec!
[
DepositAsset
{
assets
:
Wild
(
AllCounted
(
max_assets
)),
beneficiary
}])
},
};
xcm_on_dest
.0
.extend
(
custom_remote_xcm
.into_iter
());
Ok
((
local_execute_xcm
,
xcm_on_dest
))
}
...
...
polkadot/xcm/pallet-xcm/src/mock.rs
View file @
aceda465
...
...
@@ -33,10 +33,11 @@ use xcm::prelude::*;
use
xcm_builder
::{
AccountId32Aliases
,
AllowKnownQueryResponses
,
AllowSubscriptionsFrom
,
AllowTopLevelPaidExecutionFrom
,
Case
,
ChildParachainAsNative
,
ChildParachainConvertsVia
,
ChildSystemParachainAsSuperuser
,
DescribeAllTerminal
,
FixedRateOfFungible
,
FixedWeightBounds
,
FrameTransactionalProcessor
,
FungibleAdapter
,
FungiblesAdapter
,
HashedDescription
,
IsConcrete
,
MatchedConvertedConcreteId
,
NoChecking
,
SignedAccountId32AsNative
,
SignedToAccountId32
,
SovereignSignedViaLocation
,
TakeWeightCredit
,
XcmFeeManagerFromComponents
,
XcmFeeToAccount
,
ChildSystemParachainAsSuperuser
,
DescribeAllTerminal
,
EnsureDecodableXcm
,
FixedRateOfFungible
,
FixedWeightBounds
,
FrameTransactionalProcessor
,
FungibleAdapter
,
FungiblesAdapter
,
HashedDescription
,
IsConcrete
,
MatchedConvertedConcreteId
,
NoChecking
,
SignedAccountId32AsNative
,
SignedToAccountId32
,
SovereignSignedViaLocation
,
TakeWeightCredit
,
XcmFeeManagerFromComponents
,
XcmFeeToAccount
,
};
use
xcm_executor
::{
traits
::{
Identity
,
JustTry
},
...
...
@@ -413,7 +414,7 @@ parameter_types! {
)),
};
pub
const
AnyNetwork
:
Option
<
NetworkId
>
=
None
;
pub
UniversalLocation
:
InteriorLocation
=
Here
;
pub
UniversalLocation
:
InteriorLocation
=
GlobalConsensus
(
ByGenesis
([
0
;
32
]))
.into
()
;
pub
UnitWeightCost
:
u64
=
1_000
;
pub
CheckingAccount
:
AccountId
=
XcmPallet
::
check_account
();
}
...
...
@@ -488,7 +489,8 @@ pub type Barrier = (
AllowSubscriptionsFrom
<
Everything
>
,
);
pub
type
XcmRouter
=
(
TestPaidForPara3000SendXcm
,
TestSendXcmErrX8
,
TestSendXcm
);
pub
type
XcmRouter
=
EnsureDecodableXcm
<
(
TestPaidForPara3000SendXcm
,
TestSendXcmErrX8
,
TestSendXcm
)
>
;
pub
struct
XcmConfig
;
impl
xcm_executor
::
Config
for
XcmConfig
{
...
...
polkadot/xcm/pallet-xcm/src/tests/mod.rs
View file @
aceda465
...
...
@@ -20,10 +20,10 @@ pub(crate) mod assets_transfer;
use
crate
::{
mock
::
*
,
pallet
::
SupportedVersion
,
AssetTraps
,
Config
,
CurrentMigration
,
Error
,
LatestVersionedLocation
,
Pallet
,
Queries
,
QueryStatus
,
VersionDiscoveryQueue
,
VersionMigrationStage
,
VersionNotifiers
,
VersionNotifyTargets
,
WeightInfo
,
ExecuteControllerWeightInfo
,
LatestVersionedLocation
,
Pallet
,
Queries
,
QueryStatus
,
VersionDiscoveryQueue
,
VersionMigrationStage
,
VersionNotifiers
,
VersionNotifyTargets
,
WeightInfo
,
};
use
codec
::
Encode
;
use
frame_support
::{
assert_err_ignore_postinfo
,
assert_noop
,
assert_ok
,
traits
::{
Currency
,
Hooks
},
...
...
@@ -305,12 +305,11 @@ fn send_works() {
]);
let
versioned_dest
=
Box
::
new
(
RelayLocation
::
get
()
.into
());
let
versioned_message
=
VersionedXcm
::
from
(
message
.clone
());
let
encoded_versioned_message
=
versioned_message
.encode
()
.try_into
()
.unwrap
();
assert_ok!
(
XcmPallet
::
send_blob
(
let
versioned_message
=
Box
::
new
(
VersionedXcm
::
from
(
message
.clone
()));
assert_ok!
(
XcmPallet
::
send
(
RuntimeOrigin
::
signed
(
ALICE
),
versioned_dest
,
encoded_
versioned_message
versioned_message
));
let
sent_message
=
Xcm
(
Some
(
DescendOrigin
(
sender
.clone
()
.try_into
()
.unwrap
()))
.into_iter
()
...
...
@@ -342,16 +341,16 @@ fn send_fails_when_xcm_router_blocks() {
];
new_test_ext_with_balances
(
balances
)
.execute_with
(||
{
let
sender
:
Location
=
Junction
::
AccountId32
{
network
:
None
,
id
:
ALICE
.into
()
}
.into
();
let
message
=
Xcm
::
<
()
>
(
vec!
[
let
message
=
Xcm
(
vec!
[
ReserveAssetDeposited
((
Parent
,
SEND_AMOUNT
)
.into
()),
buy_execution
((
Parent
,
SEND_AMOUNT
)),
DepositAsset
{
assets
:
AllCounted
(
1
)
.into
(),
beneficiary
:
sender
},
]);
assert_noop!
(
XcmPallet
::
send
_blob
(
XcmPallet
::
send
(
RuntimeOrigin
::
signed
(
ALICE
),
Box
::
new
(
Location
::
ancestor
(
8
)
.into
()),
VersionedXcm
::
from
(
message
.clone
())
.encode
()
.try_into
()
.unwrap
(
),
Box
::
new
(
VersionedXcm
::
from
(
message
.clone
())),
),
crate
::
Error
::
<
Test
>
::
SendFailure
);
...
...
@@ -372,16 +371,13 @@ fn execute_withdraw_to_deposit_works() {
let
weight
=
BaseXcmWeight
::
get
()
*
3
;
let
dest
:
Location
=
Junction
::
AccountId32
{
network
:
None
,
id
:
BOB
.into
()
}
.into
();
assert_eq!
(
Balances
::
total_balance
(
&
ALICE
),
INITIAL_BALANCE
);
assert_ok!
(
XcmPallet
::
execute
_blob
(
assert_ok!
(
XcmPallet
::
execute
(
RuntimeOrigin
::
signed
(
ALICE
),
VersionedXcm
::
from
(
Xcm
::
<
RuntimeCall
>
(
vec!
[
Box
::
new
(
VersionedXcm
::
from
(
Xcm
(
vec!
[
WithdrawAsset
((
Here
,
SEND_AMOUNT
)
.into
()),
buy_execution
((
Here
,
SEND_AMOUNT
)),
DepositAsset
{
assets
:
AllCounted
(
1
)
.into
(),
beneficiary
:
dest
},
]))
.encode
()
.try_into
()
.unwrap
(),
]))),
weight
));
assert_eq!
(
Balances
::
total_balance
(
&
ALICE
),
INITIAL_BALANCE
-
SEND_AMOUNT
);
...
...
@@ -403,21 +399,18 @@ fn trapped_assets_can_be_claimed() {
let
weight
=
BaseXcmWeight
::
get
()
*
6
;
let
dest
:
Location
=
Junction
::
AccountId32
{
network
:
None
,
id
:
BOB
.into
()
}
.into
();
assert_ok!
(
XcmPallet
::
execute
_blob
(
assert_ok!
(
XcmPallet
::
execute
(
RuntimeOrigin
::
signed
(
ALICE
),
VersionedXcm
::
from
(
Xcm
(
vec!
[
Box
::
new
(
VersionedXcm
::
from
(
Xcm
(
vec!
[
WithdrawAsset
((
Here
,
SEND_AMOUNT
)
.into
()),
buy_execution
((
Here
,
SEND_AMOUNT
)),
// Don't propagated the error into the result.
SetErrorHandler
(
Xcm
::
<
RuntimeCall
>
(
vec!
[
ClearError
])),
SetErrorHandler
(
Xcm
(
vec!
[
ClearError
])),
// This will make an error.
Trap
(
0
),
// This would succeed, but we never get to it.
DepositAsset
{
assets
:
AllCounted
(
1
)
.into
(),
beneficiary
:
dest
.clone
()
},
]))
.encode
()
.try_into
()
.unwrap
(),
]))),
weight
));
let
source
:
Location
=
Junction
::
AccountId32
{
network
:
None
,
id
:
ALICE
.into
()
}
.into
();
...
...
@@ -444,16 +437,13 @@ fn trapped_assets_can_be_claimed() {
assert_eq!
(
trapped
,
expected
);
let
weight
=
BaseXcmWeight
::
get
()
*
3
;
assert_ok!
(
XcmPallet
::
execute
_blob
(
assert_ok!
(
XcmPallet
::
execute
(
RuntimeOrigin
::
signed
(
ALICE
),
VersionedXcm
::
from
(
Xcm
::
<
RuntimeCall
>
(
vec!
[
Box
::
new
(
VersionedXcm
::
from
(
Xcm
(
vec!
[
ClaimAsset
{
assets
:
(
Here
,
SEND_AMOUNT
)
.into
(),
ticket
:
Here
.into
()
},
buy_execution
((
Here
,
SEND_AMOUNT
)),
DepositAsset
{
assets
:
AllCounted
(
1
)
.into
(),
beneficiary
:
dest
.clone
()
},
]))
.encode
()
.try_into
()
.unwrap
(),
]))),
weight
));
...
...
@@ -463,16 +453,13 @@ fn trapped_assets_can_be_claimed() {
// Can't claim twice.
assert_err_ignore_postinfo!
(
XcmPallet
::
execute
_blob
(
XcmPallet
::
execute
(
RuntimeOrigin
::
signed
(
ALICE
),
VersionedXcm
::
from
(
Xcm
::
<
RuntimeCall
>
(
vec!
[
Box
::
new
(
VersionedXcm
::
from
(
Xcm
(
vec!
[
ClaimAsset
{
assets
:
(
Here
,
SEND_AMOUNT
)
.into
(),
ticket
:
Here
.into
()
},
buy_execution
((
Here
,
SEND_AMOUNT
)),
DepositAsset
{
assets
:
AllCounted
(
1
)
.into
(),
beneficiary
:
dest
},
]))
.encode
()
.try_into
()
.unwrap
(),
]))),
weight
),
Error
::
<
Test
>
::
LocalExecutionIncomplete
...
...
@@ -489,9 +476,9 @@ fn claim_assets_works() {
let
trapping_program
=
Xcm
::
<
RuntimeCall
>
::
builder_unsafe
()
.withdraw_asset
((
Here
,
SEND_AMOUNT
))
.build
();
// Even though assets are trapped, the extrinsic returns success.
assert_ok!
(
XcmPallet
::
execute
_blob
(
assert_ok!
(
XcmPallet
::
execute
(
RuntimeOrigin
::
signed
(
ALICE
),
VersionedXcm
::
V4
(
trapping_program
)
.encode
()
.try_into
()
.unwrap
(
),
Box
::
new
(
VersionedXcm
::
V4
(
trapping_program
)),
BaseXcmWeight
::
get
()
*
2
,
));
assert_eq!
(
Balances
::
total_balance
(
&
ALICE
),
INITIAL_BALANCE
-
SEND_AMOUNT
);
...
...
@@ -544,9 +531,9 @@ fn incomplete_execute_reverts_side_effects() {
assert_eq!
(
Balances
::
total_balance
(
&
ALICE
),
INITIAL_BALANCE
);
let
amount_to_send
=
INITIAL_BALANCE
-
ExistentialDeposit
::
get
();
let
assets
:
Assets
=
(
Here
,
amount_to_send
)
.into
();
let
result
=
XcmPallet
::
execute
_blob
(
let
result
=
XcmPallet
::
execute
(
RuntimeOrigin
::
signed
(
ALICE
),
VersionedXcm
::
from
(
Xcm
::
<
RuntimeCall
>
(
vec!
[
Box
::
new
(
VersionedXcm
::
from
(
Xcm
(
vec!
[
// Withdraw + BuyExec + Deposit should work
WithdrawAsset
(
assets
.clone
()),
buy_execution
(
assets
.inner
()[
0
]
.clone
()),
...
...
@@ -554,10 +541,7 @@ fn incomplete_execute_reverts_side_effects() {
// Withdrawing once more will fail because of InsufficientBalance, and we expect to
// revert the effects of the above instructions as well
WithdrawAsset
(
assets
),
]))
.encode
()
.try_into
()
.unwrap
(),
]))),
weight
,
);
// all effects are reverted and balances unchanged for either sender or receiver
...
...
@@ -569,7 +553,7 @@ fn incomplete_execute_reverts_side_effects() {
Err
(
sp_runtime
::
DispatchErrorWithPostInfo
{
post_info
:
frame_support
::
dispatch
::
PostDispatchInfo
{
actual_weight
:
Some
(
<<
Test
as
crate
::
Config
>
::
WeightInfo
>
::
execute
_blob
()
+
weight
<
Pallet
<
Test
>
as
ExecuteController
WeightInfo
>
::
execute
()
+
weight
),
pays_fee
:
frame_support
::
dispatch
::
Pays
::
Yes
,
},
...
...
polkadot/xcm/src/lib.rs
View file @
aceda465
...
...
@@ -25,7 +25,7 @@
extern
crate
alloc
;
use
derivative
::
Derivative
;
use
parity_scale_codec
::{
Decode
,
Encode
,
Error
as
CodecError
,
Input
,
MaxEncodedLen
};
use
parity_scale_codec
::{
Decode
,
DecodeLimit
,
Encode
,
Error
as
CodecError
,
Input
,
MaxEncodedLen
};
use
scale_info
::
TypeInfo
;
pub
mod
v2
;
...
...
@@ -48,9 +48,6 @@ mod tests;
/// Maximum nesting level for XCM decoding.
pub
const
MAX_XCM_DECODE_DEPTH
:
u32
=
8
;
/// Maximum encoded size.
/// See `decoding_respects_limit` test for more reasoning behind this value.
pub
const
MAX_XCM_ENCODED_SIZE
:
u32
=
12402
;
/// A version of XCM.
pub
type
Version
=
u32
;
...
...
@@ -456,6 +453,23 @@ impl<C> IdentifyVersion for VersionedXcm<C> {
}
}
impl
<
C
>
VersionedXcm
<
C
>
{
/// Checks that the XCM is decodable with `MAX_XCM_DECODE_DEPTH`. Consequently, it also checks
/// all decode implementations and limits, such as MAX_ITEMS_IN_ASSETS or
/// MAX_INSTRUCTIONS_TO_DECODE.
///
/// Note that this uses the limit of the sender - not the receiver. It is a best effort.
pub
fn
validate_xcm_nesting
(
&
self
)
->
Result
<
(),
()
>
{
self
.using_encoded
(|
mut
enc
|
{
Self
::
decode_all_with_depth_limit
(
MAX_XCM_DECODE_DEPTH
,
&
mut
enc
)
.map
(|
_
|
())
})
.map_err
(|
e
|
{
log
::
error!
(
target
:
"xcm::validate_xcm_nesting"
,
"Decode error: {e:?} for xcm: {self:?}!"
);
()
})
}
}
impl
<
RuntimeCall
>
From
<
v2
::
Xcm
<
RuntimeCall
>>
for
VersionedXcm
<
RuntimeCall
>
{
fn
from
(
x
:
v2
::
Xcm
<
RuntimeCall
>
)
->
Self
{
VersionedXcm
::
V2
(
x
)
...
...
@@ -704,3 +718,77 @@ fn size_limits() {
}
assert!
(
!
test_failed
);
}
#[test]
fn
validate_xcm_nesting_works
()
{
use
crate
::
latest
::{
prelude
::{
GeneralIndex
,
ReserveAssetDeposited
,
SetAppendix
},
Assets
,
Xcm
,
MAX_INSTRUCTIONS_TO_DECODE
,
MAX_ITEMS_IN_ASSETS
,
};
// closure generates assets of `count`
let
assets
=
|
count
|
{
let
mut
assets
=
Assets
::
new
();
for
i
in
0
..
count
{
assets
.push
((
GeneralIndex
(
i
as
u128
),
100
)
.into
());
}
assets
};
// closer generates `Xcm` with nested instructions of `depth`
let
with_instr
=
|
depth
|
{
let
mut
xcm
=
Xcm
::
<
()
>
(
vec!
[]);
for
_
in
0
..
depth
-
1
{
xcm
=
Xcm
::
<
()
>
(
vec!
[
SetAppendix
(
xcm
)]);
}
xcm
};
// `MAX_INSTRUCTIONS_TO_DECODE` check
assert!
(
VersionedXcm
::
<
()
>
::
from
(
Xcm
(
vec!
[
ReserveAssetDeposited
(
assets
(
1
));
(
MAX_INSTRUCTIONS_TO_DECODE
-
1
)
as
usize
]))
.validate_xcm_nesting
()
.is_ok
());
assert!
(
VersionedXcm
::
<
()
>
::
from
(
Xcm
(
vec!
[
ReserveAssetDeposited
(
assets
(
1
));
MAX_INSTRUCTIONS_TO_DECODE
as
usize
]))
.validate_xcm_nesting
()
.is_ok
());
assert!
(
VersionedXcm
::
<
()
>
::
from
(
Xcm
(
vec!
[
ReserveAssetDeposited
(
assets
(
1
));
(
MAX_INSTRUCTIONS_TO_DECODE
+
1
)
as
usize
]))
.validate_xcm_nesting
()
.is_err
());
// `MAX_XCM_DECODE_DEPTH` check
assert!
(
VersionedXcm
::
<
()
>
::
from
(
with_instr
(
MAX_XCM_DECODE_DEPTH
-
1
))
.validate_xcm_nesting
()
.is_ok
());
assert!
(
VersionedXcm
::
<
()
>
::
from
(
with_instr
(
MAX_XCM_DECODE_DEPTH
))
.validate_xcm_nesting
()
.is_ok
());
assert!
(
VersionedXcm
::
<
()
>
::
from
(
with_instr
(
MAX_XCM_DECODE_DEPTH
+
1
))
.validate_xcm_nesting
()
.is_err
());
// `MAX_ITEMS_IN_ASSETS` check
assert!
(
VersionedXcm
::
<
()
>
::
from
(
Xcm
(
vec!
[
ReserveAssetDeposited
(
assets
(
MAX_ITEMS_IN_ASSETS
))]))
.validate_xcm_nesting
()
.is_ok
());
assert!
(
VersionedXcm
::
<
()
>
::
from
(
Xcm
(
vec!
[
ReserveAssetDeposited
(
assets
(
MAX_ITEMS_IN_ASSETS
-
1
))]))
.validate_xcm_nesting
()
.is_ok
());
assert!
(
VersionedXcm
::
<
()
>
::
from
(
Xcm
(
vec!
[
ReserveAssetDeposited
(
assets
(
MAX_ITEMS_IN_ASSETS
+
1
))]))
.validate_xcm_nesting
()
.is_err
());
}
polkadot/xcm/src/v3/multiasset.rs
View file @
aceda465
...
...
@@ -825,7 +825,9 @@ impl MultiAssets {
/// Prepend a `MultiLocation` to any concrete asset items, giving it a new root location.
pub
fn
prepend_with
(
&
mut
self
,
prefix
:
&
MultiLocation
)
->
Result
<
(),
()
>
{
self
.0
.iter_mut
()
.try_for_each
(|
i
|
i
.prepend_with
(
prefix
))
self
.0
.iter_mut
()
.try_for_each
(|
i
|
i
.prepend_with
(
prefix
))
?
;
self
.0
.sort
();
Ok
(())
}
/// Mutate the location of the asset identifier if concrete, giving it the same location
...
...
@@ -1213,8 +1215,73 @@ mod tests {
vec!
[
asset_1
.clone
(),
asset_2
.clone
(),
asset_3
.clone
()]
.into
();
assert_eq!
(
assets
.clone
(),
vec!
[
asset_1
.clone
(),
asset_2
.clone
(),
asset_3
.clone
()]
.into
());
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
MultiAssets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
assert!
(
assets
.reanchor
(
&
dest
,
reanchor_context
)
.is_ok
());
assert_eq!
(
assets
,
vec!
[
asset_2_reanchored
,
asset_3_reanchored
,
asset_1_reanchored
]
.into
());
assert_eq!
(
assets
.0
,
vec!
[
asset_2_reanchored
,
asset_3_reanchored
,
asset_1_reanchored
]);
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
MultiAssets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
}
#[test]
fn
prepend_preserves_sorting
()
{
use
super
::
*
;
use
alloc
::
vec
;
let
prefix
=
MultiLocation
::
new
(
0
,
X1
(
Parachain
(
1000
)));
let
asset_1
:
MultiAsset
=
(
MultiLocation
::
new
(
0
,
X2
(
PalletInstance
(
50
),
GeneralIndex
(
1
))),
10
)
.into
();
let
mut
asset_1_prepended
=
asset_1
.clone
();
assert!
(
asset_1_prepended
.prepend_with
(
&
prefix
)
.is_ok
());
// changes interior X2->X3
assert_eq!
(
asset_1_prepended
,
(
MultiLocation
::
new
(
0
,
X3
(
Parachain
(
1000
),
PalletInstance
(
50
),
GeneralIndex
(
1
))),
10
)
.into
()
);
let
asset_2
:
MultiAsset
=
(
MultiLocation
::
new
(
1
,
X2
(
PalletInstance
(
50
),
GeneralIndex
(
1
))),
10
)
.into
();
let
mut
asset_2_prepended
=
asset_2
.clone
();
assert!
(
asset_2_prepended
.prepend_with
(
&
prefix
)
.is_ok
());
// changes parent
assert_eq!
(
asset_2_prepended
,
(
MultiLocation
::
new
(
0
,
X2
(
PalletInstance
(
50
),
GeneralIndex
(
1
))),
10
)
.into
()
);
let
asset_3
:
MultiAsset
=
(
MultiLocation
::
new
(
2
,
X2
(
PalletInstance
(
50
),
GeneralIndex
(
1
))),
10
)
.into
();
let
mut
asset_3_prepended
=
asset_3
.clone
();
assert!
(
asset_3_prepended
.prepend_with
(
&
prefix
)
.is_ok
());
// changes parent
assert_eq!
(
asset_3_prepended
,
(
MultiLocation
::
new
(
1
,
X2
(
PalletInstance
(
50
),
GeneralIndex
(
1
))),
10
)
.into
()
);
// `From` impl does sorting.
let
mut
assets
:
MultiAssets
=
vec!
[
asset_1
,
asset_2
,
asset_3
]
.into
();
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
MultiAssets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
// let's do `prepend_with`
assert!
(
assets
.prepend_with
(
&
prefix
)
.is_ok
());
assert_eq!
(
assets
.0
,
vec!
[
asset_2_prepended
,
asset_1_prepended
,
asset_3_prepended
]);
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
MultiAssets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
}
#[test]
...
...
polkadot/xcm/src/v4/asset.rs
View file @
aceda465
...
...
@@ -723,7 +723,9 @@ impl Assets {
/// Prepend a `Location` to any concrete asset items, giving it a new root location.
pub
fn
prepend_with
(
&
mut
self
,
prefix
:
&
Location
)
->
Result
<
(),
()
>
{
self
.0
.iter_mut
()
.try_for_each
(|
i
|
i
.prepend_with
(
prefix
))
self
.0
.iter_mut
()
.try_for_each
(|
i
|
i
.prepend_with
(
prefix
))
?
;
self
.0
.sort
();
Ok
(())
}
/// Return a reference to an item at a specific index or `None` if it doesn't exist.
...
...
@@ -1035,8 +1037,61 @@ mod tests {
let
mut
assets
:
Assets
=
vec!
[
asset_1
.clone
(),
asset_2
.clone
(),
asset_3
.clone
()]
.into
();
assert_eq!
(
assets
.clone
(),
vec!
[
asset_1
.clone
(),
asset_2
.clone
(),
asset_3
.clone
()]
.into
());
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
Assets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
assert!
(
assets
.reanchor
(
&
dest
,
&
reanchor_context
)
.is_ok
());
assert_eq!
(
assets
,
vec!
[
asset_2_reanchored
,
asset_3_reanchored
,
asset_1_reanchored
]
.into
());
assert_eq!
(
assets
.0
,
vec!
[
asset_2_reanchored
,
asset_3_reanchored
,
asset_1_reanchored
]);
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
Assets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
}
#[test]
fn
prepend_preserves_sorting
()
{
use
super
::
*
;
use
alloc
::
vec
;
let
prefix
=
Location
::
new
(
0
,
[
Parachain
(
1000
)]);
let
asset_1
:
Asset
=
(
Location
::
new
(
0
,
[
PalletInstance
(
50
),
GeneralIndex
(
1
)]),
10
)
.into
();
let
mut
asset_1_prepended
=
asset_1
.clone
();
assert!
(
asset_1_prepended
.prepend_with
(
&
prefix
)
.is_ok
());
// changes interior X2->X3
assert_eq!
(
asset_1_prepended
,
(
Location
::
new
(
0
,
[
Parachain
(
1000
),
PalletInstance
(
50
),
GeneralIndex
(
1
)]),
10
)
.into
()
);
let
asset_2
:
Asset
=
(
Location
::
new
(
1
,
[
PalletInstance
(
50
),
GeneralIndex
(
1
)]),
10
)
.into
();
let
mut
asset_2_prepended
=
asset_2
.clone
();
assert!
(
asset_2_prepended
.prepend_with
(
&
prefix
)
.is_ok
());
// changes parent
assert_eq!
(
asset_2_prepended
,
(
Location
::
new
(
0
,
[
PalletInstance
(
50
),
GeneralIndex
(
1
)]),
10
)
.into
()
);
let
asset_3
:
Asset
=
(
Location
::
new
(
2
,
[
PalletInstance
(
50
),
GeneralIndex
(
1
)]),
10
)
.into
();
let
mut
asset_3_prepended
=
asset_3
.clone
();
assert!
(
asset_3_prepended
.prepend_with
(
&
prefix
)
.is_ok
());
// changes parent
assert_eq!
(
asset_3_prepended
,
(
Location
::
new
(
1
,
[
PalletInstance
(
50
),
GeneralIndex
(
1
)]),
10
)
.into
()
);
// `From` impl does sorting.
let
mut
assets
:
Assets
=
vec!
[
asset_1
,
asset_2
,
asset_3
]
.into
();
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
Assets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
// let's do `prepend_with`
assert!
(
assets
.prepend_with
(
&
prefix
)
.is_ok
());
assert_eq!
(
assets
.0
,
vec!
[
asset_2_prepended
,
asset_1_prepended
,
asset_3_prepended
]);
// decoding respects limits and sorting
assert!
(
assets
.using_encoded
(|
mut
enc
|
Assets
::
decode
(
&
mut
enc
)
.map
(|
_
|
()))
.is_ok
());
}
#[test]
...
...
polkadot/xcm/src/v4/mod.rs
View file @
aceda465
...
...
@@ -1488,21 +1488,7 @@ mod tests {
let
encoded
=
big_xcm
.encode
();
assert!
(
Xcm
::
<
()
>
::
decode
(
&
mut
&
encoded
[
..
])
.is_err
());
let
mut
many_assets
=
Assets
::
new
();
for
index
in
0
..
MAX_ITEMS_IN_ASSETS
{
many_assets
.push
((
GeneralIndex
(
index
as
u128
),
1u128
)
.into
());
}
let
full_xcm_pass
=
Xcm
::
<
()
>
(
vec!
[
TransferAsset
{
assets
:
many_assets
,
beneficiary
:
Here
.into
()
};
MAX_INSTRUCTIONS_TO_DECODE
as
usize
]);
let
encoded
=
full_xcm_pass
.encode
();
assert_eq!
(
encoded
.len
(),
12402
);
assert!
(
Xcm
::
<
()
>
::
decode
(
&
mut
&
encoded
[
..
])
.is_ok
());
let
nested_xcm_fail
=
Xcm
::
<
()
>
(
vec!
[
let
nested_xcm
=
Xcm
::
<
()
>
(
vec!
[
DepositReserveAsset
{
assets
:
All
.into
(),
dest
:
Here
.into
(),
...
...
@@ -1510,10 +1496,10 @@ mod tests {
};
(
MAX_INSTRUCTIONS_TO_DECODE
/
2
)
as
usize
]);
let
encoded
=
nested_xcm
_fail
.encode
();
let
encoded
=
nested_xcm
.encode
();
assert!
(
Xcm
::
<
()
>
::
decode
(
&
mut
&
encoded
[
..
])
.is_err
());
let
even_more_nested_xcm
=
Xcm
::
<
()
>
(
vec!
[
SetAppendix
(
nested_xcm
_fail
);
64
]);
let
even_more_nested_xcm
=
Xcm
::
<
()
>
(
vec!
[
SetAppendix
(
nested_xcm
);
64
]);
let
encoded
=
even_more_nested_xcm
.encode
();
assert_eq!
(
encoded
.len
(),
342530
);
// This should not decode since the limit is 100
...
...
Prev
1
…
7
8
9
10
11
12
13
14
15
…
17
Next