From 3086c7619e0f55f45e1d29f8a45142e0626f1632 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 16 Sep 2022 17:54:00 +0300 Subject: [PATCH 01/30] Atomic NFTs swap --- frame/nfts/src/benchmarking.rs | 63 ++++++++++ frame/nfts/src/features/mod.rs | 18 +++ frame/nfts/src/features/swap.rs | 141 ++++++++++++++++++++++ frame/nfts/src/functions.rs | 4 + frame/nfts/src/lib.rs | 118 ++++++++++++++++++ frame/nfts/src/tests.rs | 208 ++++++++++++++++++++++++++++++++ frame/nfts/src/types.rs | 8 ++ frame/nfts/src/weights.rs | 45 +++++++ 8 files changed, 605 insertions(+) create mode 100644 frame/nfts/src/features/mod.rs create mode 100644 frame/nfts/src/features/swap.rs diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index ca38851222e8d..e2b52e4c23cec 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -458,5 +458,68 @@ benchmarks_instance_pallet! { }.into()); } + create_swap { + let (collection, caller, _) = create_collection::(); + let (item1, ..) = mint_item::(0); + let (item2, ..) = mint_item::(1); + let price = ItemPrice::::from(100u32); + let duration = T::BlockNumber::max_value(); + }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, item2, Some(price), Some(duration)) + verify { + assert_last_event::(Event::SwapCreated { + collection, + item: item1, + desired_collection: collection, + desired_item: item2, + price: Some(price), + deadline: Some(duration), + }.into()); + } + + cancel_swap { + let (collection, caller, _) = create_collection::(); + let (item1, ..) = mint_item::(0); + let (item2, ..) = mint_item::(1); + let price = ItemPrice::::from(100u32); + let duration = T::BlockNumber::max_value(); + let origin = SystemOrigin::Signed(caller.clone()).into(); + Nfts::::create_swap(origin, collection, item1, collection, item2, Some(price), Some(duration))?; + }: _(SystemOrigin::Signed(caller.clone()), collection, item1) + verify { + assert_last_event::(Event::SwapCancelled { + collection, + item: item1, + desired_collection: collection, + desired_item: item2, + price: Some(price), + deadline: Some(duration), + }.into()); + } + + claim_swap { + let (collection, caller, _) = create_collection::(); + let (item1, ..) = mint_item::(0); + let (item2, ..) = mint_item::(1); + let price = ItemPrice::::from(100u32); + let duration = T::BlockNumber::max_value(); + let user2: T::AccountId = account("user2", 0, SEED); + let user2_lookup = T::Lookup::unlookup(user2.clone()); + let origin = SystemOrigin::Signed(caller.clone()); + Nfts::::transfer(origin.clone().into(), collection, item1, user2_lookup)?; + Nfts::::create_swap(origin.clone().into(), collection, item1, collection, item2, Some(price), Some(duration))?; + }: _(SystemOrigin::Signed(user2.clone()), collection, item2, collection, item1, Some(price.clone())) + verify { + assert_last_event::(Event::SwapClaimed { + send_collection: collection, + send_item: item2, + send_item_owner: user2, + receive_collection: collection, + receive_item: item1, + receive_item_owner: caller, + price: Some(price), + deadline: Some(duration), + }.into()); + } + impl_benchmark_test_suite!(Nfts, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/frame/nfts/src/features/mod.rs b/frame/nfts/src/features/mod.rs new file mode 100644 index 0000000000000..2e6a7dce7d9fe --- /dev/null +++ b/frame/nfts/src/features/mod.rs @@ -0,0 +1,18 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod swap; diff --git a/frame/nfts/src/features/swap.rs b/frame/nfts/src/features/swap.rs new file mode 100644 index 0000000000000..09dfc16782bd4 --- /dev/null +++ b/frame/nfts/src/features/swap.rs @@ -0,0 +1,141 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::*; +use frame_support::{ + pallet_prelude::*, + traits::{Currency, ExistenceRequirement::KeepAlive}, +}; + +impl, I: 'static> Pallet { + pub fn do_create_swap( + sender: T::AccountId, + collection_id: T::CollectionId, + item_id: T::ItemId, + desired_collection_id: T::CollectionId, + desired_item_id: T::ItemId, + maybe_price: Option>, + maybe_duration: Option<::BlockNumber>, + ) -> DispatchResult { + let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; + ensure!(item.owner == sender, Error::::NoPermission); + + Item::::get(&desired_collection_id, &desired_item_id).ok_or(Error::::UnknownItem)?; + + let now = frame_system::Pallet::::block_number(); + let deadline = maybe_duration.map(|d| d.saturating_add(now)); + + PendingSwapOf::::insert(&collection_id, &item_id, PendingSwap { + desired_collection: desired_collection_id, + desired_item: desired_item_id, + price: maybe_price, + deadline, + }); + + Self::deposit_event(Event::SwapCreated { + collection: collection_id, + item: item_id, + desired_collection: desired_collection_id, + desired_item: desired_item_id, + price: maybe_price, + deadline, + }); + + Ok(()) + } + + pub fn do_cancel_swap( + sender: T::AccountId, + collection_id: T::CollectionId, + item_id: T::ItemId, + ) -> DispatchResult { + let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; + let swap = PendingSwapOf::::get(&collection_id, &item_id).ok_or(Error::::UnknownSwap)?; + + let is_past_deadline = if let Some(deadline) = swap.deadline { + let now = frame_system::Pallet::::block_number(); + now > deadline + } else { + false + }; + + if !is_past_deadline { + ensure!(item.owner == sender, Error::::NoPermission); + } + + PendingSwapOf::::remove(&collection_id, &item_id); + + Self::deposit_event(Event::SwapCancelled { + collection: collection_id, + item: item_id, + desired_collection: swap.desired_collection, + desired_item: swap.desired_item, + price: swap.price, + deadline: swap.deadline, + }); + + Ok(()) + } + + pub fn do_claim_swap( + sender: T::AccountId, + send_collection_id: T::CollectionId, + send_item_id: T::ItemId, + receive_collection_id: T::CollectionId, + receive_item_id: T::ItemId, + maybe_receive_amount: Option>, + ) -> DispatchResult { + let send_item = Item::::get(&send_collection_id, &send_item_id).ok_or(Error::::UnknownItem)?; + let receive_item = Item::::get(&receive_collection_id, &receive_item_id).ok_or(Error::::UnknownItem)?; + let swap = PendingSwapOf::::get(&receive_collection_id, &receive_item_id).ok_or(Error::::UnknownSwap)?; + + ensure!(send_item.owner == sender, Error::::NoPermission); + ensure!(swap.desired_collection == send_collection_id, Error::::UnknownSwap); + ensure!(swap.desired_item == send_item_id, Error::::UnknownSwap); + ensure!(swap.price == maybe_receive_amount, Error::::UnknownSwap); + + if let Some(deadline) = swap.deadline { + let now = frame_system::Pallet::::block_number(); + ensure!(deadline >= now, Error::::DeadlineExpired); + } + + if let Some(amount) = swap.price { + T::Currency::transfer( + &receive_item.owner, + &send_item.owner, + amount, + KeepAlive, + )?; + } + + Self::do_transfer(send_collection_id, send_item_id, receive_item.owner.clone(), |_, _| Ok(()))?; + Self::do_transfer(receive_collection_id, receive_item_id, send_item.owner.clone(), |_, _| Ok(()))?; + + Self::deposit_event(Event::SwapClaimed { + send_collection: send_collection_id, + send_item: send_item_id, + send_item_owner: send_item.owner, + receive_collection: receive_collection_id, + receive_item: receive_item_id, + receive_item_owner: receive_item.owner, + price: swap.price, + deadline: swap.deadline, + }); + + Ok(()) + } +} diff --git a/frame/nfts/src/functions.rs b/frame/nfts/src/functions.rs index 27ab752dbabf6..e9cb1edbadbb3 100644 --- a/frame/nfts/src/functions.rs +++ b/frame/nfts/src/functions.rs @@ -56,6 +56,7 @@ impl, I: 'static> Pallet { Item::::insert(&collection, &item, &details); ItemPriceOf::::remove(&collection, &item); + PendingSwapOf::::remove(&collection, &item); Self::deposit_event(Event::Transferred { collection, @@ -124,6 +125,8 @@ impl, I: 'static> Pallet { ItemMetadataOf::::remove_prefix(&collection, None); #[allow(deprecated)] ItemPriceOf::::remove_prefix(&collection, None); + #[allow(deprecated)] + PendingSwapOf::::remove_prefix(&collection, None); CollectionMetadataOf::::remove(&collection); #[allow(deprecated)] Attribute::::remove_prefix((&collection,), None); @@ -214,6 +217,7 @@ impl, I: 'static> Pallet { Item::::remove(&collection, &item); Account::::remove((&owner, &collection, &item)); ItemPriceOf::::remove(&collection, &item); + PendingSwapOf::::remove(&collection, &item); Self::deposit_event(Event::Burned { collection, item, owner }); Ok(()) diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index 14691c21a0ef2..ddd5dc89f8559 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -38,6 +38,7 @@ mod tests; mod functions; mod impl_nonfungibles; mod types; +mod features; pub mod weights; @@ -277,6 +278,18 @@ pub mod pallet { pub(super) type CollectionMaxSupply, I: 'static = ()> = StorageMap<_, Blake2_128Concat, T::CollectionId, u32, OptionQuery>; + #[pallet::storage] + /// Handles all the pending swaps. + pub(super) type PendingSwapOf, I: 'static = ()> = StorageDoubleMap< + _, + Blake2_128Concat, + T::CollectionId, + Blake2_128Concat, + T::ItemId, + PendingSwap, ::BlockNumber>, + OptionQuery, + >; + #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { @@ -388,6 +401,35 @@ pub mod pallet { seller: T::AccountId, buyer: T::AccountId, }, + /// An `item` swap intent was created. + SwapCreated { + collection: T::CollectionId, + item: T::ItemId, + desired_collection: T::CollectionId, + desired_item: T::ItemId, + price: Option>, + deadline: Option<::BlockNumber>, + }, + /// The swap was cancelled. + SwapCancelled { + collection: T::CollectionId, + item: T::ItemId, + desired_collection: T::CollectionId, + desired_item: T::ItemId, + price: Option>, + deadline: Option<::BlockNumber>, + }, + /// The swap has been claimed. + SwapClaimed { + send_collection: T::CollectionId, + send_item: T::ItemId, + send_item_owner: T::AccountId, + receive_collection: T::CollectionId, + receive_item: T::ItemId, + receive_item_owner: T::AccountId, + price: Option>, + deadline: Option<::BlockNumber>, + }, } #[pallet::error] @@ -426,12 +468,16 @@ pub mod pallet { MaxSupplyTooSmall, /// The given item ID is unknown. UnknownItem, + /// Swap doesn't exist. + UnknownSwap, /// Item is not for sale. NotForSale, /// The provided bid is too low. BidTooLow, /// The item has reached its approval limit. ReachedApprovalLimit, + /// The deadline has already expired. + DeadlineExpired, } impl, I: 'static> Pallet { @@ -1577,5 +1623,77 @@ pub mod pallet { let origin = ensure_signed(origin)?; Self::do_buy_item(collection, item, origin, bid_price) } + + /// Register a new atomic swap, declaring an intention to send an `item` in exchange for + /// `desired_item` from origin to target on the current blockchain. + /// The target can execute the swap during the specified `duration` of blocks (if set). + /// Additionally, the price could be set for the desired `item`. + /// + /// Origin must be Signed and must be an owner of the `item`. + /// + /// - `collection`: The collection of the item. + /// - `item`: The item an owner wants to give. + /// - `desired_collection`: The collection of the desired item. + /// - `desired_item`: The desired item an owner wants to receive. + /// - `maybe_price`: The price an owner is willing to pay for the desired `item`. + /// - `maybe_duration`: Optional deadline for the swap. Specified by providing the + /// number of blocks after which the swap will expire. + /// + /// Emits `SwapCreated` on success. + #[pallet::weight(T::WeightInfo::create_swap())] + pub fn create_swap( + origin: OriginFor, + collection: T::CollectionId, + item: T::ItemId, + desired_collection: T::CollectionId, + desired_item: T::ItemId, + maybe_price: Option>, + maybe_duration: Option<::BlockNumber>, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + Self::do_create_swap(origin, collection, item, desired_collection, desired_item, maybe_price, maybe_duration) + } + + /// Cancel an atomic swap. + /// + /// Origin must be Signed and must be an owner of the `item` if the deadline hasn't expired. + /// + /// - `collection`: The collection of the item. + /// - `item`: The item an owner wants to give. + /// + /// Emits `SwapCancelled` on success. + #[pallet::weight(T::WeightInfo::cancel_swap())] + pub fn cancel_swap( + origin: OriginFor, + collection: T::CollectionId, + item: T::ItemId, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + Self::do_cancel_swap(origin, collection, item) + } + + /// Claim an atomic swap. + /// + /// Origin must be Signed and must be an owner of the `item`. + /// + /// - `send_collection`: The collection of the item to be sent. + /// - `send_item`: The item to be sent. + /// - `receive_collection`: The collection of the item to be received. + /// - `receive_item`: The item to be received. + /// - `maybe_receive_amount`: An optional amount to be received. + /// + /// Emits `SwapClaimed` on success. + #[pallet::weight(T::WeightInfo::claim_swap())] + pub fn claim_swap( + origin: OriginFor, + send_collection: T::CollectionId, + send_item: T::ItemId, + receive_collection: T::CollectionId, + receive_item: T::ItemId, + maybe_receive_amount: Option>, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + Self::do_claim_swap(origin, send_collection, send_item, receive_collection, receive_item, maybe_receive_amount) + } } } diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 9fb29d0e95c26..890aad4e999fd 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -954,3 +954,211 @@ fn buy_item_should_work() { } }); } + +#[test] +fn create_cancel_swap_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let user_id = 1; + let collection_id = 0; + let item_1 = 1; + let item_2 = 2; + let price = 1; + let duration = 2; + let expect_deadline = 3; + + assert_ok!(Nfts::force_create(Origin::root(), collection_id, user_id, true)); + + assert_ok!(Nfts::mint(Origin::signed(user_id), collection_id, item_1, user_id)); + assert_ok!(Nfts::mint(Origin::signed(user_id), collection_id, item_2, user_id)); + + assert_ok!(Nfts::create_swap( + Origin::signed(user_id), + collection_id, + item_1, + collection_id, + item_2, + Some(price), + Some(duration), + )); + + let swap = PendingSwapOf::::get(collection_id, item_1).unwrap(); + assert_eq!(swap.desired_collection, collection_id); + assert_eq!(swap.desired_item, item_2); + assert_eq!(swap.price, Some(price)); + assert_eq!(swap.deadline, Some(expect_deadline)); + + assert!(events().contains(&Event::::SwapCreated { + collection: collection_id, + item: item_1, + desired_collection: collection_id, + desired_item: item_2, + price: Some(price), + deadline: Some(expect_deadline), + })); + + // validate we can cancel the swap + assert_ok!(Nfts::cancel_swap(Origin::signed(user_id), collection_id, item_1)); + assert!(events().contains(&Event::::SwapCancelled { + collection: collection_id, + item: item_1, + desired_collection: collection_id, + desired_item: item_2, + price: Some(price), + deadline: Some(expect_deadline), + })); + assert!(!PendingSwapOf::::contains_key(collection_id, item_1)); + + // validate anyone can cancel the expired swap + assert_ok!(Nfts::create_swap( + Origin::signed(user_id), + collection_id, + item_1, + collection_id, + item_2, + Some(price), + Some(duration), + )); + assert_noop!( + Nfts::cancel_swap(Origin::signed(user_id + 1), collection_id, item_1), + Error::::NoPermission + ); + System::set_block_number(expect_deadline + 1); + assert_ok!(Nfts::cancel_swap(Origin::signed(user_id + 1), collection_id, item_1)); + }); +} + +#[test] +fn claim_swap_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let user_1 = 1; + let user_2 = 2; + let collection_id = 0; + let item_1 = 1; + let item_2 = 2; + let item_3 = 3; + let item_4 = 4; + let item_5 = 5; + let price = 100; + let duration = 2; + let initial_balance = 1000; + let deadline = 1 + duration; + + Balances::make_free_balance_be(&user_1, initial_balance); + Balances::make_free_balance_be(&user_2, initial_balance); + + assert_ok!(Nfts::force_create(Origin::root(), collection_id, user_1, true)); + + assert_ok!(Nfts::mint(Origin::signed(user_1), collection_id, item_1, user_1)); + assert_ok!(Nfts::mint(Origin::signed(user_1), collection_id, item_2, user_2)); + assert_ok!(Nfts::mint(Origin::signed(user_1), collection_id, item_3, user_2)); + assert_ok!(Nfts::mint(Origin::signed(user_1), collection_id, item_4, user_1)); + assert_ok!(Nfts::mint(Origin::signed(user_1), collection_id, item_5, user_2)); + + assert_ok!(Nfts::create_swap( + Origin::signed(user_1), + collection_id, + item_1, + collection_id, + item_2, + Some(price), + Some(duration), + )); + + // validate the deadline + System::set_block_number(5); + assert_noop!( + Nfts::claim_swap( + Origin::signed(user_2), + collection_id, + item_2, + collection_id, + item_1, + Some(price), + ), + Error::::DeadlineExpired + ); + System::set_block_number(1); + + // validate edge cases + assert_noop!( + Nfts::claim_swap( + Origin::signed(user_2), + collection_id, + item_2, + collection_id, + item_4, // no swap was created for that asset + Some(price), + ), + Error::::UnknownSwap + ); + assert_noop!( + Nfts::claim_swap( + Origin::signed(user_2), + collection_id, + item_4, // not my item + collection_id, + item_1, + Some(price), + ), + Error::::NoPermission + ); + assert_noop!( + Nfts::claim_swap( + Origin::signed(user_2), + collection_id, + item_5, // my item, but not the one another part wants + collection_id, + item_1, + Some(price), + ), + Error::::UnknownSwap + ); + assert_noop!( + Nfts::claim_swap( + Origin::signed(user_2), + collection_id, + item_2, + collection_id, + item_1, + Some(price + 1) // wrong price + ), + Error::::UnknownSwap + ); + + assert_ok!(Nfts::claim_swap( + Origin::signed(user_2), + collection_id, + item_2, + collection_id, + item_1, + Some(price), + )); + + // validate the new owner + let item = Item::::get(collection_id, item_1).unwrap(); + assert_eq!(item.owner, user_2); + let item = Item::::get(collection_id, item_2).unwrap(); + assert_eq!(item.owner, user_1); + + // validate the balances + assert_eq!(Balances::total_balance(&user_1), initial_balance - price); + assert_eq!(Balances::total_balance(&user_2), initial_balance + price); + + // ensure we reset the swap + assert!(!PendingSwapOf::::contains_key(collection_id, item_1)); + + // validate the event + assert!(events().contains(&Event::::SwapClaimed { + send_collection: collection_id, + send_item: item_2, + send_item_owner: user_2, + receive_collection: collection_id, + receive_item: item_1, + receive_item_owner: user_1, + price: Some(price), + deadline: Some(deadline), + })); + }); +} diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index db1c351c4a9c5..293e3034b427e 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -127,3 +127,11 @@ pub struct ItemMetadata> { /// Whether the item metadata may be changed by a non Force origin. pub(super) is_frozen: bool, } + +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] +pub struct PendingSwap { + pub(super) desired_collection: CollectionId, + pub(super) desired_item: ItemId, + pub(super) price: Option, + pub(super) deadline: Option, +} diff --git a/frame/nfts/src/weights.rs b/frame/nfts/src/weights.rs index 2c90ab54fe9fb..5148f9c440b4b 100644 --- a/frame/nfts/src/weights.rs +++ b/frame/nfts/src/weights.rs @@ -73,6 +73,9 @@ pub trait WeightInfo { fn set_collection_max_supply() -> Weight; fn set_price() -> Weight; fn buy_item() -> Weight; + fn create_swap() -> Weight; + fn cancel_swap() -> Weight; + fn claim_swap() -> Weight; } /// Weights for pallet_nfts using the Substrate node and recommended hardware. @@ -298,6 +301,27 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(4 as u64)) } + // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts PendingSwapOf (r:0 w:1) + fn create_swap() -> Weight { + Weight::from_ref_time(47_967_000 as u64) + .saturating_add(T::DbWeight::get().reads(3 as u64)) + .saturating_add(T::DbWeight::get().writes(4 as u64)) + } + // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts PendingSwapOf (r:0 w:1) + fn cancel_swap() -> Weight { + Weight::from_ref_time(47_967_000 as u64) + .saturating_add(T::DbWeight::get().reads(3 as u64)) + .saturating_add(T::DbWeight::get().writes(4 as u64)) + } + // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts PendingSwapOf (r:0 w:1) + fn claim_swap() -> Weight { + Weight::from_ref_time(47_967_000 as u64) + .saturating_add(T::DbWeight::get().reads(3 as u64)) + .saturating_add(T::DbWeight::get().writes(4 as u64)) + } } // For backwards compatibility and tests @@ -522,4 +546,25 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(4 as u64)) } + // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts PendingSwapOf (r:0 w:1) + fn create_swap() -> Weight { + Weight::from_ref_time(24_745_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts PendingSwapOf (r:0 w:1) + fn cancel_swap() -> Weight { + Weight::from_ref_time(24_745_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts PendingSwapOf (r:0 w:1) + fn claim_swap() -> Weight { + Weight::from_ref_time(24_745_000 as u64) + .saturating_add(RocksDbWeight::get().reads(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } } From 12b756f89b864d68ca0a6c584c02e6011f26eedf Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 16 Sep 2022 18:01:38 +0300 Subject: [PATCH 02/30] Fmt --- frame/nfts/src/features/swap.rs | 49 ++++++++++++++++++++------------- frame/nfts/src/lib.rs | 21 ++++++++++++-- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/frame/nfts/src/features/swap.rs b/frame/nfts/src/features/swap.rs index 09dfc16782bd4..02a4a5043ee7a 100644 --- a/frame/nfts/src/features/swap.rs +++ b/frame/nfts/src/features/swap.rs @@ -34,17 +34,22 @@ impl, I: 'static> Pallet { let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; ensure!(item.owner == sender, Error::::NoPermission); - Item::::get(&desired_collection_id, &desired_item_id).ok_or(Error::::UnknownItem)?; + Item::::get(&desired_collection_id, &desired_item_id) + .ok_or(Error::::UnknownItem)?; let now = frame_system::Pallet::::block_number(); let deadline = maybe_duration.map(|d| d.saturating_add(now)); - PendingSwapOf::::insert(&collection_id, &item_id, PendingSwap { - desired_collection: desired_collection_id, - desired_item: desired_item_id, - price: maybe_price, - deadline, - }); + PendingSwapOf::::insert( + &collection_id, + &item_id, + PendingSwap { + desired_collection: desired_collection_id, + desired_item: desired_item_id, + price: maybe_price, + deadline, + }, + ); Self::deposit_event(Event::SwapCreated { collection: collection_id, @@ -64,7 +69,8 @@ impl, I: 'static> Pallet { item_id: T::ItemId, ) -> DispatchResult { let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; - let swap = PendingSwapOf::::get(&collection_id, &item_id).ok_or(Error::::UnknownSwap)?; + let swap = PendingSwapOf::::get(&collection_id, &item_id) + .ok_or(Error::::UnknownSwap)?; let is_past_deadline = if let Some(deadline) = swap.deadline { let now = frame_system::Pallet::::block_number(); @@ -99,9 +105,12 @@ impl, I: 'static> Pallet { receive_item_id: T::ItemId, maybe_receive_amount: Option>, ) -> DispatchResult { - let send_item = Item::::get(&send_collection_id, &send_item_id).ok_or(Error::::UnknownItem)?; - let receive_item = Item::::get(&receive_collection_id, &receive_item_id).ok_or(Error::::UnknownItem)?; - let swap = PendingSwapOf::::get(&receive_collection_id, &receive_item_id).ok_or(Error::::UnknownSwap)?; + let send_item = Item::::get(&send_collection_id, &send_item_id) + .ok_or(Error::::UnknownItem)?; + let receive_item = Item::::get(&receive_collection_id, &receive_item_id) + .ok_or(Error::::UnknownItem)?; + let swap = PendingSwapOf::::get(&receive_collection_id, &receive_item_id) + .ok_or(Error::::UnknownSwap)?; ensure!(send_item.owner == sender, Error::::NoPermission); ensure!(swap.desired_collection == send_collection_id, Error::::UnknownSwap); @@ -114,16 +123,18 @@ impl, I: 'static> Pallet { } if let Some(amount) = swap.price { - T::Currency::transfer( - &receive_item.owner, - &send_item.owner, - amount, - KeepAlive, - )?; + T::Currency::transfer(&receive_item.owner, &send_item.owner, amount, KeepAlive)?; } - Self::do_transfer(send_collection_id, send_item_id, receive_item.owner.clone(), |_, _| Ok(()))?; - Self::do_transfer(receive_collection_id, receive_item_id, send_item.owner.clone(), |_, _| Ok(()))?; + Self::do_transfer(send_collection_id, send_item_id, receive_item.owner.clone(), |_, _| { + Ok(()) + })?; + Self::do_transfer( + receive_collection_id, + receive_item_id, + send_item.owner.clone(), + |_, _| Ok(()), + )?; Self::deposit_event(Event::SwapClaimed { send_collection: send_collection_id, diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index ddd5dc89f8559..eb1f55e2f7426 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -35,10 +35,10 @@ pub mod mock; #[cfg(test)] mod tests; +mod features; mod functions; mod impl_nonfungibles; mod types; -mod features; pub mod weights; @@ -1651,7 +1651,15 @@ pub mod pallet { maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { let origin = ensure_signed(origin)?; - Self::do_create_swap(origin, collection, item, desired_collection, desired_item, maybe_price, maybe_duration) + Self::do_create_swap( + origin, + collection, + item, + desired_collection, + desired_item, + maybe_price, + maybe_duration, + ) } /// Cancel an atomic swap. @@ -1693,7 +1701,14 @@ pub mod pallet { maybe_receive_amount: Option>, ) -> DispatchResult { let origin = ensure_signed(origin)?; - Self::do_claim_swap(origin, send_collection, send_item, receive_collection, receive_item, maybe_receive_amount) + Self::do_claim_swap( + origin, + send_collection, + send_item, + receive_collection, + receive_item, + maybe_receive_amount, + ) } } } From fc1024a0c16939296eb937e54b57d343b7282c1c Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 20 Sep 2022 13:03:30 +0300 Subject: [PATCH 03/30] Fix benchmark --- frame/nfts/src/benchmarking.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index c952d498ebbcc..fb9f46d60edc5 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -502,17 +502,17 @@ benchmarks_instance_pallet! { let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(100u32); let duration = T::BlockNumber::max_value(); - let user2: T::AccountId = account("user2", 0, SEED); - let user2_lookup = T::Lookup::unlookup(user2.clone()); + let target: T::AccountId = account("target", 0, SEED); + let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); - Nfts::::transfer(origin.clone().into(), collection, item1, user2_lookup)?; + Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; Nfts::::create_swap(origin.clone().into(), collection, item1, collection, item2, Some(price), Some(duration))?; - }: _(SystemOrigin::Signed(user2.clone()), collection, item2, collection, item1, Some(price.clone())) + }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone())) verify { assert_last_event::(Event::SwapClaimed { send_collection: collection, send_item: item2, - send_item_owner: user2, + send_item_owner: target, receive_collection: collection, receive_item: item1, receive_item_owner: caller, From a2955be694e2f85fffe2f3385a217ed978468a66 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 20 Sep 2022 13:11:56 +0300 Subject: [PATCH 04/30] Rename swap -> atomic_swap --- frame/nfts/src/features/{swap.rs => atomic_swap.rs} | 0 frame/nfts/src/features/mod.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename frame/nfts/src/features/{swap.rs => atomic_swap.rs} (100%) diff --git a/frame/nfts/src/features/swap.rs b/frame/nfts/src/features/atomic_swap.rs similarity index 100% rename from frame/nfts/src/features/swap.rs rename to frame/nfts/src/features/atomic_swap.rs diff --git a/frame/nfts/src/features/mod.rs b/frame/nfts/src/features/mod.rs index 2e6a7dce7d9fe..b785c28fbcaba 100644 --- a/frame/nfts/src/features/mod.rs +++ b/frame/nfts/src/features/mod.rs @@ -15,4 +15,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub mod swap; +pub mod atomic_swap; From bdc0538d6150f00e432a032f8b2f47e15f7b70f8 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 20 Sep 2022 14:40:22 +0300 Subject: [PATCH 05/30] Update target balance --- frame/nfts/src/benchmarking.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index fb9f46d60edc5..7dced9e3a5297 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -505,6 +505,7 @@ benchmarks_instance_pallet! { let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); + T::Currency::make_free_balance_be(&target, DepositBalanceOf::::max_value()); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; Nfts::::create_swap(origin.clone().into(), collection, item1, collection, item2, Some(price), Some(duration))?; }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone())) From a28cbcc61784ce86c73b46a2f4641198003d08d9 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 20 Sep 2022 14:51:17 +0300 Subject: [PATCH 06/30] Rollback --- frame/nfts/src/benchmarking.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index 7dced9e3a5297..9ee969d33032f 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -502,10 +502,9 @@ benchmarks_instance_pallet! { let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(100u32); let duration = T::BlockNumber::max_value(); - let target: T::AccountId = account("target", 0, SEED); + let target: T::AccountId = account("target", 1, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); - T::Currency::make_free_balance_be(&target, DepositBalanceOf::::max_value()); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; Nfts::::create_swap(origin.clone().into(), collection, item1, collection, item2, Some(price), Some(duration))?; }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone())) From 504b7d526d8cb919caf648747db57f2828d94a03 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 20 Sep 2022 15:31:32 +0300 Subject: [PATCH 07/30] Fix --- frame/nfts/src/benchmarking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index 9ee969d33032f..ae6ae6c25ce99 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -500,9 +500,9 @@ benchmarks_instance_pallet! { let (collection, caller, _) = create_collection::(); let (item1, ..) = mint_item::(0); let (item2, ..) = mint_item::(1); - let price = ItemPrice::::from(100u32); + let price = ItemPrice::::from(0u32); let duration = T::BlockNumber::max_value(); - let target: T::AccountId = account("target", 1, SEED); + let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; From 1ccf9962b2824e94787c67c93491c56b7675e368 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Tue, 20 Sep 2022 15:21:15 +0000 Subject: [PATCH 08/30] ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts --- frame/nfts/src/weights.rs | 226 ++++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 109 deletions(-) diff --git a/frame/nfts/src/weights.rs b/frame/nfts/src/weights.rs index 5148f9c440b4b..2fe11cb67d507 100644 --- a/frame/nfts/src/weights.rs +++ b/frame/nfts/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_nfts //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-09-09, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2022-09-20, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -84,14 +84,14 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn create() -> Weight { - Weight::from_ref_time(33_018_000 as u64) + Weight::from_ref_time(33_626_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_create() -> Weight { - Weight::from_ref_time(20_957_000 as u64) + Weight::from_ref_time(21_500_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } @@ -107,26 +107,24 @@ impl WeightInfo for SubstrateWeight { /// The range of component `m` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(n: u32, m: u32, a: u32, ) -> Weight { - Weight::from_ref_time(0 as u64) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(10_091_000 as u64).saturating_mul(n as u64)) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(1_748_000 as u64).saturating_mul(m as u64)) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(1_621_000 as u64).saturating_mul(a as u64)) + Weight::from_ref_time(2_440_842_000 as u64) + // Standard Error: 27_311 + .saturating_add(Weight::from_ref_time(8_548_031 as u64).saturating_mul(n as u64)) + // Standard Error: 27_311 + .saturating_add(Weight::from_ref_time(329_119 as u64).saturating_mul(m as u64)) + // Standard Error: 27_311 + .saturating_add(Weight::from_ref_time(221_299 as u64).saturating_mul(a as u64)) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().reads((1 as u64).saturating_mul(n as u64))) - .saturating_add(T::DbWeight::get().writes(4 as u64)) - .saturating_add(T::DbWeight::get().writes((2 as u64).saturating_mul(n as u64))) - .saturating_add(T::DbWeight::get().writes((1 as u64).saturating_mul(m as u64))) - .saturating_add(T::DbWeight::get().writes((1 as u64).saturating_mul(a as u64))) + .saturating_add(T::DbWeight::get().writes(2004 as u64)) + .saturating_add(T::DbWeight::get().writes((1 as u64).saturating_mul(n as u64))) } // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:1) // Storage: Nfts CollectionMaxSupply (r:1 w:0) // Storage: Nfts Account (r:0 w:1) fn mint() -> Weight { - Weight::from_ref_time(43_007_000 as u64) + Weight::from_ref_time(42_599_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(3 as u64)) } @@ -134,27 +132,29 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Account (r:0 w:1) // Storage: Nfts ItemPriceOf (r:0 w:1) + // Storage: Nfts PendingSwapOf (r:0 w:1) fn burn() -> Weight { - Weight::from_ref_time(43_922_000 as u64) + Weight::from_ref_time(45_618_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) - .saturating_add(T::DbWeight::get().writes(4 as u64)) + .saturating_add(T::DbWeight::get().writes(5 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Account (r:0 w:2) // Storage: Nfts ItemPriceOf (r:0 w:1) + // Storage: Nfts PendingSwapOf (r:0 w:1) fn transfer() -> Weight { - Weight::from_ref_time(33_951_000 as u64) + Weight::from_ref_time(35_348_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) - .saturating_add(T::DbWeight::get().writes(4 as u64)) + .saturating_add(T::DbWeight::get().writes(5 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts Asset (r:102 w:102) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { - Weight::from_ref_time(0 as u64) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(11_194_000 as u64).saturating_mul(i as u64)) + Weight::from_ref_time(22_260_000 as u64) + // Standard Error: 9_184 + .saturating_add(Weight::from_ref_time(10_904_892 as u64).saturating_mul(i as u64)) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().reads((1 as u64).saturating_mul(i as u64))) .saturating_add(T::DbWeight::get().writes(1 as u64)) @@ -163,26 +163,26 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn freeze() -> Weight { - Weight::from_ref_time(26_745_000 as u64) + Weight::from_ref_time(27_057_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn thaw() -> Weight { - Weight::from_ref_time(27_466_000 as u64) + Weight::from_ref_time(27_046_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn freeze_collection() -> Weight { - Weight::from_ref_time(22_591_000 as u64) + Weight::from_ref_time(22_648_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn thaw_collection() -> Weight { - Weight::from_ref_time(22_392_000 as u64) + Weight::from_ref_time(22_411_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } @@ -190,20 +190,20 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:2) fn transfer_ownership() -> Weight { - Weight::from_ref_time(31_202_000 as u64) + Weight::from_ref_time(31_506_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(4 as u64)) } // Storage: Nfts Class (r:1 w:1) fn set_team() -> Weight { - Weight::from_ref_time(23_063_000 as u64) + Weight::from_ref_time(23_982_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_item_status() -> Weight { - Weight::from_ref_time(25_598_000 as u64) + Weight::from_ref_time(26_107_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } @@ -211,7 +211,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn set_attribute() -> Weight { - Weight::from_ref_time(48_684_000 as u64) + Weight::from_ref_time(48_915_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } @@ -219,76 +219,76 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn clear_attribute() -> Weight { - Weight::from_ref_time(47_267_000 as u64) + Weight::from_ref_time(47_616_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn set_metadata() -> Weight { - Weight::from_ref_time(40_174_000 as u64) + Weight::from_ref_time(40_181_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn clear_metadata() -> Weight { - Weight::from_ref_time(41_611_000 as u64) + Weight::from_ref_time(41_541_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn set_collection_metadata() -> Weight { - Weight::from_ref_time(40_073_000 as u64) + Weight::from_ref_time(39_253_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn clear_collection_metadata() -> Weight { - Weight::from_ref_time(38_191_000 as u64) + Weight::from_ref_time(38_526_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn approve_transfer() -> Weight { - Weight::from_ref_time(29_461_000 as u64) + Weight::from_ref_time(28_993_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn cancel_approval() -> Weight { - Weight::from_ref_time(29_690_000 as u64) + Weight::from_ref_time(29_457_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn clear_all_transfer_approvals() -> Weight { - Weight::from_ref_time(27_758_000 as u64) + Weight::from_ref_time(28_897_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts OwnershipAcceptance (r:1 w:1) fn set_accept_ownership() -> Weight { - Weight::from_ref_time(26_425_000 as u64) + Weight::from_ref_time(26_163_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts CollectionMaxSupply (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn set_collection_max_supply() -> Weight { - Weight::from_ref_time(24_533_000 as u64) + Weight::from_ref_time(24_958_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:0) // Storage: Nfts ItemPriceOf (r:0 w:1) fn set_price() -> Weight { - Weight::from_ref_time(24_745_000 as u64) + Weight::from_ref_time(25_279_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } @@ -296,31 +296,35 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts ItemPriceOf (r:1 w:1) // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Account (r:0 w:2) + // Storage: Nfts PendingSwapOf (r:0 w:1) fn buy_item() -> Weight { - Weight::from_ref_time(47_967_000 as u64) + Weight::from_ref_time(49_044_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) - .saturating_add(T::DbWeight::get().writes(4 as u64)) + .saturating_add(T::DbWeight::get().writes(5 as u64)) } - // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts Asset (r:2 w:0) // Storage: Nfts PendingSwapOf (r:0 w:1) fn create_swap() -> Weight { - Weight::from_ref_time(47_967_000 as u64) - .saturating_add(T::DbWeight::get().reads(3 as u64)) - .saturating_add(T::DbWeight::get().writes(4 as u64)) + Weight::from_ref_time(29_275_000 as u64) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:0) - // Storage: Nfts PendingSwapOf (r:0 w:1) + // Storage: Nfts PendingSwapOf (r:1 w:1) fn cancel_swap() -> Weight { - Weight::from_ref_time(47_967_000 as u64) - .saturating_add(T::DbWeight::get().reads(3 as u64)) - .saturating_add(T::DbWeight::get().writes(4 as u64)) + Weight::from_ref_time(29_062_000 as u64) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) } - // Storage: Nfts Asset (r:1 w:0) - // Storage: Nfts PendingSwapOf (r:0 w:1) + // Storage: Nfts Asset (r:2 w:2) + // Storage: Nfts PendingSwapOf (r:1 w:2) + // Storage: Nfts Class (r:1 w:0) + // Storage: Nfts Account (r:0 w:4) + // Storage: Nfts ItemPriceOf (r:0 w:2) fn claim_swap() -> Weight { - Weight::from_ref_time(47_967_000 as u64) - .saturating_add(T::DbWeight::get().reads(3 as u64)) - .saturating_add(T::DbWeight::get().writes(4 as u64)) + Weight::from_ref_time(66_766_000 as u64) + .saturating_add(T::DbWeight::get().reads(4 as u64)) + .saturating_add(T::DbWeight::get().writes(10 as u64)) } } @@ -329,14 +333,14 @@ impl WeightInfo for () { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn create() -> Weight { - Weight::from_ref_time(33_018_000 as u64) + Weight::from_ref_time(33_626_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_create() -> Weight { - Weight::from_ref_time(20_957_000 as u64) + Weight::from_ref_time(21_500_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } @@ -352,26 +356,24 @@ impl WeightInfo for () { /// The range of component `m` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(n: u32, m: u32, a: u32, ) -> Weight { - Weight::from_ref_time(0 as u64) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(10_091_000 as u64).saturating_mul(n as u64)) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(1_748_000 as u64).saturating_mul(m as u64)) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(1_621_000 as u64).saturating_mul(a as u64)) + Weight::from_ref_time(2_440_842_000 as u64) + // Standard Error: 27_311 + .saturating_add(Weight::from_ref_time(8_548_031 as u64).saturating_mul(n as u64)) + // Standard Error: 27_311 + .saturating_add(Weight::from_ref_time(329_119 as u64).saturating_mul(m as u64)) + // Standard Error: 27_311 + .saturating_add(Weight::from_ref_time(221_299 as u64).saturating_mul(a as u64)) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().reads((1 as u64).saturating_mul(n as u64))) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) - .saturating_add(RocksDbWeight::get().writes((2 as u64).saturating_mul(n as u64))) - .saturating_add(RocksDbWeight::get().writes((1 as u64).saturating_mul(m as u64))) - .saturating_add(RocksDbWeight::get().writes((1 as u64).saturating_mul(a as u64))) + .saturating_add(RocksDbWeight::get().writes(2004 as u64)) + .saturating_add(RocksDbWeight::get().writes((1 as u64).saturating_mul(n as u64))) } // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:1) // Storage: Nfts CollectionMaxSupply (r:1 w:0) // Storage: Nfts Account (r:0 w:1) fn mint() -> Weight { - Weight::from_ref_time(43_007_000 as u64) + Weight::from_ref_time(42_599_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(3 as u64)) } @@ -379,27 +381,29 @@ impl WeightInfo for () { // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Account (r:0 w:1) // Storage: Nfts ItemPriceOf (r:0 w:1) + // Storage: Nfts PendingSwapOf (r:0 w:1) fn burn() -> Weight { - Weight::from_ref_time(43_922_000 as u64) + Weight::from_ref_time(45_618_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) + .saturating_add(RocksDbWeight::get().writes(5 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Account (r:0 w:2) // Storage: Nfts ItemPriceOf (r:0 w:1) + // Storage: Nfts PendingSwapOf (r:0 w:1) fn transfer() -> Weight { - Weight::from_ref_time(33_951_000 as u64) + Weight::from_ref_time(35_348_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) + .saturating_add(RocksDbWeight::get().writes(5 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts Asset (r:102 w:102) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { - Weight::from_ref_time(0 as u64) - // Standard Error: 12_000 - .saturating_add(Weight::from_ref_time(11_194_000 as u64).saturating_mul(i as u64)) + Weight::from_ref_time(22_260_000 as u64) + // Standard Error: 9_184 + .saturating_add(Weight::from_ref_time(10_904_892 as u64).saturating_mul(i as u64)) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().reads((1 as u64).saturating_mul(i as u64))) .saturating_add(RocksDbWeight::get().writes(1 as u64)) @@ -408,26 +412,26 @@ impl WeightInfo for () { // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn freeze() -> Weight { - Weight::from_ref_time(26_745_000 as u64) + Weight::from_ref_time(27_057_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn thaw() -> Weight { - Weight::from_ref_time(27_466_000 as u64) + Weight::from_ref_time(27_046_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn freeze_collection() -> Weight { - Weight::from_ref_time(22_591_000 as u64) + Weight::from_ref_time(22_648_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn thaw_collection() -> Weight { - Weight::from_ref_time(22_392_000 as u64) + Weight::from_ref_time(22_411_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } @@ -435,20 +439,20 @@ impl WeightInfo for () { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:2) fn transfer_ownership() -> Weight { - Weight::from_ref_time(31_202_000 as u64) + Weight::from_ref_time(31_506_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(4 as u64)) } // Storage: Nfts Class (r:1 w:1) fn set_team() -> Weight { - Weight::from_ref_time(23_063_000 as u64) + Weight::from_ref_time(23_982_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_item_status() -> Weight { - Weight::from_ref_time(25_598_000 as u64) + Weight::from_ref_time(26_107_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } @@ -456,7 +460,7 @@ impl WeightInfo for () { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn set_attribute() -> Weight { - Weight::from_ref_time(48_684_000 as u64) + Weight::from_ref_time(48_915_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } @@ -464,76 +468,76 @@ impl WeightInfo for () { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn clear_attribute() -> Weight { - Weight::from_ref_time(47_267_000 as u64) + Weight::from_ref_time(47_616_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn set_metadata() -> Weight { - Weight::from_ref_time(40_174_000 as u64) + Weight::from_ref_time(40_181_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn clear_metadata() -> Weight { - Weight::from_ref_time(41_611_000 as u64) + Weight::from_ref_time(41_541_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn set_collection_metadata() -> Weight { - Weight::from_ref_time(40_073_000 as u64) + Weight::from_ref_time(39_253_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn clear_collection_metadata() -> Weight { - Weight::from_ref_time(38_191_000 as u64) + Weight::from_ref_time(38_526_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn approve_transfer() -> Weight { - Weight::from_ref_time(29_461_000 as u64) + Weight::from_ref_time(28_993_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn cancel_approval() -> Weight { - Weight::from_ref_time(29_690_000 as u64) + Weight::from_ref_time(29_457_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn clear_all_transfer_approvals() -> Weight { - Weight::from_ref_time(27_758_000 as u64) + Weight::from_ref_time(28_897_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts OwnershipAcceptance (r:1 w:1) fn set_accept_ownership() -> Weight { - Weight::from_ref_time(26_425_000 as u64) + Weight::from_ref_time(26_163_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts CollectionMaxSupply (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn set_collection_max_supply() -> Weight { - Weight::from_ref_time(24_533_000 as u64) + Weight::from_ref_time(24_958_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:0) // Storage: Nfts ItemPriceOf (r:0 w:1) fn set_price() -> Weight { - Weight::from_ref_time(24_745_000 as u64) + Weight::from_ref_time(25_279_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } @@ -541,30 +545,34 @@ impl WeightInfo for () { // Storage: Nfts ItemPriceOf (r:1 w:1) // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Account (r:0 w:2) + // Storage: Nfts PendingSwapOf (r:0 w:1) fn buy_item() -> Weight { - Weight::from_ref_time(47_967_000 as u64) + Weight::from_ref_time(49_044_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) + .saturating_add(RocksDbWeight::get().writes(5 as u64)) } - // Storage: Nfts Asset (r:1 w:0) + // Storage: Nfts Asset (r:2 w:0) // Storage: Nfts PendingSwapOf (r:0 w:1) fn create_swap() -> Weight { - Weight::from_ref_time(24_745_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) + Weight::from_ref_time(29_275_000 as u64) + .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:0) - // Storage: Nfts PendingSwapOf (r:0 w:1) + // Storage: Nfts PendingSwapOf (r:1 w:1) fn cancel_swap() -> Weight { - Weight::from_ref_time(24_745_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) + Weight::from_ref_time(29_062_000 as u64) + .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } - // Storage: Nfts Asset (r:1 w:0) - // Storage: Nfts PendingSwapOf (r:0 w:1) + // Storage: Nfts Asset (r:2 w:2) + // Storage: Nfts PendingSwapOf (r:1 w:2) + // Storage: Nfts Class (r:1 w:0) + // Storage: Nfts Account (r:0 w:4) + // Storage: Nfts ItemPriceOf (r:0 w:2) fn claim_swap() -> Weight { - Weight::from_ref_time(24_745_000 as u64) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + Weight::from_ref_time(66_766_000 as u64) + .saturating_add(RocksDbWeight::get().reads(4 as u64)) + .saturating_add(RocksDbWeight::get().writes(10 as u64)) } } From ca2d1ec47f5d7855c853cb6d3d09bffc84a40fff Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Thu, 29 Sep 2022 19:10:12 +0300 Subject: [PATCH 09/30] Make desired item optional --- frame/nfts/src/benchmarking.rs | 10 ++-- frame/nfts/src/features/atomic_swap.rs | 24 ++++++--- frame/nfts/src/lib.rs | 8 +-- frame/nfts/src/tests.rs | 75 +++++++++++++++++++++++--- frame/nfts/src/types.rs | 2 +- 5 files changed, 97 insertions(+), 22 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index ae6ae6c25ce99..ad0832f2f26e2 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -464,13 +464,13 @@ benchmarks_instance_pallet! { let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(100u32); let duration = T::BlockNumber::max_value(); - }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, item2, Some(price), Some(duration)) + }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price), Some(duration)) verify { assert_last_event::(Event::SwapCreated { collection, item: item1, desired_collection: collection, - desired_item: item2, + desired_item: Some(item2), price: Some(price), deadline: Some(duration), }.into()); @@ -483,14 +483,14 @@ benchmarks_instance_pallet! { let price = ItemPrice::::from(100u32); let duration = T::BlockNumber::max_value(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Nfts::::create_swap(origin, collection, item1, collection, item2, Some(price), Some(duration))?; + Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price), Some(duration))?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { assert_last_event::(Event::SwapCancelled { collection, item: item1, desired_collection: collection, - desired_item: item2, + desired_item: Some(item2), price: Some(price), deadline: Some(duration), }.into()); @@ -506,7 +506,7 @@ benchmarks_instance_pallet! { let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; - Nfts::::create_swap(origin.clone().into(), collection, item1, collection, item2, Some(price), Some(duration))?; + Nfts::::create_swap(origin.clone().into(), collection, item1, collection, Some(item2), Some(price), Some(duration))?; }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone())) verify { assert_last_event::(Event::SwapClaimed { diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index 02a4a5043ee7a..f2c985721ef45 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -27,15 +27,24 @@ impl, I: 'static> Pallet { collection_id: T::CollectionId, item_id: T::ItemId, desired_collection_id: T::CollectionId, - desired_item_id: T::ItemId, + maybe_desired_item_id: Option, maybe_price: Option>, maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; ensure!(item.owner == sender, Error::::NoPermission); - Item::::get(&desired_collection_id, &desired_item_id) - .ok_or(Error::::UnknownItem)?; + match maybe_desired_item_id { + Some(desired_item_id) => { + if !(Item::::contains_key(&desired_collection_id, &desired_item_id)) { + return Err(Error::::UnknownItem.into()) + } + }, + None => + if !(Collection::::contains_key(&desired_collection_id)) { + return Err(Error::::UnknownCollection.into()) + }, + }; let now = frame_system::Pallet::::block_number(); let deadline = maybe_duration.map(|d| d.saturating_add(now)); @@ -45,7 +54,7 @@ impl, I: 'static> Pallet { &item_id, PendingSwap { desired_collection: desired_collection_id, - desired_item: desired_item_id, + desired_item: maybe_desired_item_id, price: maybe_price, deadline, }, @@ -55,7 +64,7 @@ impl, I: 'static> Pallet { collection: collection_id, item: item_id, desired_collection: desired_collection_id, - desired_item: desired_item_id, + desired_item: maybe_desired_item_id, price: maybe_price, deadline, }); @@ -114,9 +123,12 @@ impl, I: 'static> Pallet { ensure!(send_item.owner == sender, Error::::NoPermission); ensure!(swap.desired_collection == send_collection_id, Error::::UnknownSwap); - ensure!(swap.desired_item == send_item_id, Error::::UnknownSwap); ensure!(swap.price == maybe_receive_amount, Error::::UnknownSwap); + if let Some(desired_item) = swap.desired_item { + ensure!(desired_item == send_item_id, Error::::UnknownSwap); + } + if let Some(deadline) = swap.deadline { let now = frame_system::Pallet::::block_number(); ensure!(deadline >= now, Error::::DeadlineExpired); diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index 392dfa24e3dcd..5de8095ccdf7f 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -407,7 +407,7 @@ pub mod pallet { collection: T::CollectionId, item: T::ItemId, desired_collection: T::CollectionId, - desired_item: T::ItemId, + desired_item: Option, price: Option>, deadline: Option<::BlockNumber>, }, @@ -416,7 +416,7 @@ pub mod pallet { collection: T::CollectionId, item: T::ItemId, desired_collection: T::CollectionId, - desired_item: T::ItemId, + desired_item: Option, price: Option>, deadline: Option<::BlockNumber>, }, @@ -1647,7 +1647,7 @@ pub mod pallet { collection: T::CollectionId, item: T::ItemId, desired_collection: T::CollectionId, - desired_item: T::ItemId, + maybe_desired_item: Option, maybe_price: Option>, maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { @@ -1657,7 +1657,7 @@ pub mod pallet { collection, item, desired_collection, - desired_item, + maybe_desired_item, maybe_price, maybe_duration, ) diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 75a34bb0105f9..a4a827c9613b9 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -972,19 +972,45 @@ fn create_cancel_swap_should_work() { assert_ok!(Nfts::mint(Origin::signed(user_id), collection_id, item_1, user_id)); assert_ok!(Nfts::mint(Origin::signed(user_id), collection_id, item_2, user_id)); + // validate desired item and the collection exists + assert_noop!( + Nfts::create_swap( + Origin::signed(user_id), + collection_id, + item_1, + collection_id, + Some(item_2 + 1), + Some(price), + Some(duration), + ), + Error::::UnknownItem + ); + assert_noop!( + Nfts::create_swap( + Origin::signed(user_id), + collection_id, + item_1, + collection_id + 1, + None, + Some(price), + Some(duration), + ), + Error::::UnknownCollection + ); + assert_ok!(Nfts::create_swap( Origin::signed(user_id), collection_id, item_1, collection_id, - item_2, + Some(item_2), Some(price), Some(duration), )); let swap = PendingSwapOf::::get(collection_id, item_1).unwrap(); assert_eq!(swap.desired_collection, collection_id); - assert_eq!(swap.desired_item, item_2); + assert_eq!(swap.desired_item, Some(item_2)); assert_eq!(swap.price, Some(price)); assert_eq!(swap.deadline, Some(expect_deadline)); @@ -992,7 +1018,7 @@ fn create_cancel_swap_should_work() { collection: collection_id, item: item_1, desired_collection: collection_id, - desired_item: item_2, + desired_item: Some(item_2), price: Some(price), deadline: Some(expect_deadline), })); @@ -1003,7 +1029,7 @@ fn create_cancel_swap_should_work() { collection: collection_id, item: item_1, desired_collection: collection_id, - desired_item: item_2, + desired_item: Some(item_2), price: Some(price), deadline: Some(expect_deadline), })); @@ -1015,7 +1041,7 @@ fn create_cancel_swap_should_work() { collection_id, item_1, collection_id, - item_2, + Some(item_2), Some(price), Some(duration), )); @@ -1025,6 +1051,20 @@ fn create_cancel_swap_should_work() { ); System::set_block_number(expect_deadline + 1); assert_ok!(Nfts::cancel_swap(Origin::signed(user_id + 1), collection_id, item_1)); + + // validate optional desired_item param + assert_ok!(Nfts::create_swap( + Origin::signed(user_id), + collection_id, + item_1, + collection_id, + None, + Some(price), + Some(duration), + )); + + let swap = PendingSwapOf::::get(collection_id, item_1).unwrap(); + assert_eq!(swap.desired_item, None); }); } @@ -1061,7 +1101,7 @@ fn claim_swap_should_work() { collection_id, item_1, collection_id, - item_2, + Some(item_2), Some(price), Some(duration), )); @@ -1160,5 +1200,28 @@ fn claim_swap_should_work() { price: Some(price), deadline: Some(deadline), })); + + // validate the optional desired_item param + assert_ok!(Nfts::create_swap( + Origin::signed(user_1), + collection_id, + item_4, + collection_id, + None, + Some(price), + Some(duration), + )); + assert_ok!(Nfts::claim_swap( + Origin::signed(user_2), + collection_id, + item_1, + collection_id, + item_4, + Some(price), + )); + let item = Item::::get(collection_id, item_1).unwrap(); + assert_eq!(item.owner, user_1); + let item = Item::::get(collection_id, item_4).unwrap(); + assert_eq!(item.owner, user_2); }); } diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index 293e3034b427e..80baf531a4e64 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -131,7 +131,7 @@ pub struct ItemMetadata> { #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] pub struct PendingSwap { pub(super) desired_collection: CollectionId, - pub(super) desired_item: ItemId, + pub(super) desired_item: Option, pub(super) price: Option, pub(super) deadline: Option, } From 78f457082765c11aa8cf117cad4bb536ea649b3a Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 13:13:21 +0300 Subject: [PATCH 10/30] Apply suggestions --- frame/nfts/src/benchmarking.rs | 12 ++++++------ frame/nfts/src/features/atomic_swap.rs | 24 ++++++++++++------------ frame/nfts/src/lib.rs | 12 ++++++------ frame/nfts/src/tests.rs | 12 ++++++------ 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index ad0832f2f26e2..eb44e99bc9b9d 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -510,12 +510,12 @@ benchmarks_instance_pallet! { }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone())) verify { assert_last_event::(Event::SwapClaimed { - send_collection: collection, - send_item: item2, - send_item_owner: target, - receive_collection: collection, - receive_item: item1, - receive_item_owner: caller, + sent_collection: collection, + sent_item: item2, + sent_item_owner: target, + received_collection: collection, + received_item: item1, + received_item_owner: caller, price: Some(price), deadline: Some(duration), }.into()); diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index f2c985721ef45..23b1861ece3c2 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -23,7 +23,7 @@ use frame_support::{ impl, I: 'static> Pallet { pub fn do_create_swap( - sender: T::AccountId, + caller: T::AccountId, collection_id: T::CollectionId, item_id: T::ItemId, desired_collection_id: T::CollectionId, @@ -32,7 +32,7 @@ impl, I: 'static> Pallet { maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; - ensure!(item.owner == sender, Error::::NoPermission); + ensure!(item.owner == caller, Error::::NoPermission); match maybe_desired_item_id { Some(desired_item_id) => { @@ -73,7 +73,7 @@ impl, I: 'static> Pallet { } pub fn do_cancel_swap( - sender: T::AccountId, + caller: T::AccountId, collection_id: T::CollectionId, item_id: T::ItemId, ) -> DispatchResult { @@ -89,7 +89,7 @@ impl, I: 'static> Pallet { }; if !is_past_deadline { - ensure!(item.owner == sender, Error::::NoPermission); + ensure!(item.owner == caller, Error::::NoPermission); } PendingSwapOf::::remove(&collection_id, &item_id); @@ -107,7 +107,7 @@ impl, I: 'static> Pallet { } pub fn do_claim_swap( - sender: T::AccountId, + caller: T::AccountId, send_collection_id: T::CollectionId, send_item_id: T::ItemId, receive_collection_id: T::CollectionId, @@ -121,7 +121,7 @@ impl, I: 'static> Pallet { let swap = PendingSwapOf::::get(&receive_collection_id, &receive_item_id) .ok_or(Error::::UnknownSwap)?; - ensure!(send_item.owner == sender, Error::::NoPermission); + ensure!(send_item.owner == caller, Error::::NoPermission); ensure!(swap.desired_collection == send_collection_id, Error::::UnknownSwap); ensure!(swap.price == maybe_receive_amount, Error::::UnknownSwap); @@ -149,12 +149,12 @@ impl, I: 'static> Pallet { )?; Self::deposit_event(Event::SwapClaimed { - send_collection: send_collection_id, - send_item: send_item_id, - send_item_owner: send_item.owner, - receive_collection: receive_collection_id, - receive_item: receive_item_id, - receive_item_owner: receive_item.owner, + sent_collection: send_collection_id, + sent_item: send_item_id, + sent_item_owner: send_item.owner, + received_collection: receive_collection_id, + received_item: receive_item_id, + received_item_owner: receive_item.owner, price: swap.price, deadline: swap.deadline, }); diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index 5de8095ccdf7f..2594a037a4e94 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -422,12 +422,12 @@ pub mod pallet { }, /// The swap has been claimed. SwapClaimed { - send_collection: T::CollectionId, - send_item: T::ItemId, - send_item_owner: T::AccountId, - receive_collection: T::CollectionId, - receive_item: T::ItemId, - receive_item_owner: T::AccountId, + sent_collection: T::CollectionId, + sent_item: T::ItemId, + sent_item_owner: T::AccountId, + received_collection: T::CollectionId, + received_item: T::ItemId, + received_item_owner: T::AccountId, price: Option>, deadline: Option<::BlockNumber>, }, diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index a4a827c9613b9..b8498bf3a5f53 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -1191,12 +1191,12 @@ fn claim_swap_should_work() { // validate the event assert!(events().contains(&Event::::SwapClaimed { - send_collection: collection_id, - send_item: item_2, - send_item_owner: user_2, - receive_collection: collection_id, - receive_item: item_1, - receive_item_owner: user_1, + sent_collection: collection_id, + sent_item: item_2, + sent_item_owner: user_2, + received_collection: collection_id, + received_item: item_1, + received_item_owner: user_1, price: Some(price), deadline: Some(deadline), })); From 7c1581426e2bdcf17214a0108fc8483126fbf3a0 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> Date: Fri, 30 Sep 2022 13:15:57 +0300 Subject: [PATCH 11/30] Update frame/nfts/src/features/atomic_swap.rs Co-authored-by: Squirrel --- frame/nfts/src/features/atomic_swap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index 23b1861ece3c2..7b7aaded18c59 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -131,7 +131,7 @@ impl, I: 'static> Pallet { if let Some(deadline) = swap.deadline { let now = frame_system::Pallet::::block_number(); - ensure!(deadline >= now, Error::::DeadlineExpired); + ensure!(now <= deadline, Error::::DeadlineExpired); } if let Some(amount) = swap.price { From 6232aa48b4e5dced5aa6046fd8e97c8f648cd5b0 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 13:22:37 +0300 Subject: [PATCH 12/30] Rename fields --- frame/nfts/src/benchmarking.rs | 8 +++---- frame/nfts/src/features/atomic_swap.rs | 30 ++++++++++++++------------ frame/nfts/src/lib.rs | 22 +++++++++---------- frame/nfts/src/tests.rs | 8 +++---- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index eb44e99bc9b9d..008a67692e680 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -467,8 +467,8 @@ benchmarks_instance_pallet! { }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price), Some(duration)) verify { assert_last_event::(Event::SwapCreated { - collection, - item: item1, + offered_collection: collection, + offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price), @@ -487,8 +487,8 @@ benchmarks_instance_pallet! { }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { assert_last_event::(Event::SwapCancelled { - collection, - item: item1, + offered_collection: collection, + offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price), diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index 7b7aaded18c59..dad960ebc1eb7 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -24,14 +24,15 @@ use frame_support::{ impl, I: 'static> Pallet { pub fn do_create_swap( caller: T::AccountId, - collection_id: T::CollectionId, - item_id: T::ItemId, + offered_collection_id: T::CollectionId, + offered_item_id: T::ItemId, desired_collection_id: T::CollectionId, maybe_desired_item_id: Option, maybe_price: Option>, maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { - let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; + let item = Item::::get(&offered_collection_id, &offered_item_id) + .ok_or(Error::::UnknownItem)?; ensure!(item.owner == caller, Error::::NoPermission); match maybe_desired_item_id { @@ -50,8 +51,8 @@ impl, I: 'static> Pallet { let deadline = maybe_duration.map(|d| d.saturating_add(now)); PendingSwapOf::::insert( - &collection_id, - &item_id, + &offered_collection_id, + &offered_item_id, PendingSwap { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, @@ -61,8 +62,8 @@ impl, I: 'static> Pallet { ); Self::deposit_event(Event::SwapCreated { - collection: collection_id, - item: item_id, + offered_collection: offered_collection_id, + offered_item: offered_item_id, desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price, @@ -74,11 +75,12 @@ impl, I: 'static> Pallet { pub fn do_cancel_swap( caller: T::AccountId, - collection_id: T::CollectionId, - item_id: T::ItemId, + offered_collection_id: T::CollectionId, + offered_item_id: T::ItemId, ) -> DispatchResult { - let item = Item::::get(&collection_id, &item_id).ok_or(Error::::UnknownItem)?; - let swap = PendingSwapOf::::get(&collection_id, &item_id) + let item = Item::::get(&offered_collection_id, &offered_item_id) + .ok_or(Error::::UnknownItem)?; + let swap = PendingSwapOf::::get(&offered_collection_id, &offered_item_id) .ok_or(Error::::UnknownSwap)?; let is_past_deadline = if let Some(deadline) = swap.deadline { @@ -92,11 +94,11 @@ impl, I: 'static> Pallet { ensure!(item.owner == caller, Error::::NoPermission); } - PendingSwapOf::::remove(&collection_id, &item_id); + PendingSwapOf::::remove(&offered_collection_id, &offered_item_id); Self::deposit_event(Event::SwapCancelled { - collection: collection_id, - item: item_id, + offered_collection: offered_collection_id, + offered_item: offered_item_id, desired_collection: swap.desired_collection, desired_item: swap.desired_item, price: swap.price, diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index 2594a037a4e94..9128a52a9bb0f 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -404,8 +404,8 @@ pub mod pallet { }, /// An `item` swap intent was created. SwapCreated { - collection: T::CollectionId, - item: T::ItemId, + offered_collection: T::CollectionId, + offered_item: T::ItemId, desired_collection: T::CollectionId, desired_item: Option, price: Option>, @@ -413,8 +413,8 @@ pub mod pallet { }, /// The swap was cancelled. SwapCancelled { - collection: T::CollectionId, - item: T::ItemId, + offered_collection: T::CollectionId, + offered_item: T::ItemId, desired_collection: T::CollectionId, desired_item: Option, price: Option>, @@ -1644,8 +1644,8 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::create_swap())] pub fn create_swap( origin: OriginFor, - collection: T::CollectionId, - item: T::ItemId, + offered_collection: T::CollectionId, + offered_item: T::ItemId, desired_collection: T::CollectionId, maybe_desired_item: Option, maybe_price: Option>, @@ -1654,8 +1654,8 @@ pub mod pallet { let origin = ensure_signed(origin)?; Self::do_create_swap( origin, - collection, - item, + offered_collection, + offered_item, desired_collection, maybe_desired_item, maybe_price, @@ -1674,11 +1674,11 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::cancel_swap())] pub fn cancel_swap( origin: OriginFor, - collection: T::CollectionId, - item: T::ItemId, + offered_collection: T::CollectionId, + offered_item: T::ItemId, ) -> DispatchResult { let origin = ensure_signed(origin)?; - Self::do_cancel_swap(origin, collection, item) + Self::do_cancel_swap(origin, offered_collection, offered_item) } /// Claim an atomic swap. diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index b8498bf3a5f53..7fd03bf4c8a6d 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -1015,8 +1015,8 @@ fn create_cancel_swap_should_work() { assert_eq!(swap.deadline, Some(expect_deadline)); assert!(events().contains(&Event::::SwapCreated { - collection: collection_id, - item: item_1, + offered_collection: collection_id, + offered_item: item_1, desired_collection: collection_id, desired_item: Some(item_2), price: Some(price), @@ -1026,8 +1026,8 @@ fn create_cancel_swap_should_work() { // validate we can cancel the swap assert_ok!(Nfts::cancel_swap(Origin::signed(user_id), collection_id, item_1)); assert!(events().contains(&Event::::SwapCancelled { - collection: collection_id, - item: item_1, + offered_collection: collection_id, + offered_item: item_1, desired_collection: collection_id, desired_item: Some(item_2), price: Some(price), From 9acfb5c4091271ef8482090b000203369bfbd82a Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 13:34:30 +0300 Subject: [PATCH 13/30] Optimisation --- frame/nfts/src/features/atomic_swap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index dad960ebc1eb7..021c62a41265d 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -78,8 +78,6 @@ impl, I: 'static> Pallet { offered_collection_id: T::CollectionId, offered_item_id: T::ItemId, ) -> DispatchResult { - let item = Item::::get(&offered_collection_id, &offered_item_id) - .ok_or(Error::::UnknownItem)?; let swap = PendingSwapOf::::get(&offered_collection_id, &offered_item_id) .ok_or(Error::::UnknownSwap)?; @@ -91,6 +89,8 @@ impl, I: 'static> Pallet { }; if !is_past_deadline { + let item = Item::::get(&offered_collection_id, &offered_item_id) + .ok_or(Error::::UnknownItem)?; ensure!(item.owner == caller, Error::::NoPermission); } From 8d6cbda4654f186adef1e2cdac87d324e789dac2 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 13:40:24 +0300 Subject: [PATCH 14/30] Add a comment --- frame/nfts/src/features/atomic_swap.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index 021c62a41265d..516e5d3a4b9c3 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -140,6 +140,7 @@ impl, I: 'static> Pallet { T::Currency::transfer(&receive_item.owner, &send_item.owner, amount, KeepAlive)?; } + // This also removes the swap. Self::do_transfer(send_collection_id, send_item_id, receive_item.owner.clone(), |_, _| { Ok(()) })?; From 2ce1ea371080eb17c134e64dea70bc0f843a7181 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 14:10:16 +0300 Subject: [PATCH 15/30] deadline -> maybe_deadline --- frame/nfts/src/features/atomic_swap.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index 516e5d3a4b9c3..2255d3718e985 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -48,7 +48,7 @@ impl, I: 'static> Pallet { }; let now = frame_system::Pallet::::block_number(); - let deadline = maybe_duration.map(|d| d.saturating_add(now)); + let maybe_deadline = maybe_duration.map(|d| d.saturating_add(now)); PendingSwapOf::::insert( &offered_collection_id, @@ -57,7 +57,7 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price, - deadline, + deadline: maybe_deadline, }, ); @@ -67,7 +67,7 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price, - deadline, + deadline: maybe_deadline, }); Ok(()) From 99d1eb5d2957b6f854ae5a944a55420fd12db7fe Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 14:14:41 +0300 Subject: [PATCH 16/30] Add docs --- frame/nfts/src/types.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index ea50460240ec8..3db049b903c17 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -149,8 +149,12 @@ pub struct ItemTip { #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] pub struct PendingSwap { + /// A collection of the item user wants to receive. pub(super) desired_collection: CollectionId, + /// An item user wants to receive. pub(super) desired_item: Option, + /// A price the user is willing to pay for the desired `item`. pub(super) price: Option, + /// An optional deadline for the swap. pub(super) deadline: Option, } From b404705ccc476fa0af7ab106c89781e777b8b38c Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 14:19:50 +0300 Subject: [PATCH 17/30] Change comments --- frame/nfts/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index e39a365229b5e..009af70a1fe21 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -1724,7 +1724,8 @@ pub mod pallet { /// Cancel an atomic swap. /// - /// Origin must be Signed and must be an owner of the `item` if the deadline hasn't expired. + /// Origin must be Signed. + /// Origin must be an owner of the `item` if the deadline hasn't expired. /// /// - `collection`: The collection of the item. /// - `item`: The item an owner wants to give. @@ -1741,6 +1742,7 @@ pub mod pallet { } /// Claim an atomic swap. + /// This method executes a pending swap, that was created by a counterpart before. /// /// Origin must be Signed and must be an owner of the `item`. /// From cccebd3f6ed7bb886b83419dff0e98feab962517 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 30 Sep 2022 17:00:16 +0300 Subject: [PATCH 18/30] Add price direction field --- frame/nfts/src/benchmarking.rs | 25 +++++++++++--- frame/nfts/src/features/atomic_swap.rs | 31 ++++++++++++++--- frame/nfts/src/lib.rs | 19 +++++++++-- frame/nfts/src/tests.rs | 47 +++++++++++++++++++++++--- frame/nfts/src/types.rs | 10 +++++- 5 files changed, 115 insertions(+), 17 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index 149e81be27b74..85d9a78ec2dc5 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -481,8 +481,9 @@ benchmarks_instance_pallet! { let (item1, ..) = mint_item::(0); let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(100u32); + let price_direction = PriceDirection::Receive; let duration = T::BlockNumber::max_value(); - }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price), Some(duration)) + }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price), Some(price_direction.clone()), Some(duration)) verify { assert_last_event::(Event::SwapCreated { offered_collection: collection, @@ -490,6 +491,7 @@ benchmarks_instance_pallet! { desired_collection: collection, desired_item: Some(item2), price: Some(price), + price_direction: Some(price_direction), deadline: Some(duration), }.into()); } @@ -499,9 +501,10 @@ benchmarks_instance_pallet! { let (item1, ..) = mint_item::(0); let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(100u32); - let duration = T::BlockNumber::max_value(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price), Some(duration))?; + let duration = T::BlockNumber::max_value(); + let price_direction = PriceDirection::Receive; + Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price), Some(price_direction.clone()), Some(duration))?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { assert_last_event::(Event::SwapCancelled { @@ -510,6 +513,7 @@ benchmarks_instance_pallet! { desired_collection: collection, desired_item: Some(item2), price: Some(price), + price_direction: Some(price_direction), deadline: Some(duration), }.into()); } @@ -519,13 +523,23 @@ benchmarks_instance_pallet! { let (item1, ..) = mint_item::(0); let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(0u32); + let price_direction = PriceDirection::Receive; let duration = T::BlockNumber::max_value(); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; - Nfts::::create_swap(origin.clone().into(), collection, item1, collection, Some(item2), Some(price), Some(duration))?; - }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone())) + Nfts::::create_swap( + origin.clone().into(), + collection, + item1, + collection, + Some(item2), + Some(price), + Some(price_direction.clone()), + Some(duration), + )?; + }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone()), Some(price_direction.clone())) verify { assert_last_event::(Event::SwapClaimed { sent_collection: collection, @@ -535,6 +549,7 @@ benchmarks_instance_pallet! { received_item: item1, received_item_owner: caller, price: Some(price), + price_direction: Some(price_direction), deadline: Some(duration), }.into()); } diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index 2255d3718e985..a9d72ea77bb50 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -29,6 +29,7 @@ impl, I: 'static> Pallet { desired_collection_id: T::CollectionId, maybe_desired_item_id: Option, maybe_price: Option>, + maybe_price_direction: Option, maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { let item = Item::::get(&offered_collection_id, &offered_item_id) @@ -47,6 +48,13 @@ impl, I: 'static> Pallet { }, }; + if maybe_price.is_some() && maybe_price_direction.is_none() { + return Err(Error::::PriceDirectionNotSet.into()) + } + if maybe_price.is_none() && maybe_price_direction.is_some() { + return Err(Error::::PriceDirectionCannotBeSet.into()) + } + let now = frame_system::Pallet::::block_number(); let maybe_deadline = maybe_duration.map(|d| d.saturating_add(now)); @@ -57,6 +65,7 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price, + price_direction: maybe_price_direction.clone(), deadline: maybe_deadline, }, ); @@ -67,6 +76,7 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price, + price_direction: maybe_price_direction, deadline: maybe_deadline, }); @@ -102,6 +112,7 @@ impl, I: 'static> Pallet { desired_collection: swap.desired_collection, desired_item: swap.desired_item, price: swap.price, + price_direction: swap.price_direction, deadline: swap.deadline, }); @@ -114,7 +125,8 @@ impl, I: 'static> Pallet { send_item_id: T::ItemId, receive_collection_id: T::CollectionId, receive_item_id: T::ItemId, - maybe_receive_amount: Option>, + maybe_price: Option>, + maybe_price_direction: Option, ) -> DispatchResult { let send_item = Item::::get(&send_collection_id, &send_item_id) .ok_or(Error::::UnknownItem)?; @@ -124,8 +136,12 @@ impl, I: 'static> Pallet { .ok_or(Error::::UnknownSwap)?; ensure!(send_item.owner == caller, Error::::NoPermission); - ensure!(swap.desired_collection == send_collection_id, Error::::UnknownSwap); - ensure!(swap.price == maybe_receive_amount, Error::::UnknownSwap); + ensure!( + swap.desired_collection == send_collection_id && + swap.price == maybe_price && + swap.price_direction == maybe_price_direction, + Error::::UnknownSwap + ); if let Some(desired_item) = swap.desired_item { ensure!(desired_item == send_item_id, Error::::UnknownSwap); @@ -137,7 +153,13 @@ impl, I: 'static> Pallet { } if let Some(amount) = swap.price { - T::Currency::transfer(&receive_item.owner, &send_item.owner, amount, KeepAlive)?; + match swap.price_direction { + Some(PriceDirection::Send) => + T::Currency::transfer(&receive_item.owner, &send_item.owner, amount, KeepAlive)?, + Some(PriceDirection::Receive) => + T::Currency::transfer(&send_item.owner, &receive_item.owner, amount, KeepAlive)?, + _ => {}, + }; } // This also removes the swap. @@ -159,6 +181,7 @@ impl, I: 'static> Pallet { received_item: receive_item_id, received_item_owner: receive_item.owner, price: swap.price, + price_direction: swap.price_direction, deadline: swap.deadline, }); diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index 009af70a1fe21..cc783911b9163 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -452,6 +452,7 @@ pub mod pallet { desired_collection: T::CollectionId, desired_item: Option, price: Option>, + price_direction: Option, deadline: Option<::BlockNumber>, }, /// The swap was cancelled. @@ -461,6 +462,7 @@ pub mod pallet { desired_collection: T::CollectionId, desired_item: Option, price: Option>, + price_direction: Option, deadline: Option<::BlockNumber>, }, /// The swap has been claimed. @@ -472,6 +474,7 @@ pub mod pallet { received_item: T::ItemId, received_item_owner: T::AccountId, price: Option>, + price_direction: Option, deadline: Option<::BlockNumber>, }, } @@ -522,6 +525,10 @@ pub mod pallet { ReachedApprovalLimit, /// The deadline has already expired. DeadlineExpired, + /// Price direction should be set. + PriceDirectionNotSet, + /// Price direction can't be set. + PriceDirectionCannotBeSet, } impl, I: 'static> Pallet { @@ -1695,7 +1702,9 @@ pub mod pallet { /// - `item`: The item an owner wants to give. /// - `desired_collection`: The collection of the desired item. /// - `desired_item`: The desired item an owner wants to receive. - /// - `maybe_price`: The price an owner is willing to pay for the desired `item`. + /// - `maybe_price`: The price an owner is willing to pay or receive for the desired `item`. + /// - `maybe_price_direction`: Specifies whether a user is willing to pay or receive a + /// `price`. Should be set when the `maybe_price` is not None. /// - `maybe_duration`: Optional deadline for the swap. Specified by providing the /// number of blocks after which the swap will expire. /// @@ -1708,6 +1717,7 @@ pub mod pallet { desired_collection: T::CollectionId, maybe_desired_item: Option, maybe_price: Option>, + maybe_price_direction: Option, maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { let origin = ensure_signed(origin)?; @@ -1718,6 +1728,7 @@ pub mod pallet { desired_collection, maybe_desired_item, maybe_price, + maybe_price_direction, maybe_duration, ) } @@ -1760,7 +1771,8 @@ pub mod pallet { send_item: T::ItemId, receive_collection: T::CollectionId, receive_item: T::ItemId, - maybe_receive_amount: Option>, + maybe_price: Option>, + maybe_price_direction: Option, ) -> DispatchResult { let origin = ensure_signed(origin)?; Self::do_claim_swap( @@ -1769,7 +1781,8 @@ pub mod pallet { send_item, receive_collection, receive_item, - maybe_receive_amount, + maybe_price, + maybe_price_direction, ) } } diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 0c6e771f98467..99d8d542eb452 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -1117,6 +1117,7 @@ fn create_cancel_swap_should_work() { let price = 1; let duration = 2; let expect_deadline = 3; + let price_direction = PriceDirection::Receive; assert_ok!(Nfts::force_create(RuntimeOrigin::root(), user_id, true)); @@ -1132,6 +1133,7 @@ fn create_cancel_swap_should_work() { collection_id, Some(item_2 + 1), Some(price), + Some(price_direction.clone()), Some(duration), ), Error::::UnknownItem @@ -1144,6 +1146,7 @@ fn create_cancel_swap_should_work() { collection_id + 1, None, Some(price), + Some(price_direction.clone()), Some(duration), ), Error::::UnknownCollection @@ -1156,6 +1159,7 @@ fn create_cancel_swap_should_work() { collection_id, Some(item_2), Some(price), + Some(price_direction.clone()), Some(duration), )); @@ -1163,6 +1167,7 @@ fn create_cancel_swap_should_work() { assert_eq!(swap.desired_collection, collection_id); assert_eq!(swap.desired_item, Some(item_2)); assert_eq!(swap.price, Some(price)); + assert_eq!(swap.price_direction, Some(price_direction.clone())); assert_eq!(swap.deadline, Some(expect_deadline)); assert!(events().contains(&Event::::SwapCreated { @@ -1171,6 +1176,7 @@ fn create_cancel_swap_should_work() { desired_collection: collection_id, desired_item: Some(item_2), price: Some(price), + price_direction: Some(price_direction.clone()), deadline: Some(expect_deadline), })); @@ -1182,6 +1188,7 @@ fn create_cancel_swap_should_work() { desired_collection: collection_id, desired_item: Some(item_2), price: Some(price), + price_direction: Some(price_direction.clone()), deadline: Some(expect_deadline), })); assert!(!PendingSwapOf::::contains_key(collection_id, item_1)); @@ -1194,6 +1201,7 @@ fn create_cancel_swap_should_work() { collection_id, Some(item_2), Some(price), + Some(price_direction.clone()), Some(duration), )); assert_noop!( @@ -1211,6 +1219,7 @@ fn create_cancel_swap_should_work() { collection_id, None, Some(price), + Some(price_direction), Some(duration), )); @@ -1235,6 +1244,7 @@ fn claim_swap_should_work() { let duration = 2; let initial_balance = 1000; let deadline = 1 + duration; + let price_direction = PriceDirection::Receive; Balances::make_free_balance_be(&user_1, initial_balance); Balances::make_free_balance_be(&user_2, initial_balance); @@ -1254,6 +1264,7 @@ fn claim_swap_should_work() { collection_id, Some(item_2), Some(price), + Some(price_direction.clone()), Some(duration), )); @@ -1267,6 +1278,7 @@ fn claim_swap_should_work() { collection_id, item_1, Some(price), + Some(price_direction.clone()), ), Error::::DeadlineExpired ); @@ -1281,6 +1293,7 @@ fn claim_swap_should_work() { collection_id, item_4, // no swap was created for that asset Some(price), + Some(price_direction.clone()), ), Error::::UnknownSwap ); @@ -1292,6 +1305,7 @@ fn claim_swap_should_work() { collection_id, item_1, Some(price), + Some(price_direction.clone()), ), Error::::NoPermission ); @@ -1303,6 +1317,7 @@ fn claim_swap_should_work() { collection_id, item_1, Some(price), + Some(price_direction.clone()), ), Error::::UnknownSwap ); @@ -1313,7 +1328,20 @@ fn claim_swap_should_work() { item_2, collection_id, item_1, - Some(price + 1) // wrong price + Some(price + 1), // wrong price + Some(price_direction.clone()), + ), + Error::::UnknownSwap + ); + assert_noop!( + Nfts::claim_swap( + RuntimeOrigin::signed(user_2), + collection_id, + item_2, + collection_id, + item_1, + Some(price), + Some(PriceDirection::Send), // wrong direction ), Error::::UnknownSwap ); @@ -1325,6 +1353,7 @@ fn claim_swap_should_work() { collection_id, item_1, Some(price), + Some(price_direction.clone()), )); // validate the new owner @@ -1334,8 +1363,8 @@ fn claim_swap_should_work() { assert_eq!(item.owner, user_1); // validate the balances - assert_eq!(Balances::total_balance(&user_1), initial_balance - price); - assert_eq!(Balances::total_balance(&user_2), initial_balance + price); + assert_eq!(Balances::total_balance(&user_1), initial_balance + price); + assert_eq!(Balances::total_balance(&user_2), initial_balance - price); // ensure we reset the swap assert!(!PendingSwapOf::::contains_key(collection_id, item_1)); @@ -1349,10 +1378,15 @@ fn claim_swap_should_work() { received_item: item_1, received_item_owner: user_1, price: Some(price), + price_direction: Some(price_direction.clone()), deadline: Some(deadline), })); - // validate the optional desired_item param + // validate the optional desired_item param and another price direction + let price_direction = PriceDirection::Send; + Balances::make_free_balance_be(&user_1, initial_balance); + Balances::make_free_balance_be(&user_2, initial_balance); + assert_ok!(Nfts::create_swap( RuntimeOrigin::signed(user_1), collection_id, @@ -1360,6 +1394,7 @@ fn claim_swap_should_work() { collection_id, None, Some(price), + Some(price_direction.clone()), Some(duration), )); assert_ok!(Nfts::claim_swap( @@ -1369,10 +1404,14 @@ fn claim_swap_should_work() { collection_id, item_4, Some(price), + Some(price_direction), )); let item = Item::::get(collection_id, item_1).unwrap(); assert_eq!(item.owner, user_1); let item = Item::::get(collection_id, item_4).unwrap(); assert_eq!(item.owner, user_2); + + assert_eq!(Balances::total_balance(&user_1), initial_balance - price); + assert_eq!(Balances::total_balance(&user_2), initial_balance + price); }); } diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index 3db049b903c17..faedfeac99f48 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -40,6 +40,12 @@ pub(super) type ItemTipOf = ItemTip< BalanceOf, >; +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub enum PriceDirection { + Send, + Receive, +} + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct CollectionDetails { /// Can change `owner`, `issuer`, `freezer` and `admin` accounts. @@ -153,8 +159,10 @@ pub struct PendingSwap { pub(super) desired_collection: CollectionId, /// An item user wants to receive. pub(super) desired_item: Option, - /// A price the user is willing to pay for the desired `item`. + /// A price for the desired `item`. pub(super) price: Option, + /// Specifies whether a user is willing to pay or receive a `price`. + pub(super) price_direction: Option, /// An optional deadline for the swap. pub(super) deadline: Option, } From 2202f0d92b73947f16457a5b3e24541432745ecb Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Fri, 30 Sep 2022 14:53:48 +0000 Subject: [PATCH 19/30] ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts --- frame/nfts/src/weights.rs | 182 +++++++++++++++++++------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/frame/nfts/src/weights.rs b/frame/nfts/src/weights.rs index 5882a9cdbae0e..9d62db0f8d85d 100644 --- a/frame/nfts/src/weights.rs +++ b/frame/nfts/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_nfts //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-09-24, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2022-09-30, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -86,7 +86,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn create() -> Weight { - Weight::from_ref_time(37_627_000 as u64) + Weight::from_ref_time(38_062_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(3 as u64)) } @@ -94,7 +94,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_create() -> Weight { - Weight::from_ref_time(25_748_000 as u64) + Weight::from_ref_time(25_917_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(3 as u64)) } @@ -110,13 +110,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `m` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(n: u32, m: u32, a: u32, ) -> Weight { - Weight::from_ref_time(2_449_817_000 as u64) - // Standard Error: 27_329 - .saturating_add(Weight::from_ref_time(8_423_500 as u64).saturating_mul(n as u64)) - // Standard Error: 27_329 - .saturating_add(Weight::from_ref_time(315_839 as u64).saturating_mul(m as u64)) - // Standard Error: 27_329 - .saturating_add(Weight::from_ref_time(217_497 as u64).saturating_mul(a as u64)) + Weight::from_ref_time(2_432_555_000 as u64) + // Standard Error: 28_964 + .saturating_add(Weight::from_ref_time(8_474_465 as u64).saturating_mul(n as u64)) + // Standard Error: 28_964 + .saturating_add(Weight::from_ref_time(333_758 as u64).saturating_mul(m as u64)) + // Standard Error: 28_964 + .saturating_add(Weight::from_ref_time(222_052 as u64).saturating_mul(a as u64)) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().reads((1 as u64).saturating_mul(n as u64))) .saturating_add(T::DbWeight::get().writes(2004 as u64)) @@ -127,7 +127,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts CollectionMaxSupply (r:1 w:0) // Storage: Nfts Account (r:0 w:1) fn mint() -> Weight { - Weight::from_ref_time(43_014_000 as u64) + Weight::from_ref_time(43_755_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(3 as u64)) } @@ -137,7 +137,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts ItemPriceOf (r:0 w:1) // Storage: Nfts PendingSwapOf (r:0 w:1) fn burn() -> Weight { - Weight::from_ref_time(44_421_000 as u64) + Weight::from_ref_time(46_768_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(5 as u64)) } @@ -147,7 +147,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts ItemPriceOf (r:0 w:1) // Storage: Nfts PendingSwapOf (r:0 w:1) fn transfer() -> Weight { - Weight::from_ref_time(34_315_000 as u64) + Weight::from_ref_time(36_282_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(5 as u64)) } @@ -155,9 +155,9 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Asset (r:102 w:102) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { - Weight::from_ref_time(22_836_000 as u64) - // Standard Error: 9_131 - .saturating_add(Weight::from_ref_time(10_894_264 as u64).saturating_mul(i as u64)) + Weight::from_ref_time(23_359_000 as u64) + // Standard Error: 9_645 + .saturating_add(Weight::from_ref_time(10_822_144 as u64).saturating_mul(i as u64)) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().reads((1 as u64).saturating_mul(i as u64))) .saturating_add(T::DbWeight::get().writes(1 as u64)) @@ -166,26 +166,26 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn freeze() -> Weight { - Weight::from_ref_time(27_329_000 as u64) + Weight::from_ref_time(27_805_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn thaw() -> Weight { - Weight::from_ref_time(27_842_000 as u64) + Weight::from_ref_time(27_712_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn freeze_collection() -> Weight { - Weight::from_ref_time(23_129_000 as u64) + Weight::from_ref_time(23_068_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn thaw_collection() -> Weight { - Weight::from_ref_time(22_584_000 as u64) + Weight::from_ref_time(23_200_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } @@ -193,20 +193,20 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:2) fn transfer_ownership() -> Weight { - Weight::from_ref_time(31_684_000 as u64) + Weight::from_ref_time(31_800_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(4 as u64)) } // Storage: Nfts Class (r:1 w:1) fn set_team() -> Weight { - Weight::from_ref_time(23_143_000 as u64) + Weight::from_ref_time(23_959_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_item_status() -> Weight { - Weight::from_ref_time(25_684_000 as u64) + Weight::from_ref_time(26_334_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } @@ -214,7 +214,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn set_attribute() -> Weight { - Weight::from_ref_time(50_159_000 as u64) + Weight::from_ref_time(50_978_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } @@ -222,76 +222,76 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn clear_attribute() -> Weight { - Weight::from_ref_time(47_824_000 as u64) + Weight::from_ref_time(49_555_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn set_metadata() -> Weight { - Weight::from_ref_time(39_968_000 as u64) + Weight::from_ref_time(41_099_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn clear_metadata() -> Weight { - Weight::from_ref_time(42_182_000 as u64) + Weight::from_ref_time(42_893_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn set_collection_metadata() -> Weight { - Weight::from_ref_time(39_330_000 as u64) + Weight::from_ref_time(39_785_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn clear_collection_metadata() -> Weight { - Weight::from_ref_time(38_351_000 as u64) + Weight::from_ref_time(39_764_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn approve_transfer() -> Weight { - Weight::from_ref_time(29_530_000 as u64) + Weight::from_ref_time(29_577_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn cancel_approval() -> Weight { - Weight::from_ref_time(29_417_000 as u64) + Weight::from_ref_time(29_696_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn clear_all_transfer_approvals() -> Weight { - Weight::from_ref_time(28_482_000 as u64) + Weight::from_ref_time(28_692_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts OwnershipAcceptance (r:1 w:1) fn set_accept_ownership() -> Weight { - Weight::from_ref_time(25_851_000 as u64) + Weight::from_ref_time(26_345_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts CollectionMaxSupply (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn set_collection_max_supply() -> Weight { - Weight::from_ref_time(24_836_000 as u64) + Weight::from_ref_time(24_826_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:0) // Storage: Nfts ItemPriceOf (r:0 w:1) fn set_price() -> Weight { - Weight::from_ref_time(25_665_000 as u64) + Weight::from_ref_time(26_376_000 as u64) .saturating_add(T::DbWeight::get().reads(1 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } @@ -301,21 +301,27 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Account (r:0 w:2) // Storage: Nfts PendingSwapOf (r:0 w:1) fn buy_item() -> Weight { - Weight::from_ref_time(47_502_000 as u64) + Weight::from_ref_time(49_140_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(5 as u64)) } + /// The range of component `n` is `[0, 10]`. + fn pay_tips(n: u32, ) -> Weight { + Weight::from_ref_time(5_477_000 as u64) + // Standard Error: 33_188 + .saturating_add(Weight::from_ref_time(4_285_339 as u64).saturating_mul(n as u64)) + } // Storage: Nfts Asset (r:2 w:0) // Storage: Nfts PendingSwapOf (r:0 w:1) fn create_swap() -> Weight { - Weight::from_ref_time(29_275_000 as u64) + Weight::from_ref_time(30_330_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } - // Storage: Nfts Asset (r:1 w:0) // Storage: Nfts PendingSwapOf (r:1 w:1) + // Storage: Nfts Asset (r:1 w:0) fn cancel_swap() -> Weight { - Weight::from_ref_time(29_062_000 as u64) + Weight::from_ref_time(30_516_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } @@ -325,16 +331,10 @@ impl WeightInfo for SubstrateWeight { // Storage: Nfts Account (r:0 w:4) // Storage: Nfts ItemPriceOf (r:0 w:2) fn claim_swap() -> Weight { - Weight::from_ref_time(66_766_000 as u64) + Weight::from_ref_time(66_191_000 as u64) .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(10 as u64)) } - /// The range of component `n` is `[0, 10]`. - fn pay_tips(n: u32, ) -> Weight { - Weight::from_ref_time(5_417_000 as u64) - // Standard Error: 32_526 - .saturating_add(Weight::from_ref_time(4_304_363 as u64).saturating_mul(n as u64)) - } } // For backwards compatibility and tests @@ -343,7 +343,7 @@ impl WeightInfo for () { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn create() -> Weight { - Weight::from_ref_time(37_627_000 as u64) + Weight::from_ref_time(38_062_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(3 as u64)) } @@ -351,7 +351,7 @@ impl WeightInfo for () { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_create() -> Weight { - Weight::from_ref_time(25_748_000 as u64) + Weight::from_ref_time(25_917_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(3 as u64)) } @@ -367,13 +367,13 @@ impl WeightInfo for () { /// The range of component `m` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(n: u32, m: u32, a: u32, ) -> Weight { - Weight::from_ref_time(2_449_817_000 as u64) - // Standard Error: 27_329 - .saturating_add(Weight::from_ref_time(8_423_500 as u64).saturating_mul(n as u64)) - // Standard Error: 27_329 - .saturating_add(Weight::from_ref_time(315_839 as u64).saturating_mul(m as u64)) - // Standard Error: 27_329 - .saturating_add(Weight::from_ref_time(217_497 as u64).saturating_mul(a as u64)) + Weight::from_ref_time(2_432_555_000 as u64) + // Standard Error: 28_964 + .saturating_add(Weight::from_ref_time(8_474_465 as u64).saturating_mul(n as u64)) + // Standard Error: 28_964 + .saturating_add(Weight::from_ref_time(333_758 as u64).saturating_mul(m as u64)) + // Standard Error: 28_964 + .saturating_add(Weight::from_ref_time(222_052 as u64).saturating_mul(a as u64)) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().reads((1 as u64).saturating_mul(n as u64))) .saturating_add(RocksDbWeight::get().writes(2004 as u64)) @@ -384,7 +384,7 @@ impl WeightInfo for () { // Storage: Nfts CollectionMaxSupply (r:1 w:0) // Storage: Nfts Account (r:0 w:1) fn mint() -> Weight { - Weight::from_ref_time(43_014_000 as u64) + Weight::from_ref_time(43_755_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(3 as u64)) } @@ -394,7 +394,7 @@ impl WeightInfo for () { // Storage: Nfts ItemPriceOf (r:0 w:1) // Storage: Nfts PendingSwapOf (r:0 w:1) fn burn() -> Weight { - Weight::from_ref_time(44_421_000 as u64) + Weight::from_ref_time(46_768_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(5 as u64)) } @@ -404,7 +404,7 @@ impl WeightInfo for () { // Storage: Nfts ItemPriceOf (r:0 w:1) // Storage: Nfts PendingSwapOf (r:0 w:1) fn transfer() -> Weight { - Weight::from_ref_time(34_315_000 as u64) + Weight::from_ref_time(36_282_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(5 as u64)) } @@ -412,9 +412,9 @@ impl WeightInfo for () { // Storage: Nfts Asset (r:102 w:102) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { - Weight::from_ref_time(22_836_000 as u64) - // Standard Error: 9_131 - .saturating_add(Weight::from_ref_time(10_894_264 as u64).saturating_mul(i as u64)) + Weight::from_ref_time(23_359_000 as u64) + // Standard Error: 9_645 + .saturating_add(Weight::from_ref_time(10_822_144 as u64).saturating_mul(i as u64)) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().reads((1 as u64).saturating_mul(i as u64))) .saturating_add(RocksDbWeight::get().writes(1 as u64)) @@ -423,26 +423,26 @@ impl WeightInfo for () { // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn freeze() -> Weight { - Weight::from_ref_time(27_329_000 as u64) + Weight::from_ref_time(27_805_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn thaw() -> Weight { - Weight::from_ref_time(27_842_000 as u64) + Weight::from_ref_time(27_712_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn freeze_collection() -> Weight { - Weight::from_ref_time(23_129_000 as u64) + Weight::from_ref_time(23_068_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) fn thaw_collection() -> Weight { - Weight::from_ref_time(22_584_000 as u64) + Weight::from_ref_time(23_200_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } @@ -450,20 +450,20 @@ impl WeightInfo for () { // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:2) fn transfer_ownership() -> Weight { - Weight::from_ref_time(31_684_000 as u64) + Weight::from_ref_time(31_800_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(4 as u64)) } // Storage: Nfts Class (r:1 w:1) fn set_team() -> Weight { - Weight::from_ref_time(23_143_000 as u64) + Weight::from_ref_time(23_959_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassAccount (r:0 w:1) fn force_item_status() -> Weight { - Weight::from_ref_time(25_684_000 as u64) + Weight::from_ref_time(26_334_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } @@ -471,7 +471,7 @@ impl WeightInfo for () { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn set_attribute() -> Weight { - Weight::from_ref_time(50_159_000 as u64) + Weight::from_ref_time(50_978_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } @@ -479,76 +479,76 @@ impl WeightInfo for () { // Storage: Nfts InstanceMetadataOf (r:1 w:0) // Storage: Nfts Attribute (r:1 w:1) fn clear_attribute() -> Weight { - Weight::from_ref_time(47_824_000 as u64) + Weight::from_ref_time(49_555_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn set_metadata() -> Weight { - Weight::from_ref_time(39_968_000 as u64) + Weight::from_ref_time(41_099_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts InstanceMetadataOf (r:1 w:1) fn clear_metadata() -> Weight { - Weight::from_ref_time(42_182_000 as u64) + Weight::from_ref_time(42_893_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:1) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn set_collection_metadata() -> Weight { - Weight::from_ref_time(39_330_000 as u64) + Weight::from_ref_time(39_785_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts ClassMetadataOf (r:1 w:1) fn clear_collection_metadata() -> Weight { - Weight::from_ref_time(38_351_000 as u64) + Weight::from_ref_time(39_764_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn approve_transfer() -> Weight { - Weight::from_ref_time(29_530_000 as u64) + Weight::from_ref_time(29_577_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn cancel_approval() -> Weight { - Weight::from_ref_time(29_417_000 as u64) + Weight::from_ref_time(29_696_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Class (r:1 w:0) // Storage: Nfts Asset (r:1 w:1) fn clear_all_transfer_approvals() -> Weight { - Weight::from_ref_time(28_482_000 as u64) + Weight::from_ref_time(28_692_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts OwnershipAcceptance (r:1 w:1) fn set_accept_ownership() -> Weight { - Weight::from_ref_time(25_851_000 as u64) + Weight::from_ref_time(26_345_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts CollectionMaxSupply (r:1 w:1) // Storage: Nfts Class (r:1 w:0) fn set_collection_max_supply() -> Weight { - Weight::from_ref_time(24_836_000 as u64) + Weight::from_ref_time(24_826_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } // Storage: Nfts Asset (r:1 w:0) // Storage: Nfts ItemPriceOf (r:0 w:1) fn set_price() -> Weight { - Weight::from_ref_time(25_665_000 as u64) + Weight::from_ref_time(26_376_000 as u64) .saturating_add(RocksDbWeight::get().reads(1 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } @@ -558,21 +558,27 @@ impl WeightInfo for () { // Storage: Nfts Account (r:0 w:2) // Storage: Nfts PendingSwapOf (r:0 w:1) fn buy_item() -> Weight { - Weight::from_ref_time(47_502_000 as u64) + Weight::from_ref_time(49_140_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(5 as u64)) } + /// The range of component `n` is `[0, 10]`. + fn pay_tips(n: u32, ) -> Weight { + Weight::from_ref_time(5_477_000 as u64) + // Standard Error: 33_188 + .saturating_add(Weight::from_ref_time(4_285_339 as u64).saturating_mul(n as u64)) + } // Storage: Nfts Asset (r:2 w:0) // Storage: Nfts PendingSwapOf (r:0 w:1) fn create_swap() -> Weight { - Weight::from_ref_time(29_275_000 as u64) + Weight::from_ref_time(30_330_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } - // Storage: Nfts Asset (r:1 w:0) // Storage: Nfts PendingSwapOf (r:1 w:1) + // Storage: Nfts Asset (r:1 w:0) fn cancel_swap() -> Weight { - Weight::from_ref_time(29_062_000 as u64) + Weight::from_ref_time(30_516_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } @@ -582,14 +588,8 @@ impl WeightInfo for () { // Storage: Nfts Account (r:0 w:4) // Storage: Nfts ItemPriceOf (r:0 w:2) fn claim_swap() -> Weight { - Weight::from_ref_time(66_766_000 as u64) + Weight::from_ref_time(66_191_000 as u64) .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(10 as u64)) } - /// The range of component `n` is `[0, 10]`. - fn pay_tips(n: u32, ) -> Weight { - Weight::from_ref_time(5_417_000 as u64) - // Standard Error: 32_526 - .saturating_add(Weight::from_ref_time(4_304_363 as u64).saturating_mul(n as u64)) - } } From 2688fe56a42357e8688d6885418c01e9778c360d Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 4 Oct 2022 13:13:09 +0300 Subject: [PATCH 20/30] Wrap price and direction --- frame/nfts/src/features/atomic_swap.rs | 44 +++++++---------- frame/nfts/src/lib.rs | 34 +++++-------- frame/nfts/src/tests.rs | 67 +++++++++++--------------- frame/nfts/src/types.rs | 28 ++++++----- 4 files changed, 75 insertions(+), 98 deletions(-) diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index a9d72ea77bb50..eac7096052f83 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -28,8 +28,7 @@ impl, I: 'static> Pallet { offered_item_id: T::ItemId, desired_collection_id: T::CollectionId, maybe_desired_item_id: Option, - maybe_price: Option>, - maybe_price_direction: Option, + maybe_price: Option>>, maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { let item = Item::::get(&offered_collection_id, &offered_item_id) @@ -48,13 +47,6 @@ impl, I: 'static> Pallet { }, }; - if maybe_price.is_some() && maybe_price_direction.is_none() { - return Err(Error::::PriceDirectionNotSet.into()) - } - if maybe_price.is_none() && maybe_price_direction.is_some() { - return Err(Error::::PriceDirectionCannotBeSet.into()) - } - let now = frame_system::Pallet::::block_number(); let maybe_deadline = maybe_duration.map(|d| d.saturating_add(now)); @@ -64,8 +56,7 @@ impl, I: 'static> Pallet { PendingSwap { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, - price: maybe_price, - price_direction: maybe_price_direction.clone(), + price: maybe_price.clone(), deadline: maybe_deadline, }, ); @@ -76,7 +67,6 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price, - price_direction: maybe_price_direction, deadline: maybe_deadline, }); @@ -112,7 +102,6 @@ impl, I: 'static> Pallet { desired_collection: swap.desired_collection, desired_item: swap.desired_item, price: swap.price, - price_direction: swap.price_direction, deadline: swap.deadline, }); @@ -125,8 +114,7 @@ impl, I: 'static> Pallet { send_item_id: T::ItemId, receive_collection_id: T::CollectionId, receive_item_id: T::ItemId, - maybe_price: Option>, - maybe_price_direction: Option, + witness_price: Option>>, ) -> DispatchResult { let send_item = Item::::get(&send_collection_id, &send_item_id) .ok_or(Error::::UnknownItem)?; @@ -137,9 +125,7 @@ impl, I: 'static> Pallet { ensure!(send_item.owner == caller, Error::::NoPermission); ensure!( - swap.desired_collection == send_collection_id && - swap.price == maybe_price && - swap.price_direction == maybe_price_direction, + swap.desired_collection == send_collection_id && swap.price == witness_price, Error::::UnknownSwap ); @@ -152,13 +138,20 @@ impl, I: 'static> Pallet { ensure!(now <= deadline, Error::::DeadlineExpired); } - if let Some(amount) = swap.price { - match swap.price_direction { - Some(PriceDirection::Send) => - T::Currency::transfer(&receive_item.owner, &send_item.owner, amount, KeepAlive)?, - Some(PriceDirection::Receive) => - T::Currency::transfer(&send_item.owner, &receive_item.owner, amount, KeepAlive)?, - _ => {}, + if let Some(ref price) = swap.price { + match price.direction { + PriceDirection::Send => T::Currency::transfer( + &receive_item.owner, + &send_item.owner, + price.amount, + KeepAlive, + )?, + PriceDirection::Receive => T::Currency::transfer( + &send_item.owner, + &receive_item.owner, + price.amount, + KeepAlive, + )?, }; } @@ -181,7 +174,6 @@ impl, I: 'static> Pallet { received_item: receive_item_id, received_item_owner: receive_item.owner, price: swap.price, - price_direction: swap.price_direction, deadline: swap.deadline, }); diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index cc783911b9163..9e6c20ee9c210 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -320,7 +320,12 @@ pub mod pallet { T::CollectionId, Blake2_128Concat, T::ItemId, - PendingSwap, ::BlockNumber>, + PendingSwap< + T::CollectionId, + T::ItemId, + PriceWithDirection>, + ::BlockNumber, + >, OptionQuery, >; @@ -451,8 +456,7 @@ pub mod pallet { offered_item: T::ItemId, desired_collection: T::CollectionId, desired_item: Option, - price: Option>, - price_direction: Option, + price: Option>>, deadline: Option<::BlockNumber>, }, /// The swap was cancelled. @@ -461,8 +465,7 @@ pub mod pallet { offered_item: T::ItemId, desired_collection: T::CollectionId, desired_item: Option, - price: Option>, - price_direction: Option, + price: Option>>, deadline: Option<::BlockNumber>, }, /// The swap has been claimed. @@ -473,8 +476,7 @@ pub mod pallet { received_collection: T::CollectionId, received_item: T::ItemId, received_item_owner: T::AccountId, - price: Option>, - price_direction: Option, + price: Option>>, deadline: Option<::BlockNumber>, }, } @@ -525,10 +527,6 @@ pub mod pallet { ReachedApprovalLimit, /// The deadline has already expired. DeadlineExpired, - /// Price direction should be set. - PriceDirectionNotSet, - /// Price direction can't be set. - PriceDirectionCannotBeSet, } impl, I: 'static> Pallet { @@ -1703,8 +1701,6 @@ pub mod pallet { /// - `desired_collection`: The collection of the desired item. /// - `desired_item`: The desired item an owner wants to receive. /// - `maybe_price`: The price an owner is willing to pay or receive for the desired `item`. - /// - `maybe_price_direction`: Specifies whether a user is willing to pay or receive a - /// `price`. Should be set when the `maybe_price` is not None. /// - `maybe_duration`: Optional deadline for the swap. Specified by providing the /// number of blocks after which the swap will expire. /// @@ -1716,8 +1712,7 @@ pub mod pallet { offered_item: T::ItemId, desired_collection: T::CollectionId, maybe_desired_item: Option, - maybe_price: Option>, - maybe_price_direction: Option, + maybe_price: Option>>, maybe_duration: Option<::BlockNumber>, ) -> DispatchResult { let origin = ensure_signed(origin)?; @@ -1728,7 +1723,6 @@ pub mod pallet { desired_collection, maybe_desired_item, maybe_price, - maybe_price_direction, maybe_duration, ) } @@ -1761,7 +1755,7 @@ pub mod pallet { /// - `send_item`: The item to be sent. /// - `receive_collection`: The collection of the item to be received. /// - `receive_item`: The item to be received. - /// - `maybe_receive_amount`: An optional amount to be received. + /// - `witness_price`: A price that was previously agreed on. /// /// Emits `SwapClaimed` on success. #[pallet::weight(T::WeightInfo::claim_swap())] @@ -1771,8 +1765,7 @@ pub mod pallet { send_item: T::ItemId, receive_collection: T::CollectionId, receive_item: T::ItemId, - maybe_price: Option>, - maybe_price_direction: Option, + witness_price: Option>>, ) -> DispatchResult { let origin = ensure_signed(origin)?; Self::do_claim_swap( @@ -1781,8 +1774,7 @@ pub mod pallet { send_item, receive_collection, receive_item, - maybe_price, - maybe_price_direction, + witness_price, ) } } diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 99d8d542eb452..1f028d53b61ea 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -1115,9 +1115,11 @@ fn create_cancel_swap_should_work() { let item_1 = 1; let item_2 = 2; let price = 1; + let price_direction = PriceDirection::Receive; + let price_with_direction = + PriceWithDirection { amount: price, direction: price_direction.clone() }; let duration = 2; let expect_deadline = 3; - let price_direction = PriceDirection::Receive; assert_ok!(Nfts::force_create(RuntimeOrigin::root(), user_id, true)); @@ -1132,8 +1134,7 @@ fn create_cancel_swap_should_work() { item_1, collection_id, Some(item_2 + 1), - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), Some(duration), ), Error::::UnknownItem @@ -1145,8 +1146,7 @@ fn create_cancel_swap_should_work() { item_1, collection_id + 1, None, - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), Some(duration), ), Error::::UnknownCollection @@ -1158,16 +1158,14 @@ fn create_cancel_swap_should_work() { item_1, collection_id, Some(item_2), - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), Some(duration), )); let swap = PendingSwapOf::::get(collection_id, item_1).unwrap(); assert_eq!(swap.desired_collection, collection_id); assert_eq!(swap.desired_item, Some(item_2)); - assert_eq!(swap.price, Some(price)); - assert_eq!(swap.price_direction, Some(price_direction.clone())); + assert_eq!(swap.price, Some(price_with_direction.clone())); assert_eq!(swap.deadline, Some(expect_deadline)); assert!(events().contains(&Event::::SwapCreated { @@ -1175,8 +1173,7 @@ fn create_cancel_swap_should_work() { offered_item: item_1, desired_collection: collection_id, desired_item: Some(item_2), - price: Some(price), - price_direction: Some(price_direction.clone()), + price: Some(price_with_direction.clone()), deadline: Some(expect_deadline), })); @@ -1187,8 +1184,7 @@ fn create_cancel_swap_should_work() { offered_item: item_1, desired_collection: collection_id, desired_item: Some(item_2), - price: Some(price), - price_direction: Some(price_direction.clone()), + price: Some(price_with_direction.clone()), deadline: Some(expect_deadline), })); assert!(!PendingSwapOf::::contains_key(collection_id, item_1)); @@ -1200,8 +1196,7 @@ fn create_cancel_swap_should_work() { item_1, collection_id, Some(item_2), - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), Some(duration), )); assert_noop!( @@ -1218,8 +1213,7 @@ fn create_cancel_swap_should_work() { item_1, collection_id, None, - Some(price), - Some(price_direction), + Some(price_with_direction), Some(duration), )); @@ -1241,10 +1235,12 @@ fn claim_swap_should_work() { let item_4 = 4; let item_5 = 5; let price = 100; + let price_direction = PriceDirection::Receive; + let price_with_direction = + PriceWithDirection { amount: price, direction: price_direction.clone() }; let duration = 2; let initial_balance = 1000; let deadline = 1 + duration; - let price_direction = PriceDirection::Receive; Balances::make_free_balance_be(&user_1, initial_balance); Balances::make_free_balance_be(&user_2, initial_balance); @@ -1263,8 +1259,7 @@ fn claim_swap_should_work() { item_1, collection_id, Some(item_2), - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), Some(duration), )); @@ -1277,8 +1272,7 @@ fn claim_swap_should_work() { item_2, collection_id, item_1, - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), ), Error::::DeadlineExpired ); @@ -1292,8 +1286,7 @@ fn claim_swap_should_work() { item_2, collection_id, item_4, // no swap was created for that asset - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), ), Error::::UnknownSwap ); @@ -1304,8 +1297,7 @@ fn claim_swap_should_work() { item_4, // not my item collection_id, item_1, - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), ), Error::::NoPermission ); @@ -1316,8 +1308,7 @@ fn claim_swap_should_work() { item_5, // my item, but not the one another part wants collection_id, item_1, - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), ), Error::::UnknownSwap ); @@ -1328,8 +1319,7 @@ fn claim_swap_should_work() { item_2, collection_id, item_1, - Some(price + 1), // wrong price - Some(price_direction.clone()), + Some(PriceWithDirection { amount: price + 1, direction: price_direction.clone() }), // wrong price ), Error::::UnknownSwap ); @@ -1340,8 +1330,7 @@ fn claim_swap_should_work() { item_2, collection_id, item_1, - Some(price), - Some(PriceDirection::Send), // wrong direction + Some(PriceWithDirection { amount: price, direction: PriceDirection::Send }), // wrong direction ), Error::::UnknownSwap ); @@ -1352,8 +1341,7 @@ fn claim_swap_should_work() { item_2, collection_id, item_1, - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), )); // validate the new owner @@ -1377,13 +1365,14 @@ fn claim_swap_should_work() { received_collection: collection_id, received_item: item_1, received_item_owner: user_1, - price: Some(price), - price_direction: Some(price_direction.clone()), + price: Some(price_with_direction.clone()), deadline: Some(deadline), })); // validate the optional desired_item param and another price direction let price_direction = PriceDirection::Send; + let price_with_direction = + PriceWithDirection { amount: price, direction: price_direction.clone() }; Balances::make_free_balance_be(&user_1, initial_balance); Balances::make_free_balance_be(&user_2, initial_balance); @@ -1393,8 +1382,7 @@ fn claim_swap_should_work() { item_4, collection_id, None, - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), Some(duration), )); assert_ok!(Nfts::claim_swap( @@ -1403,8 +1391,7 @@ fn claim_swap_should_work() { item_1, collection_id, item_4, - Some(price), - Some(price_direction), + Some(price_with_direction), )); let item = Item::::get(collection_id, item_1).unwrap(); assert_eq!(item.owner, user_1); diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index faedfeac99f48..380a1707e9420 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -40,12 +40,6 @@ pub(super) type ItemTipOf = ItemTip< BalanceOf, >; -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub enum PriceDirection { - Send, - Receive, -} - #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct CollectionDetails { /// Can change `owner`, `issuer`, `freezer` and `admin` accounts. @@ -154,15 +148,27 @@ pub struct ItemTip { } #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] -pub struct PendingSwap { +pub struct PendingSwap { /// A collection of the item user wants to receive. pub(super) desired_collection: CollectionId, /// An item user wants to receive. pub(super) desired_item: Option, - /// A price for the desired `item`. - pub(super) price: Option, - /// Specifies whether a user is willing to pay or receive a `price`. - pub(super) price_direction: Option, + /// A price for the desired `item` with the direction. + pub(super) price: Option, /// An optional deadline for the swap. pub(super) deadline: Option, } + +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub enum PriceDirection { + Send, + Receive, +} + +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct PriceWithDirection { + /// An amount. + pub(super) amount: Amount, + /// A direction (send or receive). + pub(super) direction: PriceDirection, +} From 2dd02afe37d5135cf201044624cd7077771621ac Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 4 Oct 2022 13:19:39 +0300 Subject: [PATCH 21/30] Fix benchmarks --- frame/nfts/src/benchmarking.rs | 21 ++++++++++----------- frame/nfts/src/tests.rs | 6 ++---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index 85d9a78ec2dc5..9343e4db3aeb6 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -482,16 +482,16 @@ benchmarks_instance_pallet! { let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(100u32); let price_direction = PriceDirection::Receive; + let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; let duration = T::BlockNumber::max_value(); - }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price), Some(price_direction.clone()), Some(duration)) + }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), Some(duration)) verify { assert_last_event::(Event::SwapCreated { offered_collection: collection, offered_item: item1, desired_collection: collection, desired_item: Some(item2), - price: Some(price), - price_direction: Some(price_direction), + price: Some(price_with_direction), deadline: Some(duration), }.into()); } @@ -504,7 +504,8 @@ benchmarks_instance_pallet! { let origin = SystemOrigin::Signed(caller.clone()).into(); let duration = T::BlockNumber::max_value(); let price_direction = PriceDirection::Receive; - Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price), Some(price_direction.clone()), Some(duration))?; + let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; + Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price_with_direction.clone()), Some(duration))?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { assert_last_event::(Event::SwapCancelled { @@ -512,8 +513,7 @@ benchmarks_instance_pallet! { offered_item: item1, desired_collection: collection, desired_item: Some(item2), - price: Some(price), - price_direction: Some(price_direction), + price: Some(price_with_direction), deadline: Some(duration), }.into()); } @@ -524,6 +524,7 @@ benchmarks_instance_pallet! { let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(0u32); let price_direction = PriceDirection::Receive; + let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; let duration = T::BlockNumber::max_value(); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); @@ -535,11 +536,10 @@ benchmarks_instance_pallet! { item1, collection, Some(item2), - Some(price), - Some(price_direction.clone()), + Some(price_with_direction.clone()), Some(duration), )?; - }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price.clone()), Some(price_direction.clone())) + }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price_with_direction.clone())) verify { assert_last_event::(Event::SwapClaimed { sent_collection: collection, @@ -548,8 +548,7 @@ benchmarks_instance_pallet! { received_collection: collection, received_item: item1, received_item_owner: caller, - price: Some(price), - price_direction: Some(price_direction), + price: Some(price_with_direction), deadline: Some(duration), }.into()); } diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 1f028d53b61ea..0727ca31bf814 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -1116,8 +1116,7 @@ fn create_cancel_swap_should_work() { let item_2 = 2; let price = 1; let price_direction = PriceDirection::Receive; - let price_with_direction = - PriceWithDirection { amount: price, direction: price_direction.clone() }; + let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; let duration = 2; let expect_deadline = 3; @@ -1371,8 +1370,7 @@ fn claim_swap_should_work() { // validate the optional desired_item param and another price direction let price_direction = PriceDirection::Send; - let price_with_direction = - PriceWithDirection { amount: price, direction: price_direction.clone() }; + let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; Balances::make_free_balance_be(&user_1, initial_balance); Balances::make_free_balance_be(&user_2, initial_balance); From e565989975a163babe1947c47751c243383503fe Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 4 Oct 2022 15:06:37 +0300 Subject: [PATCH 22/30] Use ensure! instead of if {} --- frame/nfts/src/features/atomic_swap.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index eac7096052f83..0970fb31bb0aa 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -36,15 +36,14 @@ impl, I: 'static> Pallet { ensure!(item.owner == caller, Error::::NoPermission); match maybe_desired_item_id { - Some(desired_item_id) => { - if !(Item::::contains_key(&desired_collection_id, &desired_item_id)) { - return Err(Error::::UnknownItem.into()) - } - }, - None => - if !(Collection::::contains_key(&desired_collection_id)) { - return Err(Error::::UnknownCollection.into()) - }, + Some(desired_item_id) => ensure!( + Item::::contains_key(&desired_collection_id, &desired_item_id), + Error::::UnknownItem + ), + None => ensure!( + Collection::::contains_key(&desired_collection_id), + Error::::UnknownCollection + ), }; let now = frame_system::Pallet::::block_number(); From 82841fc9e467b1a84b5b692b6a74140b5e624371 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 4 Oct 2022 18:22:30 +0300 Subject: [PATCH 23/30] Make duration param mandatory and limit it to MaxDeadlineDuration --- bin/node/runtime/src/lib.rs | 2 ++ frame/nfts/src/benchmarking.rs | 21 +++++++------ frame/nfts/src/features/atomic_swap.rs | 26 ++++++---------- frame/nfts/src/lib.rs | 16 +++++++--- frame/nfts/src/mock.rs | 1 + frame/nfts/src/tests.rs | 42 ++++++++++++++++++-------- frame/nfts/src/types.rs | 2 +- 7 files changed, 67 insertions(+), 43 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index eb6941e85215c..875346472f21a 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1473,6 +1473,7 @@ parameter_types! { pub const ValueLimit: u32 = 256; pub const ApprovalsLimit: u32 = 20; pub const MaxTips: u32 = 10; + pub const MaxDeadlineDuration: BlockNumber = 12 * 30 * DAYS; } impl pallet_uniques::Config for Runtime { @@ -1512,6 +1513,7 @@ impl pallet_nfts::Config for Runtime { type ValueLimit = ValueLimit; type ApprovalsLimit = ApprovalsLimit; type MaxTips = MaxTips; + type MaxDeadlineDuration = MaxDeadlineDuration; type WeightInfo = pallet_nfts::weights::SubstrateWeight; #[cfg(feature = "runtime-benchmarks")] type Helper = (); diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index 9343e4db3aeb6..f467efb92b388 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -483,16 +483,17 @@ benchmarks_instance_pallet! { let price = ItemPrice::::from(100u32); let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; - let duration = T::BlockNumber::max_value(); - }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), Some(duration)) + let duration = T::MaxDeadlineDuration::get(); + }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration) verify { + let expect_deadline = duration + frame_system::Pallet::::block_number(); assert_last_event::(Event::SwapCreated { offered_collection: collection, offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price_with_direction), - deadline: Some(duration), + deadline: expect_deadline, }.into()); } @@ -502,19 +503,20 @@ benchmarks_instance_pallet! { let (item2, ..) = mint_item::(1); let price = ItemPrice::::from(100u32); let origin = SystemOrigin::Signed(caller.clone()).into(); - let duration = T::BlockNumber::max_value(); + let duration = T::MaxDeadlineDuration::get(); let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; - Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price_with_direction.clone()), Some(duration))?; + Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration)?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { + let expect_deadline = duration + frame_system::Pallet::::block_number(); assert_last_event::(Event::SwapCancelled { offered_collection: collection, offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price_with_direction), - deadline: Some(duration), + deadline: expect_deadline, }.into()); } @@ -525,7 +527,7 @@ benchmarks_instance_pallet! { let price = ItemPrice::::from(0u32); let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; - let duration = T::BlockNumber::max_value(); + let duration = T::MaxDeadlineDuration::get(); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); @@ -537,10 +539,11 @@ benchmarks_instance_pallet! { collection, Some(item2), Some(price_with_direction.clone()), - Some(duration), + duration, )?; }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price_with_direction.clone())) verify { + let expect_deadline = duration + frame_system::Pallet::::block_number(); assert_last_event::(Event::SwapClaimed { sent_collection: collection, sent_item: item2, @@ -549,7 +552,7 @@ benchmarks_instance_pallet! { received_item: item1, received_item_owner: caller, price: Some(price_with_direction), - deadline: Some(duration), + deadline: expect_deadline, }.into()); } diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index 0970fb31bb0aa..f62163dcde164 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -29,8 +29,10 @@ impl, I: 'static> Pallet { desired_collection_id: T::CollectionId, maybe_desired_item_id: Option, maybe_price: Option>>, - maybe_duration: Option<::BlockNumber>, + duration: ::BlockNumber, ) -> DispatchResult { + ensure!(duration <= T::MaxDeadlineDuration::get(), Error::::WrongDuration); + let item = Item::::get(&offered_collection_id, &offered_item_id) .ok_or(Error::::UnknownItem)?; ensure!(item.owner == caller, Error::::NoPermission); @@ -47,7 +49,7 @@ impl, I: 'static> Pallet { }; let now = frame_system::Pallet::::block_number(); - let maybe_deadline = maybe_duration.map(|d| d.saturating_add(now)); + let deadline = duration.saturating_add(now); PendingSwapOf::::insert( &offered_collection_id, @@ -56,7 +58,7 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price.clone(), - deadline: maybe_deadline, + deadline: deadline.clone(), }, ); @@ -66,7 +68,7 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price, - deadline: maybe_deadline, + deadline, }); Ok(()) @@ -80,14 +82,8 @@ impl, I: 'static> Pallet { let swap = PendingSwapOf::::get(&offered_collection_id, &offered_item_id) .ok_or(Error::::UnknownSwap)?; - let is_past_deadline = if let Some(deadline) = swap.deadline { - let now = frame_system::Pallet::::block_number(); - now > deadline - } else { - false - }; - - if !is_past_deadline { + let now = frame_system::Pallet::::block_number(); + if swap.deadline > now { let item = Item::::get(&offered_collection_id, &offered_item_id) .ok_or(Error::::UnknownItem)?; ensure!(item.owner == caller, Error::::NoPermission); @@ -132,10 +128,8 @@ impl, I: 'static> Pallet { ensure!(desired_item == send_item_id, Error::::UnknownSwap); } - if let Some(deadline) = swap.deadline { - let now = frame_system::Pallet::::block_number(); - ensure!(now <= deadline, Error::::DeadlineExpired); - } + let now = frame_system::Pallet::::block_number(); + ensure!(now <= swap.deadline, Error::::DeadlineExpired); if let Some(ref price) = swap.price { match price.direction { diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index 9e6c20ee9c210..7e9b2a42f7e14 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -182,6 +182,10 @@ pub mod pallet { #[pallet::constant] type MaxTips: Get; + /// The max duration in blocks for deadlines. + #[pallet::constant] + type MaxDeadlineDuration: Get<::BlockNumber>; + #[cfg(feature = "runtime-benchmarks")] /// A set of helper functions for benchmarking. type Helper: BenchmarkHelper; @@ -457,7 +461,7 @@ pub mod pallet { desired_collection: T::CollectionId, desired_item: Option, price: Option>>, - deadline: Option<::BlockNumber>, + deadline: ::BlockNumber, }, /// The swap was cancelled. SwapCancelled { @@ -466,7 +470,7 @@ pub mod pallet { desired_collection: T::CollectionId, desired_item: Option, price: Option>>, - deadline: Option<::BlockNumber>, + deadline: ::BlockNumber, }, /// The swap has been claimed. SwapClaimed { @@ -477,7 +481,7 @@ pub mod pallet { received_item: T::ItemId, received_item_owner: T::AccountId, price: Option>>, - deadline: Option<::BlockNumber>, + deadline: ::BlockNumber, }, } @@ -527,6 +531,8 @@ pub mod pallet { ReachedApprovalLimit, /// The deadline has already expired. DeadlineExpired, + /// The duration provided should be less or equal to MaxDeadlineDuration. + WrongDuration, } impl, I: 'static> Pallet { @@ -1713,7 +1719,7 @@ pub mod pallet { desired_collection: T::CollectionId, maybe_desired_item: Option, maybe_price: Option>>, - maybe_duration: Option<::BlockNumber>, + duration: ::BlockNumber, ) -> DispatchResult { let origin = ensure_signed(origin)?; Self::do_create_swap( @@ -1723,7 +1729,7 @@ pub mod pallet { desired_collection, maybe_desired_item, maybe_price, - maybe_duration, + duration, ) } diff --git a/frame/nfts/src/mock.rs b/frame/nfts/src/mock.rs index c13298aa8162d..23493829eaca7 100644 --- a/frame/nfts/src/mock.rs +++ b/frame/nfts/src/mock.rs @@ -102,6 +102,7 @@ impl Config for Test { type ValueLimit = ConstU32<50>; type ApprovalsLimit = ConstU32<10>; type MaxTips = ConstU32<10>; + type MaxDeadlineDuration = ConstU64<10000>; type WeightInfo = (); #[cfg(feature = "runtime-benchmarks")] type Helper = (); diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 0727ca31bf814..0d2d0c661b273 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -18,7 +18,11 @@ //! Tests for Nfts pallet. use crate::{mock::*, Event, *}; -use frame_support::{assert_noop, assert_ok, dispatch::Dispatchable, traits::Currency}; +use frame_support::{ + assert_noop, assert_ok, + dispatch::Dispatchable, + traits::{Currency, Get}, +}; use pallet_balances::Error as BalancesError; use sp_std::prelude::*; @@ -1134,7 +1138,7 @@ fn create_cancel_swap_should_work() { collection_id, Some(item_2 + 1), Some(price_with_direction.clone()), - Some(duration), + duration, ), Error::::UnknownItem ); @@ -1146,11 +1150,25 @@ fn create_cancel_swap_should_work() { collection_id + 1, None, Some(price_with_direction.clone()), - Some(duration), + duration, ), Error::::UnknownCollection ); + let max_duration: u64 = ::MaxDeadlineDuration::get(); + assert_noop!( + Nfts::create_swap( + RuntimeOrigin::signed(user_id), + collection_id, + item_1, + collection_id, + Some(item_2), + Some(price_with_direction.clone()), + max_duration.saturating_add(1), + ), + Error::::WrongDuration + ); + assert_ok!(Nfts::create_swap( RuntimeOrigin::signed(user_id), collection_id, @@ -1158,14 +1176,14 @@ fn create_cancel_swap_should_work() { collection_id, Some(item_2), Some(price_with_direction.clone()), - Some(duration), + duration, )); let swap = PendingSwapOf::::get(collection_id, item_1).unwrap(); assert_eq!(swap.desired_collection, collection_id); assert_eq!(swap.desired_item, Some(item_2)); assert_eq!(swap.price, Some(price_with_direction.clone())); - assert_eq!(swap.deadline, Some(expect_deadline)); + assert_eq!(swap.deadline, expect_deadline); assert!(events().contains(&Event::::SwapCreated { offered_collection: collection_id, @@ -1173,7 +1191,7 @@ fn create_cancel_swap_should_work() { desired_collection: collection_id, desired_item: Some(item_2), price: Some(price_with_direction.clone()), - deadline: Some(expect_deadline), + deadline: expect_deadline, })); // validate we can cancel the swap @@ -1184,7 +1202,7 @@ fn create_cancel_swap_should_work() { desired_collection: collection_id, desired_item: Some(item_2), price: Some(price_with_direction.clone()), - deadline: Some(expect_deadline), + deadline: expect_deadline, })); assert!(!PendingSwapOf::::contains_key(collection_id, item_1)); @@ -1196,7 +1214,7 @@ fn create_cancel_swap_should_work() { collection_id, Some(item_2), Some(price_with_direction.clone()), - Some(duration), + duration, )); assert_noop!( Nfts::cancel_swap(RuntimeOrigin::signed(user_id + 1), collection_id, item_1), @@ -1213,7 +1231,7 @@ fn create_cancel_swap_should_work() { collection_id, None, Some(price_with_direction), - Some(duration), + duration, )); let swap = PendingSwapOf::::get(collection_id, item_1).unwrap(); @@ -1259,7 +1277,7 @@ fn claim_swap_should_work() { collection_id, Some(item_2), Some(price_with_direction.clone()), - Some(duration), + duration, )); // validate the deadline @@ -1365,7 +1383,7 @@ fn claim_swap_should_work() { received_item: item_1, received_item_owner: user_1, price: Some(price_with_direction.clone()), - deadline: Some(deadline), + deadline, })); // validate the optional desired_item param and another price direction @@ -1381,7 +1399,7 @@ fn claim_swap_should_work() { collection_id, None, Some(price_with_direction.clone()), - Some(duration), + duration, )); assert_ok!(Nfts::claim_swap( RuntimeOrigin::signed(user_2), diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index 380a1707e9420..399de3c5dad1e 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -156,7 +156,7 @@ pub struct PendingSwap { /// A price for the desired `item` with the direction. pub(super) price: Option, /// An optional deadline for the swap. - pub(super) deadline: Option, + pub(super) deadline: Deadline, } #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] From 7fbf33987463148072f354249ddc65f00c13aa5f Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 4 Oct 2022 18:32:16 +0300 Subject: [PATCH 24/30] Make the code safer --- frame/nfts/src/benchmarking.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index f467efb92b388..5719b31234a1a 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -486,7 +486,7 @@ benchmarks_instance_pallet! { let duration = T::MaxDeadlineDuration::get(); }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration) verify { - let expect_deadline = duration + frame_system::Pallet::::block_number(); + let expect_deadline = duration.saturating_add(frame_system::Pallet::::block_number()); assert_last_event::(Event::SwapCreated { offered_collection: collection, offered_item: item1, @@ -509,7 +509,7 @@ benchmarks_instance_pallet! { Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration)?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { - let expect_deadline = duration + frame_system::Pallet::::block_number(); + let expect_deadline = duration.saturating_add(frame_system::Pallet::::block_number()); assert_last_event::(Event::SwapCancelled { offered_collection: collection, offered_item: item1, @@ -543,7 +543,7 @@ benchmarks_instance_pallet! { )?; }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price_with_direction.clone())) verify { - let expect_deadline = duration + frame_system::Pallet::::block_number(); + let expect_deadline = duration.saturating_add(frame_system::Pallet::::block_number()); assert_last_event::(Event::SwapClaimed { sent_collection: collection, sent_item: item2, From e9565947b6b46e103f34d90400c0eb9d771b9331 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 4 Oct 2022 18:34:36 +0300 Subject: [PATCH 25/30] Fix clippy --- frame/nfts/src/features/atomic_swap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/nfts/src/features/atomic_swap.rs b/frame/nfts/src/features/atomic_swap.rs index f62163dcde164..116da57477f4e 100644 --- a/frame/nfts/src/features/atomic_swap.rs +++ b/frame/nfts/src/features/atomic_swap.rs @@ -58,7 +58,7 @@ impl, I: 'static> Pallet { desired_collection: desired_collection_id, desired_item: maybe_desired_item_id, price: maybe_price.clone(), - deadline: deadline.clone(), + deadline, }, ); From b52a61584e6a81583d1d9032809f96b1ae6e7231 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Tue, 4 Oct 2022 19:02:32 +0300 Subject: [PATCH 26/30] Chore --- frame/nfts/src/benchmarking.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index 5719b31234a1a..4ec15d5d205fc 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -484,6 +484,7 @@ benchmarks_instance_pallet! { let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; let duration = T::MaxDeadlineDuration::get(); + let current_block = frame_system::Pallet::::block_number(); }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration) verify { let expect_deadline = duration.saturating_add(frame_system::Pallet::::block_number()); @@ -493,7 +494,7 @@ benchmarks_instance_pallet! { desired_collection: collection, desired_item: Some(item2), price: Some(price_with_direction), - deadline: expect_deadline, + deadline: duration.saturating_add(current_block), }.into()); } @@ -506,17 +507,17 @@ benchmarks_instance_pallet! { let duration = T::MaxDeadlineDuration::get(); let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; + let current_block = frame_system::Pallet::::block_number(); Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration)?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { - let expect_deadline = duration.saturating_add(frame_system::Pallet::::block_number()); assert_last_event::(Event::SwapCancelled { offered_collection: collection, offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price_with_direction), - deadline: expect_deadline, + deadline: duration.saturating_add(current_block), }.into()); } @@ -531,6 +532,7 @@ benchmarks_instance_pallet! { let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); + let current_block = frame_system::Pallet::::block_number(); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; Nfts::::create_swap( origin.clone().into(), @@ -552,7 +554,7 @@ benchmarks_instance_pallet! { received_item: item1, received_item_owner: caller, price: Some(price_with_direction), - deadline: expect_deadline, + deadline: duration.saturating_add(current_block), }.into()); } From 3b41ee10f5d7e67b80d41cf4ca40691474f230ab Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Wed, 5 Oct 2022 09:37:54 +0300 Subject: [PATCH 27/30] Remove unused vars --- frame/nfts/src/benchmarking.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index 4ec15d5d205fc..ece024c21ebec 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -487,7 +487,6 @@ benchmarks_instance_pallet! { let current_block = frame_system::Pallet::::block_number(); }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration) verify { - let expect_deadline = duration.saturating_add(frame_system::Pallet::::block_number()); assert_last_event::(Event::SwapCreated { offered_collection: collection, offered_item: item1, @@ -545,7 +544,6 @@ benchmarks_instance_pallet! { )?; }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price_with_direction.clone())) verify { - let expect_deadline = duration.saturating_add(frame_system::Pallet::::block_number()); assert_last_event::(Event::SwapClaimed { sent_collection: collection, sent_item: item2, From 239bf17da05abd34238eb4cbea6b6cd89d1e2475 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Wed, 5 Oct 2022 12:46:53 +0300 Subject: [PATCH 28/30] try --- frame/nfts/src/benchmarking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index ece024c21ebec..aef692ab5ac65 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -484,16 +484,16 @@ benchmarks_instance_pallet! { let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; let duration = T::MaxDeadlineDuration::get(); - let current_block = frame_system::Pallet::::block_number(); }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration) verify { + let current_block = frame_system::Pallet::::block_number(); assert_last_event::(Event::SwapCreated { offered_collection: collection, offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price_with_direction), - deadline: duration.saturating_add(current_block), + deadline: current_block.saturating_add(duration), }.into()); } From d086e81a08d09bc3d67da9f42e47f02713f424c4 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Wed, 5 Oct 2022 13:14:21 +0300 Subject: [PATCH 29/30] try 2 --- frame/nfts/src/benchmarking.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index aef692ab5ac65..a22b08b018e50 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -506,17 +506,17 @@ benchmarks_instance_pallet! { let duration = T::MaxDeadlineDuration::get(); let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; - let current_block = frame_system::Pallet::::block_number(); Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration)?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { + let current_block = frame_system::Pallet::::block_number(); assert_last_event::(Event::SwapCancelled { offered_collection: collection, offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price_with_direction), - deadline: duration.saturating_add(current_block), + deadline: current_block.saturating_add(duration), }.into()); } @@ -531,7 +531,6 @@ benchmarks_instance_pallet! { let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); - let current_block = frame_system::Pallet::::block_number(); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; Nfts::::create_swap( origin.clone().into(), @@ -544,6 +543,7 @@ benchmarks_instance_pallet! { )?; }: _(SystemOrigin::Signed(target.clone()), collection, item2, collection, item1, Some(price_with_direction.clone())) verify { + let current_block = frame_system::Pallet::::block_number(); assert_last_event::(Event::SwapClaimed { sent_collection: collection, sent_item: item2, @@ -552,7 +552,7 @@ benchmarks_instance_pallet! { received_item: item1, received_item_owner: caller, price: Some(price_with_direction), - deadline: duration.saturating_add(current_block), + deadline: current_block.saturating_add(duration), }.into()); } From c2afaa4689b2c2d84d0c4797153ce3fee91ac6a6 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Wed, 5 Oct 2022 13:33:16 +0300 Subject: [PATCH 30/30] try 3 --- frame/nfts/src/benchmarking.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frame/nfts/src/benchmarking.rs b/frame/nfts/src/benchmarking.rs index a22b08b018e50..b35122cf919c7 100644 --- a/frame/nfts/src/benchmarking.rs +++ b/frame/nfts/src/benchmarking.rs @@ -29,7 +29,7 @@ use frame_support::{ BoundedVec, }; use frame_system::RawOrigin as SystemOrigin; -use sp_runtime::traits::Bounded; +use sp_runtime::traits::{Bounded, One}; use sp_std::prelude::*; use crate::Pallet as Nfts; @@ -484,6 +484,7 @@ benchmarks_instance_pallet! { let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; let duration = T::MaxDeadlineDuration::get(); + frame_system::Pallet::::set_block_number(One::one()); }: _(SystemOrigin::Signed(caller.clone()), collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration) verify { let current_block = frame_system::Pallet::::block_number(); @@ -506,17 +507,17 @@ benchmarks_instance_pallet! { let duration = T::MaxDeadlineDuration::get(); let price_direction = PriceDirection::Receive; let price_with_direction = PriceWithDirection { amount: price, direction: price_direction }; + frame_system::Pallet::::set_block_number(One::one()); Nfts::::create_swap(origin, collection, item1, collection, Some(item2), Some(price_with_direction.clone()), duration)?; }: _(SystemOrigin::Signed(caller.clone()), collection, item1) verify { - let current_block = frame_system::Pallet::::block_number(); assert_last_event::(Event::SwapCancelled { offered_collection: collection, offered_item: item1, desired_collection: collection, desired_item: Some(item2), price: Some(price_with_direction), - deadline: current_block.saturating_add(duration), + deadline: duration.saturating_add(One::one()), }.into()); } @@ -531,6 +532,7 @@ benchmarks_instance_pallet! { let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); let origin = SystemOrigin::Signed(caller.clone()); + frame_system::Pallet::::set_block_number(One::one()); Nfts::::transfer(origin.clone().into(), collection, item2, target_lookup)?; Nfts::::create_swap( origin.clone().into(), @@ -552,7 +554,7 @@ benchmarks_instance_pallet! { received_item: item1, received_item_owner: caller, price: Some(price_with_direction), - deadline: current_block.saturating_add(duration), + deadline: duration.saturating_add(One::one()), }.into()); }