difftreelog
Merge pull request #317 from UniqueNetwork/feature/CORE-238
in: master
CORE-283 add effective_collection_limits
9 files changed
Cargo.lockdiffbeforeafterboth9759 "thiserror",9759 "thiserror",9760]9760]97619762[[package]]9763name = "sc-consensus-epochs"9764version = "0.10.0-dev"9765source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e"9766dependencies = [9767 "fork-tree",9768 "parity-scale-codec",9769 "sc-client-api",9770 "sc-consensus",9771 "sp-blockchain",9772 "sp-runtime",9773]97749775[[package]]9776name = "sc-consensus-manual-seal"9777version = "0.10.0-dev"9778source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e"9779dependencies = [9780 "assert_matches",9781 "async-trait",9782 "futures 0.3.21",9783 "jsonrpc-core",9784 "jsonrpc-core-client",9785 "jsonrpc-derive",9786 "log",9787 "parity-scale-codec",9788 "sc-client-api",9789 "sc-consensus",9790 "sc-consensus-aura",9791 "sc-consensus-babe",9792 "sc-consensus-epochs",9793 "sc-transaction-pool",9794 "sc-transaction-pool-api",9795 "serde",9796 "sp-api",9797 "sp-blockchain",9798 "sp-consensus",9799 "sp-consensus-aura",9800 "sp-consensus-babe",9801 "sp-consensus-slots",9802 "sp-core",9803 "sp-inherents",9804 "sp-keystore",9805 "sp-runtime",9806 "sp-timestamp",9807 "substrate-prometheus-endpoint",9808 "thiserror",9809]976198109762[[package]]9811[[package]]9763name = "sc-consensus-slots"9812name = "sc-consensus-slots"12212 "chrono",12261 "chrono",12213 "lazy_static",12262 "lazy_static",12214 "matchers",12263 "matchers",12215 "parking_lot 0.11.2",12264 "parking_lot 0.10.2",12216 "regex",12265 "regex",12217 "serde",12266 "serde",12218 "serde_json",12267 "serde_json",client/rpc/src/lib.rsdiffbeforeafterboth19use codec::Decode;19use codec::Decode;20use jsonrpc_core::{Error as RpcError, ErrorCode, Result};20use jsonrpc_core::{Error as RpcError, ErrorCode, Result};21use jsonrpc_derive::rpc;21use jsonrpc_derive::rpc;22use up_data_structs::{Collection, CollectionId, CollectionStats, TokenId};22use up_data_structs::{Collection, CollectionId, CollectionStats, CollectionLimits, TokenId};23use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};23use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};24use sp_blockchain::HeaderBackend;24use sp_blockchain::HeaderBackend;25use up_rpc::UniqueApi as UniqueRuntimeApi;25use up_rpc::UniqueApi as UniqueRuntimeApi;119 ) -> Result<Option<Collection<AccountId>>>;119 ) -> Result<Option<Collection<AccountId>>>;120 #[rpc(name = "unique_collectionStats")]120 #[rpc(name = "unique_collectionStats")]121 fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;121 fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;122 #[rpc(name = "unique_effectiveCollectionLimits")]123 fn effective_collection_limits(124 &self,125 collection_id: CollectionId,126 at: Option<BlockHash>,127 ) -> Result<Option<CollectionLimits>>;122}128}123129124pub struct Unique<C, P> {130pub struct Unique<C, P> {222 pass_method!(last_token_id(collection: CollectionId) -> TokenId);228 pass_method!(last_token_id(collection: CollectionId) -> TokenId);223 pass_method!(collection_by_id(collection: CollectionId) -> Option<Collection<AccountId>>);229 pass_method!(collection_by_id(collection: CollectionId) -> Option<Collection<AccountId>>);224 pass_method!(collection_stats() -> CollectionStats);230 pass_method!(collection_stats() -> CollectionStats);231 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>);225}232}226233pallets/common/src/lib.rsdiffbeforeafterboth33 TokenId, Weight, WithdrawReasons, CollectionStats, MAX_TOKEN_OWNERSHIP, CollectionMode,33 TokenId, Weight, WithdrawReasons, CollectionStats, MAX_TOKEN_OWNERSHIP, CollectionMode,34 NFT_SPONSOR_TRANSFER_TIMEOUT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,34 NFT_SPONSOR_TRANSFER_TIMEOUT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,35 REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT, CUSTOM_DATA_LIMIT, CollectionLimits,35 REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT, CUSTOM_DATA_LIMIT, CollectionLimits,36 CustomDataLimit, CreateCollectionData, SponsorshipState, CreateItemExData,36 CustomDataLimit, CreateCollectionData, SponsorshipState, CreateItemExData, SponsoringRateLimit,37};37};38pub use pallet::*;38pub use pallet::*;39use sp_core::H160;39use sp_core::H160;418 }418 }419 }419 }420421 pub fn effective_collection_limits(collection: CollectionId) -> Option<CollectionLimits> {422 let collection = <CollectionById<T>>::get(collection);423 if collection.is_none() {424 return None;425 }426427 let collection = collection.unwrap();428 let limits = collection.limits;429 let effective_limits = CollectionLimits {430 account_token_ownership_limit: Some(limits.account_token_ownership_limit()),431 sponsored_data_size: Some(limits.sponsored_data_size()),432 sponsored_data_rate_limit: Some(433 limits434 .sponsored_data_rate_limit435 .unwrap_or(SponsoringRateLimit::SponsoringDisabled),436 ),437 token_limit: Some(limits.token_limit()),438 sponsor_transfer_timeout: Some(limits.sponsor_transfer_timeout(439 match collection.mode {440 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,441 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,442 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,443 },444 )),445 sponsor_approve_timeout: Some(limits.sponsor_approve_timeout()),446 owner_can_transfer: Some(limits.owner_can_transfer()),447 owner_can_destroy: Some(limits.owner_can_destroy()),448 transfers_enabled: Some(limits.transfers_enabled()),449 };450451 Some(effective_limits)452 }420}453}421454422impl<T: Config> Pallet<T> {455impl<T: Config> Pallet<T> {primitives/rpc/src/lib.rsdiffbeforeafterboth161617#![cfg_attr(not(feature = "std"), no_std)]17#![cfg_attr(not(feature = "std"), no_std)]181819use up_data_structs::{CollectionId, TokenId, Collection, CollectionStats};19use up_data_structs::{CollectionId, TokenId, Collection, CollectionStats, CollectionLimits};20use sp_std::vec::Vec;20use sp_std::vec::Vec;21use sp_core::H160;21use sp_core::H160;22use codec::Decode;22use codec::Decode;59 fn last_token_id(collection: CollectionId) -> Result<TokenId>;59 fn last_token_id(collection: CollectionId) -> Result<TokenId>;60 fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>>;60 fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>>;61 fn collection_stats() -> Result<CollectionStats>;61 fn collection_stats() -> Result<CollectionStats>;62 fn effective_collection_limits(collection_id: CollectionId) -> Result<Option<CollectionLimits>>;62 }63 }63}64}6465runtime/common/src/runtime_apis.rsdiffbeforeafterboth70 Ok(<pallet_common::Pallet<Runtime>>::collection_stats())70 Ok(<pallet_common::Pallet<Runtime>>::collection_stats())71 }71 }7273 fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {74 Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))75 }72 }76 }737774 impl sp_api::Core<Block> for Runtime {78 impl sp_api::Core<Block> for Runtime {tests/package.jsondiffbeforeafterboth67 "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",67 "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",68 "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",68 "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",69 "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts",69 "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts",70 "testLimits": "mocha --timeout 9999999 -r ts-node/register ./**/limits.test.ts",70 "polkadot-types-fetch-metadata": "curl -H 'Content-Type: application/json' -d '{\"id\":\"1\", \"jsonrpc\":\"2.0\", \"method\": \"state_getMetadata\", \"params\":[]}' http://localhost:9933 > src/interfaces/metadata.json",71 "polkadot-types-fetch-metadata": "curl -H 'Content-Type: application/json' -d '{\"id\":\"1\", \"jsonrpc\":\"2.0\", \"method\": \"state_getMetadata\", \"params\":[]}' http://localhost:9933 > src/interfaces/metadata.json",71 "polkadot-types-from-defs": "echo 'export default {}' > src/interfaces/lookup.ts && ts-node ./node_modules/.bin/polkadot-types-from-defs --endpoint src/interfaces/metadata.json --input src/interfaces/ --package .",72 "polkadot-types-from-defs": "echo 'export default {}' > src/interfaces/lookup.ts && ts-node ./node_modules/.bin/polkadot-types-from-defs --endpoint src/interfaces/metadata.json --input src/interfaces/ --package .",72 "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint src/interfaces/metadata.json --output src/interfaces/ --package .",73 "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint src/interfaces/metadata.json --output src/interfaces/ --package .",tests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit2/* eslint-disable */2/* eslint-disable */334import type { PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsCollection, UpDataStructsCollectionStats } from './unique';4import type { PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsCollection, UpDataStructsCollectionStats, UpDataStructsCollectionStats } from './unique';5import type { AugmentedRpc } from '@polkadot/rpc-core/types';5import type { AugmentedRpc } from '@polkadot/rpc-core/types';6import type { Metadata, StorageKey } from '@polkadot/types';6import type { Metadata, StorageKey } from '@polkadot/types';7import type { Bytes, HashMap, Json, Null, Option, Text, U256, U64, Vec, bool, u128, u32, u64 } from '@polkadot/types-codec';7import type { Bytes, HashMap, Json, Null, Option, Text, U256, U64, Vec, bool, u128, u32, u64 } from '@polkadot/types-codec';603 * Get token constant metadata603 * Get token constant metadata604 **/604 **/605 constMetadata: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Bytes>>;605 constMetadata: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Bytes>>;606 /**607 * Get effective collection limits608 **/609 effectiveCollectionLimits: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<UpDataStructsCollectionLimits>>>;606 /**610 /**607 * Get last token id611 * Get last token id608 **/612 **/tests/src/interfaces/unique/definitions.tsdiffbeforeafterboth55 collectionById: fun('Get collection by specified id', [collectionParam], 'Option<UpDataStructsCollection>'),55 collectionById: fun('Get collection by specified id', [collectionParam], 'Option<UpDataStructsCollection>'),56 collectionStats: fun('Get collection stats', [], 'UpDataStructsCollectionStats'),56 collectionStats: fun('Get collection stats', [], 'UpDataStructsCollectionStats'),57 allowed: fun('Check if user is allowed to use collection', [collectionParam, crossAccountParam()], 'bool'),57 allowed: fun('Check if user is allowed to use collection', [collectionParam, crossAccountParam()], 'bool'),58 effectiveCollectionLimits: fun('Get effective collection limits', [collectionParam], 'Option<UpDataStructsCollectionLimits>'),58 },59 },59};60};6061tests/src/limits.test.tsdiffbeforeafterboth396 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);396 //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);397 });397 });398 399 it('Effective collection limits', async () => {400 await usingApi(async (api) => {401 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});402 403 { // Check that limits is undefined404 const collection = await api.rpc.unique.collectionById(collectionId);405 expect(collection.isSome).to.be.true;406 const limits = collection.unwrap().limits;407 expect(limits).to.be.any;408 409 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.null;410 expect(limits.sponsoredDataSize.toHuman()).to.be.null;411 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.null;412 expect(limits.tokenLimit.toHuman()).to.be.null;413 expect(limits.sponsorTransferTimeout.toHuman()).to.be.null;414 expect(limits.sponsorApproveTimeout.toHuman()).to.be.null;415 expect(limits.ownerCanTransfer.toHuman()).to.be.null;416 expect(limits.ownerCanDestroy.toHuman()).to.be.null;417 expect(limits.transfersEnabled.toHuman()).to.be.null;418 }419 420 { // Check that limits is undefined for non-existent collection421 const limits = await api.rpc.unique.effectiveCollectionLimits(11111);422 expect(limits.toHuman()).to.be.null;423 }424 425 { // Check that default values defined for collection limits426 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);427 expect(limitsOpt.isNone).to.be.false;428 const limits = limitsOpt.unwrap();429 430 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('100,000');431 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('2,048');432 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');433 expect(limits.tokenLimit.toHuman()).to.be.eq('4,294,967,295');434 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');435 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');436 expect(limits.ownerCanTransfer.toHuman()).to.be.true;437 expect(limits.ownerCanDestroy.toHuman()).to.be.true;438 expect(limits.transfersEnabled.toHuman()).to.be.true;439 }440441 { //Check the values for collection limits442 await setCollectionLimitsExpectSuccess(alice, collectionId, {443 accountTokenOwnershipLimit: 99_999,444 sponsoredDataSize: 1024,445 tokenLimit: 123,446 transfersEnabled: false,447 });448449 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);450 expect(limitsOpt.isNone).to.be.false;451 const limits = limitsOpt.unwrap();452 453 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('99,999');454 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('1,024');455 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');456 expect(limits.tokenLimit.toHuman()).to.be.eq('123');457 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');458 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');459 expect(limits.ownerCanTransfer.toHuman()).to.be.true;460 expect(limits.ownerCanDestroy.toHuman()).to.be.true;461 expect(limits.transfersEnabled.toHuman()).to.be.false;462 }463 });464 });398});465});399466467