From fb765eeaeca05ea607d86ff4f0f5b0ba772439c1 Mon Sep 17 00:00:00 2001 From: Seun Lanlege Date: Mon, 13 Jan 2025 14:44:45 +0000 Subject: [PATCH] simplify pallet-token-gateway --- Cargo.lock | 2 +- Cargo.toml | 5 +- modules/pallets/testsuite/src/runtime.rs | 4 +- .../src/tests/pallet_token_gateway.rs | 37 +----- modules/pallets/token-gateway/Cargo.toml | 12 +- .../pallets/token-gateway/src/benchmarking.rs | 114 ++++++++---------- modules/pallets/token-gateway/src/lib.rs | 98 ++------------- 7 files changed, 72 insertions(+), 200 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45fedbf2..cea96888 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13006,7 +13006,7 @@ dependencies = [ [[package]] name = "pallet-token-gateway" -version = "15.0.0" +version = "15.1.0" dependencies = [ "alloy-primitives", "alloy-sol-macro", diff --git a/Cargo.toml b/Cargo.toml index 2f9d92f2..40ef624c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -348,10 +348,7 @@ tesseract-config = { path = "tesseract/config" } [workspace.dependencies.ethabi] version = "18.0.0" default-features = false -features = [ - "rlp", - "parity-codec", -] +features = ["rlp", "parity-codec"] [workspace.dependencies.ethers] git = "https://github.com/polytope-labs/ethers-rs" diff --git a/modules/pallets/testsuite/src/runtime.rs b/modules/pallets/testsuite/src/runtime.rs index fa460c7f..6722667b 100644 --- a/modules/pallets/testsuite/src/runtime.rs +++ b/modules/pallets/testsuite/src/runtime.rs @@ -23,7 +23,7 @@ use frame_support::{ traits::{ConstU32, ConstU64, Get}, PalletId, }; -use frame_system::{EnsureRoot, EventRecord}; +use frame_system::{EnsureRoot, EnsureSigned, EventRecord}; use ismp::{ consensus::{ ConsensusClient, ConsensusClientId, StateCommitment, StateMachineClient, @@ -245,7 +245,7 @@ impl pallet_token_gateway::Config for Test { type Assets = Assets; type NativeCurrency = Balances; type NativeAssetId = NativeAssetId; - type AssetIdFactory = AssetIdFactory; + type CreateOrigin = EnsureSigned; type Decimals = Decimals; type AssetAdmin = AssetAdmin; type EvmToSubstrate = (); diff --git a/modules/pallets/testsuite/src/tests/pallet_token_gateway.rs b/modules/pallets/testsuite/src/tests/pallet_token_gateway.rs index d786de48..d8525b2b 100644 --- a/modules/pallets/testsuite/src/tests/pallet_token_gateway.rs +++ b/modules/pallets/testsuite/src/tests/pallet_token_gateway.rs @@ -16,9 +16,7 @@ use pallet_token_gateway::{ use sp_core::{ByteArray, Get, Pair, H160, H256, U256}; use sp_runtime::{AccountId32, MultiSignature}; -use token_gateway_primitives::{ - AssetMetadata, GatewayAssetRegistration, PALLET_TOKEN_GATEWAY_ID, TOKEN_GOVERNOR_ID, -}; +use token_gateway_primitives::{GatewayAssetRegistration, PALLET_TOKEN_GATEWAY_ID}; use xcm_simulator_example::ALICE; use crate::runtime::{ @@ -306,39 +304,6 @@ fn inspector_should_handle_timeout_correctly() { }); } -#[test] -fn receiving_remote_asset_creation() { - new_test_ext().execute_with(|| { - let asset_metadata = AssetMetadata { - name: "USDC".as_bytes().to_vec().try_into().unwrap(), - symbol: "USDC".as_bytes().to_vec().try_into().unwrap(), - decimals: 6, - minimum_balance: None, - }; - - let post = PostRequest { - source: StateMachine::Polkadot(3367), - dest: StateMachine::Kusama(100), - nonce: 0, - from: TOKEN_GOVERNOR_ID.to_vec(), - to: PALLET_TOKEN_GATEWAY_ID.to_vec(), - timeout_timestamp: 0, - body: asset_metadata.encode(), - }; - - let module = TokenGateway::default(); - let res = module.on_accept(post); - println!("{res:?}"); - assert!(res.is_ok()); - let local_asset_id = - AssetIdFactory::create_asset_id(asset_metadata.symbol.to_vec()).unwrap(); - let asset = pallet_token_gateway::SupportedAssets::::get(local_asset_id).unwrap(); - // For the test we use the same asset id construction for local and token gateway, they - // should be equal - assert_eq!(local_asset_id, asset); - }) -} - #[test] fn dispatching_remote_asset_creation() { new_test_ext().execute_with(|| { diff --git a/modules/pallets/token-gateway/Cargo.toml b/modules/pallets/token-gateway/Cargo.toml index 822739d2..3cca6df5 100644 --- a/modules/pallets/token-gateway/Cargo.toml +++ b/modules/pallets/token-gateway/Cargo.toml @@ -1,14 +1,20 @@ [package] name = "pallet-token-gateway" -version = "15.0.0" +version = "15.1.0" edition = "2021" description = "A substrate implementation of the token gateway protocol" authors = ["Polytope Labs "] license = "Apache-2.0" repository = "https://github.com/polytope-labs/hyperbridge" -homepage = "https://docs.hyperbridge.network/developers/polkadot/tokengateway" +homepage = "https://docs.hyperbridge.network/developers/polkadot/token-gateway" documentation = "https://docs.rs/pallet-token-gateway" -keywords = ["substrate", "polkadot-sdk", "ISMP", "interoperability", "pallet-assets"] +keywords = [ + "substrate", + "polkadot-sdk", + "ISMP", + "interoperability", + "pallet-assets", +] readme = "README.md" [dependencies] diff --git a/modules/pallets/token-gateway/src/benchmarking.rs b/modules/pallets/token-gateway/src/benchmarking.rs index b54a3d75..4d2a2428 100644 --- a/modules/pallets/token-gateway/src/benchmarking.rs +++ b/modules/pallets/token-gateway/src/benchmarking.rs @@ -3,7 +3,7 @@ use crate::{types::*, *}; use frame_benchmarking::v2::*; use frame_support::{ - traits::{fungible, fungibles}, + traits::{fungible, fungibles, Currency}, BoundedVec, }; use frame_system::RawOrigin; @@ -12,34 +12,6 @@ use scale_info::prelude::collections::BTreeMap; use sp_runtime::AccountId32; use token_gateway_primitives::{GatewayAssetRegistration, GatewayAssetUpdate}; -fn dummy_teleport_asset( - asset_id: AssetId, -) -> TeleportParams, <::NativeCurrency as Currency>::Balance> -where - T: Config, - <::NativeCurrency as Currency>::Balance: From, -{ - TeleportParams { - asset_id, - destination: StateMachine::Evm(100), - recepient: H256::from([1u8; 32]), - amount: 1100000000u128.into(), - timeout: 10, - token_gateway: vec![1, 2, 3, 4, 5], - relayer_fee: 1000000002u128.into(), - call_data: None, - } -} - -fn create_dummy_asset( - asset_details: GatewayAssetRegistration, -) -> AssetRegistration> -where -{ - let local_id = T::AssetIdFactory::create_asset_id(asset_details.symbol.to_vec()).unwrap(); - AssetRegistration { local_id, reg: asset_details, native: true } -} - #[benchmarks( where <::NativeCurrency as Currency>::Balance: From, @@ -65,7 +37,11 @@ mod benches { chains: vec![StateMachine::Evm(100)], minimum_balance: Some(10), }; - let asset = create_dummy_asset::(asset_details); + let asset = AssetRegistration { + local_id: T::NativeAssetId::get(), + reg: asset_details, + native: true, + }; >::set_balance(&account, u128::MAX.into()); @@ -79,30 +55,43 @@ mod benches { fn teleport() -> Result<(), BenchmarkError> { let account: T::AccountId = whitelisted_caller(); - let asset_details = GatewayAssetRegistration { - name: BoundedVec::try_from(b"Spectre".to_vec()).unwrap(), - symbol: BoundedVec::try_from(b"SPC".to_vec()).unwrap(), - chains: vec![StateMachine::Evm(100)], - minimum_balance: None, - }; - let asset = create_dummy_asset::(asset_details); + let asset_id = T::NativeAssetId::get(); Pallet::::create_erc6160_asset( RawOrigin::Signed(account.clone()).into(), - asset.clone(), + AssetRegistration { + local_id: asset_id.clone(), + reg: GatewayAssetRegistration { + name: BoundedVec::try_from(b"Spectre".to_vec()).unwrap(), + symbol: BoundedVec::try_from(b"SPC".to_vec()).unwrap(), + chains: vec![StateMachine::Evm(100)], + minimum_balance: None, + }, + native: true, + }, )?; - let dummy_teleport_params = dummy_teleport_asset::(asset.local_id); - - >::set_balance(&account, u128::MAX.into()); + let _ = T::NativeCurrency::deposit_creating(&account, u128::MAX.into()); + let teleport_params = TeleportParams { + asset_id, + destination: StateMachine::Evm(100), + recepient: H256::from([1u8; 32]), + amount: 10_000_000_000_000u128.into(), + timeout: 0, + token_gateway: vec![1, 2, 3, 4, 5], + relayer_fee: 0u128.into(), + call_data: None, + }; #[extrinsic_call] - teleport(RawOrigin::Signed(account), dummy_teleport_params); + _(RawOrigin::Signed(account), teleport_params); Ok(()) } #[benchmark] - fn set_token_gateway_addresses(x: Linear<5, 100>) -> Result<(), BenchmarkError> { + fn set_token_gateway_addresses(x: Linear<1, 100>) -> Result<(), BenchmarkError> { + let account: T::AccountId = whitelisted_caller(); + let mut addresses = BTreeMap::new(); for i in 0..x { let addr = i.to_string().as_bytes().to_vec(); @@ -110,46 +99,39 @@ mod benches { } #[extrinsic_call] - _(RawOrigin::Root, addresses); + _(RawOrigin::Signed(account), addresses); Ok(()) } #[benchmark] fn update_erc6160_asset() -> Result<(), BenchmarkError> { - let acc_origin: T::AccountId = whitelisted_caller(); + let account: T::AccountId = whitelisted_caller(); - let asset_details = GatewayAssetRegistration { - name: BoundedVec::try_from(b"Spectre".to_vec()).unwrap(), - symbol: BoundedVec::try_from(b"SPC".to_vec()).unwrap(), - chains: vec![StateMachine::Evm(100)], - minimum_balance: None, - }; - let asset = create_dummy_asset::(asset_details.clone()); - - // set balances - >::set_balance(&acc_origin, u128::MAX.into()); - let asset_id = T::AssetIdFactory::create_asset_id(asset_details.symbol.to_vec()).unwrap(); - >::create( - asset_id.into(), - acc_origin.clone(), - true, - 1000000000u128.into(), - )?; + let local_id = T::NativeAssetId::get(); Pallet::::create_erc6160_asset( - RawOrigin::Signed(acc_origin.clone()).into(), - asset.clone(), + RawOrigin::Signed(account.clone()).into(), + AssetRegistration { + local_id, + reg: GatewayAssetRegistration { + name: BoundedVec::try_from(b"Spectre".to_vec()).unwrap(), + symbol: BoundedVec::try_from(b"SPC".to_vec()).unwrap(), + chains: vec![StateMachine::Evm(100)], + minimum_balance: None, + }, + native: true, + }, )?; let asset_update = GatewayAssetUpdate { - asset_id: H256::zero(), + asset_id: sp_io::hashing::keccak_256(b"SPC".as_ref()).into(), add_chains: BoundedVec::try_from(vec![StateMachine::Evm(200)]).unwrap(), remove_chains: BoundedVec::try_from(Vec::new()).unwrap(), new_admins: BoundedVec::try_from(Vec::new()).unwrap(), }; #[extrinsic_call] - _(RawOrigin::Signed(acc_origin), asset_update); + _(RawOrigin::Signed(account), asset_update); Ok(()) } } diff --git a/modules/pallets/token-gateway/src/lib.rs b/modules/pallets/token-gateway/src/lib.rs index e82ba6ab..4e6dde35 100644 --- a/modules/pallets/token-gateway/src/lib.rs +++ b/modules/pallets/token-gateway/src/lib.rs @@ -44,12 +44,8 @@ use ismp::{ use sp_core::{Get, H160, U256}; use sp_runtime::{traits::Dispatchable, MultiSignature}; -use token_gateway_primitives::{ - AssetMetadata, DeregisterAssets, PALLET_TOKEN_GATEWAY_ID, TOKEN_GOVERNOR_ID, -}; -use types::{ - AssetId, Body, BodyWithCall, CreateAssetId, EvmToSubstrate, RequestBody, SubstrateCalldata, -}; +use token_gateway_primitives::{PALLET_TOKEN_GATEWAY_ID, TOKEN_GOVERNOR_ID}; +use types::{AssetId, Body, BodyWithCall, EvmToSubstrate, RequestBody, SubstrateCalldata}; use alloc::{string::ToString, vec, vec::Vec}; use frame_system::RawOrigin; @@ -59,9 +55,6 @@ use primitive_types::H256; // Re-export pallet items so that they can be accessed from the crate namespace. pub use pallet::*; -/// Minimum balance for token gateway assets -const MIN_BALANCE: u128 = 1_000_000_000; - #[frame_support::pallet] pub mod pallet { use alloc::collections::BTreeMap; @@ -108,6 +101,9 @@ pub mod pallet { /// creation type AssetAdmin: Get; + /// Account that is authorized to create and update assets. + type CreateOrigin: EnsureOrigin; + /// Fungible asset implementation type Assets: fungibles::Mutate + fungibles::Inspect @@ -118,9 +114,6 @@ pub mod pallet { /// The native asset ID type NativeAssetId: Get>; - /// A trait that can be used to create new asset Ids - type AssetIdFactory: CreateAssetId>; - /// The decimals of the native currency #[pallet::constant] type Decimals: Get; @@ -369,7 +362,7 @@ pub mod pallet { origin: OriginFor, addresses: BTreeMap>, ) -> DispatchResult { - T::AdminOrigin::ensure_origin(origin)?; + T::CreateOrigin::ensure_origin(origin)?; for (chain, address) in addresses { TokenGatewayAddresses::::insert(chain, address.clone()); } @@ -387,8 +380,8 @@ pub mod pallet { origin: OriginFor, asset: AssetRegistration>, ) -> DispatchResult { - let who = ensure_signed(origin)?; - + T::CreateOrigin::ensure_origin(origin)?; + let who = T::AssetAdmin::get(); // charge hyperbridge fees let VersionedHostParams::V1(SubstrateHostParams { asset_registration_fee, .. }) = pallet_hyperbridge::Pallet::::host_params(); @@ -441,10 +434,8 @@ pub mod pallet { origin: OriginFor, asset: GatewayAssetUpdate, ) -> DispatchResult { - let who = ensure_signed(origin)?; - let asset_id = LocalAssets::::get(asset.asset_id.clone()) - .ok_or_else(|| Error::::UnregisteredAsset)?; - Self::ensure_admin(who.clone(), asset_id)?; + T::CreateOrigin::ensure_origin(origin)?; + let who = T::AssetAdmin::get(); // charge hyperbridge fees let VersionedHostParams::V1(SubstrateHostParams { asset_registration_fee, .. }) = @@ -499,65 +490,6 @@ where &self, PostRequest { body, from, source, dest, nonce, .. }: PostRequest, ) -> Result<(), anyhow::Error> { - // The only requests allowed from token governor on Hyperbridge is asset creation, updating - // and deregistering - if &from == &TOKEN_GOVERNOR_ID[..] && Some(source) == T::Coprocessor::get() { - if let Ok(metadata) = AssetMetadata::decode(&mut &body[..]) { - let asset_id: H256 = sp_io::hashing::keccak_256(metadata.symbol.as_ref()).into(); - // If the local aset Id exists, then it must mean this is an update. - if let Some(local_asset_id) = LocalAssets::::get(asset_id) { - >::set( - local_asset_id.clone(), - &T::AssetAdmin::get(), - metadata.name.to_vec(), - metadata.symbol.to_vec(), - // We do not change the asset's native decimal - >::decimals( - local_asset_id.clone(), - ), - ) - .map_err(|e| anyhow!("{e:?}"))?; - // Note the asset's ERC counterpart decimal - Decimals::::insert(local_asset_id, metadata.decimals); - } else { - let min_balance = metadata.minimum_balance.unwrap_or(MIN_BALANCE); - let local_asset_id = - T::AssetIdFactory::create_asset_id(metadata.symbol.to_vec())?; - >::create( - local_asset_id.clone(), - T::AssetAdmin::get(), - true, - min_balance.into(), - ) - .map_err(|e| anyhow!("{e:?}"))?; - >::set( - local_asset_id.clone(), - &T::AssetAdmin::get(), - metadata.name.to_vec(), - metadata.symbol.to_vec(), - 18, - ) - .map_err(|e| anyhow!("{e:?}"))?; - SupportedAssets::::insert(local_asset_id.clone(), asset_id.clone()); - LocalAssets::::insert(asset_id, local_asset_id.clone()); - // Note the asset's ERC counterpart decimal - Decimals::::insert(local_asset_id, metadata.decimals); - } - return Ok(()); - } - - if let Ok(meta) = DeregisterAssets::decode(&mut &body[..]) { - for asset_id in meta.asset_ids { - if let Some(local_asset_id) = LocalAssets::::get(H256::from(asset_id.0)) { - SupportedAssets::::remove(local_asset_id.clone()); - LocalAssets::::remove(H256::from(asset_id.0)); - Decimals::::remove(local_asset_id.clone()); - } - } - - return Ok(()); - } - } let expected = TokenGatewayAddresses::::get(source) .ok_or_else(|| anyhow!("Not configured to receive assets from {source:?}"))?; ensure!( @@ -804,13 +736,3 @@ where Ok(()) } } - -impl Pallet { - /// Ensure the signer is the asset admin - pub fn ensure_admin(who: T::AccountId, asset_id: AssetId) -> Result<(), Error> { - let owner = >::admin(asset_id) - .ok_or_else(|| Error::::UnknownAsset)?; - ensure!(who == owner, Error::::NotAssetOwner); - Ok(()) - } -}