Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Granular NFT traits and new XCM NFT types #4300

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e7003fd
feat(frame-support): add asset ops
mrshiposha Apr 25, 2024
6c6cf4b
feat(pallet-uniques): implement asset ops
mrshiposha Apr 25, 2024
a2099c0
feat(xcm): add unique instances adapters using asset ops
mrshiposha Apr 25, 2024
3f7c3a2
feat(rococo,westend): use xcm unique instances adapter
mrshiposha Apr 25, 2024
21323ff
Merge branch 'master' into feature/asset-ops-traits
mrshiposha Apr 26, 2024
2db1903
Merge branch 'master' into feature/asset-ops-traits
mrshiposha May 28, 2024
0016ec2
refactor: asset-ops related stuff, add Stash+Restore ops
mrshiposha Jun 11, 2024
17f54ab
refactor: unique instances XCM stuff
mrshiposha Jun 11, 2024
a725bbd
fix: add derives to NonFungibleAsset
mrshiposha Jun 11, 2024
b4893df
chore: remove unneeded
mrshiposha Jun 11, 2024
105ebfa
feat: add derives to id assignments
mrshiposha Jun 12, 2024
379d6cd
refactor(asset-ops): lifetimes in common strategies
mrshiposha Jun 13, 2024
d28ad75
refactor: xcm unique-instances derivatives traits
mrshiposha Jun 15, 2024
c45c7ca
refactor: id assignment
mrshiposha Jun 24, 2024
a5b1b1c
fix: remove unneeded imports
mrshiposha Jun 25, 2024
be99d8e
feat: add pallet-xnft
mrshiposha Jun 25, 2024
ae08d7e
Merge branch 'master' into feature/asset-ops-traits
mrshiposha Jun 27, 2024
6e06663
fix(xcm-builder): remove unneeded uses, add mod doc comment
mrshiposha Jun 27, 2024
aa2f827
fix(asset-ops): doc comment
mrshiposha Jun 27, 2024
79cae0a
fix: add pallet-xnft to workspace
mrshiposha Jun 27, 2024
4c7a0ca
fix: add Success type to all strategies
mrshiposha Jun 27, 2024
4585528
chore: cargo fmt
mrshiposha Jun 27, 2024
5324c5b
fix: impl StashStrategy,RestoreStrategy for WithOrigin
mrshiposha Jun 27, 2024
8f94c1d
fix: CI errors
mrshiposha Jul 3, 2024
23c36be
fix: remove unused imports
mrshiposha Jul 3, 2024
845149a
fix: clippy
mrshiposha Jul 3, 2024
f7e2c3e
fix: clippy
mrshiposha Jul 3, 2024
ce0b2e3
Merge branch 'master' into feature/asset-ops-traits
mrshiposha Jul 15, 2024
d30a218
Merge branch 'master' into feature/asset-ops-traits
mrshiposha Aug 5, 2024
d870d91
fix: cargo fmt, remove unneeded use
mrshiposha Aug 5, 2024
1a50904
fix: umbrella crate
mrshiposha Aug 5, 2024
cd24f76
refactor: replace pallet-xnft with pallet-derivatives
mrshiposha Sep 19, 2024
c1ff41e
refactor: simplify unique instances derivatives types
mrshiposha Sep 19, 2024
7bfb0fd
refactor: remove RegisterOnCreate/DeregisterOnDestroy
mrshiposha Sep 19, 2024
1b90a48
refactor: use result type in all registry's methods
mrshiposha Sep 19, 2024
15c0c53
feat: add AssetIdOf
mrshiposha Sep 19, 2024
a7e1809
refactor: use options to get original/derivative
mrshiposha Sep 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ members = [
"polkadot/xcm/docs",
"polkadot/xcm/pallet-xcm",
"polkadot/xcm/pallet-xcm-benchmarks",
"polkadot/xcm/pallet-derivatives",
"polkadot/xcm/procedural",
"polkadot/xcm/xcm-builder",
"polkadot/xcm/xcm-executor",
Expand Down Expand Up @@ -983,6 +984,7 @@ pallet-xcm = { path = "polkadot/xcm/pallet-xcm", default-features = false }
pallet-xcm-benchmarks = { path = "polkadot/xcm/pallet-xcm-benchmarks", default-features = false }
pallet-xcm-bridge-hub = { path = "bridges/modules/xcm-bridge-hub", default-features = false }
pallet-xcm-bridge-hub-router = { path = "bridges/modules/xcm-bridge-hub-router", default-features = false }
pallet-derivatives = { path = "polkadot/xcm/pallet-derivatives", default-features = false }
parachain-info = { path = "cumulus/parachains/pallets/parachain-info", default-features = false, package = "staging-parachain-info" }
parachain-template-runtime = { path = "templates/parachain/runtime" }
parachains-common = { path = "cumulus/parachains/common", default-features = false }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ use testnet_parachains_constants::rococo::snowbridge::{
};
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain,
AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily,
EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter,
GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete, LocalMint,
NetworkExportTableItem, NoChecking, NonFungiblesAdapter, ParentAsSuperuser, ParentIsPreset,
RelayChainAsNative, SendXcmFeeToAccount, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SignedToAccountId32, SovereignPaidRemoteExporter,
SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
XcmFeeManagerFromComponents,
unique_instances::UniqueInstancesAdapter, AccountId32Aliases, AllowExplicitUnpaidExecutionFrom,
AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry,
DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin, FrameTransactionalProcessor,
FungibleAdapter, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription,
IsConcrete, LocalMint, MatchInClassInstances, NetworkExportTableItem, NoChecking,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SendXcmFeeToAccount,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignPaidRemoteExporter, SovereignSignedViaLocation, StartsWith,
StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
};
use xcm_executor::XcmExecutor;

