diff --git a/auction/src/lib.rs b/auction/src/lib.rs index b6c1604a112b3892ee02b90bef2e3512ce806b70..fd8e733d53b258ad42138fb467cd5d3311af558e 100644 --- a/auction/src/lib.rs +++ b/auction/src/lib.rs @@ -4,7 +4,7 @@ use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, P use frame_system::{self as system, ensure_signed}; use orml_utilities::{LinkedItem, LinkedList}; use sp_runtime::{ - traits::{MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic, Zero}, + traits::{MaybeSerializeDeserialize, Member, One, SimpleArithmetic, Zero}, DispatchResult, }; @@ -38,7 +38,7 @@ type AuctionIdLinkedItem<T> = LinkedItem<<T as Trait>::AuctionId>; decl_storage! { trait Store for Module<T: Trait> as Auction { pub Auctions get(fn auctions): map T::AuctionId => Option<AuctionInfo<T::AccountId, T::Balance, T::BlockNumber>>; - pub AuctionsCount get(fn auctions_count): T::AuctionId; + pub AuctionsIndex get(fn auctions_index): T::AuctionId; pub AuctionEndTime get(fn auction_end_time): map(T::BlockNumber, Option<T::AuctionId>) => Option<AuctionIdLinkedItem<T>>; } } @@ -105,14 +105,11 @@ decl_error! { impl<T: Trait> Module<T> { fn _on_finalize(now: T::BlockNumber) { let ended_auctions = <AuctionEndTimeList<T>>::take_all(&now); - let mut count = Self::auctions_count(); ended_auctions.for_each(|auction_id| { if let Some(auction) = <Auctions<T>>::take(&auction_id) { T::Handler::on_auction_ended(auction_id, auction.bid.clone()); - count = count.saturating_sub(T::AuctionId::one()); } }); - <AuctionsCount<T>>::put(count); } } @@ -141,8 +138,8 @@ impl<T: Trait> Auction<T::AccountId, T::BlockNumber> for Module<T> { fn new_auction(start: T::BlockNumber, end: Option<T::BlockNumber>) -> Self::AuctionId { let auction = AuctionInfo { bid: None, start, end }; - let auction_id = Self::auctions_count(); - <AuctionsCount<T>>::mutate(|n| *n += Self::AuctionId::from(1)); + let auction_id = Self::auctions_index(); + <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); @@ -150,4 +147,12 @@ impl<T: Trait> Auction<T::AccountId, T::BlockNumber> for Module<T> { auction_id } + + 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); + } + } + } } diff --git a/auction/src/tests.rs b/auction/src/tests.rs index 79e4f583592464465e1d733a4c21e8ebb5ce9379..1792f0f78544d16aff712be442af209cca89abaf 100644 --- a/auction/src/tests.rs +++ b/auction/src/tests.rs @@ -71,18 +71,33 @@ fn bid_should_fail() { }); } +#[test] +fn remove_auction_should_work() { + ExtBuilder::default().build().execute_with(|| { + 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); + AuctionModule::remove_auction(0); + assert_eq!(AuctionModule::auctions(0), None); + assert_eq!(AuctionModule::auction_end_time((100, Some(0))), None); + }); +} + #[test] fn cleanup_auction_should_work() { ExtBuilder::default().build().execute_with(|| { assert_eq!(AuctionModule::new_auction(10, Some(100)), 0); - assert_eq!(AuctionModule::auctions_count(), 1); + assert_eq!(AuctionModule::auctions_index(), 1); assert_eq!(AuctionModule::new_auction(10, Some(50)), 1); - assert_eq!(AuctionModule::auctions_count(), 2); - AuctionModule::on_finalize(1); - assert_eq!(AuctionModule::auctions_count(), 2); + assert_eq!(AuctionModule::auctions_index(), 2); + assert_eq!(AuctionModule::auctions(0).is_some(), true); + assert_eq!(AuctionModule::auctions(1).is_some(), true); AuctionModule::on_finalize(50); - assert_eq!(AuctionModule::auctions_count(), 1); + assert_eq!(AuctionModule::auctions(0).is_some(), true); + assert_eq!(AuctionModule::auctions(1).is_some(), false); AuctionModule::on_finalize(100); - assert_eq!(AuctionModule::auctions_count(), 0); + assert_eq!(AuctionModule::auctions(0).is_some(), false); + assert_eq!(AuctionModule::auctions(1).is_some(), false); }); } diff --git a/traits/src/auction.rs b/traits/src/auction.rs index 1805acdd231cff3e0db9ffddeefdcd5d49962cef..0878c01f85155d0c5ae7b91632ad0641a9263a4a 100644 --- a/traits/src/auction.rs +++ b/traits/src/auction.rs @@ -1,6 +1,9 @@ use codec::FullCodec; use codec::{Decode, Encode}; -use rstd::fmt::Debug; +use rstd::{ + cmp::{Eq, PartialEq}, + fmt::Debug, +}; use sp_runtime::{ traits::{MaybeSerializeDeserialize, SimpleArithmetic}, DispatchResult, RuntimeDebug, @@ -21,7 +24,7 @@ pub struct AuctionInfo<AccountId, Balance, BlockNumber> { /// Abstraction over a simple auction system. pub trait Auction<AccountId, BlockNumber> { /// The id of an AuctionInfo - type AuctionId: FullCodec + Default + Copy + MaybeSerializeDeserialize + Debug; + type AuctionId: FullCodec + Default + Copy + Eq + PartialEq + MaybeSerializeDeserialize + Debug; /// The price to bid. type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default; @@ -31,6 +34,8 @@ pub trait Auction<AccountId, BlockNumber> { fn update_auction(id: Self::AuctionId, info: AuctionInfo<AccountId, Self::Balance, BlockNumber>) -> DispatchResult; /// Create new auction with specific startblock and endblock, return the id of the auction fn new_auction(start: BlockNumber, end: Option<BlockNumber>) -> Self::AuctionId; + /// Remove auction by `id` + fn remove_auction(id: Self::AuctionId); } /// The result of bid handling.