git.delta.rocks / unique-network / refs/commits / 82ca9c1be6da

difftreelog

Merge pull request #25 from usetech-llc/feature/NFTPAR-110_contract_spam

str-mv2020-12-02parents: #61a5f4d #33c31e8.patch.diff
in: master
Feature/nftpar 110 contract spam protection

4 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
366 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;366 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;
367367
368 // Contract Sponsorship and Ownership368 // Contract Sponsorship and Ownership
369 pub ContractOwner get(fn contract_owner): map hasher(identity) T::AccountId => T::AccountId;369 pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;
370 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(identity) T::AccountId => bool;370 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;
371 pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;
372 pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;
371 }373 }
372 add_extra_genesis {374 add_extra_genesis {
373 build(|config: &GenesisConfig<T>| {375 build(|config: &GenesisConfig<T>| {
1323 Ok(())1325 Ok(())
1324 }1326 }
1327
1328 /// Set the rate limit for contract sponsoring to specified number of blocks.
1329 ///
1330 /// If not set (has the default value of 0 blocks), the sponsoring will be disabled.
1331 /// If set to the number B (for blocks), the transactions will be sponsored with a rate
1332 /// limit of B, i.e. fees for every transaction sent to this smart contract will be paid
1333 /// from contract endowment if there are at least B blocks between such transactions.
1334 /// Nonetheless, if transactions are sent more frequently, the fees are paid by the sender.
1335 ///
1336 /// # Permissions
1337 ///
1338 /// * Contract Owner
1339 ///
1340 /// # Arguments
1341 ///
1342 /// -`contract_address`: Address of the contract to sponsor
1343 /// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed
1344 ///
1345 #[weight = 0]
1346 pub fn set_contract_sponsoring_rate_limit(
1347 origin,
1348 contract_address: T::AccountId,
1349 rate_limit: T::BlockNumber
1350 ) -> DispatchResult {
1351 let sender = ensure_signed(origin)?;
1352 let mut is_owner = false;
1353 if <ContractOwner<T>>::contains_key(contract_address.clone()) {
1354 let owner = <ContractOwner<T>>::get(&contract_address);
1355 is_owner = sender == owner;
1356 }
1357 ensure!(is_owner, Error::<T>::NoPermission);
1358
1359 <ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);
1360 Ok(())
1361 }
13251362
1326 }1363 }
1327}1364}
2230 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is2267 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is
2231 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {2268 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {
22322269
2270 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());
2271
2272 let mut sponsor_transfer = false;
2273 if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {
2274 let last_tx_block = <ContractSponsorBasket<T>>::get(&called_contract);
2275 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
2276 let rate_limit = <ContractSponsoringRateLimit<T>>::get(&called_contract);
2277 let limit_time = last_tx_block + rate_limit;
2278
2279 if block_number >= limit_time {
2280 <ContractSponsorBasket<T>>::insert(called_contract.clone(), block_number);
2281 sponsor_transfer = true;
2282 }
2283 } else {
2284 sponsor_transfer = false;
2285 }
2286
2287
2233 let mut sp = T::AccountId::default();2288 let mut sp = T::AccountId::default();
2234 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());2289 if sponsor_transfer {
2235 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {2290 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {
2236 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {2291 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {
2237 sp = called_contract;2292 sp = called_contract;
2238 }2293 }
2239 }2294 }
2295 }
22402296
2241 sp2297 sp
2242 },2298 },
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