Skip to content

Commit 5600d1c

Browse files
NunoAlexandreshaunxwxlc
authored
asset-registry: Pass Asset Id to AuthorityOrigin (#762)
* asset-registry: Pass Asset Id to AuthorityOrigin Different AssetId's may require different origin checks, which is currently not possible. These changes use EnsureOriginWithArg to allow users of this pallet to tailor the origin check to take the `asset_id` itself in consideration when choosing the specific `EnsureOrigin` implementation to be applied. * fixup! * Update asset-registry/src/mock/para.rs * Update asset-registry/src/mock/para.rs * fmt Co-authored-by: Shaun Wang <[email protected]> Co-authored-by: Bryan Chen <[email protected]>
1 parent c8d31a2 commit 5600d1c

File tree

3 files changed

+77
-16
lines changed

3 files changed

+77
-16
lines changed

asset-registry/src/lib.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
// Older clippy versions give a false positive on the expansion of [pallet::call].
33
// This is fixed in https://github.com/rust-lang/rust-clippy/issues/8321
44
#![allow(clippy::large_enum_variant)]
5-
6-
use frame_support::{pallet_prelude::*, traits::EnsureOrigin, transactional};
5+
use frame_support::{pallet_prelude::*, traits::EnsureOriginWithArg, transactional};
76
use frame_system::pallet_prelude::*;
87
use orml_traits::asset_registry::AssetProcessor;
98
use scale_info::TypeInfo;
@@ -19,9 +18,12 @@ pub use module::*;
1918
pub use weights::WeightInfo;
2019

2120
mod impls;
21+
mod weights;
22+
23+
#[cfg(test)]
2224
mod mock;
25+
#[cfg(test)]
2326
mod tests;
24-
mod weights;
2527

2628
/// Data describing the asset properties.
2729
#[derive(scale_info::TypeInfo, Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
@@ -48,8 +50,8 @@ pub mod module {
4850
/// The type used as a unique asset id,
4951
type AssetId: Parameter + Member + Default + TypeInfo;
5052

51-
/// The origin that is allowed to manipulate metadata.
52-
type AuthorityOrigin: EnsureOrigin<<Self as frame_system::Config>::Origin>;
53+
/// Checks that an origin has the authority to register/update an asset
54+
type AuthorityOrigin: EnsureOriginWithArg<Self::Origin, Option<Self::AssetId>>;
5355

5456
/// A filter ran upon metadata registration that assigns an is and
5557
/// potentially modifies the supplied metadata.
@@ -88,10 +90,6 @@ pub mod module {
8890
asset_id: T::AssetId,
8991
metadata: AssetMetadata<T::Balance, T::CustomMetadata>,
9092
},
91-
SetLocation {
92-
asset_id: T::AssetId,
93-
location: Box<VersionedMultiLocation>,
94-
},
9593
}
9694

9795
/// The metadata of an asset, indexed by asset id.
@@ -147,7 +145,7 @@ pub mod module {
147145
metadata: AssetMetadata<T::Balance, T::CustomMetadata>,
148146
asset_id: Option<T::AssetId>,
149147
) -> DispatchResult {
150-
T::AuthorityOrigin::ensure_origin(origin)?;
148+
T::AuthorityOrigin::ensure_origin(origin, &asset_id)?;
151149

152150
Self::do_register_asset(metadata, asset_id)
153151
}
@@ -165,7 +163,7 @@ pub mod module {
165163
location: Option<Option<VersionedMultiLocation>>,
166164
additional: Option<T::CustomMetadata>,
167165
) -> DispatchResult {
168-
T::AuthorityOrigin::ensure_origin(origin)?;
166+
T::AuthorityOrigin::ensure_origin(origin, &Some(asset_id.clone()))?;
169167

170168
Self::do_update_asset(
171169
asset_id,

asset-registry/src/mock/para.rs

+32-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ use crate as orml_asset_registry;
44

55
use codec::{Decode, Encode};
66
use cumulus_primitives_core::{ChannelStatus, GetChannelInfo, ParaId};
7+
use frame_support::traits::{EnsureOrigin, EnsureOriginWithArg};
78
use frame_support::{
8-
construct_runtime, match_types, parameter_types,
9+
construct_runtime, match_types, ord_parameter_types, parameter_types,
910
traits::{ConstU128, ConstU32, ConstU64, Everything, Nothing},
1011
weights::{constants::WEIGHT_PER_SECOND, Weight},
1112
PalletId,
1213
};
13-
use frame_system::EnsureRoot;
14+
use frame_system::{EnsureRoot, EnsureSignedBy};
1415
use orml_asset_registry::{AssetRegistryTrader, FixedRateAssetRegistryTrader};
1516
use orml_traits::{
1617
location::{AbsoluteReserveProvider, RelativeReserveProvider},
@@ -105,11 +106,39 @@ pub struct CustomMetadata {
105106
pub fee_per_second: u128,
106107
}
107108

109+
const ADMIN_ASSET_TWO: AccountId = AccountId32::new([42u8; 32]);
110+
111+
ord_parameter_types! {
112+
pub const AdminAssetTwo: AccountId = ADMIN_ASSET_TWO;
113+
}
114+
115+
pub struct AssetAuthority;
116+
impl EnsureOriginWithArg<Origin, Option<u32>> for AssetAuthority {
117+
type Success = ();
118+
119+
fn try_origin(origin: Origin, asset_id: &Option<u32>) -> Result<Self::Success, Origin> {
120+
match asset_id {
121+
// We mock an edge case where the asset_id 2 requires a special origin check.
122+
Some(2) => EnsureSignedBy::<AdminAssetTwo, AccountId32>::try_origin(origin.clone())
123+
.map(|_| ())
124+
.map_err(|_| origin),
125+
126+
// Any other `asset_id` defaults to EnsureRoot
127+
_ => EnsureRoot::try_origin(origin),
128+
}
129+
}
130+
131+
#[cfg(feature = "runtime-benchmarks")]
132+
fn successful_origin(_asset_id: &Option<u32>) -> Origin {
133+
unimplemented!()
134+
}
135+
}
136+
108137
impl orml_asset_registry::Config for Runtime {
109138
type Event = Event;
110139
type Balance = Balance;
111140
type AssetId = u32;
112-
type AuthorityOrigin = EnsureRoot<AccountId>;
141+
type AuthorityOrigin = AssetAuthority;
113142
type CustomMetadata = CustomMetadata;
114143
type AssetProcessor = orml_asset_registry::SequentialId<Runtime>;
115144
type WeightInfo = ();

asset-registry/src/tests.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
use super::*;
44
use crate as orml_asset_registry;
5-
use crate::tests::para::{AssetRegistry, CustomMetadata, Origin, Tokens, TreasuryAccount};
5+
use crate::tests::para::{AdminAssetTwo, AssetRegistry, CustomMetadata, Origin, Tokens, TreasuryAccount};
66
use frame_support::{assert_noop, assert_ok};
77
use mock::*;
88
use orml_traits::MultiCurrency;
99
use polkadot_parachain::primitives::Sibling;
10-
use sp_runtime::{traits::AccountIdConversion, AccountId32};
10+
11+
use sp_runtime::{
12+
traits::{AccountIdConversion, BadOrigin},
13+
AccountId32,
14+
};
1115
use xcm_simulator::TestExt;
1216

1317
fn treasury_account() -> AccountId32 {
@@ -458,3 +462,33 @@ fn test_existential_deposits() {
458462
);
459463
});
460464
}
465+
466+
#[test]
467+
fn test_asset_authority() {
468+
TestNet::reset();
469+
470+
ParaA::execute_with(|| {
471+
let metadata = dummy_metadata();
472+
473+
// Assert that root can register an asset with id 1
474+
assert_ok!(AssetRegistry::register_asset(Origin::root(), metadata.clone(), Some(1)));
475+
476+
// Assert that only Account42 can register asset with id 42
477+
let metadata = AssetMetadata {
478+
location: None,
479+
..dummy_metadata()
480+
};
481+
482+
// It fails when signed with root...
483+
assert_noop!(
484+
AssetRegistry::register_asset(Origin::root(), metadata.clone(), Some(2)),
485+
BadOrigin
486+
);
487+
// It works when signed with the right account
488+
assert_ok!(AssetRegistry::register_asset(
489+
Origin::signed(AdminAssetTwo::get()),
490+
metadata,
491+
Some(2)
492+
));
493+
});
494+
}

0 commit comments

Comments
 (0)