Expand Down Expand Up @@ -149,19 +149,11 @@ pub type UniquesConvertedConcreteId =
assets_common::UniquesConvertedConcreteId<UniquesPalletLocation>;

/// Means for transacting unique assets.
pub type UniquesTransactor = NonFungiblesAdapter<
// Use this non-fungibles implementation:
Uniques,
// This adapter will handle any non-fungible asset from the uniques pallet.
UniquesConvertedConcreteId,
// Convert an XCM Location into a local account id:
LocationToAccountId,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
pub type UniquesTransactor = UniqueInstancesAdapter<
AccountId,
// Does not check teleports.
NoChecking,
// The account to use for tracking teleports.
CheckingAccount,
LocationToAccountId,
MatchInClassInstances<UniquesConvertedConcreteId>,
Uniques,
>;

/// `AssetId`/`Balance` converter for `ForeignAssets`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,17 @@ use polkadot_runtime_common::xcm_sender::ExponentialPrice;
use sp_runtime::traits::{AccountIdConversion, ConvertInto};
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain,
AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
DenyReserveTransferToRelayChain, DenyThenTry, DescribeFamily, DescribePalletTerminal,
EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter,
GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete, LocalMint,
NetworkExportTableItem, NoChecking, NonFungiblesAdapter, ParentAsSuperuser, ParentIsPreset,
RelayChainAsNative, SendXcmFeeToAccount, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, StartsWith,
StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
unique_instances::UniqueInstancesAdapter, AccountId32Aliases, AllowExplicitUnpaidExecutionFrom,
AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeFamily,
DescribePalletTerminal, EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter,
FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete,
LocalMint, MatchInClassInstances, NetworkExportTableItem, NoChecking, ParentAsSuperuser,
ParentIsPreset, RelayChainAsNative, SendXcmFeeToAccount, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
XcmFeeManagerFromComponents,
};
use xcm_executor::XcmExecutor;

Expand Down Expand Up @@ -141,19 +142,11 @@ pub type UniquesConvertedConcreteId =
assets_common::UniquesConvertedConcreteId<UniquesPalletLocation>;

/// Means for transacting unique assets.
pub type UniquesTransactor = NonFungiblesAdapter<
// Use this non-fungibles implementation:
Uniques,
// This adapter will handle any non-fungible asset from the uniques pallet.
UniquesConvertedConcreteId,
// Convert an XCM Location into a local account id:
LocationToAccountId,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
pub type UniquesTransactor = UniqueInstancesAdapter<
AccountId,
// Does not check teleports.
NoChecking,
// The account to use for tracking teleports.
CheckingAccount,
LocationToAccountId,
MatchInClassInstances<UniquesConvertedConcreteId>,
Uniques,
>;

/// `AssetId`/`Balance` converter for `ForeignAssets`.
Expand Down
63 changes: 63 additions & 0 deletions polkadot/xcm/pallet-derivatives/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
[package]
name = "pallet-derivatives"
version = "1.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage = "https://substrate.io"
repository.workspace = true
description = "XCM derivatives pallet"
readme = "README.md"

[lints]
workspace = true

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false }
log = { workspace = true }
scale-info = { version = "2.11.1", default-features = false, features = ["derive"] }
frame-benchmarking = { optional = true, workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }

xcm = { workspace = true }
xcm-executor = { workspace = true }
xcm-builder = { workspace = true }

[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"log/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"sp-runtime/try-runtime",
]
1 change: 1 addition & 0 deletions polkadot/xcm/pallet-derivatives/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# derivatives
140 changes: 140 additions & 0 deletions polkadot/xcm/pallet-derivatives/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![recursion_limit = "256"]
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::pallet_prelude::*;
use sp_runtime::DispatchResult;
use xcm_builder::unique_instances::derivatives::DerivativesRegistry;

pub use pallet::*;

/// The log target of this pallet.
pub const LOG_TARGET: &'static str = "runtime::xcm::derivatives";

type OriginalOf<T, I> = <T as Config<I>>::Original;

type DerivativeOf<T, I> = <T as Config<I>>::Derivative;

