From 8cc1fd0d5a8f119e8c4fafd43593c28de07429dd Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 31 Oct 2022 10:59:31 +0100 Subject: [PATCH 1/3] create API direct resolution --- primitives/src/traits.rs | 2 +- primitives/src/traits/dispute_api.rs | 20 ++++++++++++++++++++ zrml/authorized/src/lib.rs | 11 ++++++++++- zrml/authorized/src/mock.rs | 22 +++++++++++++++++++++- zrml/prediction-markets/src/lib.rs | 19 ++++++++++++++++++- zrml/prediction-markets/src/mock.rs | 1 + 6 files changed, 71 insertions(+), 4 deletions(-) diff --git a/primitives/src/traits.rs b/primitives/src/traits.rs index 966592ff0..6178fd11e 100644 --- a/primitives/src/traits.rs +++ b/primitives/src/traits.rs @@ -20,7 +20,7 @@ mod market_id; mod swaps; mod zeitgeist_multi_reservable_currency; -pub use dispute_api::DisputeApi; +pub use dispute_api::{DisputeApi, DisputeResolutionApi}; pub use market_id::MarketId; pub use swaps::Swaps; pub use zeitgeist_multi_reservable_currency::ZeitgeistAssetManager; diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 5796beab9..adc5cbcd1 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -52,3 +52,23 @@ pub trait DisputeApi { market: &Market, ) -> Result, DispatchError>; } + +pub trait DisputeResolutionApi { + type AccountId; + type BlockNumber; + type MarketId; + type Moment; + + /// Resolve a market. Fails if `on_resolution` from zrml-prediction-markets fails. + /// + /// **Should only be called if the market dispute** + /// **mechanism is ready for the resolution (`DisputeApi::on_resolution`).** + /// + /// # Returns + /// + /// Returns the consumed weight. + fn resolve( + market_id: &Self::MarketId, + market: &Market, + ) -> Result; +} diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index dd09bad4f..a4082cf14 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -44,7 +44,7 @@ mod pallet { use frame_system::{ensure_signed, pallet_prelude::OriginFor}; use sp_runtime::DispatchError; use zeitgeist_primitives::{ - traits::DisputeApi, + traits::{DisputeApi, DisputeResolutionApi}, types::{Market, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::MarketCommonsPalletApi; @@ -82,6 +82,8 @@ mod pallet { return Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()); } AuthorizedOutcomeReports::::insert(market_id, outcome); + // TODO(#851): Allow a small correction period (if authority made a mistake)! + let _resolution_weight = T::DisputeResolution::resolve(&market_id, &market)?; Ok(()) } } @@ -91,6 +93,13 @@ mod pallet { /// Event type Event: From> + IsType<::Event>; + type DisputeResolution: DisputeResolutionApi< + AccountId = Self::AccountId, + BlockNumber = Self::BlockNumber, + MarketId = MarketIdOf, + Moment = MomentOf, + >; + /// Market commons type MarketCommons: MarketCommonsPalletApi< AccountId = Self::AccountId, diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 8f4ceb01c..770ba3f5e 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -19,15 +19,17 @@ use crate::{self as zrml_authorized}; use frame_support::{construct_runtime, traits::Everything}; +use frame_support::pallet_prelude::DispatchError; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; use zeitgeist_primitives::{ constants::mock::{AuthorizedPalletId, BlockHashCount, MaxReserves, MinimumPeriod, BASE}, + traits::DisputeResolutionApi, types::{ AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, MarketId, Moment, - UncheckedExtrinsicTest, + UncheckedExtrinsicTest, Market, }, }; @@ -50,8 +52,26 @@ construct_runtime!( } ); +// NoopResolution implements DisputeResolutionApi with no-ops. +pub struct NoopResolution; + +impl DisputeResolutionApi for NoopResolution { + type AccountId = AccountIdTest; + type BlockNumber = BlockNumber; + type MarketId = MarketId; + type Moment = Moment; + + fn resolve( + _market_id: &Self::MarketId, + _market: &Market, + ) -> Result { + Ok(0) + } +} + impl crate::Config for Runtime { type Event = (); + type DisputeResolution = NoopResolution; type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = crate::weights::WeightInfo; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 931b78b93..1372cef59 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -56,7 +56,7 @@ mod pallet { }; use zeitgeist_primitives::{ constants::MILLISECS_PER_BLOCK, - traits::{DisputeApi, Swaps, ZeitgeistAssetManager}, + traits::{DisputeApi, DisputeResolutionApi, Swaps, ZeitgeistAssetManager}, types::{ Asset, Deadlines, Market, MarketCreation, MarketDispute, MarketDisputeMechanism, MarketPeriod, MarketStatus, MarketType, MultiHash, OutcomeReport, Report, @@ -2545,4 +2545,21 @@ mod pallet { items.swap_remove(pos); } } + + impl DisputeResolutionApi for Pallet + where + T: Config, + { + type AccountId = T::AccountId; + type BlockNumber = T::BlockNumber; + type MarketId = MarketIdOf; + type Moment = MomentOf; + + fn resolve( + market_id: &Self::MarketId, + market: &Market, + ) -> Result { + Self::on_resolution(market_id, market) + } + } } diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 49714c28f..57e7df1c4 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -211,6 +211,7 @@ impl pallet_timestamp::Config for Runtime { impl zrml_authorized::Config for Runtime { type Event = Event; + type DisputeResolution = prediction_markets::Pallet; type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = zrml_authorized::weights::WeightInfo; From 05d645a08a1ad6e2b94f06a6ad6a864377ec0c1a Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 31 Oct 2022 12:46:12 +0100 Subject: [PATCH 2/3] move MarketIdsPerDisputeBlock to simple-disputes --- runtime/common/src/lib.rs | 1 + zrml/authorized/src/mock.rs | 7 +- zrml/prediction-markets/src/lib.rs | 60 +----------- zrml/prediction-markets/src/mock.rs | 1 + zrml/simple-disputes/src/lib.rs | 145 ++++++++++++++++++++++++++-- zrml/simple-disputes/src/mock.rs | 23 ++++- 6 files changed, 167 insertions(+), 70 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 62f7ddec8..70632136e 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -865,6 +865,7 @@ macro_rules! impl_config_traits { impl zrml_authorized::Config for Runtime { type Event = Event; + type DisputeResolution = zrml_prediction_markets::Pallet; type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = zrml_authorized::weights::WeightInfo; diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 770ba3f5e..1886c5d39 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -18,8 +18,7 @@ #![cfg(test)] use crate::{self as zrml_authorized}; -use frame_support::{construct_runtime, traits::Everything}; -use frame_support::pallet_prelude::DispatchError; +use frame_support::{construct_runtime, pallet_prelude::DispatchError, traits::Everything}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, @@ -28,8 +27,8 @@ use zeitgeist_primitives::{ constants::mock::{AuthorizedPalletId, BlockHashCount, MaxReserves, MinimumPeriod, BASE}, traits::DisputeResolutionApi, types::{ - AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, MarketId, Moment, - UncheckedExtrinsicTest, Market, + AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, + UncheckedExtrinsicTest, }, }; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 1372cef59..95c3dcfdd 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -421,18 +421,12 @@ mod pallet { T::SimpleDisputes::on_dispute(&disputes, &market_id, &market)? } } - Self::remove_last_dispute_from_market_ids_per_dispute_block(&disputes, &market_id)?; + Self::set_market_as_disputed(&market, &market_id)?; let market_dispute = MarketDispute { at: curr_block_num, by: who, outcome }; >::try_mutate(market_id, |disputes| { disputes.try_push(market_dispute.clone()).map_err(|_| >::StorageOverflow) })?; - // each dispute resets dispute_duration - let dispute_duration_ends_at_block = - curr_block_num.saturating_add(market.deadlines.dispute_duration); - >::try_mutate(dispute_duration_ends_at_block, |ids| { - ids.try_push(market_id).map_err(|_| >::StorageOverflow) - })?; Self::deposit_event(Event::MarketDisputed( market_id, MarketStatus::Disputed, @@ -1629,17 +1623,6 @@ mod pallet { #[pallet::storage] pub type LastTimeFrame = StorageValue<_, TimeFrame>; - /// A mapping of market identifiers to the block they were disputed at. - /// A market only ends up here if it was disputed. - #[pallet::storage] - pub type MarketIdsPerDisputeBlock = StorageMap< - _, - Twox64Concat, - T::BlockNumber, - BoundedVec, CacheSize>, - ValueQuery, - >; - /// A mapping of market identifiers to the block that they were reported on. #[pallet::storage] pub type MarketIdsPerReportBlock = StorageMap< @@ -1764,23 +1747,10 @@ mod pallet { }, ) } - MarketStatus::Disputed => { - let disputes = Disputes::::get(market_id); - let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; - let dispute_duration_ends_at_block = - last_dispute.at.saturating_add(market.deadlines.dispute_duration); - MarketIdsPerDisputeBlock::::mutate( - dispute_duration_ends_at_block, - |ids| -> (u32, u32) { - let ids_len = ids.len() as u32; - remove_item::, _>(ids, market_id); - (ids_len, disputes.len() as u32) - }, - ) - } _ => (0u32, 0u32), }; + // TODO fix benchmark after removal Ok((ids_len, disputes_len)) } @@ -2340,21 +2310,6 @@ mod pallet { weight_basis.saturating_add(total_weight) } - fn remove_last_dispute_from_market_ids_per_dispute_block( - disputes: &[MarketDispute], - market_id: &MarketIdOf, - ) -> DispatchResult { - if let Some(last_dispute) = disputes.last() { - let market = T::MarketCommons::market(market_id)?; - let dispute_duration_ends_at_block = - last_dispute.at.saturating_add(market.deadlines.dispute_duration); - MarketIdsPerDisputeBlock::::mutate(dispute_duration_ends_at_block, |ids| { - remove_item::, _>(ids, market_id); - }); - } - Ok(()) - } - /// The reserve ID of the prediction-markets pallet. #[inline] pub fn reserve_id() -> [u8; 8] { @@ -2428,17 +2383,10 @@ mod pallet { } MarketIdsPerReportBlock::::remove(now); - // Resolve any disputed markets. - let market_ids_per_dispute_block = MarketIdsPerDisputeBlock::::get(now); - for id in market_ids_per_dispute_block.iter() { - let market = T::MarketCommons::market(id)?; - cb(id, &market)?; - } - MarketIdsPerDisputeBlock::::remove(now); - + // TODO fix benchmark after removal Ok(T::WeightInfo::market_resolution_manager( market_ids_per_report_block.len() as u32, - market_ids_per_dispute_block.len() as u32, + 0u32, )) } diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 57e7df1c4..29f032cab 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -259,6 +259,7 @@ impl zrml_rikiddo::Config for Runtime { impl zrml_simple_disputes::Config for Runtime { type Event = Event; + type DisputeResolution = prediction_markets::Pallet; type MarketCommons = MarketCommons; type PalletId = SimpleDisputesPalletId; } diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index 41fd005b1..443f92c3a 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -30,15 +30,21 @@ pub use simple_disputes_pallet_api::SimpleDisputesPalletApi; #[frame_support::pallet] mod pallet { use crate::SimpleDisputesPalletApi; - use core::marker::PhantomData; + use core::{cmp, marker::PhantomData}; use frame_support::{ dispatch::DispatchResult, + log, + pallet_prelude::{ConstU32, StorageMap, ValueQuery, Weight}, + storage::with_transaction, traits::{Currency, Get, Hooks, IsType}, - PalletId, + BoundedVec, PalletId, Twox64Concat, + }; + use sp_runtime::{ + traits::{Saturating, Zero}, + DispatchError, TransactionOutcome, }; - use sp_runtime::DispatchError; use zeitgeist_primitives::{ - traits::DisputeApi, + traits::{DisputeApi, DisputeResolutionApi}, types::{Market, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::MarketCommonsPalletApi; @@ -50,6 +56,7 @@ mod pallet { pub(crate) type MarketIdOf = <::MarketCommons as MarketCommonsPalletApi>::MarketId; pub(crate) type MomentOf = <::MarketCommons as MarketCommonsPalletApi>::Moment; + pub type CacheSize = ConstU32<64>; #[pallet::call] impl Pallet {} @@ -59,6 +66,13 @@ mod pallet { /// Event type Event: From> + IsType<::Event>; + type DisputeResolution: DisputeResolutionApi< + AccountId = Self::AccountId, + BlockNumber = Self::BlockNumber, + MarketId = MarketIdOf, + Moment = MomentOf, + >; + /// The identifier of individual markets. type MarketCommons: MarketCommonsPalletApi< AccountId = Self::AccountId, @@ -77,15 +91,49 @@ mod pallet { InvalidMarketStatus, /// On dispute or resolution, someone tried to pass a non-simple-disputes market type MarketDoesNotHaveSimpleDisputesMechanism, + StorageOverflow, } #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] pub enum Event where - T: Config, {} + T: Config, + { + /// Custom addition block initialization logic wasn't successful + BadOnInitialize, + } #[pallet::hooks] - impl Hooks for Pallet {} + impl Hooks for Pallet { + fn on_initialize(now: T::BlockNumber) -> Weight { + let mut total_weight: Weight = 0u64; + + let _ = with_transaction(|| { + let resolve = Self::resolution_manager(now, |market_id, market| { + let weight = T::DisputeResolution::resolve(market_id, &market)?; + total_weight = total_weight.saturating_add(weight); + Ok(()) + }); + + match resolve { + Err(err) => { + Self::deposit_event(Event::BadOnInitialize); + log::error!( + "Simple Disputes: Block {:?} was not initialized. Error: {:?}", + now, + err + ); + TransactionOutcome::Rollback(err.into()) + } + Ok(_) => TransactionOutcome::Commit(Ok(())), + } + }); + + // TODO fix weight calculation + total_weight + } + } impl DisputeApi for Pallet where @@ -99,13 +147,21 @@ mod pallet { type Origin = T::Origin; fn on_dispute( - _: &[MarketDispute], - _: &Self::MarketId, + disputes: &[MarketDispute], + market_id: &Self::MarketId, market: &Market>, ) -> DispatchResult { if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); } + Self::remove_last_dispute_from_market_ids_per_dispute_block(&disputes, &market_id)?; + let curr_block_num = >::block_number(); + // each dispute resets dispute_duration + let dispute_duration_ends_at_block = + curr_block_num.saturating_add(market.deadlines.dispute_duration); + >::try_mutate(dispute_duration_ends_at_block, |ids| { + ids.try_push(*market_id).map_err(|_| >::StorageOverflow) + })?; Ok(()) } @@ -130,6 +186,79 @@ mod pallet { impl SimpleDisputesPalletApi for Pallet where T: Config {} + impl Pallet + where + T: Config, + { + pub(crate) fn resolution_manager( + now: T::BlockNumber, + mut cb: F, + ) -> Result + where + F: FnMut( + &MarketIdOf, + &Market>, + ) -> DispatchResult, + { + // Resolve any disputed markets. + let market_ids_per_dispute_block = MarketIdsPerDisputeBlock::::get(now); + for id in market_ids_per_dispute_block.iter() { + if let Ok(market) = T::MarketCommons::market(id) { + // the resolved check is required, because of admin_move_market_to_resolved + // only call `on_resolution` when admin_move_market_to_resolved not executed + if market.status != MarketStatus::Resolved { + cb(id, &market)?; + } + } else { + // this is useful for admin_destroy_market + // because a market could be destroyed before, + // so only remove the id from MarketIdsPerDisputeBlock + log::info!( + "Simple Disputes: Market {:?} not found. This can happen when the market \ + was destroyed.", + id + ); + } + } + MarketIdsPerDisputeBlock::::remove(now); + + // TODO: fix weight calculation + Ok(Weight::zero()) + } + + fn remove_last_dispute_from_market_ids_per_dispute_block( + disputes: &[MarketDispute], + market_id: &MarketIdOf, + ) -> DispatchResult { + if let Some(last_dispute) = disputes.last() { + let market = T::MarketCommons::market(market_id)?; + let dispute_duration_ends_at_block = + last_dispute.at.saturating_add(market.deadlines.dispute_duration); + MarketIdsPerDisputeBlock::::mutate(dispute_duration_ends_at_block, |ids| { + remove_item::, _>(ids, market_id); + }); + } + Ok(()) + } + } + #[pallet::pallet] pub struct Pallet(PhantomData); + + /// A mapping of market identifiers to the block they were disputed at. + /// A market only ends up here if it was disputed. + #[pallet::storage] + pub type MarketIdsPerDisputeBlock = StorageMap< + _, + Twox64Concat, + T::BlockNumber, + BoundedVec, CacheSize>, + ValueQuery, + >; + + fn remove_item(items: &mut BoundedVec, item: &I) { + if let Some(pos) = items.iter().position(|i| i == item) { + items.swap_remove(pos); + } + } } diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index 3553c5aa9..2a8013e7c 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -18,15 +18,16 @@ #![cfg(test)] use crate::{self as zrml_simple_disputes}; -use frame_support::{construct_runtime, traits::Everything}; +use frame_support::{construct_runtime, pallet_prelude::DispatchError, traits::Everything}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; use zeitgeist_primitives::{ constants::mock::{BlockHashCount, MaxReserves, MinimumPeriod, SimpleDisputesPalletId}, + traits::DisputeResolutionApi, types::{ - AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, MarketId, Moment, + AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, UncheckedExtrinsicTest, }, }; @@ -46,8 +47,26 @@ construct_runtime!( } ); +// NoopResolution implements DisputeResolutionApi with no-ops. +pub struct NoopResolution; + +impl DisputeResolutionApi for NoopResolution { + type AccountId = AccountIdTest; + type BlockNumber = BlockNumber; + type MarketId = MarketId; + type Moment = Moment; + + fn resolve( + _market_id: &Self::MarketId, + _market: &Market, + ) -> Result { + Ok(0) + } +} + impl crate::Config for Runtime { type Event = (); + type DisputeResolution = NoopResolution; type MarketCommons = MarketCommons; type PalletId = SimpleDisputesPalletId; } From 439c348d1b2b739e75474069d394663a2f9ac86a Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 31 Oct 2022 13:10:48 +0100 Subject: [PATCH 3/3] modify pm benchmarks --- zrml/prediction-markets/src/benchmarks.rs | 58 ----------------------- zrml/prediction-markets/src/lib.rs | 45 +++++++++--------- zrml/prediction-markets/src/weights.rs | 19 +++----- zrml/simple-disputes/src/lib.rs | 1 + 4 files changed, 29 insertions(+), 94 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index f57f8de22..08454cee8 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -224,8 +224,6 @@ benchmarks! { admin_destroy_disputed_market{ // The number of assets. let a in (T::MinCategories::get().into())..T::MaxCategories::get().into(); - // The number of disputes. - let d in 1..T::MaxDisputes::get(); // The number of market ids per open time frame. let o in 0..63; // The number of market ids per close time frame. @@ -269,16 +267,6 @@ benchmarks! { ).unwrap(); } - let disputes = Disputes::::get(market_id); - let last_dispute = disputes.last().unwrap(); - let dispute_at = last_dispute.at; - for i in 0..r { - MarketIdsPerDisputeBlock::::try_mutate( - dispute_at, - |ids| ids.try_push(i.into()), - ).unwrap(); - } - let destroy_origin = T::DestroyOrigin::successful_origin(); let call = Call::::admin_destroy_market { market_id }; }: { @@ -443,7 +431,6 @@ benchmarks! { admin_move_market_to_resolved_scalar_disputed { let r in 0..63; - let d in 1..T::MaxDisputes::get(); let (_, market_id) = create_close_and_report_market::( MarketCreation::Permissionless, @@ -464,28 +451,6 @@ benchmarks! { panic!("Must create scalar market"); } - for i in 1..=d { - let outcome = OutcomeReport::Scalar(i.saturated_into()); - let disputor = account("disputor", i, 0); - let dispute_bond = crate::pallet::default_dispute_bond::(i as usize); - T::AssetManager::deposit( - Asset::Ztg, - &disputor, - dispute_bond, - )?; - Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - } - let disputes = Disputes::::get(market_id); - - let last_dispute = disputes.last().unwrap(); - let dispute_at = last_dispute.at; - for i in 0..r { - MarketIdsPerDisputeBlock::::try_mutate( - dispute_at, - |ids| ids.try_push(i.into()), - ).unwrap(); - } - let close_origin = T::CloseOrigin::successful_origin(); let call = Call::::admin_move_market_to_resolved { market_id }; }: { @@ -500,7 +465,6 @@ benchmarks! { admin_move_market_to_resolved_categorical_disputed { let r in 0..63; - let d in 1..T::MaxDisputes::get(); let categories = T::MaxCategories::get(); let (caller, market_id) = @@ -515,28 +479,6 @@ benchmarks! { Ok(()) })?; - for i in 1..=d { - let outcome = OutcomeReport::Categorical((i % 2).saturated_into::()); - let disputor = account("disputor", i, 0); - let dispute_bond = crate::pallet::default_dispute_bond::(i as usize); - T::AssetManager::deposit( - Asset::Ztg, - &disputor, - dispute_bond, - )?; - Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - } - let disputes = Disputes::::get(market_id); - - let last_dispute = disputes.last().unwrap(); - let dispute_at = last_dispute.at; - for i in 0..r { - MarketIdsPerDisputeBlock::::try_mutate( - dispute_at, - |ids| ids.try_push(i.into()), - ).unwrap(); - } - let close_origin = T::CloseOrigin::successful_origin(); let call = Call::::admin_move_market_to_resolved { market_id }; }: { diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 95c3dcfdd..01c0998ce 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -98,7 +98,6 @@ mod pallet { ) .max(T::WeightInfo::admin_destroy_disputed_market( T::MaxCategories::get().into(), - T::MaxDisputes::get(), CacheSize::get(), CacheSize::get(), CacheSize::get(), @@ -158,7 +157,7 @@ mod pallet { let open_ids_len = Self::clear_auto_open(&market_id)?; let close_ids_len = Self::clear_auto_close(&market_id)?; - let (ids_len, disputes_len) = Self::clear_auto_resolve(&market_id)?; + let ids_len = Self::clear_auto_resolve(&market_id)?; T::MarketCommons::remove_market(&market_id)?; Disputes::::remove(market_id); @@ -181,7 +180,6 @@ mod pallet { Ok(( Some(T::WeightInfo::admin_destroy_disputed_market( category_count, - disputes_len, open_ids_len, close_ids_len, ids_len, @@ -245,13 +243,11 @@ mod pallet { T::WeightInfo::admin_move_market_to_resolved_categorical_reported(CacheSize::get()) ).max( T::WeightInfo::admin_move_market_to_resolved_scalar_disputed( - CacheSize::get(), - T::MaxDisputes::get() + CacheSize::get() ) ).max( T::WeightInfo::admin_move_market_to_resolved_categorical_disputed( - CacheSize::get(), - T::MaxDisputes::get() + CacheSize::get() ) ), Pays::No, @@ -268,7 +264,7 @@ mod pallet { market.status == MarketStatus::Reported || market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus, ); - let (ids_len, disputes_len) = Self::clear_auto_resolve(&market_id)?; + let ids_len = Self::clear_auto_resolve(&market_id)?; let market = T::MarketCommons::market(&market_id)?; let _ = Self::on_resolution(&market_id, &market)?; let weight = match market.market_type { @@ -277,10 +273,7 @@ mod pallet { T::WeightInfo::admin_move_market_to_resolved_scalar_reported(ids_len) } MarketStatus::Disputed => { - T::WeightInfo::admin_move_market_to_resolved_scalar_disputed( - ids_len, - disputes_len, - ) + T::WeightInfo::admin_move_market_to_resolved_scalar_disputed(ids_len) } _ => return Err(Error::::InvalidMarketStatus.into()), }, @@ -289,10 +282,7 @@ mod pallet { T::WeightInfo::admin_move_market_to_resolved_categorical_reported(ids_len) } MarketStatus::Disputed => { - T::WeightInfo::admin_move_market_to_resolved_categorical_disputed( - ids_len, - disputes_len, - ) + T::WeightInfo::admin_move_market_to_resolved_categorical_disputed(ids_len) } _ => return Err(Error::::InvalidMarketStatus.into()), }, @@ -1633,6 +1623,16 @@ mod pallet { ValueQuery, >; + // TODO(#851): remove storage element after migration to simple disputes was successful + #[pallet::storage] + pub type MarketIdsPerDisputeBlock = StorageMap< + _, + Twox64Concat, + T::BlockNumber, + BoundedVec, CacheSize>, + ValueQuery, + >; + /// Contains a list of all markets that are currently collecting subsidy and the deadline. // All the values are "cached" here. Results in data duplication, but speeds up the iteration // over every market significantly (otherwise 25µs per relevant market per block). @@ -1731,27 +1731,26 @@ mod pallet { } /// Clears this market from being stored for automatic resolution. - fn clear_auto_resolve(market_id: &MarketIdOf) -> Result<(u32, u32), DispatchError> { + fn clear_auto_resolve(market_id: &MarketIdOf) -> Result { let market = T::MarketCommons::market(market_id)?; - let (ids_len, disputes_len) = match market.status { + let ids_len = match market.status { MarketStatus::Reported => { let report = market.report.ok_or(Error::::MarketIsNotReported)?; let dispute_duration_ends_at_block = report.at.saturating_add(market.deadlines.dispute_duration); MarketIdsPerReportBlock::::mutate( dispute_duration_ends_at_block, - |ids| -> (u32, u32) { + |ids| -> u32 { let ids_len = ids.len() as u32; remove_item::, _>(ids, market_id); - (ids_len, 0u32) + ids_len }, ) } - _ => (0u32, 0u32), + _ => 0u32, }; - // TODO fix benchmark after removal - Ok((ids_len, disputes_len)) + Ok(ids_len) } pub(crate) fn do_buy_complete_set( diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index 2571f8852..cbb53a9e5 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -45,13 +45,13 @@ use frame_support::{traits::Get, weights::Weight}; /// Trait containing the required functions for weight retrival within /// zrml_prediction_markets (automatically generated) pub trait WeightInfoZeitgeist { - fn admin_destroy_disputed_market(a: u32, d: u32, o: u32, c: u32, r: u32) -> Weight; + fn admin_destroy_disputed_market(a: u32, o: u32, c: u32, r: u32) -> Weight; fn admin_destroy_reported_market(a: u32, o: u32, c: u32, r: u32) -> Weight; fn admin_move_market_to_closed(o: u32, c: u32) -> Weight; fn admin_move_market_to_resolved_scalar_reported(r: u32) -> Weight; fn admin_move_market_to_resolved_categorical_reported(r: u32) -> Weight; - fn admin_move_market_to_resolved_scalar_disputed(r: u32, d: u32) -> Weight; - fn admin_move_market_to_resolved_categorical_disputed(r: u32, d: u32) -> Weight; + fn admin_move_market_to_resolved_scalar_disputed(r: u32) -> Weight; + fn admin_move_market_to_resolved_categorical_disputed(r: u32) -> Weight; fn approve_market() -> Weight; fn buy_complete_set(a: u32) -> Weight; fn create_market(m: u32) -> Weight; @@ -88,7 +88,7 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Tokens TotalIssuance (r:2 w:2) // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) - fn admin_destroy_disputed_market(a: u32, _d: u32, o: u32, c: u32, r: u32) -> Weight { + fn admin_destroy_disputed_market(a: u32, o: u32, c: u32, r: u32) -> Weight { (0 as Weight) // Standard Error: 54_000 .saturating_add((32_618_000 as Weight).saturating_mul(a as Weight)) @@ -172,14 +172,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) // Storage: System Account (r:7 w:7) // Storage: MarketCommons MarketPool (r:1 w:0) - fn admin_move_market_to_resolved_scalar_disputed(_r: u32, d: u32) -> Weight { + fn admin_move_market_to_resolved_scalar_disputed(_r: u32) -> Weight { (119_367_000 as Weight) // Standard Error: 162_000 - .saturating_add((28_533_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(6 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(d as Weight))) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) @@ -189,16 +186,12 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: System Account (r:6 w:6) // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) - fn admin_move_market_to_resolved_categorical_disputed(r: u32, d: u32) -> Weight { + fn admin_move_market_to_resolved_categorical_disputed(r: u32) -> Weight { (166_932_000 as Weight) // Standard Error: 14_000 .saturating_add((348_000 as Weight).saturating_mul(r as Weight)) - // Standard Error: 198_000 - .saturating_add((30_863_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(7 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(d as Weight))) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index 443f92c3a..9244997cc 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -118,6 +118,7 @@ mod pallet { match resolve { Err(err) => { + // DisputeResolution::resolve failed Self::deposit_event(Event::BadOnInitialize); log::error!( "Simple Disputes: Block {:?} was not initialized. Error: {:?}",