Skip to content

Commit

Permalink
refactor(asset-ops): lifetimes in common strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
mrshiposha committed Jun 13, 2024
1 parent 105ebfa commit 379d6cd
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 148 deletions.
18 changes: 9 additions & 9 deletions polkadot/xcm/xcm-builder/src/unique_instances/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ impl<AccountId, AccountIdConverter, Matcher, InstanceOps> TransactAsset
where
AccountIdConverter: ConvertLocation<AccountId>,
Matcher: MatchesInstance<InstanceOps::Id>,
for<'a> InstanceOps: AssetDefinition<Instance>
+ Create<Instance, Owned<'a, AccountId, AssignId<'a, InstanceOps::Id>>>
+ Transfer<Instance, FromTo<'a, AccountId>>
+ Destroy<Instance, IfOwnedBy<'a, AccountId>>,
InstanceOps: AssetDefinition<Instance>
+ Create<Instance, Owned<AccountId, AssignId<InstanceOps::Id>>>
+ Transfer<Instance, FromTo<AccountId>>
+ Destroy<Instance, IfOwnedBy<AccountId>>,
{
fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult {
log::trace!(
Expand All @@ -55,7 +55,7 @@ where
let who = AccountIdConverter::convert_location(who)
.ok_or(MatchError::AccountIdConversionFailed)?;

InstanceOps::create(Owned::new(&who, AssignId(&instance_id)))
InstanceOps::create(Owned::new(who, AssignId(instance_id)))
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))
}

Expand All @@ -75,7 +75,7 @@ where
let who = AccountIdConverter::convert_location(who)
.ok_or(MatchError::AccountIdConversionFailed)?;

InstanceOps::destroy(&instance_id, IfOwnedBy(&who))
InstanceOps::destroy(&instance_id, IfOwnedBy(who))
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;

Ok(what.clone().into())
Expand All @@ -102,7 +102,7 @@ where
let to = AccountIdConverter::convert_location(to)
.ok_or(MatchError::AccountIdConversionFailed)?;

InstanceOps::transfer(&instance_id, FromTo(&from, &to))
InstanceOps::transfer(&instance_id, FromTo(from, to))
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;

Ok(what.clone().into())
Expand Down Expand Up @@ -133,7 +133,7 @@ impl<AccountId, AccountIdConverter, Matcher, IdAssignment, InstanceCreateOp> Tra
AccountIdConverter: ConvertLocation<AccountId>,
IdAssignment: asset_ops::IdAssignment,
Matcher: MatchesInstance<IdAssignment>,
for<'a> InstanceCreateOp: Create<Instance, Owned<'a, AccountId, IdAssignment>>,
InstanceCreateOp: Create<Instance, Owned<AccountId, IdAssignment>>,
{
fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult {
log::trace!(
Expand All @@ -148,7 +148,7 @@ impl<AccountId, AccountIdConverter, Matcher, IdAssignment, InstanceCreateOp> Tra
let who = AccountIdConverter::convert_location(who)
.ok_or(MatchError::AccountIdConversionFailed)?;

InstanceCreateOp::create(Owned::new(&who, instance_id_assignment))
InstanceCreateOp::create(Owned::new(who, instance_id_assignment))
.map(|_reported_id| ())
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))
}
Expand Down
17 changes: 7 additions & 10 deletions polkadot/xcm/xcm-builder/src/unique_instances/derivatives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,13 @@ pub struct RegisterDerivativeId<InstanceIdSource> {
}