#[frame_support::pallet]
pub mod pallet {
use super::*;

/// The in-code storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(0);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);

#[pallet::config]
/// The module configuration trait.
pub trait Config<I: 'static = ()>: frame_system::Config {
/// The overarching event type.
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;

type Original: Member + Parameter + MaxEncodedLen;
type Derivative: Member + Parameter + MaxEncodedLen;
}

#[pallet::storage]
#[pallet::getter(fn original_to_derivative)]
pub type OriginalToDerivative<T: Config<I>, I: 'static = ()> =
StorageMap<_, Blake2_128, OriginalOf<T, I>, DerivativeOf<T, I>, OptionQuery>;

#[pallet::storage]
#[pallet::getter(fn derivative_to_original)]
pub type DerivativeToOriginal<T: Config<I>, I: 'static = ()> =
StorageMap<_, Blake2_128, DerivativeOf<T, I>, OriginalOf<T, I>, OptionQuery>;

#[pallet::event]
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> {
/// A derivative is registered.
DerivativeRegistered { original: OriginalOf<T, I>, derivative: DerivativeOf<T, I> },

/// A derivative is de-registered.
DerivativeDeregistered { original: OriginalOf<T, I>, derivative: DerivativeOf<T, I> },
}

#[pallet::error]
pub enum Error<T, I = ()> {
/// A derivative already exists.
DerivativeAlreadyExists,

/// Failed to deregister a non-registered derivative.
NoDerivativeToDeregister,

/// Failed to get a derivative for the given original.
DerivativeNotFound,

/// Failed to get an original for the given derivative.
OriginalNotFound,
}

#[pallet::call]
impl<T: Config<I>, I: 'static> Pallet<T, I> {}
}

impl<T: Config<I>, I: 'static> DerivativesRegistry<OriginalOf<T, I>, DerivativeOf<T, I>>
for Pallet<T, I>
{
fn try_register_derivative(
original: &OriginalOf<T, I>,
derivative: &DerivativeOf<T, I>,
) -> DispatchResult {
ensure!(
Self::original_to_derivative(original).is_none(),
Error::<T, I>::DerivativeAlreadyExists,
);

<OriginalToDerivative<T, I>>::insert(original, derivative);
<DerivativeToOriginal<T, I>>::insert(derivative, original);

Self::deposit_event(Event::<T, I>::DerivativeRegistered {
original: original.clone(),
derivative: derivative.clone(),
});

Ok(())
}

fn try_deregister_derivative(derivative: &DerivativeOf<T, I>) -> DispatchResult {
let original = <DerivativeToOriginal<T, I>>::take(&derivative)
.ok_or(Error::<T, I>::NoDerivativeToDeregister)?;

<OriginalToDerivative<T, I>>::remove(&original);

Self::deposit_event(Event::<T, I>::DerivativeDeregistered {
original: original.clone(),
derivative: derivative.clone(),
});

Ok(())
}

fn get_derivative(original: &OriginalOf<T, I>) -> Option<DerivativeOf<T, I>> {
<OriginalToDerivative<T, I>>::get(original)
}

fn get_original(derivative: &DerivativeOf<T, I>) -> Option<OriginalOf<T, I>> {
<DerivativeToOriginal<T, I>>::get(derivative)
}
}
24 changes: 23 additions & 1 deletion polkadot/xcm/xcm-builder/src/asset_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ use core::{marker::PhantomData, result};
use frame_support::traits::{Contains, Get};
use sp_runtime::traits::MaybeEquivalence;
use xcm::latest::prelude::*;
use xcm_executor::traits::{Error as MatchError, MatchesFungibles, MatchesNonFungibles};
use xcm_executor::traits::{
Error as MatchError, MatchesFungibles, MatchesInstance, MatchesNonFungible, MatchesNonFungibles,
};

/// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be
/// `TryFrom/TryInto<u128>`) into a `GeneralIndex` junction, prefixed by some `Location` value.
Expand Down Expand Up @@ -152,6 +154,26 @@ impl<
}
}

pub struct MatchInClassInstances<Matcher>(PhantomData<Matcher>);

impl<ClassId, InstanceId, Matcher: MatchesNonFungibles<ClassId, InstanceId>>
MatchesInstance<(ClassId, InstanceId)> for MatchInClassInstances<Matcher>
{
fn matches_instance(a: &Asset) -> result::Result<(ClassId, InstanceId), MatchError> {
Matcher::matches_nonfungibles(a)
}
}

pub struct MatchClasslessInstances<Matcher>(PhantomData<Matcher>);

impl<InstanceId, Matcher: MatchesNonFungible<InstanceId>> MatchesInstance<InstanceId>
for MatchClasslessInstances<Matcher>
{
fn matches_instance(a: &Asset) -> result::Result<InstanceId, MatchError> {
Matcher::matches_nonfungible(a).ok_or(MatchError::AssetNotHandled)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading