From 0c9dfc515d68df5615956fa576ebd397412eeceb Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Thu, 21 Apr 2022 12:22:04 +0000 Subject: [PATCH] CORE-302 Implement methods for setup collection. --- --- a/pallets/common/src/lib.rs +++ b/pallets/common/src/lib.rs @@ -115,7 +115,7 @@ }) } - pub fn new_with_recorder(id: CollectionId, recorder: Rc>) -> Option { + pub fn new_with_recorder(id: CollectionId, recorder: SubstrateRecorder) -> Option { >::get(id).map(|collection| Self { id, collection, @@ -153,6 +153,15 @@ pub fn set_sponsor(&mut self, sponsor: T::AccountId) { self.collection.sponsorship = SponsorshipState::Unconfirmed(sponsor); } + + pub fn confirm_sponsorship(&mut self, sender: &T::AccountId) -> bool { + if self.collection.sponsorship.pending_sponsor() != Some(sender) { + return false; + }; + + self.collection.sponsorship = SponsorshipState::Confirmed(sender.clone()); + true + } } impl Deref for CollectionHandle { type Target = Collection; --- a/pallets/evm-collection/src/eth.rs +++ b/pallets/evm-collection/src/eth.rs @@ -17,7 +17,7 @@ use core::marker::PhantomData; use evm_coder::{abi::AbiWriter, execution::*, generate_stubgen, solidity_interface, types::*, ToLog}; use ethereum as _; -use pallet_common::{CollectionById, CollectionHandle}; +use pallet_common::CollectionById; use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; use pallet_evm::{ ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, @@ -26,7 +26,7 @@ use sp_core::H160; use up_data_structs::{ CreateCollectionData, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, - MAX_COLLECTION_NAME_LENGTH, SponsorshipState, + MAX_COLLECTION_NAME_LENGTH, }; use crate::{Config, Pallet}; use frame_support::traits::Get; @@ -57,7 +57,6 @@ #[solidity_interface(name = "Collection")] impl EvmCollection { - fn create_721_collection( &self, caller: caller, @@ -103,28 +102,16 @@ Ok(address) } - fn set_sponsor( - &self, - caller: caller, - contract_address: address, - sponsor: address, - ) -> Result { - let collection_id = - pallet_common::eth::map_eth_to_id(&contract_address).ok_or(Error::Revert("".into()))?; - let mut collection = - pallet_common::CollectionHandle::new_with_recorder(collection_id, self.0.clone()) - .ok_or(Error::Revert("".into()))?; - - let caller = T::CrossAccountId::from_eth(caller); - collection.check_is_owner(&caller).map_err(|e| Error::Revert(format!("{:?}", e)))?; + // fn set_sponsor(collection_id: address, sponsor: address) -> Result { + // let collection_id = + // pallet_common::eth::map_eth_to_id(&collection_id).ok_or(Error::Revert("".into()))?; + // let mut collection = >::get(collection_id).ok_or(Error::Revert("".into()))?; + // let sponsor = T::CrossAccountId::from_eth(sponsor); + // collection.sponsorship = SponsorshipState::Unconfirmed(sponsor.as_sub().clone()); + // >::insert(collection_id, collection); + // Ok(()) + // } - let sponsor = T::CrossAccountId::from_eth(sponsor); - collection.set_sponsor(sponsor.as_sub().clone()); - collection - .save() - .map_err(|e| Error::Revert(format!("{:?}", e))) - } - // fn set_offchain_shema(shema: string) -> Result { // Ok(()) // } @@ -168,7 +155,7 @@ return None; } - let helpers = EvmCollection::(SubstrateRecorder::::new(gas_left)); + let helpers = EvmCollection::(SubstrateRecorder::new(gas_left)); pallet_evm_coder_substrate::call(*source, helpers, value, input) } --- a/pallets/evm-collection/src/stubs/Collection.sol +++ b/pallets/evm-collection/src/stubs/Collection.sol @@ -21,7 +21,7 @@ } } -// Selector: 6503bbc2 +// Selector: d32d5104 contract Collection is Dummy, ERC165 { // Selector: create721Collection(string,string,string) 951c0151 function create721Collection( @@ -38,10 +38,53 @@ } // Selector: setSponsor(address,address) f01fba93 - function setSponsor(address contractAddress, address sponsor) public view { + function setSponsor(address collectionAddress, address sponsor) + public + view + { require(false, stub_error); - contractAddress; + collectionAddress; sponsor; dummy; } + + // Selector: confirmSponsorship(address) abc00001 + function confirmSponsorship(address collectionAddress) public view { + require(false, stub_error); + collectionAddress; + dummy; + } + + // Selector: setOffchainShema(address,string) d7dc2de3 + function setOffchainShema(address collectionAddress, string memory shema) + public + view + { + require(false, stub_error); + collectionAddress; + shema; + dummy; + } + + // Selector: setVariableOnChainSchema(address,string) 582691c3 + function setVariableOnChainSchema( + address collectionAddress, + string memory variable + ) public view { + require(false, stub_error); + collectionAddress; + variable; + dummy; + } + + // Selector: setConstOnChainSchema(address,string) 921456e7 + function setConstOnChainSchema( + address collectionAddress, + string memory constOnChain + ) public view { + require(false, stub_error); + collectionAddress; + constOnChain; + dummy; + } } --- a/pallets/unique/src/lib.rs +++ b/pallets/unique/src/lib.rs @@ -544,11 +544,9 @@ let mut target_collection = >::try_get(collection_id)?; ensure!( - target_collection.sponsorship.pending_sponsor() == Some(&sender), + target_collection.confirm_sponsorship(&sender), Error::::ConfirmUnsetSponsorFail ); - - target_collection.sponsorship = SponsorshipState::Confirmed(sender.clone()); >::deposit_event(Event::::SponsorshipConfirmed( collection_id, --- a/tests/src/eth/api/Collection.sol +++ b/tests/src/eth/api/Collection.sol @@ -12,7 +12,7 @@ function supportsInterface(bytes4 interfaceID) external view returns (bool); } -// Selector: 6503bbc2 +// Selector: d32d5104 interface Collection is Dummy, ERC165 { // Selector: create721Collection(string,string,string) 951c0151 function create721Collection( @@ -22,5 +22,27 @@ ) external view returns (address); // Selector: setSponsor(address,address) f01fba93 - function setSponsor(address contractAddress, address sponsor) external view; + function setSponsor(address collectionAddress, address sponsor) + external + view; + + // Selector: confirmSponsorship(address) abc00001 + function confirmSponsorship(address collectionAddress) external view; + + // Selector: setOffchainShema(address,string) d7dc2de3 + function setOffchainShema(address collectionAddress, string memory shema) + external + view; + + // Selector: setVariableOnChainSchema(address,string) 582691c3 + function setVariableOnChainSchema( + address collectionAddress, + string memory variable + ) external view; + + // Selector: setConstOnChainSchema(address,string) 921456e7 + function setConstOnChainSchema( + address collectionAddress, + string memory constOnChain + ) external view; } --- a/tests/src/eth/collectionAbi.json +++ b/tests/src/eth/collectionAbi.json @@ -1,6 +1,19 @@ [ { "inputs": [ + { + "internalType": "address", + "name": "collectionAddress", + "type": "address" + } + ], + "name": "confirmSponsorship", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "string", "name": "name", "type": "string" }, { "internalType": "string", "name": "description", "type": "string" }, { "internalType": "string", "name": "tokenPrefix", "type": "string" } @@ -14,7 +27,35 @@ "inputs": [ { "internalType": "address", - "name": "contractAddress", + "name": "collectionAddress", + "type": "address" + }, + { "internalType": "string", "name": "constOnChain", "type": "string" } + ], + "name": "setConstOnChainSchema", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collectionAddress", + "type": "address" + }, + { "internalType": "string", "name": "shema", "type": "string" } + ], + "name": "setOffchainShema", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collectionAddress", "type": "address" }, { "internalType": "address", "name": "sponsor", "type": "address" } @@ -26,6 +67,20 @@ }, { "inputs": [ + { + "internalType": "address", + "name": "collectionAddress", + "type": "address" + }, + { "internalType": "string", "name": "variable", "type": "string" } + ], + "name": "setVariableOnChainSchema", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" } ], "name": "supportsInterface", --- a/tests/src/eth/createCollection.test.ts +++ b/tests/src/eth/createCollection.test.ts @@ -57,10 +57,47 @@ const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); const sponsor = await createEthAccountWithBalance(api, web3); result = await helper.methods.setSponsor(collectionIdAddress, sponsor).send(); - const collection = (await getDetailedCollectionInfo(api, collectionId))!; + let collection = (await getDetailedCollectionInfo(api, collectionId))!; expect(collection.sponsorship.isUnconfirmed).to.be.true; expect(collection.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor)); + await expect(helper.methods.confirmSponsorship(collectionIdAddress).call()).to.be.rejectedWith('Caller is not set as sponsor'); + const sponsorHelper = collectionHelper(web3, sponsor); + await sponsorHelper.methods.confirmSponsorship(collectionIdAddress).send(); + collection = (await getDetailedCollectionInfo(api, collectionId))!; + expect(collection.sponsorship.isConfirmed).to.be.true; + expect(collection.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor)); + }); + + itWeb3('Set offchain shema', async ({api, web3}) => { + const owner = await createEthAccountWithBalance(api, web3); + const helper = collectionHelper(web3, owner); + let result = await helper.methods.create721Collection('Shema collection', '2', '2').send(); + const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + const shema = 'Some shema'; + result = await helper.methods.setOffchainShema(collectionIdAddress, shema).send(); + const collection = (await getDetailedCollectionInfo(api, collectionId))!; + expect(collection.offchainSchema.toHuman()).to.be.eq(shema); }); - - + + itWeb3('Set variable on chain schema', async ({api, web3}) => { + const owner = await createEthAccountWithBalance(api, web3); + const helper = collectionHelper(web3, owner); + let result = await helper.methods.create721Collection('Variable collection', '3', '3').send(); + const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + const variable = 'Some variable'; + result = await helper.methods.setVariableOnChainSchema(collectionIdAddress, variable).send(); + const collection = (await getDetailedCollectionInfo(api, collectionId))!; + expect(collection.variableOnChainSchema.toHuman()).to.be.eq(variable); + }); + + itWeb3('Set const on chain schema', async ({api, web3}) => { + const owner = await createEthAccountWithBalance(api, web3); + const helper = collectionHelper(web3, owner); + let result = await helper.methods.create721Collection('Const collection', '4', '4').send(); + const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + const constShema = 'Some const'; + result = await helper.methods.setConstOnChainSchema(collectionIdAddress, constShema).send(); + const collection = (await getDetailedCollectionInfo(api, collectionId))!; + expect(collection.constOnChainSchema.toHuman()).to.be.eq(constShema); + }); }); \ No newline at end of file -- gitstuff