pub struct RegisterOnCreate<Registrar, InstanceOps>(PhantomData<(Registrar, InstanceOps)>);
impl<'a, AccountId, InstanceIdSource, Registrar, InstanceOps>
Create<Instance, Owned<'a, AccountId, AssignId<'a, RegisterDerivativeId<InstanceIdSource>>>>
impl<AccountId, InstanceIdSource, Registrar, InstanceOps>
Create<Instance, Owned<AccountId, AssignId<RegisterDerivativeId<InstanceIdSource>>>>
for RegisterOnCreate<Registrar, InstanceOps>
where
Registrar: TryRegisterDerivative<InstanceOps::Id>,
InstanceOps: AssetDefinition<Instance>
+ for<'b> Create<
Instance,
Owned<'b, AccountId, DeriveAndReportId<'b, InstanceIdSource, InstanceOps::Id>>,
>,
+ Create<Instance, Owned<AccountId, DeriveAndReportId<InstanceIdSource, InstanceOps::Id>>>,
{
fn create(
strategy: Owned<AccountId, AssignId<RegisterDerivativeId<InstanceIdSource>>>,
Expand All @@ -57,7 +54,7 @@ where
..
} = strategy;

if Registrar::is_derivative_registered(foreign_asset) {
if Registrar::is_derivative_registered(&foreign_asset) {
return Err(DispatchError::Other(
"an attempt to register a duplicate of an existing derivative instance",
));
Expand All @@ -66,7 +63,7 @@ where
let instance_id =
InstanceOps::create(Owned::new(owner, DeriveAndReportId::from(instance_id_source)))?;

Registrar::try_register_derivative(foreign_asset, &instance_id)
Registrar::try_register_derivative(&foreign_asset, &instance_id)
}
}

Expand All @@ -78,11 +75,11 @@ where
{
type Id = InstanceOps::Id;
}
impl<'a, AccountId, Registrar, InstanceOps> Destroy<Instance, IfOwnedBy<'a, AccountId>>
impl<AccountId, Registrar, InstanceOps> Destroy<Instance, IfOwnedBy<AccountId>>
for DeregisterOnDestroy<Registrar, InstanceOps>
where
Registrar: TryDeregisterDerivative<InstanceOps::Id>,
InstanceOps: for<'b> Destroy<Instance, IfOwnedBy<'b, AccountId>>,
InstanceOps: Destroy<Instance, IfOwnedBy<AccountId>>,
{
fn destroy(id: &Self::Id, strategy: IfOwnedBy<AccountId>) -> DispatchResult {
if !Registrar::is_derivative(id) {
Expand Down
26 changes: 12 additions & 14 deletions polkadot/xcm/xcm-builder/src/unique_instances/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,44 +61,43 @@ where
{
type Id = InstanceOps::Id;
}
impl<'a, StashAccount, InstanceOps> Stash<Instance, IfOwnedBy<'a, StashAccount::Type>>
impl<StashAccount, InstanceOps> Stash<Instance, IfOwnedBy<StashAccount::Type>>
for SimpleStash<StashAccount, InstanceOps>
where
StashAccount: TypedGet,
InstanceOps: for<'b> Transfer<Instance, FromTo<'b, StashAccount::Type>>,
InstanceOps: Transfer<Instance, FromTo<StashAccount::Type>>,
{
fn stash(
id: &Self::Id,
IfOwnedBy(possible_owner): IfOwnedBy<StashAccount::Type>,
) -> DispatchResult {
InstanceOps::transfer(id, FromTo(possible_owner, &StashAccount::get()))
InstanceOps::transfer(id, FromTo(possible_owner, StashAccount::get()))
}
}
impl<'a, StashAccount, InstanceOps> Restore<Instance, IfRestorable<'a, StashAccount::Type>>
impl<StashAccount, InstanceOps> Restore<Instance, IfRestorable<StashAccount::Type>>
for SimpleStash<StashAccount, InstanceOps>
where
StashAccount: TypedGet,
InstanceOps: for<'b> Transfer<Instance, FromTo<'b, StashAccount::Type>>,
InstanceOps: Transfer<Instance, FromTo<StashAccount::Type>>,
{
fn restore(
id: &Self::Id,
IfRestorable(owner): IfRestorable<StashAccount::Type>,
) -> DispatchResult {
InstanceOps::transfer(id, FromTo(&StashAccount::get(), owner))
InstanceOps::transfer(id, FromTo(StashAccount::get(), owner))
}
}

pub struct RestoreOnCreate<InstanceOps>(PhantomData<InstanceOps>);
impl<'a, AccountId, InstanceOps>
Create<Instance, Owned<'a, AccountId, AssignId<'a, InstanceOps::Id>>>
impl<AccountId, InstanceOps> Create<Instance, Owned<AccountId, AssignId<InstanceOps::Id>>>
for RestoreOnCreate<InstanceOps>
where
InstanceOps: for<'b> Restore<Instance, IfRestorable<'b, AccountId>>,
InstanceOps: Restore<Instance, IfRestorable<AccountId>>,
{
fn create(strategy: Owned<AccountId, AssignId<InstanceOps::Id>>) -> DispatchResult {
let Owned { owner, id_assignment: AssignId(instance_id), .. } = strategy;

InstanceOps::restore(instance_id, IfRestorable(owner))
InstanceOps::restore(&instance_id, IfRestorable(owner))
}
}

Expand All @@ -109,12 +108,11 @@ where
{
type Id = InstanceOps::Id;
}
impl<'a, AccountId, InstanceOps> Destroy<Instance, IfOwnedBy<'a, AccountId>>
for StashOnDestroy<InstanceOps>
impl<AccountId, InstanceOps> Destroy<Instance, IfOwnedBy<AccountId>> for StashOnDestroy<InstanceOps>
where
InstanceOps: for<'b> Stash<Instance, IfOwnedBy<'b, AccountId>>,
InstanceOps: Stash<Instance, IfOwnedBy<AccountId>>,
{
fn destroy(id: &Self::Id, strategy: IfOwnedBy<'a, AccountId>) -> DispatchResult {
fn destroy(id: &Self::Id, strategy: IfOwnedBy<AccountId>) -> DispatchResult {
InstanceOps::stash(id, strategy)
}
}
110 changes: 53 additions & 57 deletions substrate/frame/support/src/traits/tokens/asset_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,18 +291,18 @@ pub mod common_strategies {
/// It accepts whatever parameters are set in its generic argument.
/// For instance, for an unchecked transfer,
/// this strategy may take a reference to a beneficiary account.
pub struct JustDo<'a, Params = ()>(pub &'a Params);
impl<'a> Default for JustDo<'a, ()> {
pub struct JustDo<Params = ()>(pub Params);
impl Default for JustDo<()> {
fn default() -> Self {
Self(&())
Self(())
}
}
impl<'a, Owner> TransferStrategy for JustDo<'a, Owner> {}
impl<'a> DestroyStrategy for JustDo<'a> {
impl<Params> TransferStrategy for JustDo<Params> {}
impl<Params> DestroyStrategy for JustDo<Params> {
type Success = ();
}
impl<'a> StashStrategy for JustDo<'a> {}
impl<'a, Owner> RestoreStrategy for JustDo<'a, Owner> {}
impl<Params> StashStrategy for JustDo<Params> {}
impl<Params> RestoreStrategy for JustDo<Params> {}

/// The `Bytes` strategy represents raw metadata bytes.
/// It is both an [inspect](MetadataInspectStrategy) and [update](MetadataUpdateStrategy)
Expand Down Expand Up @@ -459,8 +459,8 @@ pub mod common_strategies {
/// It accepts `Params` to assign an ID to the newly created asset.
/// This ID assignment approach doesn't report the ID upon the asset's creation.
#[derive(RuntimeDebug, PartialEq, Eq, Clone, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct AssignId<'a, Params>(pub &'a Params);
impl<'a, Params> IdAssignment for AssignId<'a, Params> {
pub struct AssignId<Params>(pub Params);
impl<Params> IdAssignment for AssignId<Params> {
type ReportedId = ();
}

Expand All @@ -475,13 +475,13 @@ pub mod common_strategies {
/// An example of ID derivation is the creation of an NFT inside a collection using the
/// collection ID as `Params`. The `Id` in this case is the full ID of the NFT.
#[derive(RuntimeDebug, PartialEq, Eq, Clone, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct DeriveAndReportId<'a, Params, Id>(pub &'a Params, pub PhantomData<Id>);
impl<'a, Params, Id> DeriveAndReportId<'a, Params, Id> {
pub fn from(params: &'a Params) -> Self {
pub struct DeriveAndReportId<Params, Id>(pub Params, pub PhantomData<Id>);
impl<Params, Id> DeriveAndReportId<Params, Id> {
pub fn from(params: Params) -> Self {
Self(params, PhantomData)
}
}
impl<'a, ParentId, Id> IdAssignment for DeriveAndReportId<'a, ParentId, Id> {
impl<Params, Id> IdAssignment for DeriveAndReportId<Params, Id> {
type ReportedId = Id;
}

Expand All @@ -495,28 +495,24 @@ pub mod common_strategies {
///
/// The [`Success`](CreateStrategy::Success) will contain
/// the [reported ID](IdAssignment::ReportedId) of the ID assignment approach.
pub struct Owned<'a, Owner, Assignment: IdAssignment, Config = (), Witness = ()> {
pub owner: &'a Owner,
pub struct Owned<Owner, Assignment: IdAssignment, Config = (), Witness = ()> {
pub owner: Owner,
pub id_assignment: Assignment,
pub config: &'a Config,
pub witness: &'a Witness,
pub config: Config,
pub witness: Witness,
}
impl<'a, Owner, Assignment: IdAssignment> Owned<'a, Owner, Assignment, (), ()> {
pub fn new(owner: &'a Owner, id_assignment: Assignment) -> Self {
Self { id_assignment, owner, config: &(), witness: &() }
impl<Owner, Assignment: IdAssignment> Owned<Owner, Assignment, (), ()> {
pub fn new(owner: Owner, id_assignment: Assignment) -> Self {
Self { id_assignment, owner, config: (), witness: () }
}
}
impl<'a, Owner, Assignment: IdAssignment, Config> Owned<'a, Owner, Assignment, Config, ()> {
pub fn new_configured(
owner: &'a Owner,
id_assignment: Assignment,
config: &'a Config,
) -> Self {
Self { id_assignment, owner, config, witness: &() }
impl<Owner, Assignment: IdAssignment, Config> Owned<Owner, Assignment, Config, ()> {
pub fn new_configured(owner: Owner, id_assignment: Assignment, config: Config) -> Self {
Self { id_assignment, owner, config, witness: () }
}
}
impl<'a, Owner, Assignment: IdAssignment, Config, Witness> CreateStrategy
for Owned<'a, Owner, Assignment, Config, Witness>
impl<Owner, Assignment: IdAssignment, Config, Witness> CreateStrategy
for Owned<Owner, Assignment, Config, Witness>
{
type Success = Assignment::ReportedId;
}
Expand All @@ -532,77 +528,77 @@ pub mod common_strategies {
///
/// The [`Success`](CreateStrategy::Success) will contain
/// the [reported ID](IdAssignment::ReportedId) of the ID assignment approach.
pub struct Adminable<'a, Account, Assignment: IdAssignment, Config = (), Witness = ()> {
pub owner: &'a Account,
pub admin: &'a Account,
pub struct Adminable<Account, Assignment: IdAssignment, Config = (), Witness = ()> {
pub owner: Account,
pub admin: Account,
pub id_assignment: Assignment,
pub config: &'a Config,
pub witness: &'a Witness,
pub config: Config,
pub witness: Witness,
}
impl<'a, Account, Assignment: IdAssignment> Adminable<'a, Account, Assignment, (), ()> {
pub fn new(id_assignment: Assignment, owner: &'a Account, admin: &'a Account) -> Self {
Self { id_assignment, owner, admin, config: &(), witness: &() }
impl<Account, Assignment: IdAssignment> Adminable<Account, Assignment, (), ()> {
pub fn new(id_assignment: Assignment, owner: Account, admin: Account) -> Self {
Self { id_assignment, owner, admin, config: (), witness: () }
}
}
impl<'a, Account, Assignment: IdAssignment, Config> Adminable<'a, Account, Assignment, Config, ()> {
impl<Account, Assignment: IdAssignment, Config> Adminable<Account, Assignment, Config, ()> {
pub fn new_configured(
owner: &'a Account,
admin: &'a Account,
owner: Account,
admin: Account,
id_assignment: Assignment,
config: &'a Config,
config: Config,
) -> Self {
Self { id_assignment, owner, admin, config, witness: &() }
Self { id_assignment, owner, admin, config, witness: () }
}
}
impl<'a, Account, Assignment: IdAssignment, Config, Witness> CreateStrategy
for Adminable<'a, Account, Assignment, Config, Witness>
impl<Account, Assignment: IdAssignment, Config, Witness> CreateStrategy
for Adminable<Account, Assignment, Config, Witness>
{
type Success = Assignment::ReportedId;
}

/// The `FromTo` is a [`transfer strategy`](TransferStrategy).
///
/// It accepts two parameters: `from` and `to` whom the asset should be transferred.
pub struct FromTo<'a, Owner>(pub &'a Owner, pub &'a Owner);
impl<'a, Owner> TransferStrategy for FromTo<'a, Owner> {}
pub struct FromTo<Owner>(pub Owner, pub Owner);
impl<Owner> TransferStrategy for FromTo<Owner> {}

/// The `IfOwnedBy` is both a [`destroy strategy`](DestroyStrategy)
/// and a [`stash strategy`](StashStrategy).
///
/// It accepts a possible owner of the asset.
/// If the provided entity owns the asset, the corresponding operation will be performed.
pub struct IfOwnedBy<'a, Owner>(pub &'a Owner);
impl<'a, Owner> DestroyStrategy for IfOwnedBy<'a, Owner> {
pub struct IfOwnedBy<Owner>(pub Owner);
impl<Owner> DestroyStrategy for IfOwnedBy<Owner> {
type Success = ();
}
impl<'a, Owner> StashStrategy for IfOwnedBy<'a, Owner> {}
impl<Owner> StashStrategy for IfOwnedBy<Owner> {}

/// The `IfRestorable` is a [`restore strategy`](RestoreStrategy).
///
/// It accepts whatever parameters are set in its generic argument.
/// For instance, if an asset is restorable,
/// this strategy may reference a beneficiary account,
/// which should own the asset upon restoration.
pub struct IfRestorable<'a, Params>(pub &'a Params);
impl<'a, Params> RestoreStrategy for IfRestorable<'a, Params> {}
pub struct IfRestorable<Params>(pub Params);
impl<Params> RestoreStrategy for IfRestorable<Params> {}

/// The `WithWitness` is a [`destroy strategy`](DestroyStrategy).
///
/// It accepts a `Witness` to destroy an asset.
/// It will also return a `Witness` value upon destruction.
pub struct WithWitness<'a, Witness>(pub &'a Witness);
impl<'a, Witness> DestroyStrategy for WithWitness<'a, Witness> {
pub struct WithWitness<Witness>(pub Witness);
impl<Witness> DestroyStrategy for WithWitness<Witness> {
type Success = Witness;
}

/// The `IfOwnedByWithWitness` is a [`destroy strategy`](DestroyStrategy).
///
/// It is a combination of the [`IfOwnedBy`] and the [`WithWitness`] strategies.
pub struct IfOwnedByWithWitness<'a, Owner, Witness> {
pub owner: &'a Owner,
pub witness: &'a Witness,
pub struct IfOwnedByWithWitness<Owner, Witness> {
pub owner: Owner,
pub witness: Witness,
}
impl<'a, Owner, Witness> DestroyStrategy for IfOwnedByWithWitness<'a, Owner, Witness> {
impl<Owner, Witness> DestroyStrategy for IfOwnedByWithWitness<Owner, Witness> {
type Success = Witness;
}
}
Loading

0 comments on commit 379d6cd

Please sign in to comment.