From 1ebb60c715d5f9b7276ce149c49f36ea99ddfdcc Mon Sep 17 00:00:00 2001
From: Ermal Kaleci <ermalkaleci@gmail.com>
Date: Tue, 31 Mar 2020 04:21:34 +0200
Subject: [PATCH] migrate AuctionEndTime to double_map (#132)

* migrate AuctionEndTime to double_map

* use drain
---
 auction/Cargo.toml   |  2 --
 auction/src/lib.rs   | 30 +++++++++++-------------------
 auction/src/tests.rs | 16 ++++++++++++++--
 3 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/auction/Cargo.toml b/auction/Cargo.toml
index 0be70e4..e017cc4 100644
--- a/auction/Cargo.toml
+++ b/auction/Cargo.toml
@@ -15,7 +15,6 @@ frame-support = { version = "2.0.0-alpha.5", default-features = false }
 frame-system = { version = "2.0.0-alpha.5", default-features = false }
 
 orml-traits = { path = "../traits", default-features = false }
-orml-utilities = { path = "../utilities", default-features = false }
 
 [dev-dependencies]
 sp-core = { version = "2.0.0-alpha.5", default-features = false }
@@ -33,5 +32,4 @@ std = [
 	"frame-support/std",
 	"frame-system/std",
 	"orml-traits/std",
-	"orml-utilities/std",
 ]
diff --git a/auction/src/lib.rs b/auction/src/lib.rs
index 51ae761..6b66422 100644
--- a/auction/src/lib.rs
+++ b/auction/src/lib.rs
@@ -1,15 +1,13 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, IterableStorageDoubleMap, Parameter};
 use frame_system::{self as system, ensure_signed};
-use orml_utilities::{LinkedItem, LinkedList};
+use orml_traits::{Auction, AuctionHandler, AuctionInfo};
 use sp_runtime::{
 	traits::{AtLeast32Bit, MaybeSerializeDeserialize, Member, One, Zero},
 	DispatchResult,
 };
 
-use orml_traits::{Auction, AuctionHandler, AuctionInfo};
-
 mod mock;
 mod tests;
 
@@ -20,9 +18,6 @@ pub trait Trait: frame_system::Trait {
 	type Handler: AuctionHandler<Self::AccountId, Self::Balance, Self::BlockNumber, Self::AuctionId>;
 }
 
-type AuctionEndTimeList<T> =
-	LinkedList<AuctionEndTime<T>, <T as frame_system::Trait>::BlockNumber, <T as Trait>::AuctionId>;
-
 decl_event!(
 	pub enum Event<T> where
 		<T as frame_system::Trait>::AccountId,
@@ -33,13 +28,11 @@ decl_event!(
 	}
 );
 
-type AuctionIdLinkedItem<T> = LinkedItem<<T as Trait>::AuctionId>;
-
 decl_storage! {
 	trait Store for Module<T: Trait> as Auction {
 		pub Auctions get(fn auctions): map hasher(twox_64_concat) T::AuctionId => Option<AuctionInfo<T::AccountId, T::Balance, T::BlockNumber>>;
 		pub AuctionsIndex get(fn auctions_index): T::AuctionId;
-		pub AuctionEndTime get(fn auction_end_time): map hasher(twox_64_concat) (T::BlockNumber, Option<T::AuctionId>) => Option<AuctionIdLinkedItem<T>>;
+		pub AuctionEndTime get(fn auction_end_time): double_map hasher(twox_64_concat) T::BlockNumber, hasher(twox_64_concat) T::AuctionId => Option<()>;
 	}
 }
 
