diff --git a/Cargo.lock b/Cargo.lock index cba8f5564c3b..9abd787f5493 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12363,17 +12363,25 @@ dependencies = [ "frame-support", "frame-system", "pallet-balances", + "pallet-message-queue", "pallet-uniques", + "pallet-xcm", "parity-scale-codec", + "polkadot-core-primitives", + "polkadot-parachain-primitives", + "polkadot-runtime-parachains", "scale-info", "serde", "sp-core 28.0.0", "sp-io 30.0.0", "sp-runtime 31.0.1", "sp-std 14.0.0", + "sp-tracing 16.0.0", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", + "staging-xcm-executor", + "xcm-simulator", ] [[package]] diff --git a/templates/parachain_two/pallets/xcnft/Cargo.toml b/templates/parachain_two/pallets/xcnft/Cargo.toml index c6519e04e54b..28420b1bf9f9 100644 --- a/templates/parachain_two/pallets/xcnft/Cargo.toml +++ b/templates/parachain_two/pallets/xcnft/Cargo.toml @@ -49,6 +49,17 @@ sp-io = { workspace = true, default-features = true } pallet-balances = { workspace = true, default-features = true } +# For unit tests +xcm-builder = { workspace = true, default-features = true } +xcm-simulator = { workspace = true, default-features = true } +xcm-executor = { workspace = true, default-features = true } +sp-tracing = { workspace = true, default-features = true } +pallet-xcm = { workspace = true, default-features = true } +polkadot-core-primitives = { workspace = true, default-features = true } +polkadot-runtime-parachains = { workspace = true, default-features = true } +polkadot-parachain-primitives = { workspace = true, default-features = true } +pallet-message-queue = { workspace = true, default-features = true } + [features] default = [ "std" ] runtime-benchmarks = [ @@ -56,17 +67,24 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-uniques/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "polkadot-parachain-primitives/runtime-benchmarks", + "polkadot-runtime-parachains/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", ] std = [ "codec/std", "scale-info/std", - "pallet-uniques/std", "frame-benchmarking?/std", "frame-support/std", "frame-system/std", + "pallet-uniques/std", "sp-runtime/std", - "cumulus-pallet-xcm/std", - "cumulus-primitives-core/std", "sp-std/std", "xcm/std", "xcm-builder/std", diff --git a/templates/parachain_two/pallets/xcnft/src/mock.rs b/templates/parachain_two/pallets/xcnft/src/mock.rs index a87e24a6d2df..f69f5691eff4 100644 --- a/templates/parachain_two/pallets/xcnft/src/mock.rs +++ b/templates/parachain_two/pallets/xcnft/src/mock.rs @@ -30,7 +30,7 @@ mod test_runtime { #[runtime::pallet_index(0)] pub type System = frame_system; - #[runtime::pallet_index(1)] + #[runtime::pallet_index(5)] pub type XcNFT = crate; #[runtime::pallet_index(2)] diff --git a/templates/parachain_two/pallets/xcnft/src/tests.rs b/templates/parachain_two/pallets/xcnft/src/tests.rs index f634a81b53cb..cf47edea41b6 100644 --- a/templates/parachain_two/pallets/xcnft/src/tests.rs +++ b/templates/parachain_two/pallets/xcnft/src/tests.rs @@ -2,43 +2,198 @@ use crate::{ mock::*, Error, Event, GeneralizedDestroyWitness, Proposal, ReceivedAssets, ReceivedCollections, ReceivedCols, ReceivedStruct, SentAssets, SentStruct, }; + +pub mod testpara; +pub mod testrelay; + use frame_support::assert_noop; -use pallet_uniques::Event::Destroyed; -use sp_runtime::{AccountId32, BoundedVec}; +use sp_runtime::{traits::Bounded, AccountId32, BoundedVec, BuildStorage}; +use cumulus_primitives_core::Parachain; +use xcm_executor::traits::ConvertLocation; +use xcm::prelude::*; +use crate::tests::testpara::XcNFT; pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); +pub const INITIAL_BALANCE: u128 = 1_000_000_000; -#[test] -fn try_sending_collection_that_doesnt_exist() { - new_test_ext().execute_with(|| { +use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; +use sp_tracing; + +pub fn parent_account_id() -> testpara::AccountId { + let location = (Parent,); + testpara::location_converter::LocationConverter::convert_location(&location.into()).unwrap() +} + +pub fn child_account_id(para: u32) -> testrelay::AccountId { + let location = (Parachain(para),); + testrelay::location_converter::LocationConverter::convert_location(&location.into()).unwrap() +} + +decl_test_parachain! { + pub struct ParaA { + Runtime = testpara::Runtime, + XcmpMessageHandler = testpara::MsgQueue, + DmpMessageHandler = testpara::MsgQueue, + new_ext = para_ext(1000), + } +} + +decl_test_parachain! { + pub struct ParaB { + Runtime = testpara::Runtime, + XcmpMessageHandler = testpara::MsgQueue, + DmpMessageHandler = testpara::MsgQueue, + new_ext = para_ext(2000), + } +} + +decl_test_relay_chain! { + pub struct Relay { + Runtime = testrelay::Runtime, + RuntimeCall = testrelay::RuntimeCall, + RuntimeEvent = testrelay::RuntimeEvent, + XcmConfig = testrelay::XcmConfig, + MessageQueue = testrelay::MessageQueue, + System = testrelay::System, + new_ext = relay_ext(), + } +} + +decl_test_network! { + pub struct MockNet { + relay_chain = Relay, + parachains = vec![ + (1000, ParaA), + (2000, ParaB), + ], + } +} + + + +pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { + use testpara::{MsgQueue, Runtime, System}; + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INITIAL_BALANCE), (parent_account_id(), INITIAL_BALANCE)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + sp_tracing::try_init_simple(); + System::set_block_number(1); + MsgQueue::set_para_id(para_id.into()); + }); + ext +} + +pub fn relay_ext() -> sp_io::TestExternalities { + use testrelay::{Runtime, RuntimeOrigin, System, NFTs}; + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![ + (ALICE, INITIAL_BALANCE), + (child_account_id(1), INITIAL_BALANCE), + (child_account_id(2), INITIAL_BALANCE), + ], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { System::set_block_number(1); + }); + ext +} + +#[test] +fn try_sending_collection_empty_success() { + ParaA::execute_with(|| { + testpara::System::set_block_number(1); const COLLECTION_ID: u32 = 1; - assert_noop!( - XcNFT::collection_x_transfer( - RuntimeOrigin::signed(ALICE), - COLLECTION_ID, - Some(COLLECTION_ID), - 2000.into(), - None - ), - Error::::CollectionDoesNotExist + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + + let _ = testpara::XcNFT::collection_x_transfer( + testpara::RuntimeOrigin::signed(ALICE), + 0, + Some(COLLECTION_ID), + 2000.into(), + None + ); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionTransferred { origin_collection_id: 0, origin_collection_metadata: BoundedVec::new(), destination_para_id: 2000.into()})); + + }); +} + +#[test] +fn try_sending_collection_same_owner_success() { + ParaA::execute_with(|| { + testpara::System::set_block_number(1); + const COLLECTION_ID: u32 = 1; + + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0,ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 1, ALICE); + + let _ = testpara::XcNFT::collection_x_transfer( + testpara::RuntimeOrigin::signed(ALICE), + 0, + Some(COLLECTION_ID), + 2000.into(), + None + ); + + let nft_ids = vec![0, 1]; + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionAndNFTsTransferred { origin_collection_id: 0, nft_ids, destination_para_id: 2000.into()})); + + }); +} + +#[test] +fn try_sending_collection_different_owners_success() { + ParaA::execute_with(|| { + testpara::System::set_block_number(1); + const COLLECTION_ID: u32 = 1; + + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0,ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 1, BOB); + + let _ = testpara::XcNFT::collection_x_transfer( + testpara::RuntimeOrigin::signed(ALICE), + 0, + Some(COLLECTION_ID), + 2000.into(), + None ); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionTransferProposalCreated { proposal_id: 0, collection_id: 0, proposer: ALICE, destination: 2000.into()})); + }); } #[test] fn try_sending_collection_that_user_doesnt_own() { - new_test_ext().execute_with(|| { - System::set_block_number(1); + ParaA::execute_with(|| { + testpara::System::set_block_number(1); const COLLECTION_ID: u32 = 1; - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); assert_noop!( - XcNFT::collection_x_transfer( - RuntimeOrigin::signed(BOB), + testpara::XcNFT::collection_x_transfer( + testpara::RuntimeOrigin::signed(BOB), 0, Some(COLLECTION_ID), 2000.into(), @@ -49,13 +204,14 @@ fn try_sending_collection_that_user_doesnt_own() { }); } + #[test] fn try_voting_on_non_existing_proposal() { - new_test_ext().execute_with(|| { - System::set_block_number(1); + ParaA::execute_with(|| { + testpara::System::set_block_number(1); assert_noop!( - XcNFT::collection_x_transfer_vote(RuntimeOrigin::signed(ALICE), 0, crate::Vote::Aye), + testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(ALICE), 0, crate::Vote::Aye), Error::::ProposalDoesNotExist ); }); @@ -63,8 +219,8 @@ fn try_voting_on_non_existing_proposal() { #[test] fn try_voting_on_proposal_when_no_owner() { - new_test_ext().execute_with(|| { - System::set_block_number(1); + ParaA::execute_with(|| { + testpara::System::set_block_number(1); const COLLECTION_ID: u32 = 1; //Create proposal @@ -83,7 +239,7 @@ fn try_voting_on_proposal_when_no_owner() { let _ = crate::CrossChainProposals::insert(1, proposal); assert_noop!( - XcNFT::collection_x_transfer_vote(RuntimeOrigin::signed(BOB), 1, crate::Vote::Aye), + testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(BOB), 1, crate::Vote::Aye), Error::::NotNFTOwner ); }); @@ -91,8 +247,8 @@ fn try_voting_on_proposal_when_no_owner() { #[test] fn try_voting_on_proposal_expired() { - new_test_ext().execute_with(|| { - System::set_block_number(3); + ParaA::execute_with(|| { + testpara::System::set_block_number(3); const COLLECTION_ID: u32 = 1; //Create owners vector @@ -115,16 +271,16 @@ fn try_voting_on_proposal_expired() { let _ = crate::CrossChainProposals::insert(1, proposal); let _ = - XcNFT::collection_x_transfer_vote(RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); + testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); - System::assert_last_event(RuntimeEvent::XcNFT(Event::ProposalExpired { proposal_id: 1 })); + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::ProposalExpired { proposal_id: 1 })); }); } #[test] fn try_voting_on_proposal_did_not_pass() { - new_test_ext().execute_with(|| { - System::set_block_number(3); + ParaA::execute_with(|| { + testpara::System::set_block_number(3); const COLLECTION_ID: u32 = 1; //Create owners vector @@ -147,9 +303,9 @@ fn try_voting_on_proposal_did_not_pass() { let _ = crate::CrossChainProposals::insert(1, proposal); let _ = - XcNFT::collection_x_transfer_vote(RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); + testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); - System::assert_last_event(RuntimeEvent::XcNFT(Event::ProposalDidNotPass { + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::ProposalDidNotPass { proposal_id: 1, })); }); @@ -157,8 +313,8 @@ fn try_voting_on_proposal_did_not_pass() { #[test] fn try_voting_on_proposal_again_same_vote() { - new_test_ext().execute_with(|| { - System::set_block_number(1); + ParaA::execute_with(|| { + testpara::System::set_block_number(1); const COLLECTION_ID: u32 = 1; //Create owners vector @@ -181,10 +337,10 @@ fn try_voting_on_proposal_again_same_vote() { let _ = crate::CrossChainProposals::insert(1, proposal); let _ = - XcNFT::collection_x_transfer_vote(RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); + testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); assert_noop!( - XcNFT::collection_x_transfer_vote(RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye), + testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye), Error::::AlreadyVotedThis ); }); @@ -192,8 +348,8 @@ fn try_voting_on_proposal_again_same_vote() { #[test] fn vote_on_proposal_successfuly() { - new_test_ext().execute_with(|| { - System::set_block_number(1); + ParaA::execute_with(|| { + testpara::System::set_block_number(1); const COLLECTION_ID: u32 = 1; //Create owners vector @@ -216,9 +372,9 @@ fn vote_on_proposal_successfuly() { let _ = crate::CrossChainProposals::insert(1, proposal); let _ = - XcNFT::collection_x_transfer_vote(RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); + testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(ALICE), 1, crate::Vote::Aye); - System::assert_last_event(RuntimeEvent::XcNFT(Event::CrossChainPropoposalVoteRegistered { + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CrossChainPropoposalVoteRegistered { proposal_id: 1, voter: ALICE, vote: crate::Vote::Aye, @@ -226,13 +382,44 @@ fn vote_on_proposal_successfuly() { }); } +#[test] +fn initiate_proposal_successfuly() { + ParaA::execute_with(|| { + testpara::System::set_block_number(1); + const COLLECTION_ID: u32 = 1; + + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0,ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 1, BOB); + + let _ = testpara::XcNFT::collection_x_transfer( + testpara::RuntimeOrigin::signed(ALICE), + 0, + Some(COLLECTION_ID), + 2000.into(), + None + ); + + let _ = testpara::XcNFT::collection_x_transfer_vote(testpara::RuntimeOrigin::signed(ALICE), 0, crate::Vote::Aye); + + testpara::System::set_block_number(11); + + let _ = testpara::XcNFT::collection_x_transfer_initiate(testpara::RuntimeOrigin::signed(ALICE), 0); + + let nfts = vec![(0, ALICE, BoundedVec::new()), (1, BOB, BoundedVec::new())]; + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionAndNFTsDiffTransferred { origin_collection_id: 0, nfts: nfts, destination_para_id: 2000.into(), to_address: ALICE })); + + }); +} + #[test] fn try_initiating_proposal_doesnt_exist() { - new_test_ext().execute_with(|| { - System::set_block_number(1); + ParaA::execute_with(|| { + testpara::System::set_block_number(1); assert_noop!( - XcNFT::collection_x_transfer_initiate(RuntimeOrigin::signed(ALICE), 1), + testpara::XcNFT::collection_x_transfer_initiate(testpara::RuntimeOrigin::signed(ALICE), 1), Error::::ProposalDoesNotExist ); }); @@ -240,8 +427,8 @@ fn try_initiating_proposal_doesnt_exist() { #[test] fn try_initiating_proposal_collection_doesnt_exist() { - new_test_ext().execute_with(|| { - System::set_block_number(1); + ParaA::execute_with(|| { + testpara::System::set_block_number(1); const COLLECTION_ID: u32 = 1; @@ -265,7 +452,7 @@ fn try_initiating_proposal_collection_doesnt_exist() { let _ = crate::CrossChainProposals::insert(1, proposal); assert_noop!( - XcNFT::collection_x_transfer_initiate(RuntimeOrigin::signed(ALICE), 1), + testpara::XcNFT::collection_x_transfer_initiate(testpara::RuntimeOrigin::signed(ALICE), 1), Error::::CollectionDoesNotExist ); }); @@ -273,9 +460,10 @@ fn try_initiating_proposal_collection_doesnt_exist() { #[test] fn try_initiating_proposal_no_collection_owner() { - new_test_ext().execute_with(|| { - System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(BOB), 0, ALICE); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(BOB), 0, ALICE); //Create owners vector let mut owners = BoundedVec::new(); @@ -297,7 +485,7 @@ fn try_initiating_proposal_no_collection_owner() { let _ = crate::CrossChainProposals::insert(1, proposal); assert_noop!( - XcNFT::collection_x_transfer_initiate(RuntimeOrigin::signed(ALICE), 1), + testpara::XcNFT::collection_x_transfer_initiate(testpara::RuntimeOrigin::signed(ALICE), 1), Error::::NotCollectionOwner ); }); @@ -305,10 +493,10 @@ fn try_initiating_proposal_no_collection_owner() { #[test] fn try_initiating_proposal_that_did_not_pass() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); //Create owners vector let mut owners = BoundedVec::new(); @@ -328,19 +516,34 @@ fn try_initiating_proposal_that_did_not_pass() { }; let _ = crate::CrossChainProposals::insert(1, proposal); - let _ = XcNFT::collection_x_transfer_initiate(RuntimeOrigin::signed(ALICE), 1); + let _ = testpara::XcNFT::collection_x_transfer_initiate(testpara::RuntimeOrigin::signed(ALICE), 1); - System::assert_has_event(RuntimeEvent::XcNFT(Event::ProposalDidNotPass { proposal_id: 1 })); + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::ProposalDidNotPass { proposal_id: 1 })); + }); +} + +#[test] +fn try_sending_nft_successful() { + + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0,ALICE); + + let _ = testpara::XcNFT::nft_x_transfer(testpara::RuntimeOrigin::signed(ALICE), 0, 0, 1000.into(), 1, 1); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::NFTTransferred { origin_collection_id: 0, origin_asset_id: 0, destination_para_id: 1000.into(), destination_collection_id: 1, destination_asset_id: 1 })); }); } #[test] fn try_sending_nft_no_collection() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); assert_noop!( - XcNFT::nft_x_transfer(RuntimeOrigin::signed(ALICE), 1, 0, 1000.into(), 1, 1), + testpara::XcNFT::nft_x_transfer(testpara::RuntimeOrigin::signed(ALICE), 1, 0, 1000.into(), 1, 1), Error::::CollectionDoesNotExist ); }); @@ -348,13 +551,13 @@ fn try_sending_nft_no_collection() { #[test] fn try_sending_nft_no_nft() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); assert_noop!( - XcNFT::nft_x_transfer(RuntimeOrigin::signed(ALICE), 0, 0, 1000.into(), 1, 1), + testpara::XcNFT::nft_x_transfer(testpara::RuntimeOrigin::signed(ALICE), 0, 0, 1000.into(), 1, 1), Error::::NFTDoesNotExist ); }); @@ -362,15 +565,15 @@ fn try_sending_nft_no_nft() { #[test] fn try_sending_nft_not_nft_owner() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0, 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0, ALICE); assert_noop!( - XcNFT::nft_x_transfer(RuntimeOrigin::signed(BOB), 0, 0, 1000.into(), 1, 1), + testpara::XcNFT::nft_x_transfer(testpara::RuntimeOrigin::signed(BOB), 0, 0, 1000.into(), 1, 1), Error::::NotNFTOwner ); }); @@ -378,11 +581,11 @@ fn try_sending_nft_not_nft_owner() { #[test] fn try_claiming_nft_no_collection() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); assert_noop!( - XcNFT::nft_x_claim(RuntimeOrigin::signed(ALICE), 1u32, 0u32, 100u32.into(), 1u32, 1u32), + testpara::XcNFT::nft_x_claim(testpara::RuntimeOrigin::signed(ALICE), 1u32, 0u32, 100u32.into(), 1u32, 1u32), Error::::CollectionDoesNotExist ); }); @@ -390,13 +593,13 @@ fn try_claiming_nft_no_collection() { #[test] fn try_claiming_nft_no_collection_origin() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); assert_noop!( - XcNFT::nft_x_claim(RuntimeOrigin::signed(ALICE), 1u32, 0u32, 100u32.into(), 1u32, 1u32), + testpara::XcNFT::nft_x_claim(testpara::RuntimeOrigin::signed(ALICE), 1u32, 0u32, 100u32.into(), 1u32, 1u32), Error::::CollectionDoesNotExist ); }); @@ -404,10 +607,10 @@ fn try_claiming_nft_no_collection_origin() { #[test] fn try_claiming_nft_wrong_origin_collection() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); let collections: ReceivedCols = ReceivedCols:: { origin_para_id: 1000.into(), @@ -418,7 +621,7 @@ fn try_claiming_nft_wrong_origin_collection() { let _ = ReceivedCollections::::insert(0, collections); assert_noop!( - XcNFT::nft_x_claim(RuntimeOrigin::signed(ALICE), 0u32, 0u32, 100u32.into(), 0u32, 1u32), + testpara::XcNFT::nft_x_claim(testpara::RuntimeOrigin::signed(ALICE), 0u32, 0u32, 100u32.into(), 0u32, 1u32), Error::::WrongOriginCollectionAtOrigin ); }); @@ -426,10 +629,11 @@ fn try_claiming_nft_wrong_origin_collection() { #[test] fn try_claiming_nft_wrong_nft() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); let collections: ReceivedCols = ReceivedCols:: { origin_para_id: 1000.into(), @@ -440,7 +644,7 @@ fn try_claiming_nft_wrong_nft() { let _ = ReceivedCollections::::insert(0, collections); assert_noop!( - XcNFT::nft_x_claim(RuntimeOrigin::signed(ALICE), 0u32, 0u32, 100u32.into(), 0u32, 0u32), + testpara::XcNFT::nft_x_claim(testpara::RuntimeOrigin::signed(ALICE), 0u32, 0u32, 100u32.into(), 0u32, 0u32), Error::::NFTNotReceived ); }); @@ -448,16 +652,16 @@ fn try_claiming_nft_wrong_nft() { #[test] fn try_claiming_nft_not_owner() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0u32, 0u32, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0u32, 0u32, ALICE); - System::set_block_number(3); + testpara::System::set_block_number(3); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 1, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 1u32, 0u32, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 1, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 1u32, 0u32, ALICE); let collections: ReceivedCols = ReceivedCols:: { origin_para_id: 1000.into(), @@ -478,7 +682,7 @@ fn try_claiming_nft_not_owner() { let _ = ReceivedAssets::::insert((1, 0), nfts); assert_noop!( - XcNFT::nft_x_claim(RuntimeOrigin::signed(BOB), 0u32, 0u32, 0u32, 1u32, 0u32), + testpara::XcNFT::nft_x_claim(testpara::RuntimeOrigin::signed(BOB), 0u32, 0u32, 0u32, 1u32, 0u32), Error::::NotNFTOwner ); }); @@ -486,16 +690,16 @@ fn try_claiming_nft_not_owner() { #[test] fn try_claiming_nft_success() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0u32, 0u32, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0u32, 0u32, ALICE); System::set_block_number(3); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 1, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 1u32, 0u32, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 1, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 1u32, 0u32, ALICE); let collections: ReceivedCols = ReceivedCols:: { origin_para_id: 1000.into(), @@ -514,11 +718,11 @@ fn try_claiming_nft_success() { }; let _ = ReceivedAssets::::insert((1, 0), nfts); - System::set_block_number(3); + testpara::System::set_block_number(3); - let _ = XcNFT::nft_x_claim(RuntimeOrigin::signed(ALICE), 0u32, 0u32, 0u32, 1u32, 0u32); + let _ = testpara::XcNFT::nft_x_claim(testpara::RuntimeOrigin::signed(ALICE), 0u32, 0u32, 0u32, 1u32, 0u32); - System::assert_has_event(RuntimeEvent::XcNFT(Event::NFTClaimed { + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::NFTClaimed { collection_claimed_from: 1, asset_removed: 0, collection_claimed_to: 0, @@ -529,18 +733,18 @@ fn try_claiming_nft_success() { #[test] fn try_collection_parse_empty_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = XcNFT::parse_collection_empty( - RuntimeOrigin::signed(ALICE), + let _ = testpara::XcNFT::parse_collection_empty( + testpara::RuntimeOrigin::signed(ALICE), 1, None, BoundedVec::new(), None, ); - System::assert_has_event(RuntimeEvent::XcNFT(Event::CollectionReceived { + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionReceived { origin_collection_id: 1, received_collection_id: 1, to_address: ALICE, @@ -550,17 +754,17 @@ fn try_collection_parse_empty_successful() { #[test] fn try_parse_collection_burn_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); let destroy_witness = GeneralizedDestroyWitness { item_meta: 0, item_configs: 0, attributes: 0 }; - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = XcNFT::parse_collection_burn(RuntimeOrigin::signed(ALICE), 0, destroy_witness); + let _ = testpara::XcNFT::parse_collection_burn(testpara::RuntimeOrigin::signed(ALICE), 0, destroy_witness); - System::assert_has_event(RuntimeEvent::Uniques(pallet_uniques::Event::Destroyed { + testpara::System::assert_has_event(testpara::RuntimeEvent::NFTs(pallet_uniques::Event::Destroyed { collection: 0, })); }); @@ -568,36 +772,34 @@ fn try_parse_collection_burn_successful() { #[test] fn try_parse_collection_metadata_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); let _ = - XcNFT::parse_collection_metadata(RuntimeOrigin::signed(ALICE), 0, BoundedVec::new()); - - System::assert_has_event(RuntimeEvent::Uniques( - pallet_uniques::Event::CollectionMetadataSet { - collection: 0, - data: BoundedVec::new(), - is_frozen: false, - }, - )); + testpara::XcNFT::parse_collection_metadata(testpara::RuntimeOrigin::signed(ALICE), 0, BoundedVec::new()); + + testpara::System::assert_has_event(testpara::RuntimeEvent::NFTs(pallet_uniques::Event::CollectionMetadataSet { + collection: 0, + data: BoundedVec::new(), + is_frozen: false, + })); }); } #[test] fn try_parse_collection_owner_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); pallet_uniques::OwnershipAcceptance::::insert(BOB, 0); - let _ = XcNFT::parse_collection_owner(RuntimeOrigin::signed(ALICE), BOB, 0); + let _ = testpara::XcNFT::parse_collection_owner(testpara::RuntimeOrigin::signed(ALICE), BOB, 0); - System::assert_has_event(RuntimeEvent::Uniques(pallet_uniques::Event::OwnerChanged { + testpara::System::assert_has_event(testpara::RuntimeEvent::NFTs(pallet_uniques::Event::OwnerChanged { collection: 0, new_owner: BOB, })); @@ -606,16 +808,16 @@ fn try_parse_collection_owner_successful() { #[test] fn try_parse_nft_burn_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0, 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0, ALICE); - let _ = XcNFT::parse_nft_burn(RuntimeOrigin::signed(ALICE), 0, 0); + let _ = testpara::XcNFT::parse_nft_burn(testpara::RuntimeOrigin::signed(ALICE), 0, 0); - System::assert_has_event(RuntimeEvent::Uniques(pallet_uniques::Event::Burned { + testpara::System::assert_has_event(testpara::RuntimeEvent::NFTs(pallet_uniques::Event::Burned { collection: 0, item: 0, owner: ALICE, @@ -625,36 +827,36 @@ fn try_parse_nft_burn_successful() { #[test] fn try_parse_nft_metadata_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0, 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0, ALICE); - let _ = XcNFT::parse_nft_metadata(RuntimeOrigin::signed(ALICE), 0, 0, BoundedVec::new()); + let _ = testpara::XcNFT::parse_nft_metadata(testpara::RuntimeOrigin::signed(ALICE), 0, 0, BoundedVec::new()); - System::assert_has_event(RuntimeEvent::Uniques(pallet_uniques::Event::MetadataSet { + testpara::System::assert_has_event(testpara::RuntimeEvent::NFTs(pallet_uniques::Event::MetadataSet { collection: 0, item: 0, data: BoundedVec::new(), - is_frozen: false, + is_frozen: false })); }); } #[test] fn try_parse_nft_owner_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0, 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0, ALICE); - let _ = XcNFT::parse_nft_owner(RuntimeOrigin::signed(ALICE), BOB, 0, 0); + let _ = testpara::XcNFT::parse_nft_owner(testpara::RuntimeOrigin::signed(ALICE), BOB, 0, 0); - System::assert_has_event(RuntimeEvent::Uniques(pallet_uniques::Event::Transferred { + testpara::System::assert_has_event(testpara::RuntimeEvent::NFTs(pallet_uniques::Event::Transferred { collection: 0, item: 0, from: ALICE, @@ -665,12 +867,12 @@ fn try_parse_nft_owner_successful() { #[test] fn try_parse_nft_transfer_no_collection() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); assert_noop!( - XcNFT::parse_nft_transfer( - RuntimeOrigin::signed(ALICE), + testpara::XcNFT::parse_nft_transfer( + testpara::RuntimeOrigin::signed(ALICE), 0, 0, BoundedVec::new(), @@ -685,12 +887,12 @@ fn try_parse_nft_transfer_no_collection() { #[test] fn try_parse_nft_transfer_already_received() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0, 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0, ALICE); let nfts: ReceivedStruct = ReceivedStruct:: { origin_para_id: 1000.into(), @@ -703,8 +905,8 @@ fn try_parse_nft_transfer_already_received() { let _ = ReceivedAssets::::insert((0, 0), nfts); assert_noop!( - XcNFT::parse_nft_transfer( - RuntimeOrigin::signed(ALICE), + testpara::XcNFT::parse_nft_transfer( + testpara::RuntimeOrigin::signed(ALICE), 0, 0, BoundedVec::new(), @@ -719,15 +921,15 @@ fn try_parse_nft_transfer_already_received() { #[test] fn try_parse_nft_transfer_not_collection_owner() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0, 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0, ALICE); assert_noop!( - XcNFT::parse_nft_transfer( - RuntimeOrigin::signed(BOB), + testpara::XcNFT::parse_nft_transfer( + testpara::RuntimeOrigin::signed(BOB), 0, 0, BoundedVec::new(), @@ -742,15 +944,15 @@ fn try_parse_nft_transfer_not_collection_owner() { #[test] fn try_parse_nft_transfer_not_existing_nft() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = Uniques::mint(RuntimeOrigin::signed(ALICE), 0, 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::mint(testpara::RuntimeOrigin::signed(ALICE), 0, 0, ALICE); assert_noop!( - XcNFT::parse_nft_transfer( - RuntimeOrigin::signed(ALICE), + testpara::XcNFT::parse_nft_transfer( + testpara::RuntimeOrigin::signed(ALICE), 0, 0, BoundedVec::new(), @@ -765,12 +967,12 @@ fn try_parse_nft_transfer_not_existing_nft() { #[test] fn try_parse_nft_transfer_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); - let _ = XcNFT::parse_nft_transfer( - RuntimeOrigin::signed(ALICE), + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::XcNFT::parse_nft_transfer( + testpara::RuntimeOrigin::signed(ALICE), 0, 0, BoundedVec::new(), @@ -778,7 +980,7 @@ fn try_parse_nft_transfer_successful() { 0, 1000.into(), ); - System::assert_has_event(RuntimeEvent::XcNFT(Event::NFTReceived { + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::NFTReceived { origin_collection_id: 0, origin_asset_id: 0, received_collection_id: 0, @@ -790,10 +992,10 @@ fn try_parse_nft_transfer_successful() { #[test] fn try_parse_nft_transfer_return_to_origin() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let _ = Uniques::create(RuntimeOrigin::signed(ALICE), 0, ALICE); + let _ = testpara::NFTs::create(testpara::RuntimeOrigin::signed(ALICE), 0, ALICE); let sent = SentStruct:: { origin_para_id: ParachainInfo::parachain_id(), @@ -808,8 +1010,8 @@ fn try_parse_nft_transfer_return_to_origin() { //Set parachain id to 1000 ParachainInfo::parachain_id(); - let _ = XcNFT::parse_nft_transfer( - RuntimeOrigin::signed(ALICE), + let _ = testpara::XcNFT::parse_nft_transfer( + testpara::RuntimeOrigin::signed(ALICE), 0, 0, BoundedVec::new(), @@ -817,7 +1019,7 @@ fn try_parse_nft_transfer_return_to_origin() { 0, ParachainInfo::parachain_id(), ); - System::assert_has_event(RuntimeEvent::XcNFT(Event::NFTReturnedToOrigin { + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::NFTReturnedToOrigin { returned_from_collection_id: 0, returned_from_asset_id: 0, to_address: ALICE, @@ -827,14 +1029,14 @@ fn try_parse_nft_transfer_return_to_origin() { #[test] fn parse_collection_same_owner_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let mut nfts: Vec<(u32, BoundedVec)> = Vec::new(); + let mut nfts: Vec<(u32, BoundedVec)> = Vec::new(); nfts.push((1, BoundedVec::new())); - let _ = XcNFT::parse_collection_same_owner( - RuntimeOrigin::signed(ALICE), + let _ = testpara::XcNFT::parse_collection_same_owner( + testpara::RuntimeOrigin::signed(ALICE), None, BoundedVec::new(), nfts.clone(), @@ -842,7 +1044,7 @@ fn parse_collection_same_owner_successful() { 0, None, ); - System::assert_has_event(RuntimeEvent::XcNFT(Event::CollectionWithNftsReceived { + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionWithNftsReceived { collection_id: 0, items: nfts.clone(), })); @@ -851,14 +1053,14 @@ fn parse_collection_same_owner_successful() { #[test] fn parse_collection_diff_nft_owners_successful() { - new_test_ext().execute_with(|| { - System::set_block_number(2); + ParaA::execute_with(|| { + testpara::System::set_block_number(2); - let mut nfts: Vec<(u32, AccountId32, BoundedVec)> = Vec::new(); + let mut nfts: Vec<(u32, AccountId32, BoundedVec)> = Vec::new(); nfts.push((1, BOB, BoundedVec::new())); - let _ = XcNFT::parse_collection_diff_owners( - RuntimeOrigin::signed(ALICE), + let _ = testpara::XcNFT::parse_collection_diff_owners( + testpara::RuntimeOrigin::signed(ALICE), None, BoundedVec::new(), nfts.clone(), @@ -866,8 +1068,76 @@ fn parse_collection_diff_nft_owners_successful() { 0, None, ); - System::assert_has_event(RuntimeEvent::XcNFT( + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT( Event::CollectionWithNftsDiffOwnersReceived { collection_id: 0, items: nfts.clone() }, )); }); } + +#[test] +fn try_collection_metadata_success(){ + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let _ = testpara::XcNFT::collection_x_update(testpara::RuntimeOrigin::signed(ALICE), 0, 1000.into(), BoundedVec::new()); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionMetadataSent { collection_id: 0, proposed_data: BoundedVec::new(), owner: ALICE, destination: 1000.into()})); + }); +} + +#[test] +fn try_collection_owner_send_success(){ + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let _ = testpara::XcNFT::collection_x_change_owner(testpara::RuntimeOrigin::signed(ALICE), 0, 1000.into(), BOB); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionOwnershipSent { collection_id: 0, proposed_owner: BOB, destination: 1000.into() })); + }); +} + +#[test] +fn try_collection_burn_success(){ + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let witness = GeneralizedDestroyWitness { item_meta: 0, item_configs: 0, attributes: 0 }; + + let _ = testpara::XcNFT::collection_x_burn(testpara::RuntimeOrigin::signed(ALICE), 0, 1000.into(), witness.clone()); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::CollectionBurnSent { collection_id: 0, burn_data: witness.clone(), owner: ALICE, destination: 1000.into() })); + }); +} + +#[test] +fn try_nft_metadata_successful() { + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let _ = testpara::XcNFT::nft_x_update(testpara::RuntimeOrigin::signed(ALICE), 0, 0, 1000.into(), BoundedVec::new()); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::NFTMetadataSent { collection_id: 0, asset_id: 0, proposed_data: BoundedVec::new(), owner: ALICE, destination: 1000.into() })); + }); +} + +#[test] +fn try_nft_owner_successful() { + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let _ = testpara::XcNFT::nft_x_change_owner(testpara::RuntimeOrigin::signed(ALICE), 0, 0, 1000.into(), BOB); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::NFTOwnershipSent { collection_id: 0, asset_id: 0, proposed_owner: BOB, destination: 1000.into() })); + }); +} + +#[test] +fn try_nft_burn_successful() { + ParaA::execute_with(|| { + testpara::System::set_block_number(2); + + let _ = testpara::XcNFT::nft_x_burn(testpara::RuntimeOrigin::signed(ALICE), 0, 0, 1000.into()); + + testpara::System::assert_has_event(testpara::RuntimeEvent::XcNFT(Event::NFTBurnSent { collection_id: 0, asset_id: 0, owner: ALICE, destination: 1000.into() })); + }); +} \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara.rs new file mode 100644 index 000000000000..317827d6ae0b --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara.rs @@ -0,0 +1,204 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Parachain runtime mock. + +mod xcm_config; +pub use xcm_config::*; + +use parachain_info; + +use core::marker::PhantomData; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + traits::{ConstU128, ContainsPair, EnsureOrigin, EnsureOriginWithArg, Everything, Nothing}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, +}; +use frame_support::pallet_prelude::Get; +use frame_system::{EnsureRoot, EnsureSigned}; +use sp_core::ConstU32; +use sp_runtime::{ + traits::{ConstU64, Verify, IdentityLookup}, + AccountId32, BuildStorage, MultiSignature, +}; +use xcm::latest::prelude::*; +use xcm_builder::{EnsureXcmOrigin, SignedToAccountId32}; +use xcm_executor::{traits::ConvertLocation, XcmExecutor}; +use xcm_simulator::mock_message_queue; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Runtime { + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type AccountData = pallet_balances::AccountData; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; +} + + +pub const UNIT: Balance = 1; +parameter_types! { + pub const CollectionDeposit: Balance = 0 * UNIT; // 1 UNIT deposit to create asset collection + pub const ItemDeposit: Balance = 0 * UNIT; // 1/100 UNIT deposit to create asset item + pub const KeyLimit: u32 = 32; + pub const ValueLimit: u32 = 64; + pub const UniquesMetadataDepositBase: Balance = 0 * UNIT; + pub const AttributeDepositBase: Balance = 0 * UNIT; + pub const DepositPerByte: Balance = 0 * UNIT; + pub const UniquesStringLimit: u32 = 32; + pub const ApprovalsLimit: u32 = 1; + pub const ItemAttributesApprovalsLimit: u32 = 1; + pub const MaxTips: u32 = 1; + pub const MaxDeadlineDuration: u32 = 1; + pub const MaxAttributesPerCall: u32 = 10; + pub const proposal_time_in_blocks_parameter: u32 = 10; + pub const max_owners_parameter: u32 = 1000000; + pub const max_votes: u32 = 1000000; +} + +impl pallet_uniques::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CollectionId = u32; + type ItemId = u32; + type Currency = Balances; + type ForceOrigin = EnsureRoot; + type CreateOrigin = EnsureSigned; + type Locker = (); + type CollectionDeposit = CollectionDeposit; + type ItemDeposit = ItemDeposit; + type MetadataDepositBase = UniquesMetadataDepositBase; + type AttributeDepositBase = AttributeDepositBase; + type DepositPerByte = DepositPerByte; + type StringLimit = UniquesStringLimit; + type KeyLimit = KeyLimit; + type ValueLimit = ValueLimit; + type WeightInfo = (); +} + +// `EnsureOriginWithArg` impl for `CreateOrigin` which allows only XCM origins +// which are locations containing the class location. +pub struct ForeignCreators; +impl EnsureOriginWithArg for ForeignCreators { + type Success = AccountId; + + fn try_origin( + o: RuntimeOrigin, + a: &Location, + ) -> core::result::Result { + let origin_location = pallet_xcm::EnsureXcm::::try_origin(o.clone())?; + if !a.starts_with(&origin_location) { + return Err(o); + } + xcm_config::location_converter::LocationConverter::convert_location(&origin_location) + .ok_or(o) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin(a: &Location) -> Result { + Ok(pallet_xcm::Origin::Xcm(a.clone()).into()) + } +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); + pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); +} + +impl mock_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; +} + +pub type LocalOriginToLocation = + SignedToAccountId32; + +pub struct TrustedLockerCase(PhantomData); +impl> ContainsPair for TrustedLockerCase { + fn contains(origin: &Location, asset: &Asset) -> bool { + let (o, a) = T::get(); + a.matches(asset) && &o == origin + } +} + +parameter_types! { + pub RelayTokenForRelay: (Location, AssetFilter) = (Parent.into(), Wild(AllOf { id: AssetId(Parent.into()), fun: WildFungible })); +} + +pub type TrustedLockers = TrustedLockerCase; + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = weigher::Weigher; + type UniversalLocation = constants::UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = TrustedLockers; + type SovereignAccountOf = location_converter::LocationConverter; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + type AdminOrigin = EnsureRoot; +} + +impl crate::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type XcmSender = XcmRouter; + type RuntimeCall = RuntimeCall; + type ProposalTimeInBlocks = proposal_time_in_blocks_parameter; + type MaxOwners = max_owners_parameter; +} + +type Block = frame_system::mocking::MockBlock; + +impl parachain_info::Config for Runtime {} + +construct_runtime!( + pub struct Runtime { + System: frame_system, + Balances: pallet_balances, + MsgQueue: mock_message_queue, + PolkadotXcm: pallet_xcm, + NFTs: pallet_uniques, + XcNFT: crate, + ParachainInfo: parachain_info, + } +); \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/asset_transactor.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/asset_transactor.rs new file mode 100644 index 000000000000..4d1e5d1ea4d3 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/asset_transactor.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testpara::{ + constants::KsmLocation, location_converter::LocationConverter, AccountId, Balances +}; +use xcm_builder::{FungibleAdapter, IsConcrete +}; + +type LocalAssetTransactor = FungibleAdapter, LocationConverter, AccountId, ()>; + +pub type AssetTransactor = LocalAssetTransactor; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/barrier.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/barrier.rs new file mode 100644 index 000000000000..b0ac69069cf1 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/barrier.rs @@ -0,0 +1,20 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use frame_support::traits::Everything; +use xcm_builder::AllowExplicitUnpaidExecutionFrom; + +pub type Barrier = AllowExplicitUnpaidExecutionFrom; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/constants.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/constants.rs new file mode 100644 index 000000000000..59e1f077d87c --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/constants.rs @@ -0,0 +1,31 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testpara::Runtime; +use frame_support::parameter_types; +use xcm::latest::prelude::*; +use xcm_simulator::mock_message_queue::ParachainId; + +parameter_types! { + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1, 1); + pub const MaxAssetsIntoHolding: u32 = 64; +} + +parameter_types! { + pub const KsmLocation: Location = Location::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainId::::get().into())].into(); +} \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/location_converter.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/location_converter.rs new file mode 100644 index 000000000000..235bf3bfd6de --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/location_converter.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testpara::{constants::RelayNetwork, AccountId}; +use xcm_builder::{AccountId32Aliases, DescribeAllTerminal, DescribeFamily, HashedDescription}; + +type LocationToAccountId = ( + HashedDescription>, + AccountId32Aliases, +); + +pub type LocationConverter = LocationToAccountId; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/mod.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/mod.rs new file mode 100644 index 000000000000..44a7f3dc14c8 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/mod.rs @@ -0,0 +1,65 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +pub mod asset_transactor; +pub mod barrier; +pub mod constants; +pub mod location_converter; +pub mod origin_converter; +pub mod reserve; +pub mod teleporter; +pub mod weigher; + +use crate::tests::testpara::{MsgQueue, PolkadotXcm, RuntimeCall}; +use frame_support::traits::{Everything, Nothing}; +use xcm_builder::{EnsureDecodableXcm, FixedRateOfFungible, FrameTransactionalProcessor}; +use xcm_executor::traits::WithOriginFilter; + +// Generated from `decl_test_network!` +pub type XcmRouter = EnsureDecodableXcm>; + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = asset_transactor::AssetTransactor; + type OriginConverter = origin_converter::OriginConverter; + type IsReserve = reserve::TrustedReserves; + type IsTeleporter = teleporter::TrustedTeleporters; + type UniversalLocation = constants::UniversalLocation; + type Barrier = barrier::Barrier; + type Weigher = weigher::Weigher; + type Trader = FixedRateOfFungible; + type ResponseHandler = (); + type AssetTrap = (); + type AssetLocker = PolkadotXcm; + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = (); + type FeeManager = (); + type MaxAssetsIntoHolding = constants::MaxAssetsIntoHolding; + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = WithOriginFilter; + type SafeCallFilter = Everything; + type Aliasers = Everything; + type TransactionalProcessor = FrameTransactionalProcessor; + type HrmpNewChannelOpenRequestHandler = (); + type HrmpChannelAcceptedHandler = (); + type HrmpChannelClosingHandler = (); + type XcmRecorder = PolkadotXcm; +} \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/origin_converter.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/origin_converter.rs new file mode 100644 index 000000000000..aa3a32ee5abe --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/origin_converter.rs @@ -0,0 +1,29 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testpara::{ + constants::RelayNetwork, location_converter::LocationConverter, RuntimeOrigin, +}; +use pallet_xcm::XcmPassthrough; +use xcm_builder::{SignedAccountId32AsNative, SovereignSignedViaLocation}; + +type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + SignedAccountId32AsNative, + XcmPassthrough, +); + +pub type OriginConverter = XcmOriginToCallOrigin; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/reserve.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/reserve.rs new file mode 100644 index 000000000000..f0700b59bb3a --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/reserve.rs @@ -0,0 +1,21 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testpara::teleporter::TrustedTeleporters; +use frame_support::traits::EverythingBut; +use xcm_builder::NativeAsset; + +pub type TrustedReserves = (NativeAsset, EverythingBut); \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/teleporter.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/teleporter.rs new file mode 100644 index 000000000000..a068087953cd --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/teleporter.rs @@ -0,0 +1,27 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use frame_support::parameter_types; +use xcm::latest::prelude::*; + +parameter_types! { + pub NftCollectionOne: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (AssetFilter, Location) + = (NftCollectionOne::get(), (Parent,).into()); +} + +pub type TrustedTeleporters = xcm_builder::Case; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/weigher.rs b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/weigher.rs new file mode 100644 index 000000000000..74ad2278aa14 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testpara/xcm_config/weigher.rs @@ -0,0 +1,27 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testpara::RuntimeCall; +use frame_support::parameter_types; +use xcm::latest::prelude::*; +use xcm_builder::FixedWeightBounds; + +parameter_types! { + pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); + pub const MaxInstructions: u32 = 100; +} + +pub type Weigher = FixedWeightBounds; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay.rs new file mode 100644 index 000000000000..a8e5a6313858 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay.rs @@ -0,0 +1,197 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Relay chain runtime mock. + +mod xcm_config; +pub use xcm_config::*; + +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + traits::{ + AsEnsureOriginWithArg, ConstU128, Everything, Nothing, ProcessMessage, ProcessMessageError, + }, + weights::{Weight, WeightMeter}, +}; + +use frame_system::{EnsureRoot,EnsureSigned}; +use sp_core::ConstU32; +use sp_runtime::{traits::{Verify,IdentityLookup}, AccountId32,MultiSignature}; +use polkadot_runtime_parachains::{ + configuration, + inclusion::{AggregateMessageOrigin, UmpQueueId}, + origin, shared, +}; +use xcm::latest::prelude::*; +use xcm_builder::{IsConcrete, SignedToAccountId32}; +use xcm_executor::XcmExecutor; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Runtime { + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type AccountData = pallet_balances::AccountData; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; +} + +pub const UNIT: Balance = 1; +parameter_types! { + pub const CollectionDeposit: Balance = 0 * UNIT; // 1 UNIT deposit to create asset collection + pub const ItemDeposit: Balance = 0 * UNIT; // 1/100 UNIT deposit to create asset item + pub const KeyLimit: u32 = 32; + pub const ValueLimit: u32 = 64; + pub const UniquesMetadataDepositBase: Balance = 0 * UNIT; + pub const AttributeDepositBase: Balance = 0 * UNIT; + pub const DepositPerByte: Balance = 0 * UNIT; + pub const UniquesStringLimit: u32 = 32; + pub const ApprovalsLimit: u32 = 1; + pub const ItemAttributesApprovalsLimit: u32 = 1; + pub const MaxTips: u32 = 1; + pub const MaxDeadlineDuration: u32 = 1; + pub const MaxAttributesPerCall: u32 = 10; + pub const proposal_time_in_blocks_parameter: u32 = 10; + pub const max_owners_parameter: u32 = 1000000; + pub const max_votes: u32 = 1000000; +} + +impl pallet_uniques::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CollectionId = u32; + type ItemId = u32; + type Currency = Balances; + type ForceOrigin = EnsureRoot; + type CreateOrigin = EnsureSigned; + type Locker = (); + type CollectionDeposit = CollectionDeposit; + type ItemDeposit = ItemDeposit; + type MetadataDepositBase = UniquesMetadataDepositBase; + type AttributeDepositBase = AttributeDepositBase; + type DepositPerByte = DepositPerByte; + type StringLimit = UniquesStringLimit; + type KeyLimit = KeyLimit; + type ValueLimit = ValueLimit; + type WeightInfo = (); +} + +impl shared::Config for Runtime { + type DisabledValidators = (); +} + +impl configuration::Config for Runtime { + type WeightInfo = configuration::TestWeightInfo; +} + +pub type LocalOriginToLocation = + SignedToAccountId32; + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = Nothing; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = weigher::Weigher; + type UniversalLocation = constants::UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = IsConcrete; + type TrustedLockers = (); + type SovereignAccountOf = location_converter::LocationConverter; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type WeightInfo = pallet_xcm::TestWeightInfo; + type AdminOrigin = EnsureRoot; +} + +impl origin::Config for Runtime {} + +type Block = frame_system::mocking::MockBlock; + +parameter_types! { + /// Amount of weight that can be spent per block to service messages. + pub MessageQueueServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000); + pub const MessageQueueHeapSize: u32 = 65_536; + pub const MessageQueueMaxStale: u32 = 16; +} + +/// Message processor to handle any messages that were enqueued into the `MessageQueue` pallet. +pub struct MessageProcessor; +impl ProcessMessage for MessageProcessor { + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + let para = match origin { + AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para, + }; + xcm_builder::ProcessXcmMessage::< + Junction, + xcm_executor::XcmExecutor, + RuntimeCall, + >::process_message(message, Junction::Parachain(para.into()), meter, id) + } +} + +impl pallet_message_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Size = u32; + type HeapSize = MessageQueueHeapSize; + type MaxStale = MessageQueueMaxStale; + type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); + type MessageProcessor = MessageProcessor; + type QueueChangeHandler = (); + type QueuePausedQuery = (); + type WeightInfo = (); +} + +construct_runtime!( + pub enum Runtime + { + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + NFTs: pallet_uniques, + MessageQueue: pallet_message_queue, + } +); \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/asset_transactor.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/asset_transactor.rs new file mode 100644 index 000000000000..9b316306a5b3 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/asset_transactor.rs @@ -0,0 +1,28 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testrelay::{ + constants::TokenLocation, location_converter::LocationConverter, AccountId, Balances, +}; +use xcm_builder::{ + AsPrefixedGeneralIndex, ConvertedConcreteId, FungibleAdapter, IsConcrete, NoChecking, + NonFungiblesAdapter, +}; +use xcm_executor::traits::JustTry; + +type LocalAssetTransactor = FungibleAdapter, LocationConverter, AccountId, ()>; + +pub type AssetTransactor = LocalAssetTransactor; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/barrier.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/barrier.rs new file mode 100644 index 000000000000..b0ac69069cf1 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/barrier.rs @@ -0,0 +1,20 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use frame_support::traits::Everything; +use xcm_builder::AllowExplicitUnpaidExecutionFrom; + +pub type Barrier = AllowExplicitUnpaidExecutionFrom; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/constants.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/constants.rs new file mode 100644 index 000000000000..2266c223f40d --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/constants.rs @@ -0,0 +1,31 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use frame_support::parameter_types; +use xcm::latest::prelude::*; + +parameter_types! { + pub TokensPerSecondPerByte: (AssetId, u128, u128) = + (AssetId(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + pub const MaxAssetsIntoHolding: u32 = 64; +} + +parameter_types! { + pub const TokenLocation: Location = Here.into_location(); + pub RelayNetwork: NetworkId = ByGenesis([0; 32]); + pub UniversalLocation: InteriorLocation = RelayNetwork::get().into(); + pub UnitWeightCost: u64 = 1_000; +} \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/location_converter.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/location_converter.rs new file mode 100644 index 000000000000..88c26f6f7947 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/location_converter.rs @@ -0,0 +1,25 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testrelay::{constants::RelayNetwork, AccountId}; +use xcm_builder::{AccountId32Aliases, DescribeAllTerminal, DescribeFamily, HashedDescription}; + +type LocationToAccountId = ( + HashedDescription>, + AccountId32Aliases, +); + +pub type LocationConverter = LocationToAccountId; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/mod.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/mod.rs new file mode 100644 index 000000000000..d483a20d83a0 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/mod.rs @@ -0,0 +1,65 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +pub mod asset_transactor; +pub mod barrier; +pub mod constants; +pub mod location_converter; +pub mod origin_converter; +pub mod teleporter; +pub mod weigher; + +use crate::tests::testrelay::{RuntimeCall, XcmPallet}; +use frame_support::traits::{Everything, Nothing}; +use xcm_builder::{EnsureDecodableXcm, FixedRateOfFungible, FrameTransactionalProcessor}; +use xcm_executor::Config; +use xcm_executor::traits::WithOriginFilter; + +// Generated from `decl_test_network!` +pub type XcmRouter = EnsureDecodableXcm; + +pub struct XcmConfig; +impl Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = asset_transactor::AssetTransactor; + type OriginConverter = origin_converter::OriginConverter; + type IsReserve = (); + type IsTeleporter = teleporter::TrustedTeleporters; + type UniversalLocation = constants::UniversalLocation; + type Barrier = barrier::Barrier; + type Weigher = weigher::Weigher; + type Trader = FixedRateOfFungible; + type ResponseHandler = (); + type AssetTrap = (); + type AssetLocker = XcmPallet; + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = (); + type FeeManager = (); + type MaxAssetsIntoHolding = constants::MaxAssetsIntoHolding; + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = WithOriginFilter; + type SafeCallFilter = Everything; + type Aliasers = Everything; + type TransactionalProcessor = FrameTransactionalProcessor; + type HrmpNewChannelOpenRequestHandler = (); + type HrmpChannelAcceptedHandler = (); + type HrmpChannelClosingHandler = (); + type XcmRecorder = XcmPallet; +} \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/origin_converter.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/origin_converter.rs new file mode 100644 index 000000000000..ea14cbfd38e2 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/origin_converter.rs @@ -0,0 +1,34 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testrelay::{ + constants::RelayNetwork, location_converter::LocationConverter, RuntimeOrigin, +}; +use polkadot_parachain_primitives::primitives::Id as ParaId; +use polkadot_runtime_parachains::origin; +use xcm_builder::{ + ChildParachainAsNative, ChildSystemParachainAsSuperuser, SignedAccountId32AsNative, + SovereignSignedViaLocation, +}; + +type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, + ChildSystemParachainAsSuperuser, +); + +pub type OriginConverter = LocalOriginConverter; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/teleporter.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/teleporter.rs new file mode 100644 index 000000000000..0d322538c592 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/teleporter.rs @@ -0,0 +1,26 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use frame_support::parameter_types; +use xcm::latest::prelude::*; + +parameter_types! { + pub NftCollectionOnRelay: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId(GeneralIndex(1).into()) }); + pub NftCollectionForChild: (AssetFilter, Location) + = (NftCollectionOnRelay::get(), Parachain(1).into()); +} +pub type TrustedTeleporters = xcm_builder::Case; \ No newline at end of file diff --git a/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/weigher.rs b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/weigher.rs new file mode 100644 index 000000000000..b99051539394 --- /dev/null +++ b/templates/parachain_two/pallets/xcnft/src/tests/testrelay/xcm_config/weigher.rs @@ -0,0 +1,27 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::tests::testrelay::RuntimeCall; +use frame_support::parameter_types; +use xcm::latest::prelude::*; +use xcm_builder::FixedWeightBounds; + +parameter_types! { + pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); + pub const MaxInstructions: u32 = 100; +} + +pub type Weigher = FixedWeightBounds; \ No newline at end of file