Upgrade evm-template to stable2412 (#407)

This commit is contained in:
Amar Singh
2025-04-30 09:20:07 -04:00
committed by GitHub
parent 2dbd3f8d28
commit 987536368c
19 changed files with 4417 additions and 2671 deletions
+103 -35
View File
@@ -8,6 +8,8 @@ use sp_std::{
prelude::*,
};
use xcm::latest::Location;
#[cfg(feature = "runtime-benchmarks")]
use xcm::v3::MultiLocation;
use crate::{
types::{AccountId, AssetId, Balance},
@@ -30,20 +32,35 @@ pallet_assets::runtime_benchmarks_enabled! {
// Our AssetType. For now we only handle Xcm Assets
#[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)]
pub enum AssetType {
Xcm(xcm::v3::Location),
Xcm(xcm::v4::Location),
}
impl Default for AssetType {
fn default() -> Self {
Self::Xcm(xcm::v3::Location::here())
Self::Xcm(xcm::v4::Location::here())
}
}
impl From<xcm::v3::Location> for AssetType {
fn from(location: xcm::v3::Location) -> Self {
impl From<xcm::v4::Location> for AssetType {
fn from(location: xcm::v4::Location) -> Self {
Self::Xcm(location)
}
}
#[cfg(feature = "runtime-benchmarks")]
fn convert_v3_to_v4(v3: MultiLocation) -> Option<xcm::v4::Location> {
Some(xcm::v4::Location {
parents: v3.parents,
interior: xcm::v4::Junctions::try_from(v3.interior).ok()?, // Returns None if conversion fails
})
}
#[cfg(feature = "runtime-benchmarks")]
impl From<MultiLocation> for AssetType {
fn from(value: MultiLocation) -> Self {
Self::Xcm(convert_v3_to_v4(value).unwrap_or(xcm::v4::Location::default()))
}
}
// This can be removed once we fully adopt xcm::v4 everywhere
impl TryFrom<Location> for AssetType {
type Error = ();
@@ -53,7 +70,7 @@ impl TryFrom<Location> for AssetType {
}
}
impl From<AssetType> for Option<xcm::v3::Location> {
impl From<AssetType> for Option<xcm::v4::Location> {
fn from(val: AssetType) -> Self {
match val {
AssetType::Xcm(location) => Some(location),
@@ -130,7 +147,7 @@ impl pallet_asset_manager::AssetRegistrar<Runtime> for AssetRegistrar {
// This is the dispatch info of destroy
RuntimeCall::Assets(pallet_assets::Call::<Runtime>::start_destroy { id: asset.into() })
.get_dispatch_info()
.weight
.call_weight
}
}
@@ -283,55 +300,106 @@ mod tests {
#[test]
fn test_asset_type_default() {
let default_asset_type = AssetType::default();
assert_eq!(
default_asset_type,
AssetType::Xcm(xcm::v3::Location {
parents: 0,
interior: xcm::v3::Junctions::Here
})
);
match default_asset_type {
AssetType::Xcm(location) => {
assert_eq!(location, xcm::v4::Location::here());
}
}
}
#[cfg(feature = "runtime-benchmarks")]
#[test]
fn test_asset_type_from_location_v3() {
let location = xcm::v3::Location {
parents: 0,
interior: xcm::v3::Junctions::X1(xcm::v3::Junction::OnlyChild),
};
let asset_type = AssetType::from(location);
let location =
xcm::v3::MultiLocation { parents: 1, interior: xcm::v3::Junctions::Here };
assert_eq!(asset_type, AssetType::Xcm(location));
// Use the From implementation directly
let asset_type = AssetType::from(location);
assert!(matches!(asset_type, AssetType::Xcm(_)));
}
#[test]
fn test_asset_type_try_from_location_v4() {
let location =
xcm::latest::Location { parents: 0, interior: xcm::latest::Junctions::Here };
let old_location: xcm::v3::Location =
xcm::v3::Location { parents: 0, interior: xcm::v3::Junctions::Here };
let asset_type = AssetType::try_from(location)
.expect("AssetType conversion from location v4 failed");
assert_eq!(asset_type, AssetType::Xcm(old_location));
let location = xcm::v4::Location { parents: 1, interior: xcm::v4::Junctions::Here };
let asset_type = AssetType::from(location.clone());
match asset_type {
AssetType::Xcm(loc) => assert_eq!(loc, location),
}
}
#[test]
fn test_asset_type_into_location() {
let location = xcm::v3::Location { parents: 0, interior: xcm::v3::Junctions::Here };
let asset_type = AssetType::Xcm(location);
let converted: Option<xcm::v3::Location> = asset_type.into();
assert_eq!(converted, Some(location));
let location = xcm::v4::Location::here();
let asset_type = AssetType::Xcm(location.clone());
let result: Option<xcm::v4::Location> = asset_type.into();
assert_eq!(result, Some(location));
}
#[test]
fn test_asset_type_into_asset_id() {
let location = xcm::v3::Location { parents: 0, interior: xcm::v3::Junctions::Here };
let expected_asset_id: u128 = 114990615950639921045101060455076456094;
let location = xcm::v4::Location { parents: 1, interior: xcm::v4::Junctions::Here };
let asset_type = AssetType::Xcm(location);
let asset_id: AssetId = asset_type.into();
assert!(asset_id > 0);
}
let asset_id = AssetId::from(asset_type);
#[cfg(feature = "runtime-benchmarks")]
#[test]
fn test_convert_v3_to_v4() {
use std::sync::Arc;
assert_eq!(asset_id, expected_asset_id);
use xcm::v3::{Junction as JunctionV3, Junctions as JunctionsV3, MultiLocation};
use crate::configs::convert_v3_to_v4;
// Test with Here junctions
let v3_location = MultiLocation { parents: 1, interior: JunctionsV3::Here };
let v4_location = convert_v3_to_v4(v3_location).unwrap();
assert_eq!(v4_location.parents, 1);
assert_eq!(v4_location.interior, xcm::v4::Junctions::Here);
// Test with X1 junction
let v3_location = MultiLocation {
parents: 0,
interior: JunctionsV3::X1(JunctionV3::Parachain(1000)),
};
let v4_location = convert_v3_to_v4(v3_location).unwrap();
assert_eq!(v4_location.parents, 0);
// Create X1 junction with Arc
let junction_array = Arc::new([xcm::v4::Junction::Parachain(1000)]);
let expected_interior = xcm::v4::Junctions::X1(junction_array);
assert_eq!(v4_location.interior, expected_interior);
}
#[cfg(feature = "runtime-benchmarks")]
#[test]
fn test_from_multilocation_for_asset_type() {
use std::sync::Arc;
use xcm::v3::{Junction as JunctionV3, Junctions as JunctionsV3, MultiLocation};
// Test with valid conversion
let v3_location = MultiLocation { parents: 1, interior: JunctionsV3::Here };
let asset_type = AssetType::from(v3_location);
assert!(matches!(asset_type, AssetType::Xcm(_)));
// Test with more complex location
let v3_location = MultiLocation {
parents: 0,
interior: JunctionsV3::X1(JunctionV3::Parachain(1000)),
};
let asset_type = AssetType::from(v3_location);
match asset_type {
AssetType::Xcm(location) => {
assert_eq!(location.parents, 0);
// Create X1 junction with Arc
let junction_array = Arc::new([xcm::v4::Junction::Parachain(1000)]);
let expected_interior = xcm::v4::Junctions::X1(junction_array);
assert_eq!(location.interior, expected_interior);
}
}
}
}
}
+5 -6
View File
@@ -71,7 +71,7 @@ use xcm_builder::{
};
use xcm_config::*;
use xcm_executor::XcmExecutor;
use xcm_primitives::{AbsoluteAndRelativeReserve, AccountIdToLocation, AsAssetType};
use xcm_primitives::{AccountIdToLocation, AsAssetType};
#[cfg(feature = "runtime-benchmarks")]
use crate::benchmark::{OpenHrmpChannel, PayWithEnsure};
@@ -176,7 +176,8 @@ impl XcmConfig for OpenZeppelinRuntime {
type SelfReserve = SelfReserve;
type SovereignAccountDispatcherOrigin = EnsureRoot<AccountId>;
type Trader = pallet_xcm_weight_trader::Trader<Runtime>;
type TransactorReserveProvider = AbsoluteAndRelativeReserve<SelfLocationAbsolute>;
type TransactorReserveProvider =
xcm_primitives::AbsoluteAndRelativeReserve<SelfLocationAbsolute>;
type Transactors = Transactors;
type UniversalLocation = UniversalLocation;
type WeightToFee = WeightToFee;
@@ -232,8 +233,6 @@ impl AssetsConfig for OpenZeppelinRuntime {
type AssetRegistrarMetadata = AssetRegistrarMetadata;
type AssetType = AssetType;
type AssetsToBlockAuthor = AssetsToBlockAuthor<Runtime, ()>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = BenchmarkHelper;
type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
type ForceOrigin = EnsureRoot<AccountId>;
type ForeignAssetModifierOrigin = EnsureRoot<AccountId>;
@@ -290,7 +289,7 @@ pub struct TransactionConverter;
impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
UncheckedExtrinsic::new_unsigned(
UncheckedExtrinsic::new_bare(
pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
)
}
@@ -301,7 +300,7 @@ impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConve
&self,
transaction: pallet_ethereum::Transaction,
) -> opaque::UncheckedExtrinsic {
let extrinsic = UncheckedExtrinsic::new_unsigned(
let extrinsic = UncheckedExtrinsic::new_bare(
pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
);
let encoded = extrinsic.encode();
+201 -16
View File
@@ -23,9 +23,7 @@ use xcm_builder::{
WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
};
use xcm_executor::traits::{ConvertLocation, FeeReason, JustTry, TransactAsset};
use xcm_primitives::{
AbsoluteAndRelativeReserve, AsAssetType, UtilityAvailableCalls, UtilityEncodeCall, XcmTransact,
};
use xcm_primitives::{AsAssetType, UtilityAvailableCalls, UtilityEncodeCall, XcmTransact};
use crate::{
configs::{
@@ -419,6 +417,50 @@ impl Reserve for BridgedAssetReserveProvider {
}
}
// Provide reserve in relative path view
// Self tokens are represeneted as Here
// Moved from Moonbeam to implement orml_traits::location::Reserve after Moonbeam
// removed ORML dependencies
pub struct RelativeReserveProvider;
impl Reserve for RelativeReserveProvider {
fn reserve(asset: &Asset) -> Option<Location> {
let AssetId(location) = &asset.id;
if location.parents == 0
&& !matches!(location.first_interior(), Some(Junction::Parachain(_)))
{
Some(Location::here())
} else {
Some(location.chain_location())
}
}
}
/// Struct that uses RelativeReserveProvider to output relative views of multilocations
///
/// Additionally accepts a Location that aims at representing the chain part
/// (parent: 1, Parachain(paraId)) of the absolute representation of our chain.
/// If a token reserve matches against this absolute view, we return Some(Location::here())
/// This helps users by preventing errors when they try to transfer a token through xtokens
/// to our chain (either inserting the relative or the absolute value).
// Moved from Moonbeam to implement orml_traits::location::Reserve after Moonbeam
// removed ORML dependencies
pub struct AbsoluteAndRelativeReserve<AbsoluteMultiLocation>(PhantomData<AbsoluteMultiLocation>);
impl<AbsoluteMultiLocation> Reserve for AbsoluteAndRelativeReserve<AbsoluteMultiLocation>
where
AbsoluteMultiLocation: Get<Location>,
{
fn reserve(asset: &Asset) -> Option<Location> {
RelativeReserveProvider::reserve(asset).map(|relative_reserve| {
if relative_reserve == AbsoluteMultiLocation::get() {
Location::here()
} else {
relative_reserve
}
})
}
}
pub struct ReserveProviders;
impl Reserve for ReserveProviders {
@@ -639,34 +681,177 @@ mod tests {
#[test]
fn test_transactors_destination_relay() {
let transactor = Transactors::Relay;
let expected_location = Location::parent();
let result = transactor.destination();
assert_eq!(result, expected_location);
let destination = transactor.destination();
assert_eq!(destination, Location::parent());
}
#[test]
fn test_transactors_encode_call() {
sp_io::TestExternalities::default().execute_with(|| {
let transactor = Transactors::Relay;
let call = UtilityAvailableCalls::AsDerivative(1u16, Vec::<u8>::new());
let encoded_call = transactor.encode_call(call);
assert!(!encoded_call.is_empty());
let call = UtilityAvailableCalls::AsDerivative(0, vec![]);
let encoded = transactor.encode_call(call);
assert!(!encoded.is_empty());
});
}
#[test]
fn test_transactors_try_from_valid() {
let result = Transactors::try_from(0u8);
assert_eq!(result, Ok(Transactors::Relay));
let transactor = Transactors::try_from(0u8);
assert!(transactor.is_ok());
}
#[test]
fn test_transactors_try_from_invalid() {
let result = Transactors::try_from(1u8);
assert!(result.is_err());
let transactor = Transactors::try_from(1u8);
assert!(transactor.is_err());
}
}
mod reserve_providers {
use frame_support::traits::Get;
use orml_traits::location::Reserve;
use xcm::latest::{Asset, AssetId, Fungibility, Junction, Junctions, Location};
use crate::configs::{
AbsoluteAndRelativeReserve, RelativeReserveProvider, SelfLocationAbsolute,
};
#[test]
fn test_relative_reserve_provider_here() {
// Test case for a local asset (parents = 0, no Parachain junction)
let local_asset = Asset {
id: AssetId(Location { parents: 0, interior: Junctions::Here }),
fun: Fungibility::Fungible(100),
};
let reserve = RelativeReserveProvider::reserve(&local_asset);
assert_eq!(reserve, Some(Location::here()));
}
#[test]
fn test_relative_reserve_provider_local_with_junctions() {
// Test case for a local asset with junctions but not Parachain
use std::sync::Arc;
let junction = Junction::AccountId32 { network: None, id: [0; 32] };
let junction_array = Arc::new([junction]);
let local_asset_with_junctions = Asset {
id: AssetId(Location { parents: 0, interior: Junctions::X1(junction_array) }),
fun: Fungibility::Fungible(100),
};
let reserve = RelativeReserveProvider::reserve(&local_asset_with_junctions);
assert_eq!(reserve, Some(Location::here()));
}
#[test]
fn test_relative_reserve_provider_parachain() {
// Test case for a parachain asset
use std::sync::Arc;
let junction = Junction::Parachain(1000);
let junction_array = Arc::new([junction]);
let parachain_asset = Asset {
id: AssetId(Location {
parents: 0,
interior: Junctions::X1(junction_array.clone()),
}),
fun: Fungibility::Fungible(100),
};
let reserve = RelativeReserveProvider::reserve(&parachain_asset);
// Should return the chain location, not Here
let expected = Location { parents: 0, interior: Junctions::X1(junction_array) };
assert_eq!(reserve, Some(expected));
}
#[test]
fn test_relative_reserve_provider_parent() {
// Test case for a parent asset
let parent_asset = Asset {
id: AssetId(Location { parents: 1, interior: Junctions::Here }),
fun: Fungibility::Fungible(100),
};
let reserve = RelativeReserveProvider::reserve(&parent_asset);
// Should return the chain location
let location = parent_asset.id.0.clone();
assert_eq!(reserve, Some(location));
}
#[test]
fn test_absolute_and_relative_reserve_matches_absolute() {
// Create a mock implementation of AbsoluteMultiLocation
use std::sync::Arc;
struct MockAbsoluteLocation;
impl Get<Location> for MockAbsoluteLocation {
fn get() -> Location {
let junction = Junction::Parachain(1000);
let junction_array = Arc::new([junction]);
Location { parents: 1, interior: Junctions::X1(junction_array) }
}
}
// Test case where the reserve matches the absolute location
let junction = Junction::Parachain(1000);
let junction_array = Arc::new([junction]);
let asset = Asset {
id: AssetId(Location { parents: 1, interior: Junctions::X1(junction_array) }),
fun: Fungibility::Fungible(100),
};
let reserve = AbsoluteAndRelativeReserve::<MockAbsoluteLocation>::reserve(&asset);
// Should return Here since it matches the absolute location
assert_eq!(reserve, Some(Location::here()));
}
#[test]
fn test_absolute_and_relative_reserve_different_location() {
// Create a mock implementation of AbsoluteMultiLocation
use std::sync::Arc;
struct MockAbsoluteLocation;
impl Get<Location> for MockAbsoluteLocation {
fn get() -> Location {
let junction = Junction::Parachain(1000);
let junction_array = Arc::new([junction]);
Location { parents: 1, interior: Junctions::X1(junction_array) }
}
}
// Test case where the reserve doesn't match the absolute location
let junction = Junction::Parachain(2000);
let junction_array = Arc::new([junction]);
let asset = Asset {
id: AssetId(Location { parents: 1, interior: Junctions::X1(junction_array) }),
fun: Fungibility::Fungible(100),
};
let reserve = AbsoluteAndRelativeReserve::<MockAbsoluteLocation>::reserve(&asset);
// Should return the relative reserve since it doesn't match the absolute location
let expected = Location { parents: 1, interior: Junctions::X1(Arc::new([junction])) };
assert_eq!(reserve, Some(expected));
}
#[test]
fn test_absolute_and_relative_reserve_with_self_location() {
// We need to use TestExternalities for this test
sp_io::TestExternalities::default().execute_with(|| {
// Test with the actual SelfLocationAbsolute
let self_location = SelfLocationAbsolute::get();
let asset =
Asset { id: AssetId(self_location.clone()), fun: Fungibility::Fungible(100) };
let reserve = AbsoluteAndRelativeReserve::<SelfLocationAbsolute>::reserve(&asset);
// Should return Here since it matches the self location
assert_eq!(reserve, Some(Location::here()));
});
}
}
}
+5 -5
View File
@@ -1,6 +1,6 @@
use frame_support::weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight};
use sp_runtime::{create_runtime_str, Perbill};
use sp_version::RuntimeVersion;
use sp_runtime::Perbill;
use sp_version::{Cow, RuntimeVersion};
use crate::types::BlockNumber;
@@ -35,14 +35,14 @@ pub const POLY_DEGREE: u8 = 1;
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("template-parachain"),
impl_name: create_runtime_str!("template-parachain"),
spec_name: Cow::Borrowed("template-parachain"),
impl_name: Cow::Borrowed("template-parachain"),
authoring_version: 1,
spec_version: 1,
impl_version: 0,
apis: crate::RUNTIME_API_VERSIONS,
transaction_version: 1,
state_version: 1,
system_version: 1,
};
/// This determines the average expected block time that we are targeting.
@@ -508,4 +508,10 @@ impl<T: frame_system::Config> pallet_assets::WeightInfo for WeightInfo<T> {
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
}
fn transfer_all() -> Weight {
Weight::from_parts(19_482_000, 0)
.saturating_add(Weight::from_parts(0, 3675))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
}
}
@@ -78,4 +78,14 @@ impl<T: frame_system::Config> pallet_sudo::WeightInfo for WeightInfo<T> {
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
fn check_only_sudo_account() -> Weight {
// Proof Size summary in bytes:
// Measured: `98`
// Estimated: `1517`
// Minimum execution time: 11_126_000 picoseconds.
Weight::from_parts(11_411_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
}