@@ -74,10 +67,10 @@ decl_module! {
 			ensure!(bid_result.accept_bid, Error::<T>::BidNotAccepted);
 			if let Some(new_end) = bid_result.auction_end {
 				if let Some(old_end_block) = auction.end {
-					<AuctionEndTimeList<T>>::remove(&old_end_block, id);
+					<AuctionEndTime<T>>::remove(&old_end_block, id);
 				}
 				if let Some(new_end_block) = new_end {
-					<AuctionEndTimeList<T>>::append(&new_end_block, id);
+					<AuctionEndTime<T>>::insert(&new_end_block, id, ());
 				}
 				auction.end = new_end;
 			}
@@ -104,12 +97,11 @@ decl_error! {
 
 impl<T: Trait> Module<T> {
 	fn _on_finalize(now: T::BlockNumber) {
-		let ended_auctions = <AuctionEndTimeList<T>>::take_all(&now);
-		ended_auctions.for_each(|auction_id| {
+		for (auction_id, _) in <AuctionEndTime<T>>::drain(&now) {
 			if let Some(auction) = <Auctions<T>>::take(&auction_id) {
 				T::Handler::on_auction_ended(auction_id, auction.bid.clone());
 			}
-		});
+		}
 	}
 }
 
@@ -127,10 +119,10 @@ impl<T: Trait> Auction<T::AccountId, T::BlockNumber> for Module<T> {
 	) -> DispatchResult {
 		let auction = <Auctions<T>>::get(id).ok_or(Error::<T>::AuctionNotExist)?;
 		if let Some(old_end) = auction.end {
-			<AuctionEndTimeList<T>>::remove(&old_end, id);
+			<AuctionEndTime<T>>::remove(&old_end, id);
 		}
 		if let Some(new_end) = info.end {
-			<AuctionEndTimeList<T>>::append(&new_end, id);
+			<AuctionEndTime<T>>::insert(&new_end, id, ());
 		}
 		<Auctions<T>>::insert(id, info);
 		Ok(())
@@ -142,7 +134,7 @@ impl<T: Trait> Auction<T::AccountId, T::BlockNumber> for Module<T> {
 		<AuctionsIndex<T>>::mutate(|n| *n += Self::AuctionId::one());
 		<Auctions<T>>::insert(auction_id, auction);
 		if let Some(end_block) = end {
-			<AuctionEndTimeList<T>>::append(&end_block, auction_id);
+			<AuctionEndTime<T>>::insert(&end_block, auction_id, ());
 		}
 
 		auction_id
@@ -151,7 +143,7 @@ impl<T: Trait> Auction<T::AccountId, T::BlockNumber> for Module<T> {
 	fn remove_auction(id: Self::AuctionId) {
 		if let Some(auction) = <Auctions<T>>::take(&id) {
 			if let Some(end_block) = auction.end {
-				<AuctionEndTimeList<T>>::remove(&end_block, id);
+				<AuctionEndTime<T>>::remove(&end_block, id);
 			}
 		}
 	}
diff --git a/auction/src/tests.rs b/auction/src/tests.rs
index 1792f0f..8e72473 100644
--- a/auction/src/tests.rs
+++ b/auction/src/tests.rs
@@ -77,10 +77,10 @@ fn remove_auction_should_work() {
 		assert_eq!(AuctionModule::new_auction(10, Some(100)), 0);
 		assert_eq!(AuctionModule::auctions_index(), 1);
 		assert_eq!(AuctionModule::auctions(0).is_some(), true);
-		assert_eq!(AuctionModule::auction_end_time((100, Some(0))).is_some(), true);
+		assert_eq!(AuctionModule::auction_end_time(100, 0), Some(()));
 		AuctionModule::remove_auction(0);
 		assert_eq!(AuctionModule::auctions(0), None);
-		assert_eq!(AuctionModule::auction_end_time((100, Some(0))), None);
+		assert_eq!(AuctionModule::auction_end_time(100, 0), None);
 	});
 }
 
@@ -93,11 +93,23 @@ fn cleanup_auction_should_work() {
 		assert_eq!(AuctionModule::auctions_index(), 2);
 		assert_eq!(AuctionModule::auctions(0).is_some(), true);
 		assert_eq!(AuctionModule::auctions(1).is_some(), true);
+
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(0).count(), 0);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(50).count(), 1);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(100).count(), 1);
+
 		AuctionModule::on_finalize(50);
 		assert_eq!(AuctionModule::auctions(0).is_some(), true);
 		assert_eq!(AuctionModule::auctions(1).is_some(), false);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(0).count(), 0);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(50).count(), 0);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(100).count(), 1);
+
 		AuctionModule::on_finalize(100);
 		assert_eq!(AuctionModule::auctions(0).is_some(), false);
 		assert_eq!(AuctionModule::auctions(1).is_some(), false);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(0).count(), 0);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(50).count(), 0);
+		assert_eq!(<AuctionEndTime<Runtime>>::iter_prefix(100).count(), 0);
 	});
 }
-- 
GitLab