git.delta.rocks / unique-network / refs/commits / 7ff84981c059

difftreelog

Merge branch 'develop' into feature/NFTPAR-142

sotmorskiy2020-12-03parents: #d4ad9e6 #82ca9c1.patch.diff
in: master
# Conflicts:
#	pallets/nft/src/lib.rs

5 files changed

modifiedCargo.lockdiffbeforeafterboth
3737 "frame-support",3737 "frame-support",
3738 "frame-system",3738 "frame-system",
3739 "log",3739 "log",
3740 "pallet-balances",
3740 "pallet-contracts",3741 "pallet-contracts",
3742 "pallet-randomness-collective-flip",
3743 "pallet-timestamp",
3741 "pallet-transaction-payment",3744 "pallet-transaction-payment",
3742 "parity-scale-codec",3745 "parity-scale-codec",
3743 "serde",3746 "serde",
modifiedpallets/nft/src/default_weights.rsdiffbeforeafterboth
107 .saturating_add(DbWeight::get().reads(2 as Weight))107 .saturating_add(DbWeight::get().reads(2 as Weight))
108 .saturating_add(DbWeight::get().writes(1 as Weight))108 .saturating_add(DbWeight::get().writes(1 as Weight))
109 }109 }
110 // fn set_chain_limits() -> Weight {
111 // (0 as Weight)
112 // .saturating_add(DbWeight::get().reads(1 as Weight))
113 // .saturating_add(DbWeight::get().writes(1 as Weight))
114 // }
110 // fn enable_contract_sponsoring() -> Weight {115 // fn enable_contract_sponsoring() -> Weight {
116 // (0 as Weight)
117 // .saturating_add(DbWeight::get().reads(1 as Weight))
118 // .saturating_add(DbWeight::get().writes(1 as Weight))
119 // }
120 // fn set_contract_sponsoring_rate_limit() -> Weight {
111 // (0 as Weight)121 // (0 as Weight)
112 // .saturating_add(DbWeight::get().reads(1 as Weight))122 // .saturating_add(DbWeight::get().reads(1 as Weight))
113 // .saturating_add(DbWeight::get().writes(1 as Weight))123 // .saturating_add(DbWeight::get().writes(1 as Weight))
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
378 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;378 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;
379379
380 // Contract Sponsorship and Ownership380 // Contract Sponsorship and Ownership
381 pub ContractOwner get(fn contract_owner): map hasher(identity) T::AccountId => T::AccountId;381 pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;
382 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(identity) T::AccountId => bool;382 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;
383 pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;
384 pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;
383 }385 }
384 add_extra_genesis {386 add_extra_genesis {
385 build(|config: &GenesisConfig<T>| {387 build(|config: &GenesisConfig<T>| {
1336 Ok(())1338 Ok(())
1337 }1339 }
1340
1341 /// Set the rate limit for contract sponsoring to specified number of blocks.
1342 ///
1343 /// If not set (has the default value of 0 blocks), the sponsoring will be disabled.
1344 /// If set to the number B (for blocks), the transactions will be sponsored with a rate
1345 /// limit of B, i.e. fees for every transaction sent to this smart contract will be paid
1346 /// from contract endowment if there are at least B blocks between such transactions.
1347 /// Nonetheless, if transactions are sent more frequently, the fees are paid by the sender.
1348 ///
1349 /// # Permissions
1350 ///
1351 /// * Contract Owner
1352 ///
1353 /// # Arguments
1354 ///
1355 /// -`contract_address`: Address of the contract to sponsor
1356 /// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed
1357 ///
1358 #[weight = 0]
1359 pub fn set_contract_sponsoring_rate_limit(
1360 origin,
1361 contract_address: T::AccountId,
1362 rate_limit: T::BlockNumber
1363 ) -> DispatchResult {
1364 let sender = ensure_signed(origin)?;
1365 let mut is_owner = false;
1366 if <ContractOwner<T>>::contains_key(contract_address.clone()) {
1367 let owner = <ContractOwner<T>>::get(&contract_address);
1368 is_owner = sender == owner;
1369 }
1370 ensure!(is_owner, Error::<T>::NoPermission);
1371
1372 <ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);
1373 Ok(())
1374 }
1375
1338 }1376 }
1339}1377}
2242 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is2280 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is
2243 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {2281 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {
22442282
2283 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());
2284
2285 let mut sponsor_transfer = false;
2286 if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {
2287 let last_tx_block = <ContractSponsorBasket<T>>::get(&called_contract);
2288 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
2289 let rate_limit = <ContractSponsoringRateLimit<T>>::get(&called_contract);
2290 let limit_time = last_tx_block + rate_limit;
2291
2292 if block_number >= limit_time {
2293 <ContractSponsorBasket<T>>::insert(called_contract.clone(), block_number);
2294 sponsor_transfer = true;
2295 }
2296 } else {
2297 sponsor_transfer = false;
2298 }
2299
2300
2245 let mut sp = T::AccountId::default();2301 let mut sp = T::AccountId::default();
2246 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());2302 if sponsor_transfer {
2247 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {2303 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {
2248 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {2304 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {
2249 sp = called_contract;2305 sp = called_contract;
2250 }2306 }
2251 }2307 }
2308 }
22522309
2253 sp2310 sp
2254 },2311 },
modifiedpallets/nft/src/tests.rsdiffbeforeafterboth
1// Tests to be written here1// Tests to be written here
2use super::*;
2use crate::mock::*;3use crate::mock::*;
3use crate::{AccessMode, ApprovePermissions, CollectionMode, Ownership, ChainLimits, CreateItemData, CreateNftData, CreateFungibleData, CreateReFungibleData};4use crate::{AccessMode, ApprovePermissions, CollectionMode,
5 Ownership, ChainLimits, CreateItemData, CreateNftData, CreateFungibleData, CreateReFungibleData}; //Err
4use frame_support::{assert_noop, assert_ok};6use frame_support::{assert_noop, assert_ok};
5use frame_system::{ RawOrigin };7use frame_system::{ RawOrigin };
68
392 2,394 2,
393 1,395 1,
394 1,396 1,
395 1), "Only item owner, collection owner and admins can modify items");397 1), Error::<Test>::NoPermission);
396398
397 // do approve399 // do approve
398 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));400 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));
672 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));674 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));
673 assert_noop!(675 assert_noop!(
674 TemplateModule::burn_item(origin1.clone(), 1, 1),676 TemplateModule::burn_item(origin1.clone(), 1, 1),
675 "Item does not exists"677 Error::<Test>::TokenNotFound
676 );678 );
677679
678 assert_eq!(TemplateModule::balance_count(1, 1), 0);680 assert_eq!(TemplateModule::balance_count(1, 1), 0);
699 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));701 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));
700 assert_noop!(702 assert_noop!(
701 TemplateModule::burn_item(origin1.clone(), 1, 1),703 TemplateModule::burn_item(origin1.clone(), 1, 1),
702 "Item does not exists"704 Error::<Test>::TokenNotFound
703 );705 );
704706
705 assert_eq!(TemplateModule::balance_count(1, 1), 0);707 assert_eq!(TemplateModule::balance_count(1, 1), 0);
738 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));740 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));
739 assert_noop!(741 assert_noop!(
740 TemplateModule::burn_item(origin1.clone(), 1, 1),742 TemplateModule::burn_item(origin1.clone(), 1, 1),
741 "Item does not exists"743 Error::<Test>::TokenNotFound
742 );744 );
743745
744 assert_eq!(TemplateModule::balance_count(1, 1), 0);746 assert_eq!(TemplateModule::balance_count(1, 1), 0);
933 let origin2 = Origin::signed(2);935 let origin2 = Origin::signed(2);
934 assert_noop!(936 assert_noop!(
935 TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),937 TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),
936 "You do not have permissions to modify this collection"938 Error::<Test>::NoPermission
937 );939 );
938 });940 });
939}941}
947949
948 assert_noop!(950 assert_noop!(
949 TemplateModule::add_to_white_list(origin1.clone(), 1, 2),951 TemplateModule::add_to_white_list(origin1.clone(), 1, 2),
950 "This collection does not exist"952 Error::<Test>::CollectionNotFound
951 );953 );
952 });954 });
953}955}
963 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));965 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));
964 assert_noop!(966 assert_noop!(
965 TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),967 TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),
966 "This collection does not exist"968 Error::<Test>::CollectionNotFound
967 );969 );
968 });970 });
969}971}
1035 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1037 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));
1036 assert_noop!(1038 assert_noop!(
1037 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1039 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),
1038 "You do not have permissions to modify this collection"1040 Error::<Test>::NoPermission
1039 );1041 );
1040 assert_eq!(TemplateModule::white_list(collection_id)[0], 2);1042 assert_eq!(TemplateModule::white_list(collection_id)[0], 2);
1041 });1043 });
10491051
1050 assert_noop!(1052 assert_noop!(
1051 TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),1053 TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),
1052 "This collection does not exist"1054 Error::<Test>::CollectionNotFound
1053 );1055 );
1054 });1056 });
1055}1057}
1067 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1069 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));
1068 assert_noop!(1070 assert_noop!(
1069 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1071 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),
1070 "This collection does not exist"1072 Error::<Test>::CollectionNotFound
1071 );1073 );
1072 assert_eq!(TemplateModule::white_list(collection_id).len(), 0);1074 assert_eq!(TemplateModule::white_list(collection_id).len(), 0);
1073 });1075 });
11191121
1120 assert_noop!(1122 assert_noop!(
1121 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1123 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),
1122 "Address is not in white list"1124 Error::<Test>::AddresNotInWhiteList
1123 );1125 );
1124 });1126 });
1125}1127}
11551157
1156 assert_noop!(1158 assert_noop!(
1157 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1159 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),
1158 "Address is not in white list"1160 Error::<Test>::AddresNotInWhiteList
1159 );1161 );
1160 });1162 });
1161}1163}
11821184
1183 assert_noop!(1185 assert_noop!(
1184 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1186 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),
1185 "Address is not in white list"1187 Error::<Test>::AddresNotInWhiteList
1186 );1188 );
1187 });1189 });
1188}1190}
12191221
1220 assert_noop!(1222 assert_noop!(
1221 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1223 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),
1222 "Address is not in white list"1224 Error::<Test>::AddresNotInWhiteList
1223 );1225 );
1224 });1226 });
1225}1227}
1244 ));1246 ));
1245 assert_noop!(1247 assert_noop!(
1246 TemplateModule::burn_item(origin1.clone(), 1, 1),1248 TemplateModule::burn_item(origin1.clone(), 1, 1),
1247 "Address is not in white list"1249 Error::<Test>::AddresNotInWhiteList
1248 );1250 );
1249 });1251 });
1250}1252}
1267 // do approve1269 // do approve
1268 assert_noop!(1270 assert_noop!(
1269 TemplateModule::approve(origin1.clone(), 1, 1, 1),1271 TemplateModule::approve(origin1.clone(), 1, 1, 1),
1270 "Address is not in white list"1272 Error::<Test>::AddresNotInWhiteList
1271 );1273 );
1272 });1274 });
1273}1275}
14161418
1417 assert_noop!(1419 assert_noop!(
1418 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1420 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),
1419 "Public minting is not allowed for this collection"1421 Error::<Test>::PublicMintingNotAllowed
1420 );1422 );
1421 });1423 });
1422}1424}
14451447
1446 assert_noop!(1448 assert_noop!(
1447 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1449 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),
1448 "Public minting is not allowed for this collection"1450 Error::<Test>::PublicMintingNotAllowed
1449 );1451 );
1450 });1452 });
1451}1453}
15331535
1534 assert_noop!(1536 assert_noop!(
1535 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1537 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),
1536 "Address is not in white list"1538 Error::<Test>::AddresNotInWhiteList
1537 );1539 );
1538 });1540 });
1539}1541}
1603 col_desc1.clone(),1605 col_desc1.clone(),
1604 token_prefix1.clone(),1606 token_prefix1.clone(),
1605 CollectionMode::NFT1607 CollectionMode::NFT
1606 ), "Total collections bound exceeded");1608 ), Error::<Test>::TotalCollectionsLimitExceeded);
1607 });1609 });
1608}1610}
16091611
1646 1,1648 1,
1647 1,1649 1,
1648 data.into()1650 data.into()
1649 ), "Owned tokens by a single address bound exceeded");1651 ), Error::<Test>::AddressOwnershipLimitExceeded);
1650 });1652 });
1651}1653}
16521654
1692 let origin1 = Origin::signed(1);1694 let origin1 = Origin::signed(1);
16931695
1694 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1696 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));
1695 assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), "Number of collection admins bound exceeded");1697 assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), Error::<Test>::CollectionAdminsLimitExceeded);
1696 });1698 });
1697}1699}
16981700
modifiedruntime/src/nft_weights.rsdiffbeforeafterboth
108 .saturating_add(DbWeight::get().reads(2 as Weight))108 .saturating_add(DbWeight::get().reads(2 as Weight))
109 .saturating_add(DbWeight::get().writes(1 as Weight))109 .saturating_add(DbWeight::get().writes(1 as Weight))
110 }110 }
111 // fn set_chain_limits() -> Weight {
112 // (0 as Weight)
113 // .saturating_add(DbWeight::get().reads(1 as Weight))
114 // .saturating_add(DbWeight::get().writes(1 as Weight))
115 // }
116 // fn enable_contract_sponsoring() -> Weight {
117 // (0 as Weight)
118 // .saturating_add(DbWeight::get().reads(1 as Weight))
119 // .saturating_add(DbWeight::get().writes(1 as Weight))
120 // }
121 // fn set_contract_sponsoring_rate_limit() -> Weight {
122 // (0 as Weight)
123 // .saturating_add(DbWeight::get().reads(1 as Weight))
124 // .saturating_add(DbWeight::get().writes(1 as Weight))
125 // }
111}126}
112127